Files
svc.ems/plat/public/ut/inet/pub_inet_test.c
2024-09-27 15:39:34 +08:00

647 lines
14 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//////////////////////////////////////////////////
//Title : pub_inet_test.c
//Auhtor : Liu Wei
//Desc : public ipnet function test
//Created : 2007-06-22
//Revision :
//
//Revision :
//
//////////////////////////////////////////////////
#include <stdio.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netdb.h>
#include <setjmp.h>
#include <errno.h>
#include <string.h>
typedef unsigned char u8;
typedef unsigned int u32;
typedef unsigned short u16;
#define MAXINTERFACES 16
typedef struct EIF
{
u32 dIfIP;
u8 uIfState;
}
EIF;
typedef struct IF_ADDR
{
EIF tIfEntity[MAXINTERFACES];
u8 uIfNum;
}
IfAddr;
int GetNetIfInfo ( IfAddr * pIfAddr )
{
int fd;
struct ifreq buf[MAXINTERFACES];
struct arpreq arp;
struct ifconf ifc;
pIfAddr->uIfNum = 0;
if( ( fd = socket ( AF_INET, SOCK_DGRAM, 0 ) ) >= 0 )
{
ifc.ifc_len = sizeof buf;
ifc.ifc_buf = ( caddr_t ) buf;
if( !ioctl ( fd, SIOCGIFCONF, ( char * ) &ifc ) )
{
int i;
pIfAddr->uIfNum = ifc.ifc_len / sizeof ( struct ifreq );
pIfAddr->uIfNum = pIfAddr->uIfNum % MAXINTERFACES;
for ( i = 0; i < pIfAddr->uIfNum; i++ )
{
ioctl ( fd, SIOCGIFFLAGS, ( char * ) &buf[i] );
pIfAddr->tIfEntity[i].uIfState = buf[i].ifr_flags & IFF_UP;
if( !( ioctl ( fd, SIOCGIFADDR, ( char * ) &buf[i] ) ) )
{
pIfAddr->tIfEntity[i].dIfIP = ( ( struct sockaddr_in * )
( &buf[i].ifr_addr ) )->sin_addr.s_addr;
}
}
}
}
close ( fd );
return pIfAddr->uIfNum;
}
#define PACKET_SIZE 4096
#define MAX_NO_PACKETS 3
struct sockaddr_in dest_addr;
struct sockaddr_in from;
struct timeval tvrecv;
typedef void PingCallBack( int nPingResult );
typedef struct ICMP_SERVICE
{
u8 uSrvState;
u8 uPingResult;
u8 uIcmpState;
u8 uPackNo;
u8 uDataLen;
u8 nPackNumSend;
u8 nPackNumRecv;
u8 aSendBuff[PACKET_SIZE];
u8 aRecvBuff[PACKET_SIZE];
u32 wSockfd;
pid_t tPid;
struct protoent *pProtoent;
PingCallBack *fCallBack;
}
IcmpSrv;
IcmpSrv tIcmpSrvEntity;
//У<><D0A3><EFBFBD><EFBFBD><EFBFBD>
u16 IcmpCheckSum ( u16 *addr, int len )
{
int nleft = len;
int sum = 0;
u16 *w = addr;
u16 answer = 0;
//<2F><>ICMP<4D><50>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>ֽ<EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD>ۼ<EFBFBD><DBBC><EFBFBD><EFBFBD><EFBFBD>
while ( nleft > 1 )
{
sum += *w++;
nleft -= 2;
}
//<2F><>ICMP<4D><50>ͷΪ<CDB7><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڣ<D6BD><DAA3><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ֽڡ<D6BD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>Ϊһ<CEAA><D2BB>2<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݵĸ<DDB5><C4B8>ֽڣ<D6BD><DAA3><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݵĵ<DDB5><C4B5>ֽ<EFBFBD>Ϊ0<CEAA><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD>
if( nleft == 1 )
{
*( unsigned char * ) ( &answer ) = *( unsigned char * ) w;
sum += answer;
}
sum = ( sum >> 16 ) + ( sum & 0xffff );
sum += ( sum >> 16 );
answer = ~sum;
return answer;
}
//<2F><><EFBFBD><EFBFBD>ICMP<4D><50>ͷ
int IcmpPacking ( IcmpSrv *pIS )
{
int i, packsize;
struct icmp *icmp;
struct timeval *tval;
icmp = ( struct icmp * ) pIS->aSendBuff;
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_code = 0;
icmp->icmp_cksum = 0;
icmp->icmp_seq = pIS->nPackNumSend;
icmp->icmp_id = pIS->tPid;
packsize = 8 + pIS->uDataLen;
//<2F><>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
tval = ( struct timeval * ) icmp->icmp_data;
gettimeofday ( tval, NULL );
icmp->icmp_cksum = IcmpCheckSum ( (u16 *)icmp, packsize );
return packsize;
}
//<2F><>ȥICMP<4D><50>ͷ
int IcmpUnPack ( u8 *buf, int len , IcmpSrv *pIS )
{
int i, nIpHdrLen;
struct ip *pIP;
struct icmp *icmp;
struct timeval *tvSend;
struct timeval tvRecv;
double rtt;
gettimeofday ( &tvRecv, NULL );
pIP = ( struct ip * ) buf;
//<2F><>ip<69><70>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>,<2C><>ip<69><70>ͷ<EFBFBD>ij<EFBFBD><C4B3>ȱ<EFBFBD>־<EFBFBD><D6BE>4
nIpHdrLen = pIP->ip_hl << 2;
//Խ<><D4BD>ip<69><70>ͷ,ָ<><D6B8>ICMP<4D><50>ͷ
icmp = ( struct icmp * ) ( buf + nIpHdrLen );
//ICMP<4D><50>ͷ<EFBFBD><CDB7>ICMP<4D><50><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>
len -= nIpHdrLen;
if( len < 8 )
//С<><D0A1>ICMP<4D><50>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>򲻺<EFBFBD><F2B2BBBA><EFBFBD>
{
printf ( "ICMP packets's length is less than 8 " );
return 0;
}
//ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ICMP<4D>Ļ<EFBFBD>Ӧ
if( ( icmp->icmp_type == ICMP_ECHOREPLY ) && ( icmp->icmp_id == pIS->tPid ) )
{
tvSend = ( struct timeval * ) icmp->icmp_data;
rtt = ( tvRecv.tv_sec * 1000 + tvRecv.tv_usec / 1000 ) -
( tvSend->tv_sec * 1000 + tvSend->tv_usec / 1000 );
printf ( "%d byte from %s: icmp_seq=%u ttl=%d rtt=%.3f ms \n"
, len, inet_ntoa ( from.sin_addr )
, icmp->icmp_seq, pIP->ip_ttl, rtt
);
return 1;
}
return 0;
}
void IcmpStatis ( IcmpSrv *pIS )
{
int nSend , nRecv ;
nSend = pIS->nPackNumSend;
nRecv = pIS->nPackNumRecv;
printf ( " --------------------PING statistics------------------- \n" );
printf ( "%d packets transmitted, %d received , %%%d lost \n\n"
, nSend, nRecv, ( nSend - nRecv ) / nSend * 100 );
close ( pIS->wSockfd );
pIS->uSrvState = 0;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ICMP<4D><50><EFBFBD><EFBFBD>
int IcmpSend ( IcmpSrv *pIS )
{
int nSize;
if ( pIS->nPackNumSend < MAX_NO_PACKETS )
{
pIS->nPackNumSend++;
nSize = IcmpPacking ( pIS );
//<2F><><EFBFBD><EFBFBD>ICMP<4D><50>ͷ
if( sendto ( pIS->wSockfd, pIS->aSendBuff, nSize, 0,
( struct sockaddr * ) &dest_addr, sizeof ( dest_addr ) ) < 0 )
{
perror ( "sendto error" );
return 0;
}
printf("[IcmpSend] : Send icmp Pack %d \n" , pIS->nPackNumSend);
return 1;
}
return 0;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ICMP<4D><50><EFBFBD><EFBFBD>
void IcmpRecv ( IcmpSrv *pIS )
{
int n, fromlen;
extern int errno;
fromlen = sizeof ( from );
while ( pIS->nPackNumRecv < pIS->nPackNumSend )
{
if( ( n = recvfrom ( pIS->wSockfd, pIS->aRecvBuff, sizeof ( pIS->aRecvBuff ),
0, ( struct sockaddr * ) &from, &fromlen ) ) < 0 )
{
if( errno == EINTR )
continue;
perror ( "recvfrom error" );
continue;
}
if( IcmpUnPack ( pIS->aRecvBuff, n , pIS ) == -1 )
continue;
pIS->nPackNumRecv++;
}
}
int PingInit ( IcmpSrv *pIS , int nDataLen )
{
memset( pIS , 0 , sizeof(IcmpSrv) );
pIS->uSrvState = 0;
pIS->uDataLen = 56;
if( ( pIS->pProtoent = getprotobyname ( "icmp" ) ) == NULL )
{
perror ( "getprotobyname" );
exit ( 1 );
}
// <20><><EFBFBD><EFBFBD>rootȨ<74><C8A8>,<2C><><EFBFBD>õ<EFBFBD>ǰ<EFBFBD>û<EFBFBD>Ȩ<EFBFBD><C8A8>
setuid ( getuid ( ) );
//<2F><>ȡmain<69>Ľ<EFBFBD><C4BD><EFBFBD>id,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ICMP<4D>ı<EFBFBD>־<EFBFBD><D6BE>
pIS->tPid = getpid ( );
}
int PingTimer ( IcmpSrv *pIS )
{
if( pIS->uSrvState )
{
IcmpRecv( pIS );
switch( pIS->uIcmpState )
{
case 1:
case 2:
case 3:
IcmpSend( pIS );
pIS->uIcmpState++;
break;
default:
if( pIS->nPackNumRecv >= 3 )
{
IcmpStatis( pIS );
pIS->fCallBack( 1 );
}
if( pIS->uIcmpState++ > 200 )
{
IcmpStatis( pIS );
pIS->fCallBack( 0 );
}
break;
}
}
}
int PingStart( IcmpSrv *pIS , char *sIP , PingCallBack fCallBack )
{
int nSize;
struct hostent *pHost;
//struct in_addr *pInAddr;
u32 nInetAddr;
if( pIS->uSrvState )
{
return 0;
}
pIS->fCallBack = fCallBack;
//<2F><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>ICMP<4D><50>ԭʼ<D4AD>׽<EFBFBD><D7BD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD>׽<EFBFBD><D7BD><EFBFBD>ֻ<EFBFBD><D6BB>root<6F><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if( ( pIS->wSockfd = socket ( AF_INET, SOCK_RAW, pIS->pProtoent->p_proto ) ) < 0 )
{
perror ( "socket error" );
exit ( 1 );
}
//<2F><><EFBFBD><EFBFBD><EFBFBD>׽<EFBFBD><D7BD>ֽ<EFBFBD><D6BD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>50K<30><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҪΪ<D2AA>˼<EFBFBD>С<EFBFBD><D0A1><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ping<6E><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
setsockopt ( pIS->wSockfd, SOL_SOCKET, SO_RCVBUF, &nSize, sizeof ( nSize ) );
bzero ( &dest_addr, sizeof ( dest_addr ) );
dest_addr.sin_family = AF_INET;
//<2F>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ip<69><70>ַ
nInetAddr = inet_addr ( sIP ) ;
if( nInetAddr == INADDR_NONE )
{
if( ( pHost = gethostbyname ( sIP ) ) == NULL ) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
perror ( "gethostbyname error" );
exit ( 1 );
}
memcpy ( ( char * ) &dest_addr.sin_addr, pHost->h_addr, pHost->h_length );
}
else //<2F><>ip<69><70>ַ
{
dest_addr.sin_addr.s_addr = nInetAddr;
//memcpy( (char *)&dest_addr,(char *)&nInetAddr,host->h_length);
}
printf ( "PING %s(%s): %d bytes data in ICMP packets. \n", sIP
, inet_ntoa ( dest_addr.sin_addr ) , pIS->uDataLen );
pIS->uSrvState = 1 ;
pIS->uIcmpState = 1;
}
//<2F><>ӡip<69><70><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>Ϣ
void printIP ( char *packet, int len )
{
struct sockaddr_in addr_src, addr_dst;
struct ip *pip = ( struct ip * ) packet;
printf ( "ip head len:%d ", pip->ip_hl << 2 );
printf ( "ip len:%d ", ntohs ( pip->ip_len ) );
printf ( "ip pro id:%d ", pip->ip_p );
printf ( "ip ttl:%d ", pip->ip_ttl );
printf ( "ip offset:%d ", ntohs ( pip->ip_off ) & IP_OFFMASK );
memset ( &addr_src, 0, sizeof ( struct sockaddr_in ) );
memset ( &addr_dst, 0, sizeof ( struct sockaddr_in ) );
memcpy ( &addr_src, &pip->ip_src, sizeof ( struct sockaddr_in ) );
memcpy ( &addr_dst, &pip->ip_dst, sizeof ( struct sockaddr_in ) );
printf ( "src ip:%x ", addr_src.sin_addr );
printf ( "dst ip:%x ", addr_dst.sin_addr );
}
void NetCapPing( int nRet )
{
if( nRet )
{
printf("Host is rearchable\n");
}
else
{
printf("Host is not rearchable\n");
}
}
static char *pStrEqTok = NULL;
static u8 uStrEqState = 0;
#define CNULL '\0'
#define STR_CHECK_END(str,ch) ( str[strlen(str)-1] == ch )
#define STR_CUT_LAST(str) ( str[strlen(str)-1] = CNULL )
void StrTrimMoreSpace(char *pStr )
{
char *pSrc , *pDst , *pCh;
pDst = pStr;
pCh = pSrc = strdup( pStr );
for( ; *pSrc ; pSrc++ )
{
if( !( isspace(*pSrc) && isspace( *(pSrc+1) ) ) )
{
*pDst++ = *pSrc;
}
}
*pDst = CNULL;
}
char *StrEqTok( char *pStr )
{
char *p, *pCh;
char *pDel = " ";
pCh = NULL;
if( pStr == NULL )
{
pStr = pStrEqTok;
}
else
{
pStr += strspn (pStr, pDel);
if (*pStr == '\0')
{
pStrEqTok = NULL;
return NULL;
}
StrTrimMoreSpace( pStr );
}
if( pStr == NULL )
{
return NULL;
}
uStrEqState = uStrEqState > 2 ? 0 : uStrEqState;
pCh = strpbrk (pStr, pDel );
if( pCh == NULL )
{
pStrEqTok = NULL;
pCh = pStr;
}
else
{
pStrEqTok = pCh + 1;
*pCh = CNULL;
pCh = pStr;
}
p = strchr( pCh , '=');
if( p == NULL )
{
if( pStrEqTok == NULL )
{
goto STREQTOK_CLEAN_UP;
}
if( uStrEqState == 0 || uStrEqState == 2 )
{ //expres left and right
uStrEqState++;
return pCh;
}
else
{ //Miss '='
goto STREQTOK_CLEAN_UP;
}
}
else
{
if( uStrEqState == 0 && STR_CHECK_END( pCh , '=') )
{ //expres left and '='
uStrEqState+=2;
STR_CUT_LAST(pCh);
return pCh;
}
else if( uStrEqState == 1 && pCh[0] == '=')
{ //'=' meet
if( pCh[1] == CNULL )
{
if( pStrEqTok == NULL )
{
goto STREQTOK_CLEAN_UP;
}
pStr = pStrEqTok;
pCh = strpbrk (pStr, pDel);
if( pCh == NULL )
{
pStrEqTok = NULL;
pCh = pStr;
}
else
{
pStrEqTok = pCh + 1;
*pCh = CNULL;
pCh = pStr;
}
uStrEqState = 3;
return pCh;
}
else
{ //expres '=' and right
uStrEqState = 3; //all meet
return ++pCh;
}
}
else if( uStrEqState == 0 )
{ //expres left and '=' and right
if( pStrEqTok != NULL )
{
*(pStrEqTok -1) = ' ';
}
pStrEqTok = p + 1;
*p = CNULL;
uStrEqState = 2;
return pCh;
}
else
{
goto STREQTOK_CLEAN_UP;
}
}
STREQTOK_CLEAN_UP:
pStrEqTok = NULL;
uStrEqState = 0;
return NULL;
}
int main ( )
{
int i, ret = 0;
IfAddr tIfAddr;
IcmpSrv tIcmpSrv;
char tmpStr[80];
ret = GetNetIfInfo ( &tIfAddr );
printf ( "Interface num :%d \n\n", ret );
for ( i = 0; i < ret; i++ )
{
printf ( "If %d : state : %d ip : %s \n\n"
, i, tIfAddr.tIfEntity[i].uIfState
, inet_ntoa ( *((struct in_addr* )&tIfAddr.tIfEntity[i].dIfIP ))
);
}
#define STR(s) #s
printf(STR(if(NOTSO(a)) return 0\n));
#define FPOS( type, field ) /*lint -e545 */ ( (u32) &(( type *) 0)-> field ) /*lint +e545 */
#define FSIZ( type, field ) sizeof( ((type *) 0)->field )
printf("Pos : %ld \n" , FPOS(IfAddr ,uIfNum ) );
printf("Size : %ld \n" , FSIZ(IfAddr ,uIfNum ) );
printf("Pos : %ld \n" , FPOS(IfAddr ,tIfEntity ) );
printf("Size : %ld \n" , FSIZ(IfAddr ,tIfEntity ) );
printf("Pos : %ld \n" , FPOS(EIF ,dIfIP ) );
printf("Size : %ld \n" , FSIZ(EIF ,dIfIP ) );
printf("Pos : %ld \n" , FPOS(EIF ,uIfState ) );
printf("Size : %ld \n" , FSIZ(EIF ,uIfState ) );
printf("Pos : %ld \n" , FPOS(IcmpSrv ,nPackNumSend ) );
printf("Size : %ld \n" , FSIZ(IcmpSrv ,nPackNumSend ) );
printf("Pos : %ld \n" , FPOS(IcmpSrv ,aSendBuff ) );
printf("Size : %ld \n" , FSIZ(IcmpSrv ,aSendBuff ) );
printf("Please input ip and port : ");
fgets( tmpStr, 80 ,stdin );
printf("%s\n", tmpStr);
if( STR_CHECK_END(tmpStr , '\n' ) )
{
STR_CUT_LAST(tmpStr );
}
//StrTrimMoreSpace(tmpStr);
//printf("trim space : \n%s\n" ,tmpStr );
{
char *p = NULL;
u8 uFlag = 0;
p = StrEqTok(tmpStr);
printf( "Name: %-20s " , p);
for( ; p = StrEqTok(NULL); )
{
uFlag = uFlag ? 0 : 1;
if( uFlag )
{
printf( "Valu: %-20s \n" , p);
}
else
{
printf( "Name: %-20s " , p);
}
}
}
printf("\n\n");
PingInit( &tIcmpSrv , 56 );
ret = PingStart( &tIcmpSrv , "172.18.99.1" , NetCapPing );
if( !ret )
{
printf("ping is processing\n");
}
while(1)
{
PingTimer( &tIcmpSrv );
sleep ( 1 );
//ÿ<><C3BF>һ<EFBFBD><EFBFBD><EBB7A2>һ<EFBFBD><D2BB>ICMP<4D><50><EFBFBD><EFBFBD>
}
return 1;
}