ping源码

#include "stdlib.h"
#include "string.h"
#include    "stdio.h"   
#include    "fcntl.h"   
#include    "errno.h"   
#include    "signal.h"   
#include    "sys/types.h"   
#include    "sys/socket.h"   
#include    "sys/time.h"   
#include    "netinet/in.h"   
#include    "arpa/inet.h"   
#include    "netdb.h"   
   
#define    ICMP_ECHO    8   
#define    ICMP_ECHOREPLY    0   
#define    ICMP_HEADSIZE    8   
#define    IP_HEADSIZE    20   
   
#define    MAX(a,b)      ((a)    >    (b))?(a):(b)   
#define    MIN(a,b)      ((a)    >    (b))?(b):(a)   
   
   
typedef    struct    tagIpHead   
{   
u_char ip_verlen;   
u_char ip_tos;   
u_char ip_len;   
u_short ip_id;   
u_short ip_fragoff;   
u_char ip_ttl;   
u_char ip_proto;   
u_short ip_chksum;   
u_long ip_src_addr;   
u_long ip_dst_addr;   
}IPHEAD;   
   
typedef    struct    tagIcmpHead   
{   
u_char icmp_type;   
u_char icmp_code;   
u_short icmp_chksum;   
u_short icmp_id;   
u_short icmp_seq;   
u_char icmp_data[1];   
}ICMPHEAD;   
   
   
u_short    ChkSum(u_short    *    pIcmpData,    int    iDataLen)   
{   
u_short    iSum;   
u_short    iOddByte;   
   
iSum    =    0;   
   
while(iDataLen>1){   
iSum    ^=    *(pIcmpData++);   
iDataLen    -=2;   
}   
   
if(iDataLen    ==    1){   
iOddByte    =    0;   
*((u_char*)&iOddByte)    =    *(u_char*)pIcmpData;   
iSum    ^=    iOddByte;   
}   
   
iSum    ^=0xffff;   
return(iSum);   
}   
   
   
long    time_now()   
{   
struct    timeval    now;   
long    lPassed;   
gettimeofday(&now,0);   
lPassed    =    now.tv_sec    *    1000000    +    now.tv_usec;   
return    lPassed;   
}   
   
char    *    host;   
char    *    prog;   
extern      errno;   
long    lSendTime;   
u_short      seq;   
int    iTimeOut;   
int      sock,sent,recvd,max,min,total;   
u_long    lHostIp;   
struct      sockaddr_in    it;   
struct        timeval    now;   
int      ping();   
void    stat();   
   
   
   
