A previous piece of code that implements the ICMP protocol Ping tool with the raw socket RAW socket
Myping.c
#include <stdio.h>#include<errno.h>#include<signal.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<string.h>#include<fcntl.h>#include<sys/time.h>#include<sys/socket.h>#include<netinet/inch.h>#include<arpa/inet.h>#include<netdb.h>#include<netinet/ip_icmp.h>#defineIcmp_packet_size 16#defineTime_out_seconds 2unsigned ShortCal_chksum (unsigned Short*buf,intLen) {unsignedintsum =0; unsigned Shortret; while(Len >1) {sum+= *buf; BUF++; Len-=2; } if(1==Len) {Sum+ = (* (unsignedChar*) BUF); } Sum= (Sum >> -) + (Sum &0xFFFF); Sum= (Sum >> -) + (Sum &0xFFFF);//sum = (sum >> +) + sum;ret= ~sum; returnret;}intPACK_ICMP (Char*buf,intseq) { structICMP *icmp_packet = (structICMP *) buf; Icmp_packet->icmp_type =Icmp_echo; Icmp_packet->icmp_code =0; Icmp_packet->icmp_id =Getpid (); Icmp_packet->icmp_seq =seq; Icmp_packet->icmp_cksum =0;//must clean it before cal_chksum or you'll get bad chksum (can ' t error when ping your own ipaddress) structTimeval TV; Gettimeofday (&TV, NULL); memcpy (buf+8, &TV,sizeof(TV)); Icmp_packet->icmp_cksum = Cal_chksum ((unsigned Short*) icmp_packet,icmp_packet_size);}intParse_ip_icmp_info (void*buf,structsockaddr_in Answer) {unsigned Shortchk_sum; unsignedCharTTL; unsigned Shortseq; structtimeval tv_send, Tv_now; unsignedintmini_sec; structIP *ip_packet = (structIP *) buf; structICMP *icmp_packet = (structICMP *) (buf + (Ip_packet->ip_hl <<2)); if(icmp_packet->icmp_id! =Getpid ()) { return-1; } if(Icmp_packet->icmp_type! =icmp_echoreply) { return-1; } TTL= ip_packet->Ip_ttl; Seq= icmp_packet->icmp_seq; Chk_sum= icmp_packet->icmp_cksum; Icmp_packet->icmp_cksum =0; if(Chk_sum! = cal_chksum (unsigned Short*) (icmp_packet,icmp_packet_size)) {return-1; } gettimeofday (&Tv_now, NULL); memcpy (&tv_send, ((Char*) Icmp_packet +8),sizeof(Tv_send)); Mini_sec= (tv_now.tv_sec-tv_send.tv_sec) *1000000+(Tv_now.tv_usec-tv_send.tv_usec); printf ("%d bytes data from:%s icmp_seq =%d, ttl =%d, times =%.3fms\n", (Ip_packet->ip_hl <<2) + -, Inet_ntoa (answer.sin_addr), seq, TTL, mini_sec/1000.0); return 0;}intMainintargcChar*argv[]) { if(ARGC! =2) {printf ("Usage:%s ipaddr/hostname\n", argv[0]); Exit (0 ); } structHostent * host = gethostbyname (argv[1]); if(Host = =NULL) {printf ("Ping:unknow host%s \ n", argv[1]); Exit (2); } structsockaddr_in dest; Dest.sin_family=af_inet; memcpy (&DEST.SIN_ADDR, HOST->H_ADDR,sizeof(int)); intSOCK_RAW_FD =sockets (Af_inet, Sock_raw, ipproto_icmp); if(SOCK_RAW_FD = =-1) {perror ("Socket"); Exit (1); } CharBuf[icmp_packet_size]; intSeq =0; Charrecv_buf[ -]; structsockaddr_in answer; intAnswer_len =sizeof(answer); while(1) {seq++; PACK_ICMP (buf, seq); SendTo (SOCK_RAW_FD, buf, Icmp_packet_size,0, (structSOCKADDR *) &dest,sizeof(dest)); while(1) {Fd_set readset; Fd_zero (&readset); Fd_set (SOCK_RAW_FD,&readset); structTimeval TV; Tv.tv_sec=Time_out_seconds; Tv.tv_usec=0; intRET =Select(sock_raw_fd+1, &readset, NULL, NULL, &TV); if(ret = =-1) {perror ("Select"); Exit (3); } Else if(ret = =0) {printf ("Time out.\n"); Break; } Else { intResolve =0; intret = Recvfrom (SOCK_RAW_FD, Recv_buf, $,0, (structSOCKADDR *) &answer, &Answer_len); if(Ret >0) Resolve=parse_ip_icmp_info (recv_buf, answer); if(Resolve = =0) Break; }} sleep (1); } return 0;}
Compile the link execution. The output is as follows:
ICMP implementation Ping