371 lines
8.7 KiB
C
371 lines
8.7 KiB
C
//////////////////////////////////////////////////
|
|
//Title : wxc_netcap.c
|
|
//Auhtor : Liu Wei
|
|
//Desc : wxc2 netcap implementation
|
|
//Created : 2007-06-05
|
|
//Revision :
|
|
//
|
|
//Revision :
|
|
//
|
|
//////////////////////////////////////////////////
|
|
|
|
#include "./include/pub_netcap.h"
|
|
|
|
/*@ignore@*/
|
|
#ifndef IPPROTO_SCTP
|
|
#define IPPROTO_SCTP 132
|
|
#endif
|
|
|
|
static NetCap tNC;
|
|
|
|
#define BASE 65521
|
|
|
|
static u32 NcAd32 ( u32 ad, u8 * buf, int len )
|
|
{
|
|
u32 s1 = ad & 0xffff;
|
|
u32 s2 = ( ad >> 16 ) & 0xffff;
|
|
int n;
|
|
|
|
for ( n = 0; n < len; n++, buf++ )
|
|
{
|
|
s1 = ( s1 + *buf );
|
|
|
|
if ( s1 >= BASE )
|
|
s1 -= BASE;
|
|
|
|
s2 = ( s2 + s1 );
|
|
|
|
if ( s2 >= BASE )
|
|
{
|
|
|
|
s2 -= BASE;
|
|
}
|
|
}
|
|
return ( s2 << 16 ) + s1;
|
|
}
|
|
|
|
#define HEADER_LEN 12
|
|
|
|
static u32 NcCS ( u8 * ptr, u16 count )
|
|
{
|
|
|
|
u32 ad = 1L;
|
|
u32 zero = 0L;
|
|
|
|
ad = NcAd32 ( ad, ptr, sizeof ( HEADER_LEN - sizeof ( u32 ) ) );
|
|
ad = NcAd32 ( ad, ( u8 * ) & zero, sizeof ( u32 ) );
|
|
ptr += HEADER_LEN;
|
|
count -= HEADER_LEN;
|
|
|
|
ad = NcAd32 ( ad, ptr, count );
|
|
return ad;
|
|
}
|
|
|
|
static int NcGetSocket ( u32 port )
|
|
{
|
|
int nSock;
|
|
int nOn = 1;
|
|
unsigned long cmdarg = 1;
|
|
struct sockaddr_in sin_addr;
|
|
|
|
sin_addr.sin_family = AF_INET;
|
|
sin_addr.sin_port = htons ( port );
|
|
sin_addr.sin_addr.s_addr = GetLocalIP(); //htonl ( INADDR_ANY );
|
|
|
|
if ( ( nSock = socket ( AF_INET, SOCK_RAW, IPPROTO_SCTP ) ) < 0 )
|
|
{
|
|
perror ( "Get SCTP socket error " );
|
|
return -1;
|
|
}
|
|
|
|
setsockopt ( nSock, SOL_SOCKET, SO_REUSEADDR, &nOn, sizeof ( nOn ) );
|
|
|
|
ioctl ( nSock, FIONBIO, &cmdarg );
|
|
|
|
return ( nSock );
|
|
}
|
|
|
|
extern void NcSetPort ( u32 port )
|
|
{
|
|
tNC.nPort = port;
|
|
}
|
|
|
|
extern void NcSetIP ( u32 ip )
|
|
{
|
|
tNC.nDstIp = ip;
|
|
}
|
|
|
|
extern int NcInit ( )
|
|
{
|
|
memset ( &tNC, 0, sizeof ( NetCap ) );
|
|
tNC.nPort = 8000;
|
|
tNC.nDstIp = inet_addr ( "172.54.240.3" );
|
|
return 1;
|
|
}
|
|
|
|
extern int NcStart ( u32 wIP, u32 wPort )
|
|
{
|
|
if ( tNC.uState )
|
|
return 0;
|
|
tNC.nDstIp = wIP ? wIP : tNC.nDstIp;
|
|
tNC.nPort = wPort ? wPort : tNC.nPort;
|
|
tNC.nSock = NcGetSocket ( tNC.nPort );
|
|
tNC.uState = 1;
|
|
return 1;
|
|
}
|
|
|
|
extern int NcStop ( )
|
|
{
|
|
shutdown ( tNC.nSock, 2 );
|
|
tNC.uState = 0;
|
|
return 1;
|
|
}
|
|
|
|
#define SCTP_HEADER_LEN 0x1C
|
|
|
|
#define SCCTP_CS_POS 0x08
|
|
|
|
#define SCTP_CHUNKLEN_POS 15
|
|
|
|
static u8 SCTP_HEADER[] = {
|
|
0x13, 0x56, 0x13, 0x56, 0x00, 0x00, 0x2d, 0xd1,
|
|
0x05, 0x67, 0x59, 0x7a, 0x00, 0x00, 0x00, 0x3c,
|
|
0x00, 0x00, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11,
|
|
0x00, 0x00, 0x00, 0x02
|
|
};
|
|
|
|
static int NcStuffSCTP ( u8 * pIPBuff )
|
|
{
|
|
memcpy ( pIPBuff, SCTP_HEADER, SCTP_HEADER_LEN );
|
|
pIPBuff[0] = 4950 >> 8;
|
|
pIPBuff[1] = 4950 & 0xFF;
|
|
pIPBuff[2] = tNC.nPort >> 8;
|
|
pIPBuff[3] = tNC.nPort & 0xFF;
|
|
return SCTP_HEADER_LEN;
|
|
}
|
|
|
|
#define M2UA_HEADER_LEN 0x14
|
|
|
|
#define M2UA_MSGLEN_POS 0x07
|
|
|
|
#define M2UA_PARALEN_POS 0x13
|
|
|
|
static inline int NcGetM2uaParaLen ( u32 wMtp3Len )
|
|
{
|
|
return ( wMtp3Len + 4 );
|
|
}
|
|
|
|
static inline int NcGetM2uaMsgLen ( u32 wMtp3Len )
|
|
{
|
|
return ( NcGetM2uaParaLen ( wMtp3Len ) + 16 );
|
|
}
|
|
|
|
static u8 M2UA_HEADER[] = {
|
|
0x01, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x2c,
|
|
0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
|
|
0x03, 0x00, 0x00, 0x1c
|
|
};
|
|
|
|
int NcStuffM2UA ( u8 * pIPBuff, u32 wMtp3Len )
|
|
{
|
|
memcpy ( pIPBuff, M2UA_HEADER, M2UA_HEADER_LEN );
|
|
*( pIPBuff + M2UA_PARALEN_POS ) = NcGetM2uaParaLen ( wMtp3Len );
|
|
*( pIPBuff + M2UA_MSGLEN_POS ) = NcGetM2uaMsgLen ( wMtp3Len );
|
|
return M2UA_HEADER_LEN;
|
|
}
|
|
|
|
#define MTP3_HAEDER_ANSI_LEN 0x08
|
|
|
|
static u8 MTP3_HEADER_ANSI[] = {
|
|
0x83, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
#define MTP3_HAEDER_ITU_LEN 0x05
|
|
|
|
static u8 MTP3_HEADER_ITU[] = {
|
|
0x83, 0x20, 0x00, 0x08, 0x00
|
|
};
|
|
|
|
static int NcStuffMtp3 ( u8 * pIPBuff, u32 wDPC, u32 wOPC, u8 uSLS,
|
|
u8 uAnsiFlag )
|
|
{
|
|
u32 MTP3_HAEDER_LEN;
|
|
u8 *MTP3_HEADER;
|
|
|
|
//printf ( "stuff mtp3 : dpc :%ld opc :%ld sls: %d , ansi :%d \n", wDPC, wOPC,
|
|
// uSLS, uAnsiFlag );
|
|
if ( uAnsiFlag )
|
|
{
|
|
MTP3_HEADER_ANSI[1] = wDPC ? MTP3_HEADER_ANSI[1] : wDPC;
|
|
MTP3_HEADER_ANSI[4] = wOPC ? MTP3_HEADER_ANSI[4] : wOPC;
|
|
MTP3_HEADER_ANSI[7] = uSLS ? MTP3_HEADER_ANSI[7] : uSLS;
|
|
}
|
|
else
|
|
{
|
|
if ( wDPC )
|
|
{
|
|
MTP3_HEADER_ITU[1] = wDPC & 0xFF;
|
|
MTP3_HEADER_ITU[2] &= 0xC0;
|
|
MTP3_HEADER_ITU[2] |= ( wDPC >> 8 ) & 0x3F;
|
|
}
|
|
if ( wOPC )
|
|
{
|
|
MTP3_HEADER_ITU[2] &= 0x3F;
|
|
MTP3_HEADER_ITU[2] |= ( wDPC & 0x03 ) << 6;
|
|
MTP3_HEADER_ITU[3] = wDPC >> 2;
|
|
MTP3_HEADER_ITU[4] &= 0xF0;
|
|
MTP3_HEADER_ITU[4] |= wOPC >> 10;
|
|
}
|
|
|
|
MTP3_HEADER_ITU[4] &= 0x0F;
|
|
MTP3_HEADER_ITU[4] |= uSLS << 4;
|
|
}
|
|
|
|
MTP3_HEADER = uAnsiFlag ? MTP3_HEADER_ANSI : MTP3_HEADER_ITU;
|
|
MTP3_HAEDER_LEN = uAnsiFlag ? MTP3_HAEDER_ANSI_LEN : MTP3_HAEDER_ITU_LEN;
|
|
|
|
memcpy ( pIPBuff, MTP3_HEADER, MTP3_HAEDER_LEN );
|
|
return MTP3_HAEDER_LEN;
|
|
}
|
|
|
|
extern void NcMtp3Send ( u8 * pMtp3Msg, u32 wMtp3Len, u8 uAnsiFlag )
|
|
{
|
|
u8 IPBuff[512];
|
|
u32 wPackLen = 0;
|
|
u32 wM2uaLen = 0;
|
|
u32 ad = 0;
|
|
u32 MTP3_HAEDER_LEN;
|
|
u8 uPad = 0;
|
|
struct sockaddr_in sin_addr;
|
|
|
|
memset ( IPBuff, 0, 512 * sizeof ( u8 ) );
|
|
wPackLen += NcStuffSCTP ( IPBuff + wPackLen );
|
|
MTP3_HAEDER_LEN = uAnsiFlag ? MTP3_HAEDER_ANSI_LEN : MTP3_HAEDER_ITU_LEN;
|
|
wM2uaLen = NcStuffM2UA ( IPBuff + wPackLen, wMtp3Len );
|
|
wPackLen += wM2uaLen;
|
|
memcpy ( IPBuff + wPackLen, pMtp3Msg, wMtp3Len );
|
|
wPackLen += wMtp3Len;
|
|
|
|
uPad = ( IPBuff[SCTP_HEADER_LEN + 7] ) % 4;
|
|
uPad = uPad ? ( 4 - uPad ) : 0;
|
|
|
|
for ( ; uPad > 0; uPad-- )
|
|
{
|
|
IPBuff[SCTP_HEADER_LEN + 7]++; //m2ua msg len
|
|
IPBuff[wPackLen++] = 0x00;
|
|
}
|
|
|
|
IPBuff[SCTP_CHUNKLEN_POS] = 0x10 + IPBuff[SCTP_HEADER_LEN + 7];
|
|
|
|
ad = NcCS ( IPBuff, wPackLen );
|
|
IPBuff[SCCTP_CS_POS] = ad & 0xFF;
|
|
IPBuff[SCCTP_CS_POS + 1] = ad / ( 256 );
|
|
IPBuff[SCCTP_CS_POS + 2] = ad / ( 256 * 256 );
|
|
IPBuff[SCCTP_CS_POS + 3] = ad / ( 256 * 256 * 256 );
|
|
|
|
sin_addr.sin_family = AF_INET;
|
|
sin_addr.sin_port = htons ( tNC.nPort );
|
|
sin_addr.sin_addr.s_addr = tNC.nDstIp;
|
|
|
|
sendto ( tNC.nSock, ( char * ) IPBuff, wPackLen, 0,
|
|
( struct sockaddr * ) &sin_addr, sizeof ( struct sockaddr ) );
|
|
//printf ( "\nMTP3 Send Net cap message!\n " );
|
|
}
|
|
|
|
typedef struct WXC_NETCAP_SCCP_INTRA_MESSAGE
|
|
{
|
|
u8 msgsource;
|
|
u8 msgtype;
|
|
u8 msgclass;
|
|
u8 msgMNP;
|
|
int OPC;
|
|
int DPC;
|
|
u8 SLS;
|
|
}
|
|
Wxc_NCSccpIntra;
|
|
|
|
extern int NcSccpSend ( u8 * pSccpMsg, u32 wSccpLen, u8 * pIntraMsg,
|
|
BYTE uAnsiFlag )
|
|
{
|
|
u8 IPBuff[512];
|
|
u32 wPackLen = 0;
|
|
u32 wM2uaLen = 0;
|
|
u32 ad = 0;
|
|
u8 uPad = 0;
|
|
u32 MTP3_HAEDER_LEN;
|
|
struct sockaddr_in sin_addr;
|
|
Wxc_NCSccpIntra *pIntra = ( Wxc_NCSccpIntra * ) pIntraMsg;
|
|
|
|
memset ( IPBuff, 0, 512 * sizeof ( u8 ) );
|
|
wPackLen += NcStuffSCTP ( IPBuff + wPackLen );
|
|
MTP3_HAEDER_LEN = uAnsiFlag ? MTP3_HAEDER_ANSI_LEN : MTP3_HAEDER_ITU_LEN;
|
|
wM2uaLen = NcStuffM2UA ( IPBuff + wPackLen, wSccpLen + MTP3_HAEDER_LEN );
|
|
wPackLen += wM2uaLen;
|
|
|
|
wPackLen +=
|
|
NcStuffMtp3 ( IPBuff + wPackLen, pIntra->DPC, pIntra->DPC, pIntra->SLS,
|
|
uAnsiFlag );
|
|
memcpy ( IPBuff + wPackLen, pSccpMsg, wSccpLen );
|
|
wPackLen += wSccpLen;
|
|
|
|
uPad = ( IPBuff[SCTP_HEADER_LEN + 7] ) % 4;
|
|
uPad = uPad ? ( 4 - uPad ) : 0;
|
|
|
|
for ( ; uPad > 0; uPad-- )
|
|
{
|
|
IPBuff[SCTP_HEADER_LEN + 7]++; //m2ua msg len
|
|
IPBuff[wPackLen++] = 0x00;
|
|
}
|
|
|
|
IPBuff[SCTP_CHUNKLEN_POS] = 0x10 + IPBuff[SCTP_HEADER_LEN + 7];
|
|
|
|
ad = NcCS ( IPBuff, wPackLen );
|
|
|
|
IPBuff[SCCTP_CS_POS] = ad & 0xFF;
|
|
IPBuff[SCCTP_CS_POS + 1] = ad / ( 256 );
|
|
IPBuff[SCCTP_CS_POS + 2] = ad / ( 256 * 256 );
|
|
IPBuff[SCCTP_CS_POS + 3] = ad / ( 256 * 256 * 256 );
|
|
|
|
sin_addr.sin_family = AF_INET;
|
|
sin_addr.sin_port = htons ( tNC.nPort );
|
|
sin_addr.sin_addr.s_addr = tNC.nDstIp;
|
|
|
|
if ( sendto
|
|
( tNC.nSock, ( char * ) IPBuff, wPackLen, 0,
|
|
( struct sockaddr * ) &sin_addr, sizeof ( struct sockaddr ) ) < 0 )
|
|
{
|
|
perror ( "SCCP send tNC error!\n" );
|
|
return 0;
|
|
}
|
|
|
|
//printf ( "\nSCCP Send Net cap message!\n " );
|
|
//write(nSock, IPBuff, wPackLen);
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
#define SCCP_RLSE_LEN 0x0a
|
|
|
|
static u8 SCCP_RLSD[ ] =
|
|
{
|
|
0x04, 0x01, 0x04, 0x00, 0x00, 0x00, 0x74, 0x00, 0x01,
|
|
0x00
|
|
};
|
|
|
|
void main()
|
|
{
|
|
int i;
|
|
|
|
NcInit();
|
|
NcStart(inet_addr("10.167.144.35") , 8000 );
|
|
for( i = 0 ; i < 5000 ; i ++ )
|
|
{
|
|
sleep(1);
|
|
NcSccpSend( SCCP_RLSD , SCCP_RLSE_LEN );
|
|
}
|
|
NcStop();
|
|
return ;
|
|
}
|
|
*/
|
|
/*@end@*/
|