1097 lines
35 KiB
C++
1097 lines
35 KiB
C++
/***************************************************************************
|
|
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.9 2003/09/09 08:43:44 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 <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::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++)
|
|
{
|
|
/* init association from this node */
|
|
if ((instance[i].init_assoc) && (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;
|
|
|
|
instance[i].SCTP_instance_name = local_sua.instance[instance[i].local_sua_id].SCTP_instance_name ;
|
|
instance[i].SCTP_assoc_id =
|
|
sctp_associate( instance[i].SCTP_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
|
|
|
|
remote_sua.instance[instance[i].remote_sua_id].ssn.ssn = local_sua.instance[instance[i].local_sua_id].ssn.ssn;
|
|
}
|
|
}
|
|
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::passive_associate */
|
|
/***********************************************************************/
|
|
unsigned int db_Sua_AssociationList::
|
|
passive_associate( unsigned int sctp_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, j;
|
|
short i = 1, assoc_instance_idx = 0;
|
|
bool assoc_found = FALSE;
|
|
bool found_addr;
|
|
|
|
result = sctp_getAssocStatus( sctp_assoc_id,
|
|
&status
|
|
);
|
|
|
|
#ifdef DEBUG
|
|
cout << "SCTP association " << sctp_assoc_id <<" result = " << result<< "\n";
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
cout << "number of asoc = " << num_of_instance << "\n";
|
|
#endif
|
|
while ((i <= num_of_instance) && !(assoc_found)){
|
|
assoc_found = (instance[i].Dest.nr_of_addrs == status.numberOfAddresses);
|
|
if (assoc_found)
|
|
{
|
|
k = 0;
|
|
found_addr = false;
|
|
#ifdef DEBUG
|
|
cout << "same number of addresses\n";
|
|
#endif
|
|
while ((k < instance[i].Dest.nr_of_addrs) && (!found_addr))
|
|
{
|
|
j=0;
|
|
found_addr = true;
|
|
while (instance[i].Dest.address_string[k][j] != '\0'){
|
|
found_addr = found_addr && (instance[i].Dest.address_string[k][j] == status.primaryDestinationAddress[j]) ;
|
|
j++;
|
|
}
|
|
k++;
|
|
}
|
|
if (found_addr){
|
|
#ifdef DEBUG
|
|
cout << "found same ip address\n";
|
|
#endif
|
|
assoc_found = ( found_addr && (instance[i].Dest.addrs[0].sin.sin_port == status.destPort));
|
|
assoc_instance_idx = i;
|
|
}
|
|
else
|
|
assoc_found = false;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
if (!(assoc_found))
|
|
{
|
|
/* unknown association added */
|
|
/* not allowed: drop it */
|
|
#ifdef DEBUG
|
|
cout << "not found ???\n";
|
|
#endif
|
|
assoc_instance_idx = 0;
|
|
result = sctp_abort(sctp_assoc_id);
|
|
}
|
|
else
|
|
{
|
|
/* known association: no problemo */
|
|
instance[assoc_instance_idx].SCTP_assoc_id = sctp_assoc_id;
|
|
instance[assoc_instance_idx].remote_sua_id = 0;
|
|
remote_sua.instance[remote_sua.num_of_instance].ssn.ssn = local_sua.instance[instance[assoc_instance_idx].local_sua_id].ssn.ssn;
|
|
/* no msg queued, mark assoc down(from sua management viewpoint)*/
|
|
instance[assoc_instance_idx].asp.status = asp_down;
|
|
|
|
#ifdef DEBUG
|
|
cout << "Associate remote SUA(& SCTP) instance nr " << sctp_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", sctp_assoc_id, assoc_instance_idx );
|
|
event_log("sua_database.c",logstring);
|
|
|
|
}
|
|
|
|
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::increase_instance */
|
|
/***********************************************************************/
|
|
void db_Sua_AssociationList:: increase_instance(){
|
|
|
|
num_of_instance++;
|
|
|
|
}
|
|
|
|
|
|
/***********************************************************************/
|
|
/* 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
|
|
);
|
|
}
|
|
|
|
/***********************************************************************/
|
|
/* Sua_DatabaseList */
|
|
/***********************************************************************/
|
|
/***********************************************************************/
|
|
/* Sua_DatabaseList::initalize */
|
|
/***********************************************************************/
|
|
void db_Sua_DatabaseList::
|
|
initialize( )
|
|
{
|
|
/* init all parts of the SUA database */
|
|
local_sua.initialize();
|
|
remote_sua.initialize();
|
|
AssocDB.initialize();
|
|
NameDB.initialize();
|
|
ApplicServ.initialize();
|
|
|
|
}
|
|
|
|
/***********************************************************************/
|
|
/* Sua_DatabaseList::Find_local_sua */
|
|
/***********************************************************************/
|
|
unsigned int db_Sua_DatabaseList::
|
|
Find_local_sua( sccp_addr_str& local_address
|
|
)
|
|
{
|
|
pointcode_str dest_pc;
|
|
short i = 1, j = 0, k, count, addr_start, addr_stop;
|
|
unsigned int Local_sua_id = 0;
|
|
bool result = FALSE;
|
|
|
|
while ((i < db_MAX_LOCAL_SUA) && !(result))
|
|
{
|
|
j = 0;
|
|
while ((j < local_sua.instance[i].Source.nr_of_addrs) && !(result))
|
|
{
|
|
/* check IP address */
|
|
if (local_address.address_fields_present.pc == ipvx_pc_present)
|
|
{
|
|
result = (local_address.pc.ipvx.sa.sa_family == local_sua.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] == local_sua.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] == local_sua.instance[i].Source.addrs[j].ch[count]);
|
|
}
|
|
}
|
|
/* check SS7 pointcode */
|
|
else if (local_address.address_fields_present.pc == ss7_pc_present)
|
|
{
|
|
result = (local_address.pc.ss7.ITU14.family == local_sua.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 == local_sua.instance[i].Source.pc.ITU14.pc);
|
|
}
|
|
else
|
|
{
|
|
result = false;
|
|
cout << "ERROR Find_local_sua: Unknown SS7 pointcode addresstype\n";
|
|
}
|
|
}
|
|
/* check hostname */
|
|
else if (local_address.address_fields_present.name_gt == hostname_present)
|
|
{
|
|
count = 0;
|
|
result = NameDB.resolve_host_name ( local_address.name.HostName,
|
|
dest_pc
|
|
);
|
|
|
|
result = (dest_pc.ipvx.sa.sa_family == local_sua.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] == local_sua.instance[i].Source.addrs[j].ch[count]);
|
|
k++;
|
|
}
|
|
|
|
}
|
|
/* check global title */
|
|
else if (local_address.address_fields_present.name_gt == GT_present)
|
|
{
|
|
cout << "Find_local_sua: Global Title\n";
|
|
result =
|
|
(local_address.name.GT.nr_of_digits == local_sua.instance[i].Name.GT.nr_of_digits) &&
|
|
( local_address.name.GT.Translation_Type == local_sua.instance[i].Name.GT.Translation_Type) &&
|
|
( local_address.name.GT.Numbering_Plan == local_sua.instance[i].Name.GT.Numbering_Plan) &&
|
|
( local_address.name.GT.Nature_of_Address == local_sua.instance[i].Name.GT.Nature_of_Address) ;
|
|
for (k = 0; k < local_address.name.GT.nr_of_digits; k++)
|
|
{
|
|
result = result &&
|
|
( local_address.name.GT.digits[k] == local_sua.instance[i].Name.GT.digits[k]);
|
|
}
|
|
cout << "i = " << i << " Find_local_sua = " << result << "\n";
|
|
}
|
|
else
|
|
{
|
|
cout << "ERROR Find_local_sua: Unknown SUA addresstype\n";
|
|
result = false;
|
|
}
|
|
|
|
if (result)
|
|
{
|
|
Local_sua_id = i;
|
|
#ifdef DEBUG
|
|
cout << "Find_local_sua: local_sua_id = " << Local_sua_id << "\n";
|
|
#endif
|
|
}
|
|
j++;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
return(Local_sua_id);
|
|
};
|
|
|
|
|
|
/***********************************************************************/
|
|
/* Sua_DatabaseList::route_on_IPpc */
|
|
/***********************************************************************/
|
|
signed int db_Sua_DatabaseList::
|
|
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 <= remote_sua.num_of_instance);
|
|
bool found_assoc = false;
|
|
|
|
while (cont)
|
|
{
|
|
found_assoc = false;
|
|
j = 0;
|
|
while ((j < remote_sua.instance[i].Dest.nr_of_addrs) && (!found_assoc))
|
|
{
|
|
found_assoc = (dest_pc.sa.sa_family == remote_sua.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] == remote_sua.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] == remote_sua.instance[i].Dest.addrs[j].ch[count]);
|
|
}
|
|
j++;
|
|
}
|
|
|
|
if (found_assoc)
|
|
{
|
|
cont = false;
|
|
|
|
sua_assoc_id = remote_sua.instance[i].SUA_assoc_id;
|
|
sctp_assoc_id = AssocDB.instance[remote_sua.instance[i].SUA_assoc_id].SCTP_assoc_id;
|
|
|
|
#ifdef DEBUG
|
|
cout << "Remote sua " << i << " Sua association " << sua_assoc_id << " 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 = " << remote_sua.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 = " << remote_sua.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 <= remote_sua.num_of_instance);
|
|
}
|
|
}
|
|
|
|
return(sctp_assoc_id);
|
|
}
|
|
|
|
/***********************************************************************/
|
|
/* Sua_DatabaseList::route_on_SS7pc */
|
|
/***********************************************************************/
|
|
signed int db_Sua_DatabaseList::
|
|
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 <= remote_sua.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 == remote_sua.instance[i].Dest.pc.ITU14.pc));
|
|
else if (dest_pc.ITU24.family == ITU24bit) // chinese PC length: 24 bits
|
|
found_assoc = ((dest_pc.ITU24.pc == remote_sua.instance[i].Dest.pc.ITU24.pc));
|
|
else if (dest_pc.ANSI24.family == ANSI24bit) // ANSI PC length: 24 bits
|
|
found_assoc = ((dest_pc.ANSI24.pc == remote_sua.instance[i].Dest.pc.ANSI24.pc));
|
|
else
|
|
found_assoc = false;
|
|
|
|
|
|
if (found_assoc)
|
|
{
|
|
cont = false;
|
|
|
|
sua_assoc_id = remote_sua.instance[i].SUA_assoc_id;
|
|
sctp_assoc_id = AssocDB.instance[remote_sua.instance[i].SUA_assoc_id].SCTP_assoc_id;
|
|
|
|
#ifdef DEBUG
|
|
cout << "Remote sua " << i << " Sua association " << sua_assoc_id << " with SCTP assoc " << sctp_assoc_id << "\n";
|
|
|
|
cout << "CLD SS7 PC = " << dest_pc.ITU24.pc << "\n";
|
|
cout << "Remote PC = " << remote_sua.instance[i].Dest.pc.ITU24.pc << "\n";
|
|
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
i++;
|
|
cont = (i <= remote_sua.num_of_instance);
|
|
}
|
|
}
|
|
|
|
return(sctp_assoc_id);
|
|
}
|
|
|
|
|
|
/***********************************************************************/
|
|
/* Sua_DatabaseList::route_on_GTname */
|
|
/***********************************************************************/
|
|
signed int db_Sua_DatabaseList::
|
|
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 = NameDB.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_DatabaseList::route_on_GTT */
|
|
/***********************************************************************/
|
|
signed int db_Sua_DatabaseList::
|
|
route_on_GTT ( global_title_str& dest_gt,
|
|
global_title_str& org_gt,
|
|
int& sua_assoc_id,
|
|
pointcode_str& dest_pc,
|
|
pointcode_str& org_pc
|
|
)
|
|
{
|
|
int result = 0;
|
|
unsigned int sctp_assoc_id = 0;
|
|
global_title_str dest_tr_gt, org_tr_gt;
|
|
|
|
sua_assoc_id = 0;
|
|
|
|
/* resolving can be done via: */
|
|
/* - local global Titel database */
|
|
result = NameDB.perform_GTT ( dest_gt,
|
|
org_gt,
|
|
dest_tr_gt,
|
|
org_tr_gt,
|
|
dest_pc
|
|
);
|
|
|
|
#ifdef DEBUG
|
|
cout << "result of GT translation : " << result << "\n";
|
|
cout << "dest IP address = " << dest_pc.ipvx.sa.sa_family << "\n";
|
|
#endif
|
|
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_DatabaseList::route_msg */
|
|
/***********************************************************************/
|
|
signed int db_Sua_DatabaseList::
|
|
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 << "number of associations instances= : "<< AssocDB.num_of_instance << "\n";
|
|
cout << "number of remote sua instances= : "<< remote_sua.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 == GT_present) &&
|
|
(cld.routing_ind == route_on_name_gt))
|
|
{
|
|
sctp_assoc_id = route_on_GTT( cld.name.GT,
|
|
clg.name.GT,
|
|
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 <= AssocDB.num_of_instance) &&
|
|
(AssocDB.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_DatabaseList::Dynamic_Associate */
|
|
/***********************************************************************/
|
|
unsigned int db_Sua_DatabaseList::Dynamic_Associate( 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 <= AssocDB.num_of_instance) && !(partial_assoc_found)){
|
|
partial_assoc_found = (AssocDB.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 */
|
|
AssocDB.num_of_instance++;
|
|
assoc_instance_idx = AssocDB.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
|
|
|
|
AssocDB.instance[assoc_instance_idx].Source = AssocDB.instance[assoc_source_idx].Source;
|
|
AssocDB.instance[assoc_instance_idx].SCTP_instance_name = AssocDB.instance[assoc_source_idx].SCTP_instance_name;
|
|
AssocDB.instance[assoc_instance_idx].local_sua_id = AssocDB.instance[assoc_source_idx].local_sua_id;
|
|
AssocDB.instance[assoc_instance_idx].nr_of_inbound_streams = nr_of_input_streams ;
|
|
AssocDB.instance[assoc_instance_idx].nr_of_outbound_streams = nr_of_input_streams ;
|
|
|
|
/* conversion and fill in the destination address */
|
|
AssocDB.instance[assoc_instance_idx].Dest.nr_of_addrs = 1;
|
|
AssocDB.instance[assoc_instance_idx].Dest.addrs[0] = cld.pc.ipvx;
|
|
|
|
short k;
|
|
const char *ptr;
|
|
for(k=0; k < AssocDB.instance[assoc_instance_idx].Dest.nr_of_addrs ; k++)
|
|
{
|
|
if ( AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET )
|
|
ptr = inet_ntop( AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family,
|
|
&AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sin.sin_addr,
|
|
(char *)AssocDB.instance[assoc_instance_idx].Dest.address_string[k],
|
|
SCTP_MAX_IP_LEN
|
|
);
|
|
else if ( AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET6 )
|
|
ptr = inet_ntop( AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family,
|
|
&AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sin6.sin6_addr,
|
|
(char *)AssocDB.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();
|
|
|
|
AssocDB.instance[assoc_instance_idx].SCTP_assoc_id =
|
|
sctp_associate( AssocDB.instance[assoc_instance_idx].SCTP_instance_name,
|
|
AssocDB.instance[assoc_instance_idx].nr_of_outbound_streams,
|
|
AssocDB.instance[assoc_instance_idx].Dest.address_string[0],
|
|
sua_portnumber,
|
|
NULL
|
|
);
|
|
AssocDB.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[AssocDB.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 */
|
|
AssocDB.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 " << AssocDB.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, AssocDB.instance[assoc_instance_idx].local_sua_id );
|
|
event_log("sua_datasoc.c",logstring);
|
|
|
|
|
|
return(assoc_instance_idx);
|
|
}
|
|
|
|
// end of module sua_database.c
|
|
|
|
|
|
|
|
|
|
|
|
|