From 86d1df86c7da9a35004e6a9a326f10b8167c9179 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 9 Jul 2010 20:55:33 +0200 Subject: import sualibrary-0.1.0 from 2002-02-15 --- sualibrary/sua/sua_datassoc.cpp | 1000 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1000 insertions(+) create mode 100644 sualibrary/sua/sua_datassoc.cpp (limited to 'sualibrary/sua/sua_datassoc.cpp') diff --git a/sualibrary/sua/sua_datassoc.cpp b/sualibrary/sua/sua_datassoc.cpp new file mode 100644 index 0000000..c3bcc5f --- /dev/null +++ b/sualibrary/sua/sua_datassoc.cpp @@ -0,0 +1,1000 @@ +/*************************************************************************** + 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.3 2002/02/15 16:19:46 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 + * - 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; + } +} + +/***********************************************************************/ +/* 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 + ) +{ + short i = 1, j = 0; + 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 (result) + { + Local_sua_id = instance[i].local_sua_id; +#ifdef DEBUG + cout << "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; + 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; + instance[assoc_instance_idx].Dest.address_string[0] = status.primaryDestinationAddress; + instance[assoc_instance_idx].Dest.addrs[0].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 + ) +{ + struct hostent *hptr; + char **pptr; + unsigned int sctp_assoc_id = 0; + char str[INET6_ADDRSTRLEN]; + char *dest_carr; + + 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"; + + 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 + ){ + + unsigned int sctp_assoc_id = 0; + int 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 + + + + + + -- cgit v1.2.3