Files
svc.ems/plat/public_bak/src/pub_inet.c
2024-09-27 15:39:34 +08:00

343 lines
8.8 KiB
C
Raw 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.c
//Auhtor : Liu Wei
//Desc : public inet function implementation
//Created : 2007-06-22
//Revision :
//
//Revision :
//
//////////////////////////////////////////////////
#include "./include/pub_inet.h"
/*@ignore@*/
///////////////////////////////////////////////////////////////////////////
// Inet If Address infomation interface
///////////////////////////////////////////////////////////////////////////
extern 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;
}
u32 GetLocalIP ( )
{
struct hostent *host;
struct in_addr *hostip_addr;
char name[100];
gethostname ( name, 24 );
host = gethostbyname ( name );
WxcAssert ( NULL != host, "Get Local IP failed" );
hostip_addr = ( struct in_addr * ) ( *host->h_addr_list );
return hostip_addr->s_addr;
}
///////////////////////////////////////////////////////////////////////////
// Inet If Address infomation interface
///////////////////////////////////////////////////////////////////////////
//У<><D0A3><EFBFBD><EFBFBD><EFBFBD>
static 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>ͷ
static 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>ͷ
static 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 ( pIS->tFromAddr.sin_addr ), icmp->icmp_seq,
pIP->ip_ttl, rtt );
return 1;
}
return 0;
}
static 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>
static 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 * ) &pIS->tToAddr,
sizeof ( pIS->tToAddr ) ) < 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>
static void IcmpRecv ( IcmpSrv * pIS )
{
int n, fromlen;
extern int errno;
fromlen = sizeof ( pIS->tFromAddr );
while ( pIS->nPackNumRecv < pIS->nPackNumSend )
{
if ( ( n =
recvfrom ( pIS->wSockfd, pIS->aRecvBuff,
sizeof ( pIS->aRecvBuff ), 0,
( struct sockaddr * ) &pIS->tFromAddr,
&fromlen ) ) < 0 )
{
if ( errno == EINTR )
continue;
perror ( "recvfrom error" );
continue;
}
if ( IcmpUnPack ( pIS->aRecvBuff, n, pIS ) == -1 )
continue;
pIS->nPackNumRecv++;
}
}
extern 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 ( );
}
extern 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 ( &pIS->tToAddr, sizeof ( pIS->tToAddr ) );
pIS->tToAddr.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 * ) &pIS->tToAddr.sin_addr, pHost->h_addr,
pHost->h_length );
}
else //<2F><>ip<69><70>ַ
{
pIS->tToAddr.sin_addr.s_addr = nInetAddr;
//memcpy( (char *)&pIS->tToAddr,(char *)&nInetAddr,host->h_length);
}
printf ( "PING %s(%s): %d bytes data in ICMP packets. \n", sIP,
inet_ntoa ( pIS->tToAddr.sin_addr ), pIS->uDataLen );
pIS->uSrvState = 1;
pIS->uIcmpState = 1;
}
extern 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;
}
}
}
/*@end@*/