ping命令的C實現

2021-06-28 08:37:51 字數 3060 閱讀 6941

#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...