main(int    argc,    char    **    argv)   
{   
struct    hostent    *    h;   
char buf[200];   
char dst_host[32];   
int i,namelen;   
IPHEAD      *    pIpHead;   
ICMPHEAD    *    pIcmpHead;   
int    normalSize    =    0;   
int    times    =    0;   
if(argc<2){   
printf("usage:    %s    [-timeout]    host|IP/n",argv[0]);   
exit(0);   
}   
   
//printf("argc:    %d    argv:    %s",argc,*(argv+1));   
prog    =    argv[0];   
host    =    argc    ==    2?argv[1]:argv[2];   
iTimeOut    =    argc    ==    2?1:atoi(argv[1]);   
   
if((sock    =    socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0){   
perror("socket");   
exit(2);   
}   
   
bzero(&it,    sizeof(it));   
it.sin_family    =    AF_INET;   
   
if((lHostIp    =    inet_addr(host))!=    INADDR_NONE){   
it.sin_addr.s_addr    =    lHostIp;   
strcpy(dst_host,host);   
}   
else    if(h    =    gethostbyname(host)){   
bcopy(h->h_addr,&it.sin_addr,h->h_length);   
sprintf(dst_host,"%s(%s)",host,inet_ntoa(it.sin_addr));   
}   
else{   
fprintf(stderr,"bad    IP    or    host/n");   
exit(3);   
}   
   
namelen    =    sizeof(it);   
   
i    =    IP_HEADSIZE+ICMP_HEADSIZE+sizeof(long);   
printf("/npinging    %s,    send    %d    bytes/n/n",dst_host,i);   
   
seq    =    0;   
   
sigset(SIGINT,stat);   
   
sigset(SIGALRM,ping);   
   
alarm(iTimeOut);   
   
ping();   
   
for(;;){   
register    size;   
register    u_char    ttl;   
register    delta;   
register    iIpHeadLen;   
size    =    recvfrom(sock,buf,sizeof(buf),0,(struct    sockaddr    *)&it,&namelen);   
if(size    ==    -1    ){//    errno    ==    EINTR){   
// printf("recvrrom    failed,    size    is    %d/n",size);   
continue;   
}   
   
delta    =    (int)((time_now()    -    lSendTime));   
   
pIpHead    =    (IPHEAD    *)buf;   
iIpHeadLen    =    (int)((pIpHead->ip_verlen&0xf)<<2);   
   
normalSize    =    iIpHeadLen    +    ICMP_HEADSIZE;   
if(size<normalSize){   
// printf("size    of    iIPHeadLen    +    ICMP_HEADSIZE    error:    size    is    %d/n",size);   
continue;   
}   
   
ttl    =    pIpHead->ip_ttl;   
   
pIcmpHead    =    (ICMPHEAD    *)(buf+iIpHeadLen);   
   
if(pIcmpHead->icmp_type    !=    ICMP_ECHOREPLY){   
// printf("ICMP_ECHOREPLY    error/n");   
continue;   
}   
   
if(pIcmpHead->icmp_id!=seq||pIcmpHead->icmp_seq!=seq){   
// printf("icmp_id    !=    seq/n");   
continue;   
}   
   
sprintf(buf,"icmp_seq=%u    bytes=%d    ttl=%d",pIcmpHead->icmp_seq,size,ttl);   
printf("---myping---        reply    from    %s:    %s    time=%.3f    ms/n",host,buf,(float)delta/1000);   
   
max    =    MAX(delta,max);   
min    =    min<delta?MAX(delta,min):delta;   
total    +=    delta;   
++recvd;   
++seq;   
if(times    ==    3){   
stat();   
break;   
}   
times++;   
}   
   
}   
   
   
ping()   
{   
char    buf[200];   
int      iPacketSize;   
int    tag    =    -1;   
   
ICMPHEAD    *    pIcmpHead    =    (ICMPHEAD    *)buf;   
pIcmpHead->icmp_type    =    ICMP_ECHO;   
pIcmpHead->icmp_code    =    0;   
pIcmpHead->icmp_id    =    seq;   
pIcmpHead->icmp_seq    =    seq;   
pIcmpHead->icmp_chksum    =    0;   
   
*((long*)pIcmpHead->icmp_data)=time_now();   
   
iPacketSize    =    ICMP_HEADSIZE    +4;   
pIcmpHead->icmp_chksum    =    ChkSum((u_short    *)pIcmpHead,iPacketSize);   
   
lSendTime    =    time_now();   
   
tag    =    sendto(sock,buf,iPacketSize,0,(struct    sockaddr    *)&it,sizeof(it));   
if(tag<0){   
printf("/nmy_ping    send    failed/n");   
exit(6);   
}   
   
++sent;   
alarm(iTimeOut);   
}   
   
void    stat()   
{   
if(sent){   
printf("/n----%s    ping    statistics    summerized    by    Digger----/n",host);   
printf("%d    packets    sent,    %d    packets    received,    %.2f%%    lost/n",   
sent,recvd,(float)(sent-recvd)/(float)sent*100);   
}   
   
if(recvd){   
printf("round_trip    min/avg/max:    %d/%d/%d    ms/n/n",min,total/recvd,max);   
}   
exit(0);   
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值