#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define packet_size 1024
#define max_wait_time 5
#define max_no_packets 3
char sendpacket[packet_size];
char recvpacket[packet_size];
int sockfd,datalen=56;
int nsend=0,nreceived=0;
struct sockaddr_in dest_addr;
pid_t pid;
struct sockaddr_in from;
struct timeval tvrecv;
void statistics(int signo);
unsigned short cal_chksum(unsigned short *addr,int len);
int pack(int pack_no);
void send_packet(void);
void recv_packet(void);
int unpack(char *buf,int len);
void tv_sub(struct timeval *out,struct timeval *in);
void statistics(int signo)
/*校驗和演算法*/
unsigned short cal_chksum(unsigned short *addr,int len)
/*若icmp報頭為奇數個位元組,會剩下最後一位元組。把最後乙個位元組視為乙個2位元組資料的高位元組,
這個2位元組資料的低位元組為0,繼續累加*/
if( nleft==1)
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return answer;
} /*設定icmp報頭*/
int pack(int pack_no)
/*傳送三個icmp報文*/
void send_packet()
return;
} /*接收所有icmp報文*/
void recv_packet()
gettimeofday(&tvrecv,null); /*記錄接收時間*/
if(unpack(recvpacket,n)==-1) continue;
nreceived++;
break;
}return;
} /*剝去icmp報頭*/
int unpack(char *buf,int len)
/*確保所接收的是我所發的的icmp的回應*/
//printf("icmp_type = %d\n", icmp->icmp_type);
if( (icmp->icmp_type==icmp_echoreply) && (icmp->icmp_id==pid) )
else return -1;
} int main(int argc,char *argv)
memset(sendpacket, 'a', sizeof(sendpacket));
if( (protocol=getprotobyname("icmp") )==null)
/*生成使用icmp的原始套接字,這種套接字只有root才能生成*/
if( (sockfd=socket(af_inet,sock_raw,protocol->p_proto) )<0)
/* **root許可權,設定當前使用者許可權*/
setuid(getuid());
/*擴大套接字接收緩衝區到50k這樣做主要為了減小接收緩衝區溢位的
的可能性,若無意中ping乙個廣播位址或多播位址,將會引來大量應答*/
setsockopt(sockfd,sol_socket,so_rcvbuf,&size,sizeof(size) );
bzero(&dest_addr,sizeof(dest_addr));
dest_addr.sin_family=af_inet;
/*判斷是主機名還是ip位址*/
if((inaddr=inet_addr(argv[1]))==inaddr_none)
memcpy( (char *)&dest_addr.sin_addr,host->h_addr,host->h_length);
} else /*是ip位址*/
//memcpy( (char *)&dest_addr,(char *)&inaddr,host->h_length);
dest_addr.sin_addr.s_addr = inaddr;
/*獲取main的程序id,用於設定icmp的標誌符*/
pid=getpid();
printf("ping %s(%s): %d bytes data in icmp packets.\n",argv[1],
inet_ntoa(dest_addr.sin_addr),datalen);
while (nsend < max_no_packets)
statistics(sigalrm); /*進行統計*/
return 0;
} /*兩個timeval結構相減*/
void tv_sub(struct timeval *out,struct timeval *in)
out->tv_sec-=in->tv_sec;
} /*------------- the end -----------*/
ping命令的實現
ping命令的實現 include include include include include include include include include include include include include include include define packet size 4...
ping命令實現內幕
在網路上有不少ping命令的實現,但是要麼連執行都不行,要麼就是表層的僥倖的能成功一些例子。今我自己寫了個ping命令程式,自習研究了一下,原來問題頗多。很多還得看底層協議 才能搞清楚它的來龍去脈。先將除錯版ping命令程式 貼上 ping程式,completed by ben include in...
golang 實現ping 命令
在專案中,我們需要知道哪些ip是可用ip,這時候想到了用icmp internet控制報文協議 於是就在網上查詢,後來找到了乙個開源庫 github.com sparrc go ping。這個庫簡單好用,能達到專案需求,也推薦大家使用。貼乙個示例吧.當然你得先 go get github.com s...