/*************************************************************************** sua_datassoc.cpp - description ------------------- begin : Tue Jan 8 2002 copyright : (C) 2002 by Lode Coene email : lode.coene@siemens.atea.be ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* * $Id: sua_datassoc.cpp,v 1.6 2002/03/15 12:53:53 p82609 Exp $ * * SUA implementation according to SUA draft issue 6. * * Author(s): Lode Coene * * * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium. * * Realized in co-operation between Siemens Atea and * Siemens AG, Munich, Germany. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Contact: gery.verwimp@siemens.atea.be * lode.coene@siemens.atea.be * * The alternative comment * inspiration : Vera * "You ain't seen nothing yet" * "said Garfield the Ripper while putting on his binbag" * * Purpose: This code-file defines the SUA database access functions for * SUA Association Object: * - initialise association object * - shutdown association * - Dynamic association * SUA Association List: * - initialise association list * - read source address * - read Destination address * - read source port * - read destination port * - read stream number * - register instance * - associate instance(initiating) * - Find a association * - Find a local SUA instance * - Passive association instantiation(terminating) * - shutdown a association * - route on IP pointcode address * - route on Global Title/Hostname * - route message to a association * - Final destination? * - increase instance * - Dynamic association setup(initiating) */ #include "sctp.h" #include "sua_debug.h" #include "sua_database.h" #include "sua_asp_mgnt.h" #include "sua_logging.h" #include #include #include #include #include #include "unistd.h" using namespace std; struct ulp_data_str { int maximumStreamID; unsigned int chunkCount; }; static ulp_data_str ULPData[db_MAX_MULTIHOME_ADDR]; /***********************************************************************/ /* functions of the object class SUA Association Object */ /***********************************************************************/ /***********************************************************************/ /* Sua_AssociationObject::initalize */ /***********************************************************************/ void db_Sua_AssociationObject::initialize(){ short i; Source.nr_of_addrs = 0; Dest.nr_of_addrs = 0; netw = nc_empty; nr_of_inbound_streams = 0; nr_of_outbound_streams = 0; asp.status = asp_down; for (i=0; i < db_MAX_MULTIHOME_ADDR; i++) { Source.addrs[i].sa.sa_family = AF_INET; Dest.addrs[i].sa.sa_family = AF_INET; } Source.pc.ITU24.pc = 0; Dest.pc.ITU24.pc = 0; for (i=0; i < db_MAX_1ASP_IN_AS; i++) asp.linked_to_AS[i] = 0; } /***********************************************************************/ /* Sua_RemoteObject::shutdown_instance */ /***********************************************************************/ short db_Sua_AssociationObject:: shutdown(){ int result; result = sctp_shutdown( SCTP_assoc_id ); return(result); }; /***********************************************************************/ /* Sua_AssociationL::Dynamic_Associate */ /***********************************************************************/ unsigned int Dynamic_Associate( sccp_addr_str& cld, sccp_addr_str& clg ) { return(0); } /***********************************************************************/ /* functions of the object class SUA AssociationList */ /***********************************************************************/ /***********************************************************************/ /* Sua_AssociationList::initalize */ /***********************************************************************/ void db_Sua_AssociationList::initialize(){ short i; num_of_instance = 0; for (i=0; i < db_MAX_REMOTE_SUA; i++) { instance[i].initialize(); } } /***********************************************************************/ /* Sua_AssociationList::read_Source_addr */ /***********************************************************************/ void db_Sua_AssociationList:: read_Source_addr(string address){ instance[num_of_instance].Source.read_addr_param(address); } /***********************************************************************/ /* Sua_AssociationList::read_Dest_addr */ /***********************************************************************/ void db_Sua_AssociationList:: read_Dest_pointcode(string address){ instance[num_of_instance].Dest.read_pointcode_param(address); } /***********************************************************************/ /* Sua_AssociationList::read_Source_pointcode */ /***********************************************************************/ void db_Sua_AssociationList:: read_Source_pointcode(string address){ instance[num_of_instance].Source.read_pointcode_param(address); } /***********************************************************************/ /* Sua_AssociationList::read_Dest_addr */ /***********************************************************************/ void db_Sua_AssociationList:: read_Dest_addr(string address){ instance[num_of_instance].Dest.read_addr_param(address); } /***********************************************************************/ /* Sua_AssociationList::read_Source_port */ /***********************************************************************/ void db_Sua_AssociationList:: read_Source_port(string port){ instance[num_of_instance].Source.read_port_num(port); } /***********************************************************************/ /* Sua_AssociationList::read_Dest_port */ /***********************************************************************/ void db_Sua_AssociationList:: read_Dest_port(string port){ instance[num_of_instance].Dest.read_port_num(port); } /***********************************************************************/ /* Sua_AssociationList::read_stream_number */ /***********************************************************************/ void db_Sua_AssociationList:: read_stream_number(string stream_num){ int i=0; char *tokstr = new char[stream_num.length()+1]; int sua_stream_nr; stream_num.copy(tokstr,stream_num.length()); tokstr[stream_num.length()] = '\0'; sua_stream_nr = atoi(tokstr); for(i = 1; i <= num_of_instance ; i++) { instance[i].nr_of_inbound_streams = sua_stream_nr; instance[i].nr_of_outbound_streams = sua_stream_nr; } } /***********************************************************************/ /* 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:: register_instance( SCTP_ulp_Callbacks APLCallbackFunctions, Sua_ULP_CallBacks SUACallbackFunctions, db_Sua_LocalList& local_sua ){ int i; unsigned int local_sua_idx; short sua_portnumber = SUA_PORT; for(i=1; i <= num_of_instance; i++) { local_sua_idx = instance[i].local_sua_id; #ifdef DEBUG cout << "Register SUA(& SCTP) local instance nr " << local_sua_idx << " with association " << i << " ,SSN = "<< local_sua.instance[local_sua_idx].ssn.ssn <<" \n"; #endif char logstring[100]; sprintf(logstring, "Register SUA(& SCTP) local instance nr %d with association %d, SSN = %d", local_sua_idx,i,local_sua.instance[local_sua_idx].ssn.ssn ); event_log("sua_database.c",logstring); local_sua.register_instance( instance[i].local_sua_id, SUACallbackFunctions, i ); if (instance[i].Source.addrs[0].sa.sa_family == AF_INET) sua_portnumber = instance[i].Source.addrs[0].sin.sin_port; else if (instance[i].Source.addrs[0].sa.sa_family == AF_INET6) sua_portnumber = instance[i].Source.addrs[0].sin6.sin6_port; instance[i].SCTP_instance_name = sctp_registerInstance( sua_portnumber, instance[i].nr_of_inbound_streams, instance[i].nr_of_outbound_streams, instance[i].Source.nr_of_addrs, instance[i].Source.address_string, APLCallbackFunctions ); #ifdef DEBUG cout << "SCTP instance name = " << instance[i].SCTP_instance_name << " \n"; #endif sprintf(logstring, "Local SCTP instance nr %d name = %d", i, instance[i].SCTP_instance_name); event_log("sua_database.c",logstring); } return(0); }; /***********************************************************************/ /* Sua_AssociationList::associate_instance */ /***********************************************************************/ short db_Sua_AssociationList:: associate_instance( db_Sua_LocalList& local_sua, db_Sua_RemoteList& remote_sua ){ int i; SCTP_InstanceParameters SCTP_assoc_parms; SCTP_InstanceParameters *SCTP_assoc_status = &SCTP_assoc_parms; short sua_portnumber = SUA_PORT; int res=0; // get default values of association res = sctp_getAssocDefaults( instance[1].SCTP_instance_name, SCTP_assoc_status ); // fill in the TOS field needed for DIFFSERV SCTP_assoc_status->ipTos = 'a'; // set the new value for all associations res = sctp_setAssocDefaults( instance[1].SCTP_assoc_id, SCTP_assoc_status ); for(i=1; i <= num_of_instance; i++) { if (instance[i].Dest.nr_of_addrs != 0) { #ifdef DEBUG cout << "Associate remote SUA(& SCTP) instance nr " << i << " with local SUA(& SCTP) instance nr " << instance[i].local_sua_id <<" \n"; #endif char logstring[100]; sprintf(logstring, "Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", i, instance[i].local_sua_id ); event_log("sua_database.c",logstring); if (instance[i].Dest.addrs[0].sa.sa_family == AF_INET) sua_portnumber = instance[i].Dest.addrs[0].sin.sin_port; else if (instance[i].Dest.addrs[0].sa.sa_family == AF_INET6) sua_portnumber = instance[i].Dest.addrs[0].sin6.sin6_port; ULPData[0].maximumStreamID = -1; short unsigned instance_name = instance[i].SCTP_instance_name ; instance[i].SCTP_assoc_id = sctp_associate( instance_name, instance[i].nr_of_outbound_streams, instance[i].Dest.address_string[0], sua_portnumber, NULL ); /* no msg queued, mark assoc down(from sua management viewpoint)*/ instance[i].asp.status = asp_down; #ifdef DEBUG cout << "SCTP association result = " << instance[i].SCTP_assoc_id <<" \n"; #endif } } return(0); }; /***********************************************************************/ /* Sua_AssociationList::Find_association */ /***********************************************************************/ unsigned int db_Sua_AssociationList:: Find_association( unsigned int sctp_assoc_id, unsigned int &Local_sua_id, unsigned int &Remote_sua_id ) { short i = 0; unsigned int sua_assoc_id = 0; bool result = FALSE; Local_sua_id = 0; Remote_sua_id = 0; while ((i < db_MAX_REMOTE_SUA) && !(result)) { result = (instance[i].SCTP_assoc_id == sctp_assoc_id); if (result) { Local_sua_id = instance[i].local_sua_id; Remote_sua_id = instance[i].remote_sua_id; sua_assoc_id = i; } i++; } return(sua_assoc_id); }; /***********************************************************************/ /* Sua_AssociationList::Find_local_sua */ /***********************************************************************/ unsigned int db_Sua_AssociationList:: Find_local_sua( sccp_addr_str& local_address ) { 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) || (instance[i].Source.addrs[j].sin6.sin6_addr.s6_addr == local_address.pc.ipvx.sin6.sin6_addr.s6_addr)); */ 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 << "Find_local_sua: local_sua_id = " << Local_sua_id << " , instance "<< i << "\n"; #endif } j++; } i++; } return(Local_sua_id); }; /***********************************************************************/ /* Sua_AssociationList::passive_associate */ /***********************************************************************/ unsigned int db_Sua_AssociationList:: passive_associate( unsigned int assoc_id, db_Sua_LocalList &local_sua, db_Sua_RemoteList &remote_sua, unsigned short nr_of_dest_addr, unsigned short nr_of_input_streams, unsigned short nr_of_output_streams ){ SCTP_AssociationStatus status; SCTP_Path_Status path_x_status; int result; short k; int bla; short i = 1, assoc_instance_idx = 1; bool cont, partial_assoc_found = FALSE; while ((i <= num_of_instance) && !(partial_assoc_found)){ partial_assoc_found = (instance[i].Dest.nr_of_addrs == 0); if (partial_assoc_found) assoc_instance_idx = i; i++; } if (!(partial_assoc_found)) { /* new association added */ num_of_instance++; assoc_instance_idx = num_of_instance; instance[assoc_instance_idx].Source = instance[assoc_instance_idx-1].Source; instance[assoc_instance_idx].nr_of_inbound_streams = nr_of_input_streams ; instance[assoc_instance_idx].nr_of_outbound_streams = nr_of_input_streams ; } remote_sua.increase_instance(); instance[assoc_instance_idx].SCTP_assoc_id = assoc_id; instance[assoc_instance_idx].remote_sua_id = remote_sua.num_of_instance; remote_sua.instance[remote_sua.num_of_instance].ssn.ssn = local_sua.instance[local_sua.num_of_instance].ssn.ssn; // should search for the correct sua local instance(future) instance[assoc_instance_idx].local_sua_id = local_sua.num_of_instance; #ifdef DEBUG cout << "Associate remote SUA(& SCTP) instance nr " << assoc_id << " with local SUA(& SCTP) instance nr " << assoc_instance_idx << " \n"; #endif char logstring[100]; sprintf(logstring, "Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", assoc_id, assoc_instance_idx ); event_log("sua_database.c",logstring); 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; 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; cont = true; while ((k < 24) && (cont)) { if (instance[assoc_instance_idx].Dest.address_string[0][k] == '.') { cont = false; instance[assoc_instance_idx].Dest.addrs[0].sa.sa_family = AF_INET; } if (instance[assoc_instance_idx].Dest.address_string[0][k] == ':') { cont = false; instance[assoc_instance_idx].Dest.addrs[0].sa.sa_family = AF_INET6; } k++; } for(k=0; k < instance[assoc_instance_idx].Dest.nr_of_addrs ; k++) { if (instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET) bla = inet_pton( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family, (char *)instance[assoc_instance_idx].Dest.address_string[k], &instance[assoc_instance_idx].Dest.addrs[k].sin.sin_addr ); else if (instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET6) bla = inet_pton( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family, (char *)instance[assoc_instance_idx].Dest.address_string[k], &instance[assoc_instance_idx].Dest.addrs[k].sin6.sin6_addr ); else cout << "Unsupported address family in passive associate\n"; } /* no msg queued, mark assoc down(from sua management viewpoint)*/ instance[assoc_instance_idx].asp.status = asp_down; return(assoc_instance_idx); } /***********************************************************************/ /* Sua_AssociationList::shutdown_instance */ /***********************************************************************/ short db_Sua_AssociationList:: shutdown(){ int i; short result; for(i=1; i <= num_of_instance; i++) { #ifdef DEBUG cout << "shutdown remote SUA(& SCTP) instance nr " << i << " with local SUA(& SCTP) instance nr " << instance[i].local_sua_id <<" \n"; #endif char logstring[100]; sprintf(logstring, "Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", i, instance[i].local_sua_id ); event_log("sua_database.c",logstring); result = instance[i].shutdown(); } return(0); }; /***********************************************************************/ /* Sua_AssociationList::route_on_IPpc */ /***********************************************************************/ signed int db_Sua_AssociationList:: route_on_IPpc ( ipvxunion& dest_pc, ipvxunion& org_pc, int& sua_assoc_id ) { int j=0,i=1,count, addr_start, addr_stop; unsigned int sctp_assoc_id = 0; sua_assoc_id = 0; bool cont = (i <= num_of_instance); bool found_assoc = false; while (cont) { found_assoc = false; j = 0; while ((j < instance[i].Dest.nr_of_addrs) && (!found_assoc)) { found_assoc = (dest_pc.sa.sa_family == instance[i].Dest.addrs[j].sa.sa_family); if (dest_pc.sa.sa_family == AF_INET) { addr_start = 4; addr_stop = addr_start + 4; } else if (dest_pc.sa.sa_family == AF_INET6) { addr_start = 8; addr_stop = addr_start + 16; } else { addr_start = 0; addr_stop = 0; found_assoc = false; cout << "ERROR route_on_IPpc: Unknown addresstype\n"; } /* compare the address family field */ found_assoc = found_assoc && (dest_pc.ch[1] == instance[i].Dest.addrs[j].ch[1]); /* compare the ipv4/ipv6 address field */ for (count = addr_start; count < addr_stop; count++) { found_assoc = found_assoc && (dest_pc.ch[count] == instance[i].Dest.addrs[j].ch[count]); } j++; } if (found_assoc) { cont = false; sctp_assoc_id = instance[i].SCTP_assoc_id; sua_assoc_id = i; #ifdef DEBUG cout << "Found Sua association " << i << " with SCTP assoc " << sctp_assoc_id << "\n"; if (dest_pc.sa.sa_family == AF_INET) { cout << "CLD ip v4 = " << dest_pc.sin.sin_addr.s_addr << "\n"; cout << "Remote IP = " << instance[i].Dest.addrs[0].sin.sin_addr.s_addr << "\n"; } else if (dest_pc.sa.sa_family == AF_INET6) { cout << "CLD ip v6 = " << dest_pc.sin6.sin6_addr.s6_addr << "\n"; cout << "Remote IP = " << instance[i].Dest.addrs[0].sin6.sin6_addr.s6_addr << "\n"; } else cout << "Unknown CLD IP address type format\n"; #endif } else { i++; cont = (i <= num_of_instance); } } return(sctp_assoc_id); }; /***********************************************************************/ /* Sua_AssociationList::route_on_SS7pc */ /***********************************************************************/ signed int db_Sua_AssociationList:: route_on_SS7pc ( SS7union& dest_pc, SS7union& org_pc, int& sua_assoc_id ) { int i=1; unsigned int sctp_assoc_id = 0; #ifdef DEBUG cout << "route on SS7 PC\n"; cout << "PC family = " << dest_pc.ITU24.family << "\n"; cout << "PC value = " << dest_pc.ITU24.pc << "\n"; #endif sua_assoc_id = 0; bool cont = (i <= num_of_instance); bool found_assoc = false; while (cont) { if (dest_pc.ITU14.family == ITU14bit) // standard ITU: 14 bits found_assoc = ((dest_pc.ITU14.pc == instance[i].Dest.pc.ITU14.pc)); else if (dest_pc.ITU24.family == ITU24bit) // chinese PC length: 24 bits found_assoc = ((dest_pc.ITU24.pc == instance[i].Dest.pc.ITU24.pc)); else if (dest_pc.ANSI24.family == ANSI24bit) // ANSI PC length: 24 bits found_assoc = ((dest_pc.ANSI24.pc == instance[i].Dest.pc.ANSI24.pc)); else found_assoc = false; if (found_assoc) { cont = false; sctp_assoc_id = instance[i].SCTP_assoc_id; sua_assoc_id = i; #ifdef DEBUG cout << "Found Sua association " << i << " with SCTP assoc " << sctp_assoc_id << "\n"; cout << "CLD SS7 PC = " << dest_pc.ITU24.pc << "\n"; cout << "Remote PC = " << instance[i].Dest.pc.ITU24.pc << "\n"; #endif } else { i++; cont = (i <= num_of_instance); } } return(sctp_assoc_id); }; /***********************************************************************/ /* Sua_AssociationList::route_on_GTname */ /***********************************************************************/ 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 ) { 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) */ 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 ); if (sctp_assoc_id != 0 ) return(sctp_assoc_id); return(sctp_assoc_id); }; /***********************************************************************/ /* Sua_AssociationList::route_msg */ /***********************************************************************/ signed int db_Sua_AssociationList:: route_msg( sccp_addr_str& cld, sccp_addr_str& clg, int& sua_assoc_id ){ unsigned int sctp_assoc_id = 0; sua_assoc_id = 0; #ifdef DEBUG cout << "num_of_instance : "<< num_of_instance << "\n"; #endif if ((cld.address_fields_present.pc == ipvx_pc_present) && (cld.routing_ind == route_on_ssn)) { sctp_assoc_id = route_on_IPpc( cld.pc.ipvx, clg.pc.ipvx, sua_assoc_id ); } else if ((cld.address_fields_present.name_gt == hostname_present) && (cld.routing_ind == route_on_name_gt)) { sctp_assoc_id = route_on_GTname( cld.name.HostName, clg.name.HostName, sua_assoc_id, cld.pc, clg.pc ); } else if ((cld.address_fields_present.name_gt == hostname_present) && (cld.address_fields_present.pc == ipvx_pc_present) && (cld.routing_ind == route_on_name_gt_next_office)) { sctp_assoc_id = route_on_IPpc( cld.pc.ipvx, clg.pc.ipvx, sua_assoc_id ); } else if ((cld.address_fields_present.pc == ss7_pc_present) && (cld.routing_ind == route_on_ssn)) { sctp_assoc_id = route_on_SS7pc( cld.pc.ss7, clg.pc.ss7, sua_assoc_id ); } else { cout << "Unknown routing requested\n"; } #ifdef SUA_MANAGEMENT /* check if allowed to send msg over the association */ if ((sua_assoc_id > 0) && (sua_assoc_id <= num_of_instance) && (instance[sua_assoc_id].asp.status != asp_active)) { sctp_assoc_id = (-sctp_assoc_id); } #endif #ifdef DEBUG cout << "route msg towards remote SUA(& SCTP) association " << sctp_assoc_id << " \n"; #endif char logstring[100]; sprintf(logstring, "Route msg towards Remote SUA(& SCTP) instance nr %d", sctp_assoc_id ); event_log("sua_database.c",logstring); return(sctp_assoc_id); }; /***********************************************************************/ /* Sua_AssociationList::increase_instance */ /***********************************************************************/ void db_Sua_AssociationList:: increase_instance(){ num_of_instance++; } /***********************************************************************/ /* Sua_AssociationList::Dynamic_Associate */ /***********************************************************************/ unsigned int db_Sua_AssociationList::Dynamic_Associate( db_Sua_LocalList& local_sua, db_Sua_RemoteList& remote_sua, sccp_addr_str& cld, sccp_addr_str& clg, unsigned short nr_of_dest_addr, unsigned short nr_of_input_streams, unsigned short nr_of_output_streams ) { short sua_portnumber = SUA_PORT; short i = 1, assoc_instance_idx = 1, assoc_source_idx = 0; bool partial_assoc_found = FALSE; while ((i <= num_of_instance) && !(partial_assoc_found)){ partial_assoc_found = (instance[i].Dest.nr_of_addrs == 0); if (partial_assoc_found) assoc_instance_idx = i; i++; } if (!(partial_assoc_found)) { /* all assoc's are complete, allocate a new one */ num_of_instance++; assoc_instance_idx = num_of_instance; } assoc_source_idx = Find_local_sua ( clg); #ifdef DEBUG cout << " assoc source idx = " << assoc_source_idx << ", assoc_instance_idx = " << assoc_instance_idx << "\n"; #endif instance[assoc_instance_idx].Source = instance[assoc_source_idx].Source; instance[assoc_instance_idx].SCTP_instance_name = instance[assoc_source_idx].SCTP_instance_name; instance[assoc_instance_idx].local_sua_id = instance[assoc_source_idx].local_sua_id; instance[assoc_instance_idx].nr_of_inbound_streams = nr_of_input_streams ; instance[assoc_instance_idx].nr_of_outbound_streams = nr_of_input_streams ; /* conversion and fill in the destination address */ instance[assoc_instance_idx].Dest.nr_of_addrs = 1; instance[assoc_instance_idx].Dest.addrs[0] = cld.pc.ipvx; short k; const char *ptr; for(k=0; k < instance[assoc_instance_idx].Dest.nr_of_addrs ; k++) { if ( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET ) ptr = inet_ntop( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family, &instance[assoc_instance_idx].Dest.addrs[k].sin.sin_addr, (char *)instance[assoc_instance_idx].Dest.address_string[k], SCTP_MAX_IP_LEN ); else if ( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET6 ) ptr = inet_ntop( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family, &instance[assoc_instance_idx].Dest.addrs[k].sin6.sin6_addr, (char *)instance[assoc_instance_idx].Dest.address_string[k], SCTP_MAX_IP_LEN ); else cout << "Unsupported address family in dynamic associate\n"; } remote_sua.increase_instance(); instance[assoc_instance_idx].SCTP_assoc_id = sctp_associate( instance[assoc_instance_idx].SCTP_instance_name, instance[assoc_instance_idx].nr_of_outbound_streams, instance[assoc_instance_idx].Dest.address_string[0], sua_portnumber, NULL ); instance[assoc_instance_idx].remote_sua_id = remote_sua.num_of_instance; remote_sua.instance[remote_sua.num_of_instance].ssn.ssn = local_sua.instance[instance[assoc_instance_idx].local_sua_id].ssn.ssn; /* a message is queued for this association -> send decision is taken */ /* on receiving the communicationUp notification of SCTP AND whether */ /* SUA management is going to be used */ instance[assoc_instance_idx].asp.status = asp_down_traf_hold; #ifdef DEBUG cout << "Dynamic Associate remote SUA(& SCTP) instance nr " << assoc_instance_idx << " with local SUA(& SCTP) instance nr " << instance[assoc_instance_idx].local_sua_id << " \n"; #endif char logstring[100]; sprintf(logstring, "Dynamic Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", assoc_instance_idx, instance[assoc_instance_idx].local_sua_id ); event_log("sua_datasoc.c",logstring); return(assoc_instance_idx); } /***********************************************************************/ /* Sua_AssociationList::Activate_Association */ /***********************************************************************/ bool db_Sua_AssociationList::activate( unsigned int sua_assoc_id, short mode ) { return(instance[sua_assoc_id].asp.activate(mode, sua_assoc_id )); } /***********************************************************************/ /* Sua_AssociationList::DeActivate_Association */ /***********************************************************************/ void db_Sua_AssociationList::deactivate( unsigned int sua_assoc_id, short mode ) { instance[sua_assoc_id].asp.deactivate(mode, sua_assoc_id ); } /***********************************************************************/ /* Sua_AssociationList::Down_Association */ /***********************************************************************/ void db_Sua_AssociationList::down( unsigned int sua_assoc_id, short mode ) { instance[sua_assoc_id].asp.down(mode, sua_assoc_id ); } /***********************************************************************/ /* Sua_AssociationList::Up_Association */ /***********************************************************************/ void db_Sua_AssociationList::up( unsigned int sua_assoc_id, short mode ) { instance[sua_assoc_id].asp.up(mode, sua_assoc_id ); } // end of module sua_database.c