2010-07-09 18:55:33 +00:00
/***************************************************************************
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 . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
2010-07-09 18:59:00 +00:00
* $ Id : sua_datassoc . cpp , v 1.9 2003 / 09 / 09 08 : 43 : 44 p82609 Exp $
2010-07-09 18:55:33 +00:00
*
* 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
2010-07-09 18:56:56 +00:00
* - Final destination ?
2010-07-09 18:55:33 +00:00
* - 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
) ;
2010-07-09 18:58:12 +00:00
2010-07-09 18:55:33 +00:00
for ( i = 1 ; i < = num_of_instance ; i + + )
{
2010-07-09 18:58:12 +00:00
/* init association from this node */
if ( ( instance [ i ] . init_assoc ) & & ( instance [ i ] . Dest . nr_of_addrs ! = 0 ) ) {
2010-07-09 18:55:33 +00:00
# ifdef DEBUG
2010-07-09 18:58:12 +00:00
cout < < " Associate remote SUA(& SCTP) instance nr " < < i < < " with local SUA(& SCTP) instance nr " < < instance [ i ] . local_sua_id < < " \n " ;
2010-07-09 18:55:33 +00:00
# endif
2010-07-09 18:58:12 +00:00
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 ;
2010-07-09 18:55:33 +00:00
# ifdef DEBUG
2010-07-09 18:58:12 +00:00
cout < < " SCTP association result = " < < instance [ i ] . SCTP_assoc_id < < " \n " ;
2010-07-09 18:55:33 +00:00
# endif
2010-07-09 18:58:12 +00:00
remote_sua . instance [ instance [ i ] . remote_sua_id ] . ssn . ssn = local_sua . instance [ instance [ i ] . local_sua_id ] . ssn . ssn ;
}
2010-07-09 18:55:33 +00:00
}
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 ;
2010-07-09 18:58:12 +00:00
/*Remote_sua_id = instance[i].remote_sua_id;*/
2010-07-09 18:55:33 +00:00
sua_assoc_id = i ;
}
i + + ;
}
return ( sua_assoc_id ) ;
} ;
/***********************************************************************/
/* Sua_AssociationList::passive_associate */
/***********************************************************************/
unsigned int db_Sua_AssociationList : :
2010-07-09 18:58:12 +00:00
passive_associate ( unsigned int sctp_assoc_id ,
2010-07-09 18:55:33 +00:00
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
2010-07-09 18:58:12 +00:00
)
{
2010-07-09 18:55:33 +00:00
SCTP_AssociationStatus status ;
int result ;
2010-07-09 18:58:12 +00:00
short k , j ;
short i = 1 , assoc_instance_idx = 0 ;
bool assoc_found = FALSE ;
bool found_addr ;
result = sctp_getAssocStatus ( sctp_assoc_id ,
2010-07-09 18:57:43 +00:00
& status
) ;
2010-07-09 18:55:33 +00:00
2010-07-09 18:59:00 +00:00
# ifdef DEBUG
cout < < " SCTP association " < < sctp_assoc_id < < " result = " < < result < < " \n " ;
# endif
# ifdef DEBUG
cout < < " number of asoc = " < < num_of_instance < < " \n " ;
# endif
2010-07-09 18:58:12 +00:00
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 ;
2010-07-09 18:59:00 +00:00
# ifdef DEBUG
cout < < " same number of addresses \n " ;
# endif
2010-07-09 18:58:12 +00:00
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 ) {
2010-07-09 18:59:00 +00:00
# ifdef DEBUG
cout < < " found same ip address \n " ;
# endif
2010-07-09 18:58:12 +00:00
assoc_found = ( found_addr & & ( instance [ i ] . Dest . addrs [ 0 ] . sin . sin_port = = status . destPort ) ) ;
assoc_instance_idx = i ;
2010-07-09 18:57:43 +00:00
}
2010-07-09 18:58:12 +00:00
else
assoc_found = false ;
}
i + + ;
}
2010-07-09 18:57:43 +00:00
2010-07-09 18:58:12 +00:00
if ( ! ( assoc_found ) )
2010-07-09 18:55:33 +00:00
{
2010-07-09 18:58:12 +00:00
/* unknown association added */
/* not allowed: drop it */
2010-07-09 18:59:00 +00:00
# ifdef DEBUG
cout < < " not found ??? \n " ;
# endif
2010-07-09 18:58:12 +00:00
assoc_instance_idx = 0 ;
result = sctp_abort ( sctp_assoc_id ) ;
2010-07-09 18:55:33 +00:00
}
2010-07-09 18:58:12 +00:00
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 ) ;
2010-07-09 18:55:33 +00:00
2010-07-09 18:58:12 +00:00
}
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
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 ) ;
} ;
/***********************************************************************/
2010-07-09 18:57:43 +00:00
/* Sua_AssociationList::increase_instance */
2010-07-09 18:55:33 +00:00
/***********************************************************************/
2010-07-09 18:57:43 +00:00
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 */
/***********************************************************************/
2010-07-09 18:58:12 +00:00
/***********************************************************************/
/* 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 ( ) ;
}
2010-07-09 18:57:43 +00:00
/***********************************************************************/
/* Sua_DatabaseList::Find_local_sua */
/***********************************************************************/
unsigned int db_Sua_DatabaseList : :
Find_local_sua ( sccp_addr_str & local_address
)
{
pointcode_str dest_pc ;
2010-07-09 18:58:12 +00:00
short i = 1 , j = 0 , k , count , addr_start , addr_stop ;
2010-07-09 18:57:43 +00:00
unsigned int Local_sua_id = 0 ;
bool result = FALSE ;
2010-07-09 18:58:12 +00:00
while ( ( i < db_MAX_LOCAL_SUA ) & & ! ( result ) )
2010-07-09 18:57:43 +00:00
{
j = 0 ;
2010-07-09 18:58:12 +00:00
while ( ( j < local_sua . instance [ i ] . Source . nr_of_addrs ) & & ! ( result ) )
2010-07-09 18:57:43 +00:00
{
2010-07-09 18:58:12 +00:00
/* check IP address */
2010-07-09 18:57:43 +00:00
if ( local_address . address_fields_present . pc = = ipvx_pc_present )
{
2010-07-09 18:58:12 +00:00
result = ( local_address . pc . ipvx . sa . sa_family = = local_sua . instance [ i ] . Source . addrs [ j ] . sa . sa_family ) ;
2010-07-09 18:57:43 +00:00
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 & &
2010-07-09 18:58:12 +00:00
( local_address . pc . ipvx . ch [ 1 ] = = local_sua . instance [ i ] . Source . addrs [ j ] . ch [ 1 ] ) ;
2010-07-09 18:57:43 +00:00
/* compare the ipv4/ipv6 address field */
for ( count = addr_start ; count < addr_stop ; count + + )
{
result = result & &
2010-07-09 18:58:12 +00:00
( local_address . pc . ipvx . ch [ count ] = = local_sua . instance [ i ] . Source . addrs [ j ] . ch [ count ] ) ;
2010-07-09 18:57:43 +00:00
}
}
2010-07-09 18:58:12 +00:00
/* check SS7 pointcode */
2010-07-09 18:57:43 +00:00
else if ( local_address . address_fields_present . pc = = ss7_pc_present )
{
2010-07-09 18:58:12 +00:00
result = ( local_address . pc . ss7 . ITU14 . family = = local_sua . instance [ i ] . Source . pc . ITU14 . family ) ;
2010-07-09 18:57:43 +00:00
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 & &
2010-07-09 18:58:12 +00:00
( local_address . pc . ss7 . ITU14 . pc = = local_sua . instance [ i ] . Source . pc . ITU14 . pc ) ;
2010-07-09 18:57:43 +00:00
}
else
{
result = false ;
cout < < " ERROR Find_local_sua: Unknown SS7 pointcode addresstype \n " ;
}
}
2010-07-09 18:58:12 +00:00
/* check hostname */
2010-07-09 18:57:43 +00:00
else if ( local_address . address_fields_present . name_gt = = hostname_present )
{
count = 0 ;
result = NameDB . resolve_host_name ( local_address . name . HostName ,
dest_pc
) ;
2010-07-09 18:58:12 +00:00
result = ( dest_pc . ipvx . sa . sa_family = = local_sua . instance [ i ] . Source . addrs [ j ] . sa . sa_family ) ;
2010-07-09 18:57:43 +00:00
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 & &
2010-07-09 18:58:12 +00:00
( dest_pc . ipvx . ch [ count ] = = local_sua . instance [ i ] . Source . addrs [ j ] . ch [ count ] ) ;
2010-07-09 18:57:43 +00:00
k + + ;
}
}
2010-07-09 18:58:12 +00:00
/* check global title */
2010-07-09 18:57:43 +00:00
else if ( local_address . address_fields_present . name_gt = = GT_present )
{
2010-07-09 18:58:12 +00:00
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 " ;
2010-07-09 18:57:43 +00:00
}
else
{
cout < < " ERROR Find_local_sua: Unknown SUA addresstype \n " ;
result = false ;
}
if ( result )
{
2010-07-09 18:58:12 +00:00
Local_sua_id = i ;
2010-07-09 18:57:43 +00:00
# ifdef DEBUG
2010-07-09 18:58:12 +00:00
cout < < " Find_local_sua: local_sua_id = " < < Local_sua_id < < " \n " ;
2010-07-09 18:57:43 +00:00
# endif
}
j + + ;
}
i + + ;
}
return ( Local_sua_id ) ;
} ;
2010-07-09 18:58:12 +00:00
/***********************************************************************/
/* 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 ) ;
}
2010-07-09 18:57:43 +00:00
/***********************************************************************/
/* Sua_DatabaseList::route_on_GTname */
/***********************************************************************/
signed int db_Sua_DatabaseList : :
2010-07-09 18:55:33 +00:00
route_on_GTname ( hostname_str & dest_name ,
2010-07-09 18:57:43 +00:00
hostname_str & org_name ,
int & sua_assoc_id ,
pointcode_str & dest_pc ,
pointcode_str & org_pc
)
2010-07-09 18:55:33 +00:00
{
2010-07-09 18:57:43 +00:00
int result = 0 ;
2010-07-09 18:56:56 +00:00
unsigned int sctp_assoc_id = 0 ;
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
sua_assoc_id = 0 ;
2010-07-09 18:57:43 +00:00
/* resolving can be done via: */
2010-07-09 18:55:33 +00:00
/* - local global Titel database */
/* - resolve hostname via DNS(simplest for single hop translations) */
2010-07-09 18:57:43 +00:00
result = NameDB . resolve_host_name ( dest_name ,
dest_pc
) ;
/*result = resolve_host_name ( org_name,
org_pc
) ; */
2010-07-09 18:58:12 +00:00
sctp_assoc_id = route_on_IPpc ( dest_pc . ipvx ,
org_pc . ipvx ,
sua_assoc_id
) ;
2010-07-09 18:57:43 +00:00
2010-07-09 18:56:56 +00:00
if ( sctp_assoc_id ! = 0 )
2010-07-09 18:57:43 +00:00
return ( sctp_assoc_id ) ;
return ( sctp_assoc_id ) ;
} ;
2010-07-09 18:55:33 +00:00
2010-07-09 18:57:43 +00:00
/***********************************************************************/
/* 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
) ;
2010-07-09 18:59:00 +00:00
# ifdef DEBUG
cout < < " result of GT translation : " < < result < < " \n " ;
cout < < " dest IP address = " < < dest_pc . ipvx . sa . sa_family < < " \n " ;
# endif
2010-07-09 18:58:12 +00:00
sctp_assoc_id = route_on_IPpc ( dest_pc . ipvx ,
org_pc . ipvx ,
sua_assoc_id
) ;
2010-07-09 18:57:43 +00:00
if ( sctp_assoc_id ! = 0 )
return ( sctp_assoc_id ) ;
2010-07-09 18:55:33 +00:00
return ( sctp_assoc_id ) ;
} ;
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
/***********************************************************************/
2010-07-09 18:57:43 +00:00
/* Sua_DatabaseList::route_msg */
2010-07-09 18:55:33 +00:00
/***********************************************************************/
2010-07-09 18:57:43 +00:00
signed int db_Sua_DatabaseList : :
2010-07-09 18:56:56 +00:00
route_msg ( sccp_addr_str & cld ,
2010-07-09 18:57:43 +00:00
sccp_addr_str & clg ,
int & sua_assoc_id
) {
2010-07-09 18:55:33 +00:00
unsigned int sctp_assoc_id = 0 ;
2010-07-09 18:57:43 +00:00
2010-07-09 18:56:56 +00:00
sua_assoc_id = 0 ;
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
# ifdef DEBUG
2010-07-09 18:58:12 +00:00
cout < < " number of associations instances= : " < < AssocDB . num_of_instance < < " \n " ;
cout < < " number of remote sua instances= : " < < remote_sua . num_of_instance < < " \n " ;
2010-07-09 18:55:33 +00:00
# endif
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
if ( ( cld . address_fields_present . pc = = ipvx_pc_present ) & &
( cld . routing_ind = = route_on_ssn ) )
{
2010-07-09 18:58:12 +00:00
sctp_assoc_id = route_on_IPpc ( cld . pc . ipvx ,
clg . pc . ipvx ,
sua_assoc_id
) ;
2010-07-09 18:55:33 +00:00
}
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 ,
2010-07-09 18:57:43 +00:00
clg . name . HostName ,
2010-07-09 18:55:33 +00:00
sua_assoc_id ,
cld . pc ,
clg . pc
) ;
}
2010-07-09 18:57:43 +00:00
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
) ;
}
2010-07-09 18:55:33 +00:00
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 ) )
{
2010-07-09 18:58:12 +00:00
sctp_assoc_id = route_on_IPpc ( cld . pc . ipvx ,
clg . pc . ipvx ,
sua_assoc_id
) ;
2010-07-09 18:55:33 +00:00
}
else if ( ( cld . address_fields_present . pc = = ss7_pc_present ) & &
( cld . routing_ind = = route_on_ssn ) )
{
2010-07-09 18:58:12 +00:00
sctp_assoc_id = route_on_SS7pc ( cld . pc . ss7 ,
clg . pc . ss7 ,
sua_assoc_id
) ;
2010-07-09 18:55:33 +00:00
}
else
{
2010-07-09 18:57:43 +00:00
cout < < " Unknown routing requested \n " ;
2010-07-09 18:55:33 +00:00
}
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
# ifdef SUA_MANAGEMENT
/* check if allowed to send msg over the association */
if ( ( sua_assoc_id > 0 ) & &
2010-07-09 18:57:43 +00:00
( sua_assoc_id < = AssocDB . num_of_instance ) & &
( AssocDB . instance [ sua_assoc_id ] . asp . status ! = asp_active ) )
2010-07-09 18:55:33 +00:00
{
sctp_assoc_id = ( - sctp_assoc_id ) ;
}
# endif
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
# 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 ) ;
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
return ( sctp_assoc_id ) ;
} ;
/***********************************************************************/
2010-07-09 18:57:43 +00:00
/* Sua_DatabaseList::Dynamic_Associate */
2010-07-09 18:55:33 +00:00
/***********************************************************************/
2010-07-09 18:57:43 +00:00
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
)
2010-07-09 18:55:33 +00:00
{
short sua_portnumber = SUA_PORT ;
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
short i = 1 , assoc_instance_idx = 1 , assoc_source_idx = 0 ;
bool partial_assoc_found = FALSE ;
2010-07-09 18:57:43 +00:00
while ( ( i < = AssocDB . num_of_instance ) & & ! ( partial_assoc_found ) ) {
partial_assoc_found = ( AssocDB . instance [ i ] . Dest . nr_of_addrs = = 0 ) ;
if ( partial_assoc_found )
2010-07-09 18:55:33 +00:00
assoc_instance_idx = i ;
i + + ;
}
if ( ! ( partial_assoc_found ) )
{
/* all assoc's are complete, allocate a new one */
2010-07-09 18:57:43 +00:00
AssocDB . num_of_instance + + ;
assoc_instance_idx = AssocDB . num_of_instance ;
2010-07-09 18:55:33 +00:00
}
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
assoc_source_idx = Find_local_sua ( clg ) ;
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
# ifdef DEBUG
cout < < " assoc source idx = " < < assoc_source_idx < < " , assoc_instance_idx = " < < assoc_instance_idx < < " \n " ;
# endif
2010-07-09 18:57:43 +00:00
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 ;
2010-07-09 18:55:33 +00:00
short k ;
const char * ptr ;
2010-07-09 18:57:43 +00:00
for ( k = 0 ; k < AssocDB . instance [ assoc_instance_idx ] . Dest . nr_of_addrs ; k + + )
2010-07-09 18:55:33 +00:00
{
2010-07-09 18:57:43 +00:00
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 ] ,
2010-07-09 18:55:33 +00:00
SCTP_MAX_IP_LEN
2010-07-09 18:57:43 +00:00
) ;
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 ] ,
2010-07-09 18:55:33 +00:00
SCTP_MAX_IP_LEN
) ;
else
cout < < " Unsupported address family in dynamic associate \n " ;
}
remote_sua . increase_instance ( ) ;
2010-07-09 18:57:43 +00:00
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 ] ,
2010-07-09 18:55:33 +00:00
sua_portnumber ,
NULL
) ;
2010-07-09 18:57:43 +00:00
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 ;
2010-07-09 18:55:33 +00:00
/* 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 */
2010-07-09 18:57:43 +00:00
AssocDB . instance [ assoc_instance_idx ] . asp . status = asp_down_traf_hold ;
2010-07-09 18:55:33 +00:00
# ifdef DEBUG
2010-07-09 18:57:43 +00:00
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 " ;
2010-07-09 18:55:33 +00:00
# endif
char logstring [ 100 ] ;
2010-07-09 18:57:43 +00:00
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 ) ;
2010-07-09 18:55:33 +00:00
event_log ( " sua_datasoc.c " , logstring ) ;
2010-07-09 18:57:43 +00:00
2010-07-09 18:55:33 +00:00
return ( assoc_instance_idx ) ;
}
// end of module sua_database.c