diff options
author | Harald Welte <laforge@gnumonks.org> | 2010-07-09 20:56:56 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2010-07-09 20:56:56 +0200 |
commit | 7e7186ca00b33e9735c809ce200e310636006a22 (patch) | |
tree | 37ae4c48db5cfb2218830a7237a69ec787613f0b /sualibrary/sua/sua_datassoc.cpp | |
parent | acd8cf60130f88a4dd477dde5506faa4c142540c (diff) |
update to sualibrary-0.1.1 from 2002-03-15:
* Contains Relaying functionality using hostnames.
* Correct some bugs (multihoming....)
* Compiles and runs on Linux, FreeBSD ....
* Tested on IPv4 and IPV6 networks
* interoperable with other SUA implementations
* corresponds to sua draft v11
* requires SCTP implementation from www.sctp.de
Diffstat (limited to 'sualibrary/sua/sua_datassoc.cpp')
-rw-r--r-- | sualibrary/sua/sua_datassoc.cpp | 288 |
1 files changed, 210 insertions, 78 deletions
diff --git a/sualibrary/sua/sua_datassoc.cpp b/sualibrary/sua/sua_datassoc.cpp index c3bcc5f..dd29625 100644 --- a/sualibrary/sua/sua_datassoc.cpp +++ b/sualibrary/sua/sua_datassoc.cpp @@ -15,7 +15,7 @@ * * ***************************************************************************/ /* - * $Id: sua_datassoc.cpp,v 1.3 2002/02/15 16:19:46 p82609 Exp $ + * $Id: sua_datassoc.cpp,v 1.6 2002/03/15 12:53:53 p82609 Exp $ * * SUA implementation according to SUA draft issue 6. * @@ -70,6 +70,7 @@ * - route on IP pointcode address * - route on Global Title/Hostname * - route message to a association + * - Final destination? * - increase instance * - Dynamic association setup(initiating) */ @@ -240,6 +241,66 @@ void db_Sua_AssociationList:: read_stream_number(string stream_num){ } /***********************************************************************/ +/* db_Sua_AssociationList::resolve_host_name */ +/***********************************************************************/ +signed int db_Sua_AssociationList::resolve_host_name ( hostname_str& dest_name, + pointcode_str& dest_pc + ) +{ + struct hostent *hptr; + char **pptr; + char str[INET6_ADDRSTRLEN]; + char *dest_carr; + + /* resolving can be done via: */ + /* - local global Titel database */ + /* - resolve hostname via DNS(simplest for single hop translations) */ + dest_carr = dest_name; + + if ((hptr = gethostbyname( dest_carr )) == NULL) + { + cout << "Hostname " << dest_name << " not known in DNS.\n"; + return(-1); + } + +#ifdef DEBUG + cout << "Hostname " << dest_name << " resolved to dest IP address(es)\n"; + cout << "IP address length = "<< hptr->h_length << "\n"; +#endif + + /* initialise the length field of the structure: */ + /* length field is NOT always present in every Unix like operating system */ + dest_pc.ipvx.ch[0] = 0; + + pptr = hptr->h_addr_list; + for ( ; (*pptr != NULL) ;pptr++) + { + inet_ntop(hptr->h_addrtype, *pptr, str,sizeof(str)); +#ifdef DEBUG + cout << str << "\n"; +#endif + /* got a IP address */ + dest_pc.ipvx.sa.sa_family = hptr->h_addrtype; + if (dest_pc.ipvx.sa.sa_family == AF_INET) + inet_pton( AF_INET, + str, + &dest_pc.ipvx.sin.sin_addr + ); + else if (dest_pc.ipvx.sa.sa_family == AF_INET6) + inet_pton( AF_INET6, + str, + &dest_pc.ipvx.sin6.sin6_addr + ); + else + { + cout << "ERROR resolve_host_name: Unknown IP addresstype\n"; + return(-2); + } + } + return(0); +}; + +/***********************************************************************/ /* Sua_AssociationList::register_instance */ /***********************************************************************/ short db_Sua_AssociationList:: @@ -390,28 +451,125 @@ Find_association( unsigned int sctp_assoc_id, /***********************************************************************/ unsigned int db_Sua_AssociationList:: Find_local_sua( sccp_addr_str& local_address - ) + ) { - short i = 1, j = 0; - unsigned int Local_sua_id = 0; - bool result = FALSE; + pointcode_str dest_pc; + short i = 1, j = 0, count, addr_start, addr_stop; + unsigned int Local_sua_id = 0; + bool result = FALSE; while ((i < db_MAX_REMOTE_SUA) && !(result) && (instance[i].Source.nr_of_addrs != 0)) { j = 0; while ((j < instance[i].Source.nr_of_addrs) && !(result)) - { - result = ((instance[i].Source.addrs[j].sin.sin_addr.s_addr == local_address.pc.ipvx.sin.sin_addr.s_addr) || + { + /*result = ((instance[i].Source.addrs[j].sin.sin_addr.s_addr == local_address.pc.ipvx.sin.sin_addr.s_addr) || (instance[i].Source.addrs[j].sin6.sin6_addr.s6_addr == local_address.pc.ipvx.sin6.sin6_addr.s6_addr)); - if (result) - { - Local_sua_id = instance[i].local_sua_id; +*/ + if (local_address.address_fields_present.pc == ipvx_pc_present) + { + result = (local_address.pc.ipvx.sa.sa_family == instance[i].Source.addrs[j].sa.sa_family); + if (local_address.pc.ipvx.sa.sa_family == AF_INET) + { + addr_start = 4; + addr_stop = addr_start + 4; + } + else if (local_address.pc.ipvx.sa.sa_family == AF_INET6) + { + addr_start = 8; + addr_stop = addr_start + 16; + } + else + { + addr_start = 0; + addr_stop = 0; + result = false; + cout << "ERROR Find_local_sua: Unknown IPvx addresstype\n"; + } + /* compare the address family field */ + result = result && + (local_address.pc.ipvx.ch[1] == instance[i].Source.addrs[j].ch[1]); + + /* compare the ipv4/ipv6 address field */ + for (count = addr_start; count < addr_stop; count++) + { + result = result && + (local_address.pc.ipvx.ch[count] == instance[i].Source.addrs[j].ch[count]); + } + } + else if (local_address.address_fields_present.pc == ss7_pc_present) + { + result = (local_address.pc.ss7.ITU14.family == instance[i].Source.pc.ITU14.family); + if (((local_address.pc.ss7.ITU14.family == ITU14bit) || + (local_address.pc.ss7.ITU14.family == ITU24bit)) || + (local_address.pc.ss7.ITU14.family == ANSI24bit)) + { + /* compare the ITU 14/24bit or ANSI 24bit PC address field */ + result = result && + (local_address.pc.ss7.ITU14.pc == instance[i].Source.pc.ITU14.pc); + } + else + { + result = false; + cout << "ERROR Find_local_sua: Unknown SS7 pointcode addresstype\n"; + } + } + else if (local_address.address_fields_present.name_gt == hostname_present) + { + count = 0; + result = resolve_host_name ( local_address.name.HostName, + dest_pc + ); + + result = (dest_pc.ipvx.sa.sa_family == instance[i].Source.addrs[j].sa.sa_family); + + if (dest_pc.ipvx.sa.sa_family == AF_INET) + { + addr_start = 4; + addr_stop = addr_start + 4; + } + else if (dest_pc.ipvx.sa.sa_family == AF_INET6) + { + addr_start = 8; + addr_stop = addr_start + 16; + } + else + { + addr_start = 0; + addr_stop = 0; + result = false; + cout << "ERROR Find_local_sua: Unknown IPvx addresstype\n"; + } + /* compare the address family field : already done */ + /* compare the ipv4/ipv6 address field */ + short k=0; + for (count = addr_start; count < addr_stop; count++) + { + result = result && + (dest_pc.ipvx.ch[count] == instance[i].Source.addrs[j].ch[count]); + k++; + } + + } + else if (local_address.address_fields_present.name_gt == GT_present) + { + cout << "ERROR Find_local_sua: GT code not implemented yet\n"; + } + else + { + cout << "ERROR Find_local_sua: Unknown SUA addresstype\n"; + result = false; + } + + if (result) + { + Local_sua_id = instance[i].local_sua_id; #ifdef DEBUG - cout << "local_sua_id = " << Local_sua_id << " , instance "<< i << "\n"; + cout << "Find_local_sua: local_sua_id = " << Local_sua_id << " , instance "<< i << "\n"; #endif - } - j++; - } + } + j++; + } i++; } @@ -431,6 +589,7 @@ passive_associate( unsigned int assoc_id, ){ SCTP_AssociationStatus status; + SCTP_Path_Status path_x_status; int result; short k; int bla; @@ -471,13 +630,21 @@ passive_associate( unsigned int assoc_id, event_log("sua_database.c",logstring); - result = sctp_getAssocStatus(instance[assoc_instance_idx].SCTP_assoc_id, &status); + result = sctp_getAssocStatus( instance[assoc_instance_idx].SCTP_assoc_id, + &status + ); /* conversion and fill in the destination address */ instance[assoc_instance_idx].Dest.nr_of_addrs = nr_of_dest_addr; - instance[assoc_instance_idx].Dest.address_string[0] = status.primaryDestinationAddress; - instance[assoc_instance_idx].Dest.addrs[0].sin.sin_port = status.destPort; - + for(k=0; k < instance[assoc_instance_idx].Dest.nr_of_addrs ; k++) + { + result = sctp_getPathStatus( instance[assoc_instance_idx].SCTP_assoc_id, + k, + &path_x_status + ); + instance[assoc_instance_idx].Dest.address_string[k] = path_x_status.destinationAddress; + instance[assoc_instance_idx].Dest.addrs[k].sin.sin_port = status.destPort; + } /* try to figure out ipv4 or v6 address family: get it from the source address */ k = 0; instance[assoc_instance_idx].Dest.addrs[0].sa.sa_family = AF_LOCAL; @@ -692,72 +859,36 @@ route_on_SS7pc ( SS7union& dest_pc, /***********************************************************************/ signed int db_Sua_AssociationList:: route_on_GTname ( hostname_str& dest_name, - hostname_str& org_name, - int& sua_assoc_id, - pointcode_str& dest_pc, - pointcode_str& org_pc - ) + hostname_str& org_name, + int& sua_assoc_id, + pointcode_str& dest_pc, + pointcode_str& org_pc + ) { - struct hostent *hptr; - char **pptr; - unsigned int sctp_assoc_id = 0; - char str[INET6_ADDRSTRLEN]; - char *dest_carr; + int result = 0; + unsigned int sctp_assoc_id = 0; sua_assoc_id = 0; /* resolving can be done via: */ /* - local global Titel database */ /* - resolve hostname via DNS(simplest for single hop translations) */ - dest_carr = dest_name; - - if ((hptr = gethostbyname( dest_carr )) == NULL) - { - cout << "Hostname " << dest_name << " not known in DNS.\n"; - return(-1); - } - -#ifdef DEBUG - cout << "Hostname " << dest_name << " resolved to dest IP address(es)\n"; - cout << "IP address length = "<< hptr->h_length << "\n"; -#endif - - /* initialise the length field of the structure: */ - /* length field is NOT always present in every Unix like operating system */ - dest_pc.ipvx.ch[0] = 0; - org_pc.ipvx.ch[0] = 0; - - pptr = hptr->h_addr_list; - for ( ; (*pptr != NULL) ;pptr++) - { - inet_ntop(hptr->h_addrtype, *pptr, str,sizeof(str)); -#ifdef DEBUG - cout << str << "\n"; -#endif - /* got IP address, look if association already exists */ - dest_pc.ipvx.sa.sa_family = hptr->h_addrtype; - if (dest_pc.ipvx.sa.sa_family == AF_INET) - inet_pton( AF_INET, - str, - &dest_pc.ipvx.sin.sin_addr - ); - else if (dest_pc.ipvx.sa.sa_family == AF_INET6) - inet_pton( AF_INET6, - str, - &dest_pc.ipvx.sin6.sin6_addr - ); - else - cout << "ERROR route_on_GTname: Unknown IP addresstype\n"; + result = resolve_host_name ( dest_name, + dest_pc + ); + + /*result = resolve_host_name ( org_name, + org_pc + ); */ - sctp_assoc_id = route_on_IPpc( dest_pc.ipvx, - org_pc.ipvx, - sua_assoc_id - ); + sctp_assoc_id = route_on_IPpc( dest_pc.ipvx, + org_pc.ipvx, + sua_assoc_id + ); - if (sctp_assoc_id != 0 ) - return(sctp_assoc_id); + if (sctp_assoc_id != 0 ) + return(sctp_assoc_id); - } return(sctp_assoc_id); }; @@ -766,12 +897,14 @@ route_on_GTname ( hostname_str& dest_name, /* Sua_AssociationList::route_msg */ /***********************************************************************/ signed int db_Sua_AssociationList:: -route_msg( sccp_addr_str& cld, - sccp_addr_str& clg +route_msg( sccp_addr_str& cld, + sccp_addr_str& clg, + int& sua_assoc_id ){ unsigned int sctp_assoc_id = 0; - int sua_assoc_id = 0; + + sua_assoc_id = 0; #ifdef DEBUG cout << "num_of_instance : "<< num_of_instance << "\n"; @@ -837,7 +970,6 @@ route_msg( sccp_addr_str& cld, return(sctp_assoc_id); }; - /***********************************************************************/ /* Sua_AssociationList::increase_instance */ /***********************************************************************/ |