OpenSS7
SS7 for the
Common Man

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified:

Home Overview Status News Documentation Resources About
   
 Overview
 Status
 News
 Documentation
 Resources
 About

   
Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/test/etsi_m3ua/test_m3ua_sgp_a1.c


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();
}


Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/test/etsi_m3ua/test_m3ua_sgp_a1.c

OpenSS7
SS7 for the
Common Man
Home Overview Status News Documentation Resources About

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified: