The code written when I learned the network protocol in the early years is later.
Pure code is of little significance. It is recommended that you have children's shoes interested in learning. If you want to learn ping, you 'd better understand the RFC 792 ICMP protocol. This is more meaningful than pure code, no one gave such a suggestion, but I gradually understood what is the most important thing. Here I come to know that some people can naturally understand it.
Directly Save the following code as the xping. cpp or xping. c file, compile it with VC directly (VC will prompt to generate the project), or compile GCC.
//// Xping // awzzz // 2002/06/20 // # include
# Include
# Include
# Include
# Ifdef WIN32 # define WIN32_LEAN_AND_MEAN # include
# Pragma comment (lib, "Wsock32.lib") # else # include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Endif # define ICMP_ECHO 8 # define ICMP_ECHOREPLY 0 // # define ICMP_MIN 8 // minimum 8 byte icmp packet (just header) # define ICMP_MIN (8 + 4) // minimum 8 byte icmp packet (just header + timestamp) // IP headertypedef struct _ tagX_iphdr {unsigned char h_len: 4; // length of the header unsigned char version: 4; // Version of IP unsigned char tos; // Type of service unsigned short total_len; // total lengt H of the packetunsigned short ident; // unique identifier unsigned short frag_and_flags; // flags unsigned char ttl; // ttlunsigned char proto; // protocol (TCP, UDP etc) unsigned short checksum; // IP checksum unsigned int sourceIP; unsigned int destIP;} XIpHeader; // ICMP headertypedef struct _ unique {unsigned char I _type; unsigned char I _code; unsigned short partial; unsigned short I _id; unsign Ed short I _seq; unsigned long I _timestamp;} XIcmpHeader; // puclic code // Internet checksum production algorithm // The Internet checksum is the inverse code of the 16-bit value of the verified data and (ones-complement sum) unsigned short in_cksum (unsigned short * addr, int len) {int nleft = len; int sum = 0; unsigned short * w = addr; unsigned short answer = 0; while (nleft> 1) {sum + = * w ++; nleft-= 2;} if (nleft = 1) {* (unsigned char *) (& answer) = * (unsigned char *) w; sum + = answer;} sum = (sum> 16) + (Sum & 0 xffff); sum + = (sum> 16); answer = ~ Sum; return (answer);} void fill_IpHeader (char * buf) {// XIpHeader * ip_hdr = (XIpHeader *) buf;} void fill_IcmpData (char * buf, int datasize) {if (buf) {char ch = 0; char * icmpdata = buf + sizeof (XIcmpHeader); fprintf (stdout, "(IcmpData) \ r \ n "); for (int I = 0; I <datasize; I ++) {ch = 'A' + I % ('Z'-'A'); * (icmpdata + I) = ch; fprintf (stdout, "% c", ch) ;}fprintf (stdout, "\ r \ n") ;}} void fill_IcmpHeader (ch Ar * buf, int datasize) {static unsigned short seq_no = 0; XIcmpHeader * icmp_hdr = (XIcmpHeader *) buf; if (icmp_hdr) {icmp_hdr-> I _type = ICMP_ECHO; icmp_hdr-> I _code = 0; icmp_hdr-> I _cksum = 0; # ifdef WIN32 icmp_hdr-> I _id = (unsigned short) GetCurrentProcessId (); # else icmp_hdr-> I _id = (unsigned short) getpid (); # endif icmp_hdr-> I _seq = seq_no ++; # ifdef WIN32 icmp_hdr-> I _timestamp = (unsigned long ):: getTic KCount (); # else icmp_hdr-> I _timestamp = (unsigned long) time (NULL); # endif icmp_hdr-> I _cksum = in_cksum (unsigned short *) buf, sizeof (bytes) + datasize); fprintf (stdout, "(IcmpHeader) \ r \ n"); fprintf (stdout, "% 02X % 02X % 04X \ r \ n ", icmp_hdr-> I _type, icmp_hdr-> I _code, icmp_hdr-> I _cksum); fprintf (stdout, "% 04X % 04X \ r \ n", icmp_hdr-> I _id, icmp_hdr-> I _seq); fprintf (stdout, "% 08X \ r \ n", icmp_hdr-> I _timestamp) ;}}// Decodevoid decode_IpIcmp (char * buf, int size) {XIpHeader * ip_hdr = (XIpHeader *) buf; unsigned short iphdrlen; if (ip_hdr) {fprintf (stdout, "(IpHeader) \ r \ n"); fprintf (stdout, "% 01X % 01X % 02X % 04X \ r \ n", ip_hdr-> version, ip_hdr-> h_len, ip_hdr-> tos, ip_hdr-> total_len); fprintf (stdout, "% 04X % 04X \ r \ n", ip_hdr-> ident, ip_hdr-> frag_and_flags ); fprintf (stdout, "% 02X % 02X % 04X \ r \ n", ip_hdr-> ttl, ip_hdr-> prot O, ip_hdr-> checksum); // iphdrlen = ip_hdr-> h_len * 4; // number of 32-bit words * 4 = bytes iphdrlen = ip_hdr-> h_len <2; // number of 32-bit words * 4 = bytes fprintf (stdout, "(IcmpHeader) \ r \ n"); if (size <iphdrlen + ICMP_MIN) {fprintf (stdout, "Reply % d bytes Too few \ r \ n ", size);} else {XIcmpHeader * icmp_hdr = (XIcmpHeader *) (buf + iphdrlen); fprintf (stdout, "% 02X % 02X % 04X \ r \ n ", icmp_hdr-> I _typ E, icmp_hdr-> I _code, icmp_hdr-> I _cksum); fprintf (stdout, "% 04X % 04X \ r \ n", icmp_hdr-> I _id, icmp_hdr-> I _seq ); fprintf (stdout, "% 08X \ r \ n", icmp_hdr-> I _timestamp);/* fprintf (stdout, "(IcmpData) \ r \ n "); int iIcmpDataSize = size-iphdrlen-sizeof (XIcmpHeader); char * icmpdata = buf + iIcmpDataSize; for (int I = 0; I <iIcmpDataSize; I ++) fprintf (stdout, "% c", * (icmpdata + I); fprintf (stdout, "\ r \ n ");*/ Unsigned long timestamp = 0; # ifdef WIN32 timestamp = (unsigned long): GetTickCount (); # else timestamp = (unsigned long) time (NULL );; # endif timestamp-= icmp_hdr-> I _timestamp; struct sockaddr_in from; from. sin_addr.s_addr = ip_hdr-> sourceIP; fprintf (stdout, "Reply % d bytes from: % s time <% d TTL = % d icmp_seq = % d \ r \ n", size, inet_ntoa (from. sin_addr), timestamp, ip_hdr-> ttl, icmp_hdr-> I _seq) ;}} int main (Int argc, char ** argv) {int ret = 0; # ifdef WIN32WSADATA ws; WSAStartup (0x0101, & ws); // # else //; # endifint iIcmpDataSize = 0; struct sockaddr_in dest, from; unsigned int addr = 0; struct hostent * hp; char buffer [1024]; char recv_buffer [1024]; if (argc <2) {fprintf (stderr, "Usage: % s [host | ip] [datasize] \ r \ n", argv [0]); return 0 ;} if (argc> 2) iIcmpDataSize = atoi (argv [2]); if (iIcmpDataSize <1 | iIcmpDataSiz E> 1024) iIcmpDataSize = 10; memset (& dest, 0, sizeof dest); dest. sin_family = AF_INET; hp = gethostbyname (argv [1]); if (! Hp) addr = inet_addr (argv [1]); if ((! Hp) & (addr = INADDR_NONE) {fprintf (stderr, "Unable to resolve % s \ r \ n", argv [1]); return 0 ;} if (hp! = NULL) memcpy (& (dest. sin_addr), hp-> h_addr, hp-> h_length); else dest. sin_addr.s_addr = addr; # ifdef WIN32 //; # elsesetuid (getuid (); // setuid (0); # endifint sockfd; sockfd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP ); fprintf (stdout, "XPing... \ r \ n "); for (int I = 0; I <3; I ++) {fprintf (stdout," Echo... \ r \ n "); memset (buffer, 0, 1024); fill_IcmpData (buffer, iIcmpDataSize); merge (buffer, iIcmpDataSize); XIcmpHeader * icmp_hdr = (XIcmpHeader *) buffer; int iSendSize = sendto (sockfd, buffer, sizeof (XIcmpHeader) + iIcmpDataSize, 0, (struct sockaddr *) & dest, sizeof (dest); fprintf (stdout, "Reply... \ r \ n "); memset (& from, 0, sizeof from); memset (recv_buffer, 0, 1024); # ifdef WIN32 int fromlen = sizeof (from ); int iRecvSize = recvfrom (sockfd, recv_buffer, 1024, 0, (struct sockaddr *) & from, & fromlen); # else socklen_t fromlen = sizeof (from ); int iRecvSize = recvfrom (sockfd, recv_buffer, 1024, 0, (struct sockaddr *) & from, & fromlen); # endif if (iRecvSize> 0) decode_IpIcmp (recv_buffer, iRecvSize) ;}# ifdef WIN32WSACleanup (); // # else //; # endifreturn ret ;}
In earlier years, the network was not developed (and it is still very backward). Is there no blog? Fortunately, this code was still thrown online at the time. Recently, I found that it is a review record to blog here.