aboutsummaryrefslogtreecommitdiffstats
path: root/sualibrary/sua/sua_datassoc.cpp
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-07-09 20:55:33 +0200
committerHarald Welte <laforge@gnumonks.org>2010-07-09 20:55:33 +0200
commit86d1df86c7da9a35004e6a9a326f10b8167c9179 (patch)
treedbc1d77a33fe77d9e23a66115b899a271d3c5d39 /sualibrary/sua/sua_datassoc.cpp
import sualibrary-0.1.0 from 2002-02-15
Diffstat (limited to 'sualibrary/sua/sua_datassoc.cpp')
-rw-r--r--sualibrary/sua/sua_datassoc.cpp1000
1 files changed, 1000 insertions, 0 deletions
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 <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+#include <netinet/in.h>
+
+#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
+
+
+
+
+
+