|
OpenSS7 SS7 for the Common Man |
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |
||||||||||||||||||||||||||
| Home | Overview | Status | News | Documentation | Resources | About | |||||||||||||||||||||
File /code/strss7/test/etsi_m3ua/test_m3ua_sgp_a1.c
#ident "@(#) $RCSfile: test_m3ua_sgp_a1.c,v $ $Name: $($Revision: 0.8 $) $Date: 2002/04/02 08:22:50 $"
static char const ident[] = "$RCSfile: test_m3ua_sgp_a1.c,v $ $Name: $($Revision: 0.8 $) $Date: 2002/04/02 08:22:50 $";
#include <stropts.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/poll.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
#include <getopt.h>
#include <sys/npi.h>
#include <sys/npi_sctp.h>
#include <sys/npi_mtp.h>
#include <ss7/ua_lm.h>
#include <ss7/ua_lm_ioctl.h>
#define M3UA_PORT_NUMBER 2905
#define RC_DEFAULT 1
#define NA_DEFAULT 1
#define ASPID_DEFAULT 1
#define PCX_DEFAULT 0x00ffffff
#define PCZ_DEFAULT 0x00fffffe
#define ASP_ADDR_DEFAULT "127.0.0.1"
#define ASP_PORT_DEFAULT 0
#define SGP_ADDR_DEFAULT "127.0.0.2"
#define SGP_PORT_DEFAULT M3UA_PORT_NUMBER
int routing_context = RC_DEFAULT;
int network_appearance = NA_DEFAULT;
int aspid = ASPID_DEFAULT;
uint32_t pcx = PCX_DEFAULT;
uint32_t pcz = PCZ_DEFAULT;
#define HOST_BUF_LEN 256
char *aspadd = ASP_ADDR_DEFAULT;
char *sgpadd = SGP_ADDR_DEFAULT;
int asp_port = ASP_PORT_DEFAULT;
int sgp_port = SGP_PORT_DEFAULT;
char **aspp = &aspadd;
char **sgpp = &sgpadd;
char aspbuf[HOST_BUF_LEN] = "\0";
char sgpbuf[HOST_BUF_LEN] = "\0";
typedef struct addr
{
uint16_t port __attribute__((packed));
struct in_addr addr[1] __attribute__((packed));
} addr_t;
static addr_t asp_addr = { 0, { { INADDR_ANY } } };
static addr_t sgp_addr = { 0, { { INADDR_ANY } } };
void
usage(void)
{
fprintf(stderr,"\n");
fprintf(stderr,"Usage: test_m3ua_sgp_a1 [options]\n");
fprintf(stderr," Runs ETSI Test Case A.1 at SGP\n");
fprintf(stderr,"\n");
fprintf(stderr,"Options:\n");
fprintf(stderr," -s --sgp-address (default: %s)\n",SGP_ADDR_DEFAULT);
fprintf(stderr," address (or hostname) of SGP for test\n");
fprintf(stderr," -w --sgp-port (default: %d)\n",SGP_PORT_DEFAULT);
fprintf(stderr," well-known port for test\n");
fprintf(stderr," -a --asp-address (default: %s)\n",ASP_ADDR_DEFAULT);
fprintf(stderr," address (or hostname) of ASP for test\n");
fprintf(stderr," -p --asp-port (default: %d)\n",ASP_PORT_DEFAULT);
fprintf(stderr," port of ASP for test (0 if don't care)\n");
fprintf(stderr," -r --routing-context (default: %d)\n",RC_DEFAULT);
fprintf(stderr," routing context for the test\n");
fprintf(stderr," -n --network-appearance (default: %d)\n",NA_DEFAULT);
fprintf(stderr," network appearance for the test\n");
fprintf(stderr," -i --aspid (default: %d)\n",ASPID_DEFAULT);
fprintf(stderr," ASP Identifier for the test\n");
fprintf(stderr," -x --point-code-X: (default: %8x)\n",PCX_DEFAULT);
fprintf(stderr," point code of ASP in the test\n");
fprintf(stderr," -z --point-code-Z: (default: %8x)\n",PCZ_DEFAULT);
fprintf(stderr," remote point code for the test\n");
fprintf(stderr,"\n");
fprintf(stderr,"Configuration A:\n");
fprintf(stderr," This simple configuration is used for all the procedures of tests\n");
fprintf(stderr," concerning only one AS. Configuration A is shown in figure 1. AS is\n");
fprintf(stderr," handling the traffic for routing context P and N/w Appearance A. AS is\n");
fprintf(stderr," having only one ASP ASP1. SG routes Data to SS7 for PC Z. SGP serves\n");
fprintf(stderr," SG.\n");
fprintf(stderr,"\n");
fprintf(stderr," SG\n");
fprintf(stderr," +-------------+ +--------------+\n");
fprintf(stderr," | SGP | | AS DPC = X |\n");
fprintf(stderr," | | | ------- |\n");
fprintf(stderr," | |-------------------------------|--| ASP1 | |\n");
fprintf(stderr," | | | ------- |\n");
fprintf(stderr," +-------------+ +--------------+\n");
fprintf(stderr," Fig 1: Configuration A\n");
fprintf(stderr,"\n");
}
#define BUFSIZE 4096
union
{
np_ulong prim;
union N_primitives npi;
union LM_primitives lm;
char cbuf[BUFSIZE];
} cmd;
char dbuf[BUFSIZE];
struct strbuf ctrl = { BUFSIZE, 0, cmd.cbuf };
struct strbuf data = { BUFSIZE, 0, dbuf };
N_qos_sel_data_sctp_t qos_data =
{
N_QOS_SEL_DATA_SCTP, /* n_qos_type */
3, /* ppi */
0, /* sid */
0, /* ssn */
0, /* tsn */
0 /* more */
};
N_qos_sel_conn_sctp_t qos_conn =
{
N_QOS_SEL_CONN_SCTP, /* n_qos_type */
3, /* i_streams */
3 /* o_streams */
};
N_qos_sel_info_sctp_t qos_info =
{
N_QOS_SEL_INFO_SCTP, /* n_qos_type */
3, /* i_streams */
3, /* o_streams */
3, /* ppi */
0, /* sid */
8, /* max_inits */
12, /* max_retrans */
-1UL, /* ck_life */
-1UL, /* ck_inc */
SCTP_HMAC_NONE, /* hmac */
-1UL, /* throttle */
20, /* max_sack */
100, /* rto_ini */
50, /* rto_min */
200, /* rto_max */
12, /* rtx_path */
200, /* hb_itvl */
0x00 /* options */
};
int
sctp_get(int fd, int wait)
{
int ret;
int flags = 0;
while ( (ret = getmsg(fd, &ctrl, &data, &flags)) < 0 )
{
switch ( errno )
{
default:
case EPROTO:
case EINVAL:
perror("sctp_get: getmsg");
return -1;
case EINTR:
case ERESTART:
continue;
case EAGAIN:
break;
}
break;
}
if ( !ret )
return cmd.prim;
if ( !wait )
{
/*
fprintf(stderr,"\t...sctp_get: no data and no wait specified\n");
*/
return -1;
}
do {
struct pollfd pfd[] = { { fd, POLLIN|POLLPRI, 0 } };
if ( !(ret = poll(pfd, 1, wait)) )
{
if ( errno != EAGAIN )
perror("sctp_get: poll");
return -1;
}
if ( (ret == 1) | (ret == 2) )
{
if ( pfd[0].revents & (POLLIN|POLLPRI) )
{
flags = 0;
while ( (ret = getmsg(fd, &ctrl, &data, &flags)) < 0 )
{
switch ( errno )
{
case EINTR:
case ERESTART:
continue;
}
}
if ( ret < 0 )
{
perror("sctp_get: getmsg");
return -1;
}
return cmd.prim;
}
continue;
}
if ( ret == -1 )
{
perror("sctp_get: poll");
return -1;
}
}
while(1);
}
int
sctp_options(int fd, ulong flags, N_qos_sel_info_sctp_t *qos)
{
int ret;
ctrl.len = sizeof(cmd.npi.optmgmt_req)+sizeof(*qos);
cmd.prim = N_OPTMGMT_REQ;
cmd.npi.optmgmt_req.OPTMGMT_flags = flags;
cmd.npi.optmgmt_req.QOS_length = sizeof(*qos);
cmd.npi.optmgmt_req.QOS_offset = sizeof(cmd.npi.optmgmt_req);
bcopy(qos, (cmd.cbuf + sizeof(cmd.npi.optmgmt_req)), sizeof(*qos));
while ( (ret = putmsg(fd, &ctrl, NULL, MSG_HIPRI)) < 0 )
{
switch ( errno )
{
case EINTR:
case ERESTART:
continue;
}
break;
}
if ( ret < 0 )
{
perror("sctp_options: putmsg");
return -1;
}
if ( (ret = sctp_get(fd, 0)) < 0 )
{
fprintf(stderr,"\t...sctp_options: couldn't get message\n");
return -1;
}
if ( ret != N_OK_ACK )
{
fprintf(stderr,"\t...sctp_options: didn't get N_OK_ACK\n");
return -1;
}
fprintf(stderr,"\t...Options set\n");
return 0;
}
int
sctp_bind(int fd, addr_t *addr, int coninds)
{
int ret;
ctrl.len = sizeof(cmd.npi.bind_req)+sizeof(*addr);
cmd.prim = N_BIND_REQ;
cmd.npi.bind_req.ADDR_length = sizeof(*addr);
cmd.npi.bind_req.ADDR_offset = sizeof(cmd.npi.bind_req);
cmd.npi.bind_req.CONIND_number = coninds;
cmd.npi.bind_req.BIND_flags = TOKEN_REQUEST;
cmd.npi.bind_req.PROTOID_length = 0;
cmd.npi.bind_req.PROTOID_offset = 0;
bcopy(addr, (&cmd.npi.bind_req)+1, sizeof(*addr));
while ( (ret = putmsg(fd, &ctrl, NULL, MSG_HIPRI)) < 0 )
{
switch ( errno )
{
case EINTR:
case ERESTART:
continue;
}
break;
}
if ( ret < 0 )
{
perror("sctp_bind: putmsg");
return -1;
}
if ( (ret = sctp_get(fd, 0)) < 0 )
{
fprintf(stderr,"\t...sctp_bind: couldn't get message\n");
return -1;
}
if ( ret != N_BIND_ACK )
{
fprintf(stderr,"\t...sctp_bind: didn't get N_BIND_ACK\n");
return -1;
}
fprintf(stderr,"\t...STREAM bound\n");
return 0;
}
int
sctp_connect(int fd, addr_t *addr, N_qos_sel_conn_sctp_t *qos)
{
int ret;
ctrl.len = sizeof(cmd.npi.conn_req)+sizeof(*addr)+sizeof(*qos);
cmd.prim = N_CONN_REQ;
cmd.npi.conn_req.DEST_length = sizeof(*addr);
cmd.npi.conn_req.DEST_offset = sizeof(cmd.npi.conn_req);
cmd.npi.conn_req.CONN_flags = REC_CONF_OPT|EX_DATA_OPT;
cmd.npi.conn_req.QOS_length = sizeof(*qos);
cmd.npi.conn_req.QOS_offset = sizeof(cmd.npi.conn_req)+sizeof(*addr);
bcopy(addr, (cmd.cbuf + sizeof(cmd.npi.conn_req)), sizeof(*addr));
bcopy(qos, (cmd.cbuf + sizeof(cmd.npi.conn_req)+sizeof(*addr)), sizeof(*qos));
while ( (ret = putmsg(fd, &ctrl, NULL, 0)) < 0 )
{
switch ( errno )
{
case EINTR:
case ERESTART:
continue;
}
break;
}
if ( ret < 0 )
{
perror("sctp_connect: putmsg");
return -1;
}
if ( (ret = sctp_get(fd, 120000)) < 0 )
{
fprintf(stderr,"\t...sctp_connect: couldn't get message\n");
return -1;
}
if ( ret != N_CONN_CON )
{
fprintf(stderr,"\t...sctp_connect: didn't get N_CONN_CON\n");
return -1;
}
fprintf(stderr,"\t...STREAM connected\n");
return 0;
}
int
sctp_accept(int fd, int fd2, int tok)
{
int ret, seq;
if ( (ret = sctp_get(fd, -1)) < 0 )
{
fprintf(stderr,"sctp_accept: couldn't get message on listener\n");
return -1;
}
if ( ret != N_CONN_IND )
{
fprintf(stderr,"sctp_accept: didn't get N_CONN_IND\n");
return -1;
}
seq = cmd.npi.conn_ind.SEQ_number;
ctrl.len = sizeof(cmd.npi.conn_res);
cmd.prim = N_CONN_RES;
cmd.npi.conn_res.TOKEN_value = tok;
cmd.npi.conn_res.RES_offset = 0;
cmd.npi.conn_res.RES_length = 0;
cmd.npi.conn_res.SEQ_number = seq;
cmd.npi.conn_res.CONN_flags = REC_CONF_OPT|EX_DATA_OPT;
cmd.npi.conn_res.QOS_offset = 0;
cmd.npi.conn_res.QOS_length = 0;
if ( putmsg(fd, &ctrl, NULL, 0) < 0 )
{
perror("sctp_accept: putmsg");
return -1;
}
if ( (ret = sctp_get(fd, 0)) < 0 )
{
fprintf(stderr,"sctp_accept: couldn't get message\n");
return -1;
}
if ( ret != N_OK_ACK )
{
fprintf(stderr,"sctp_accept: didn't get N_OK_ACK\n");
return -1;
}
fprintf(stderr,"Connection Indication accepted\n");
return 0;
}
int
lm_try(int fd, char *caller, ulong expect)
{
int ret;
while ( (ret = putmsg(fd, &ctrl, NULL, MSG_HIPRI)) < 0 )
{
switch ( errno )
{
case EINTR:
case ERESTART:
continue;
}
break;
}
if ( ret < 0 )
{
fprintf(stderr,"ERROR: %s: putmsg: %s\n",caller,strerror(errno));
return -1;
}
if ( (ret = sctp_get(fd, 0)) < 0 )
{
fprintf(stderr,"ERROR: %s: getmsg: couldn't get message\n",caller);
return -1;
}
if ( ret != expect )
{
if ( ret == LM_ERROR_ACK )
{
fprintf(stderr,"ERROR: %s: %s\n",caller,strerror(cmd.lm.error_ack.unix_error));
return -1;
}
fprintf(stderr,"ERROR: %s: didn't get expected reply\n",caller);
return -1;
}
return 0;
}
int
lm_sg_add(int fd, uint sgid, uint tmode, uint aspid)
{
ctrl.len = sizeof(cmd.lm.sg_add);
cmd.prim = LM_SG_ADD_REQ;
cmd.lm.sg_add.sgid = sgid;
cmd.lm.sg_add.flags = LM_SG_PERM;
cmd.lm.sg_add.tmode = tmode;
cmd.lm.sg_add.prio = 1;
cmd.lm.sg_add.cost = 1;
cmd.lm.sg_add.aspid = aspid;
return lm_try(fd, "LM_SG_ADD_REQ", LM_OK_ACK);
}
int
lm_sg_del(int fd, uint sgid)
{
ctrl.len = sizeof(cmd.lm.sg_del);
cmd.prim = LM_SG_DEL_REQ;
cmd.lm.sg_del.sgid = sgid;
return lm_try(fd, "LM_SG_DEL_REQ", LM_OK_ACK);
}
int
lm_proc_add(int fd, uint type, uint aspid, uint spid)
{
ctrl.len = sizeof(cmd.lm.proc_add);
cmd.prim = LM_PROC_ADD_REQ;
cmd.lm.proc_add.type = type;
cmd.lm.proc_add.aspid = aspid;
cmd.lm.proc_add.spid = spid;
cmd.lm.proc_add.load = 1;
cmd.lm.proc_add.prio = 1;
cmd.lm.proc_add.cost = 1;
return lm_try(fd, "LM_PROC_ADD_REQ", LM_OK_ACK);
}
int
lm_proc_del(int fd, uint type, uint aspid, uint spid)
{
ctrl.len = sizeof(cmd.lm.proc_del);
cmd.prim = LM_PROC_DEL_REQ;
cmd.lm.proc_del.type = type;
cmd.lm.proc_del.aspid = aspid;
cmd.lm.proc_del.spid = spid;
return lm_try(fd, "LM_PROC_DEL_REQ", LM_OK_ACK);
}
int
lm_link_add(int fd, int muxid, int type, int spid)
{
ctrl.len = sizeof(cmd.lm.link_add);
cmd.prim = LM_LINK_ADD_REQ;
cmd.lm.link_add.muxid = muxid;
cmd.lm.link_add.type = type;
cmd.lm.link_add.aspid = aspid;
cmd.lm.link_add.spid = spid;
return lm_try(fd, "LM_LINK_ADD_REQ", LM_OK_ACK);
}
int
lm_link_del(int fd, int muxid)
{
ctrl.len = sizeof(cmd.lm.link_del);
cmd.prim = LM_LINK_DEL_REQ;
cmd.lm.link_del.muxid = muxid;
return lm_try(fd, "LM_LINK_DEL_REQ", LM_OK_ACK);
}
int
lm_as_add(int fd, int rc, int tmode, uint sgid, uint flags, uint muxid,
uint na, uint lpc, uint rpc, uint si)
{
mtp_addr_t key = { na, si, lpc };
(void)rpc;
ctrl.len = sizeof(cmd.lm.as_add)+sizeof(key);
cmd.prim = LM_AS_ADD_REQ;
cmd.lm.as_add.asid = rc;
cmd.lm.as_add.flags = flags;
cmd.lm.as_add.rc = rc;
cmd.lm.as_add.tmode = tmode;
cmd.lm.as_add.sgid = sgid;
cmd.lm.as_add.muxid = muxid;
cmd.lm.as_add.KEY_offset = sizeof(cmd.lm.as_add);
cmd.lm.as_add.KEY_length = sizeof(key);
bcopy(&key, (&cmd.lm.as_add)+1, sizeof(key));
return lm_try(fd, "LM_AS_ADD_REQ", LM_OK_ACK);
}
int
lm_as_del(int fd, int rc)
{
ctrl.len = sizeof(cmd.lm.as_del);
cmd.prim = LM_AS_DEL_REQ;
cmd.lm.as_del.asid = rc;
return lm_try(fd, "LM_AS_DEL_REQ", LM_OK_ACK);
}
int
lm_info(int fd)
{
ctrl.len = sizeof(cmd.lm.info_req);
cmd.prim = LM_INFO_REQ;
return lm_try(fd, "LM_INFO_REQ", LM_INFO_ACK);
}
int
mtp_put(int fd, char *caller)
{
int ret;
while ( (ret = putmsg(fd, &ctrl, NULL, MSG_HIPRI)) < 0 )
{
switch ( errno )
{
case EINTR:
case ERESTART:
continue;
}
break;
}
if ( ret < 0 )
{
fprintf(stderr,"ERROR: %s: putmsg: %s\n",caller,strerror(errno));
return -1;
}
return(0);
}
int
mtp_try(int fd, char *caller, ulong expect)
{
int ret;
if ( mtp_put(fd, caller) < 0 )
return(-1);
if ( (ret = sctp_get(fd, 0)) < 0 )
{
fprintf(stderr,"ERROR: %s: getmsg: couldn't get message\n",caller);
return -1;
}
if ( ret != expect )
{
if ( ret == N_ERROR_ACK )
{
fprintf(stderr,"ERROR: %s: %s\n",caller,strerror(cmd.npi.error_ack.UNIX_error));
return -1;
}
fprintf(stderr,"ERROR: %s: didn't get expected reply\n",caller);
return -1;
}
return 0;
}
int
mtp_bind_ack(int fd)
{
ctrl.len = sizeof(cmd.npi.bind_ack)+sizeof(mtp_addr_t);
cmd.prim = N_BIND_ACK;
/* change N_BIND_REQ into N_BIND_ACK */
return mtp_put(fd, "N_BIND_ACK");
}
int
mtp_ok_ack(int fd, uint prim)
{
ctrl.len = sizeof(cmd.npi.unbind_req);
cmd.prim = N_OK_ACK;
cmd.npi.ok_ack.CORRECT_prim = prim;
return mtp_put(fd, "N_OK_ACK");
}
int test_m3ua_sgp_a1(void)
{
int lfd, fd, pfd[2], mfd;
int muxid, muxpipe;
uint32_t token = 0;
int minor;
struct stat stat;
printf("ETSI M3UA Test A1 - ASP Side:\n");
printf("-----------------------------\n");
printf("Configuration:\n");
printf(" Routing Context = %d\n",routing_context);
printf(" Network Appearance = %d\n",network_appearance);
printf(" SGP Address = %s:%d\n",*aspp,sgp_port);
printf(" ASP Address = %s:%d\n",*sgpp,asp_port);
printf(" ASP Point Code X = %x\n",pcx);
printf(" SGP Point Code Z = %x\n",pcz);
printf("Preparing MTP3 Pipe:\n");
if ( pipe(pfd) < 0 )
{
perror("pipe");
exit(2);
}
printf("Pushing pipemod\n");
if ( ioctl(*pfd, I_PUSH, "pipemod") < 0 )
{
perror("ioctl");
exit(2);
}
printf("Opening SGP Mux:\n");
if ( (mfd = open("/dev/m3ua",O_NONBLOCK|O_RDWR)) < 0 )
{
perror("open");
exit(2);
}
if ( ioctl(mfd, I_SRDOPT, RMSGD) < 0 )
{
perror("ioctl");
exit(2);
}
if ( fstat(mfd, &stat) < 0 )
{
perror("fstat");
exit(2);
}
minor = stat.st_rdev & 0xff;
printf("Opened device major %d, minor %d\n",(int)(stat.st_rdev>>8),minor);
printf("Getting info about ASP\n");
if ( lm_info(mfd) < 0 )
exit(2);
minor = cmd.lm.info_ack.spid;
printf("Adding SG:\n");
if ( lm_sg_add(mfd, 1, 1, aspid) < 0 )
exit(2);
printf("Adding ASP:\n");
if ( lm_proc_add(mfd, LM_ASP|LM_UAP, aspid, 1) < 0 )
exit(2);
printf("Linking pipe under Mux\n");
if ( (muxpipe = ioctl(mfd, I_LINK, pfd[1])) < 0 )
{
perror("ioctl: I_LINK:");
exit(2);
}
printf("Adding Static AS w/ SS7-P:\n");
if ( lm_as_add(mfd, routing_context, 1 /* override */, 0 /* sgid */,
LM_AS_STATIC, muxpipe, network_appearance,
pcx, pcz, 3) < 0 )
exit(2);
printf("Opening accepting SCTP STREAM\n");
if ( (fd = open("/dev/sctp_n",O_NONBLOCK|O_RDWR)) < 0 )
{
perror("open");
exit(2);
}
printf("Setting IOCTL on accepting SCTP STREAM\n");
if ( ioctl(fd, I_SRDOPT, RMSGD) < 0 )
{
perror("ioctl");
exit(2);
}
printf("Binding accepting SCTP STREAM\n");
if ( sctp_bind(fd, &sgp_addr, 0) < 0 )
exit(2);
token = cmd.npi.bind_ack.TOKEN_value;
printf("Opening Listening SCTP STREAM\n");
if ( (lfd = open("/dev/sctp_n",O_NONBLOCK|O_RDWR)) < 0 )
{
perror("open");
exit(2);
}
printf("Setting IOCTL on Listening SCTP STREAM\n");
if ( ioctl(lfd, I_SRDOPT, RMSGD) < 0 )
{
perror("ioctl");
exit(2);
}
printf("Setting Options on Listening STREAM\n");
if ( sctp_options(lfd, 0, &qos_info) < 0 )
exit(2);
printf("Binding STREAM\n");
if ( sctp_bind(lfd, &sgp_addr, 1) < 0 )
exit(2);
printf("Waiting for ASP connection:\n");
if ( sctp_accept(lfd, fd, token) < 0 )
exit(2);
printf("Linking Association under Mux:\n");
if ( (muxid = ioctl(mfd, I_LINK, fd)) < 0 )
{
perror("ioctl: I_LINK:");
exit(2);
}
printf("Linking ASP:\n");
if ( lm_link_add(mfd, muxid, LM_ASP|LM_UAP, 0) < 0 )
exit(2);
/*
* Read our end of the pipe and look for an N_BIND_REQ, respond with
* an N_BIND_ACK and an N_UDERROR_IND indicating that pcz is
* available.
*/
printf("Waiting for AS active\n");
if ( sctp_get(pfd[0], 5000) == N_BIND_REQ )
{
printf("Got N_BIND_REQ\n");
if ( mtp_bind_ack(pfd[0]) < 0 )
exit(2);
}
/*
* Read our end of the pipe and look for N_UNITDATA_REQ. If the
* dpc is other than pcz, reply with an N_UDERROR_IND indicating that
* the given point code is prohibited. Otherwise, swap the point
* codes and echo it back as an N_UNITDATA_IND.
*/
printf("Exchanging MSUs:\n");
sleep(1);
/*
* When reading our end of the pipe, if we get an N_UNBIND_REQ, reply
* with an N_OK_ACK and we are done.
*/
printf("Waiting for AS inactive\n");
if ( sctp_get(pfd[0], 5000) == N_UNBIND_REQ )
{
printf("Got N_UNBIND_REQ\n");
if ( mtp_ok_ack(pfd[0], N_UNBIND_REQ) < 0 )
exit(2);
}
printf("Waiting for ASP down:\n");
sleep(1);
/*
* We don't actually get an ASP down.
*/
printf("Waiting for SCTP disconnect:\n");
sleep(1);
/*
* Wait for LM_ERROR_IND on mfd indicating that the SCTP association
* is down.
*/
printf("Unlinking ASP:\n");
if ( lm_link_del(mfd, muxid) < 0 )
exit(2);
printf("Unlinking SCTP Association:\n");
if ( ioctl(mfd, I_UNLINK, muxid) < 0 )
{
perror("ioctl: I_UNLINK:");
exit(2);
}
printf("Unlinking pipe:\n");
if ( ioctl(mfd, I_UNLINK, muxpipe) < 0 )
{
perror("ioctl: I_UNLINK:");
exit(2);
}
printf("Closing Listening SCTP Associations:\n");
if ( close(lfd) < 0 )
{
perror("close");
exit(2);
}
printf("Closing Accepting SCTP Associations:\n");
if ( close(fd) < 0 )
{
perror("close");
exit(2);
}
printf("Deleting AS:\n");
if ( lm_as_del(mfd, routing_context) < 0 )
exit(2);
printf("Deleting ASP:\n");
if ( lm_proc_del(mfd, LM_ASP|LM_UAP, aspid, 1) < 0 )
exit(2);
printf("Deleting SG:\n");
if ( lm_sg_del(mfd, 1) )
exit(2);
printf("Closing MUX:\n");
if ( close(mfd) < 0 )
{
perror("close");
exit(2);
}
printf("Done.\n");
exit(0);
}
int
main(int argc, char**argv)
{
int c;
struct hostent *haddr;
while (1)
{
int option_index = 0;
static struct option long_options[] =
{
{ "sgp-address", 1, 0, 's' },
{ "sgp-port", 1, 0, 'w' },
{ "asp-address", 1, 0, 'a' },
{ "asp-port", 1, 0, 'p' },
{ "routing-context", 1, 0, 'r' },
{ "network-appearance", 1, 0, 'n' },
{ "aspid", 1, 0, 'i' },
{ "point-code-X", 1, 0, 'x' },
{ "point-code-Z", 1, 0, 'z' },
{ "help", 0, 0, 'h' }
};
c = getopt_long(argc,argv,"s:w:a:p:r:n:i:x:z:h",long_options,&option_index);
if ( c == -1 )
break;
switch ( c )
{
case 0:
switch ( option_index )
{
case 0: goto option_s;
case 1: goto option_w;
case 2: goto option_a;
case 3: goto option_p;
case 4: goto option_r;
case 5: goto option_n;
case 6: goto option_i;
case 7: goto option_x;
case 8: goto option_z;
case 9: goto option_h;
default:
usage();
exit(1);
}
break;
case 's':
option_s:
strncpy(sgpbuf,optarg,HOST_BUF_LEN);
sgpadd = sgpbuf;
sgpp = &sgpadd;
break;
case 'w':
option_w:
sgp_port = atoi(optarg);
break;
case 'a':
option_a:
strncpy(aspbuf,optarg,HOST_BUF_LEN);
aspadd = aspbuf;
aspp = &aspadd;
break;
case 'p':
option_p:
asp_port = atoi(optarg);
break;
case 'r':
option_r:
routing_context = atoi(optarg);
break;
case 'n':
option_n:
network_appearance = atoi(optarg);
break;
case 'i':
option_i:
aspid = atoi(optarg);
break;
case 'x':
option_x:
pcx = atoi(optarg);
break;
case 'z':
option_z:
pcz = atoi(optarg);
break;
case 'h':
option_h:
usage();
exit(0);
default:
fprintf(stderr, "ERROR: Unrecognized option `%c'.\n",c);
usage();
exit(1);
}
}
if ( optind < argc )
{
fprintf(stderr, "ERROR: Option syntax: ");
while ( optind < argc )
fprintf(stderr, "%s ",argv[optind++]);
fprintf(stderr,"\n");
usage();
exit(1);
}
haddr = gethostbyname(*aspp);
asp_addr.port = asp_port;
asp_addr.addr[0].s_addr = *(uint32_t *)(haddr->h_addr);
haddr = gethostbyname(*sgpp);
sgp_addr.port = sgp_port;
sgp_addr.addr[0].s_addr = *(uint32_t *)(haddr->h_addr);
return test_m3ua_sgp_a1();
}
|
|||||||||||||||||||||||||||
|
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
|
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |
|||||||||||||||||||||||||||