VC sends ICMP packets through simulated Ping

Source: Internet
Author: User

Zhang Yue's explanation of Visual C ++ network programming examples is very good, and his code is very beautiful!

 

Books on network programming were abandoned for a long time. Pick up again in this period of time to fill in the deficiencies!

 

This is an example of his first chapter. Simulate ping to send ICMP Packets:

 

1. program source code

//////////////////////////////////////// //// // <Br/> // comm. hfile </P> <p> // contains some common functions </P> <p> # ifndef _ comm_h __< BR/> # DEFINE _ comm_h __</ p> <p> // calculate the checksum <br/> // Add the buffer content in 16-bit characters, if the buffer length is an odd number, <br/> // Add a byte. <Br/> ushortchecksum (ushort * buff, int size); </P> <p> boolsetttl (socket s, int nvalue); <br/> boolsettimeout (socket S, int ntime, bool brecv = true); </P> <p> # endif/_ comm_h __

 

//////////////////////////////////////// //// // <Br/> // protoinfo. hfile </P> <p>/* </P> <p> define the Protocol format <br/> define the macros used in the Protocol </P> <p> */ </P> <p> # ifndef _ protoinfo_h __< BR/> # DEFINE _ protoinfo_h __</P> <p> # define ethertype_ip 0x0800 <br/> # define ethertype_arp 0x0806 </P> <p> typedef struct _ etheader // 14-byte Ethernet header <br/>{< br/> uchardhost [6]; // destination MAC address <br/> ucharshost [6]; // source MAC address <br/> Ushorttype; // underlying protocol type, such as IP (ethertype_ip) and ARP (ethertype_arp) <br/>} etheader, * petheader; </P> <p> # define arphrd_ether 1 </P> <p> // ARP Opcodes <br/> # definearpop_request1 // ARP request <br/> # definearpop_reply2/ /ARP response </P> <p> typedef struct _ arpheader // 28-byte ARP header <br/>{< br/> ushorthrd; // hardware address space, which is arphrd_ether over Ethernet. <br/> ushorteth_type; // Ethernet type, ethertype_ip ?? <Br/> ucharmaclen; // length of the MAC address, which is 6 <br/> uchariplen; // length of the IP address, which is 4 <br/> ushortopcode; // operation code, arpop_request is a request, and arpop_reply is a response <br/> ucharsmac [6]; // source MAC address <br/> ucharsaddr [4]; // source IP address <br/> uchardmac [6]; // destination MAC address <br/> uchardaddr [4]; // destination IP address <br/>} arpheader, * parpheader; </P> <p> // protocol <br/> # define proto_icmp 1 <br/> # define proto_igmp 2 <br/> # define proto_tcp 6 <br/> # define proto_udp 17 </P> <p> typedef struct _ ipheader // 20-byte IP header <br/>{< br/> uchar iphverlen; // version number and header length (4 digits each) <br/> uchar iptos; // service type <br/> ushort iplength; // total package length, that is, the length of the IP packet <br/> ushort ipid; // The packet ID, which uniquely identifies each datagram sent <br/> ushort ipflags; // flag <br/> uchar ipttl; // TTL <br/> uchar ipprotocol; // protocol, it may be TCP, UDP, ICMP, etc. <br/> ushort ipchecksum; // checksum <br/> ulong ipsource; // source IP address <br/> ulong ipdestination; // target IP address <br/>} ipheader, * pipheader; </P> <p> // define the TCP flag <br/> # define tcp_fin 0x01 <br/> # define tcp_syn 0x02 <br/> # define tcp_rst 0x04 <br/> # define tcp_psh 0x08 <br/> # define tcp_ack 0x10 <br/> # define tcp_urg 0x20 <br/> # define tcp_ace 0x40 <br/> # define tcp_cwr 0x80 </P> <p> typedef struct _ tcpheader // 20-byte TCP Header <br/> {<br/> ushortsourceport; // 16-bit source port number <br/> ushortdestinationport; // 16-bit destination port number <br/> ulongsequencenumber; // 32-bit serial number <br/> ulongacknowledgenumber; // 32-bit confirmation number <br/> uchardataoffset; // 4-bit height indicates data offset <br/> ucharflags; // 6-digit flag <br/> // fin-0x01 <br/> // syn-0x02 <br/> // RST-0x04 <br/> // push-0x08 <br/> // ack-0x10 <br/> // URG-0x20 <br/> // ace- 0x40 <br/> // CWR-0x80 </P> <p> ushortwindows; // 16-bit window size <br/> ushortchecksum; // 16-bit checksum <br/> ushorturgentpointer; // 16-bit emergency data offset <br/>} tcpheader, * ptcpheader; </P> <p> typedef struct _ udpheader <br/> {<br/> ushortsourceport; // source port number <br/> ushortdestinationport; // destination port number <br/> ushortlen; // packet length <br/> ushortchecksum; // checksum <br/>} udpheader, * pudpheader; </P> <p> # endif // _ protoinfo_h __

 

 

//////////////////////////////////////// //// // <Br/> // comm. CPP file </P> <p> # include <winsock2.h> <br/> # include <windows. h> <br/> # include "ws2tcpip. H "</P> <p> # include" Comm. H "</P> <p> ushort checksum (ushort * buff, int size) <br/>{< br/> unsigned long cksum = 0; <br/> while (size> 1) <br/> {<br/> cksum + = * buff ++; <br/> size-= sizeof (ushort ); <br/>}< br/> // It is an odd number <br/> If (size) <br/> {<br/> cksum + = * (uchar *) Bu Ff; <br/>}< br/> // Add the 32-bit chsum high 16 bits and low 16 bits, then, return the inverse result <br/> cksum = (cksum> 16) + (cksum & 0 xFFFF); <br/> cksum + = (cksum> 16 ); <br/> return (ushort )(~ Cksum); <br/>}</P> <p> bool setttl (socket S, int nvalue) <br/>{< br/> int ret = :: setsockopt (S, ipproto_ip, ip_ttl, (char *) & nvalue, sizeof (nvalue); <br/> return ret! = Socket_error; <br/>}</P> <p> bool setTimeout (socket S, int ntime, bool brecv) <br/>{< br/> int ret =:: setsockopt (S, sol_socket, <br/> brecv? So_rcvtimeo: so_sndtimeo, (char *) & ntime, sizeof (ntime); <br/> return ret! = Socket_error; <br/>}< br/>

 

//////////////////////////////////////// /// <Br/> // Ping. CPP file </P> <p> # include ".. /common/initsock. H "<br/> # include ".. /common/protoinfo. H "<br/> # include ".. /common/Comm. H "</P> <p> # include <stdio. h> </P> <p> cinitsock thesock; </P> <p> typedef struct icmp_hdr <br/>{< br/> unsigned char icmp_type; // Message Type <br/> unsigned char icmp_code; // Code <br/> unsigned short icmp_checksum; // checksum </P> <p> // The echo header is shown below <br/> unsi Gned short icmp_id; // ID used to uniquely identify the request, usually set to process id <br/> unsigned short icmp_sequence; // serial number <br/> unsigned long icmp_timestamp; // timestamp <br/>}icmp_hdr, * picmp_hdr; </P> <p> int main () <br/>{< br/> // destination IP address, that is, the IP address to ping <br/> char szdestip [] = "119.147.15.13 "; // 127.0.0.1 </P> <p> // create the original set of characters <br/> socket Sraw =: socket (af_inet, sock_raw, ipproto_icmp ); </P> <p> // set the receiving timeout <br/> setTimeout (Sraw, 1000, true); </P> <p>/ /Set the destination address <br/> sockaddr_in DEST; <br/> DeST. sin_family = af_inet; <br/> DeST. sin_port = htons (0); <br/> DeST. sin_addr.s_un.s_addr = inet_addr (szdestip); </P> <p> // create an ICMP packet <br/> char buff [sizeof (icmp_hdr) + 32]; <br/> icmp_hdr * picmp = (icmp_hdr *) Buff; </P> <p> // enter the ICMP packet data, request an ICMP echo <br/> picmp-> icmp_type = 8; <br/> picmp-> icmp_code = 0; <br/> picmp-> icmp_id = (ushort ):: getcurrentprocessid (); <br/> picmp-> IC Mp_checksum = 0; <br/> picmp-> icmp_sequence = 0; </P> <p> // fill in the data section, can be any <br/> memset (& buff [sizeof (icmp_hdr)], 'E', 32 ); </P> <p> // start sending and receiving ICMP packets <br/> ushortnseq = 0; <br/> char recvbuf [1024]; <br/> sockaddr_in from; <br/> int nlen = sizeof (from); <br/> while (true) <br/> {<br/> static int ncount = 0; <br/> int nret; </P> <p> // Ping Times <br/> If (ncount ++ = 1000) <br/> break; </P> <p> picmp-> icmp_checksum = 0; <br/> PIC MP-> icmp_timestamp =: gettickcount (); <br/> picmp-> icmp_sequence = nseq ++; <br/> picmp-> icmp_checksum = checksum (ushort *) buff, sizeof (icmp_hdr) + 32); <br/> nret =: sendto (Sraw, buff, sizeof (icmp_hdr) + 32, 0, (sockaddr *) & DEST, sizeof (DEST); <br/> If (nret = socket_error) <br/> {<br/> printf ("sendto () failed: % d/N ",: wsagetlasterror (); <br/> return-1; <br/>}< br/> nret =: recvfrom (Sraw, recvbu F, 1024, 0, (sockaddr *) & from, & nlen); <br/> If (nret = socket_error) <br/>{< br/> If (:: wsagetlasterror () = wsaetimedout) <br/>{< br/> printf ("timed out/N"); <br/> continue; <br/>}< br/> printf ("recvfrom () failed: % d/N",: wsagetlasterror (); <br/> return-1; <br/>}</P> <p> // The ICMP packets received are parsed below. <br/> int ntick =: gettickcount (); <br/> If (nret <sizeof (ipheader) + sizeof (icmp_hdr) <br/>{< br/> printf ("too Few bytes from % s/n ",: inet_ntoa (from. sin_addr); <br/>}</P> <p> // the received data contains an IP header, which is 20 bytes in size, therefore, add 20 to obtain the ICMP header <br/> // (icmp_hdr *) (recvbuf + sizeof (ipheader); <br/> icmp_hdr * precvicmp = (icmp_hdr *) (recvbuf + 20); <br/> If (precvicmp-> icmp_type! = 0) // echo <br/>{< br/> printf ("nonecho type % d recvd/N", precvicmp-> icmp_type ); <br/> return-1; <br/>}</P> <p> If (precvicmp-> icmp_id! =: Getcurrentprocessid () <br/>{< br/> printf ("someone else's packet! /N "); <br/> return-1; <br/>}</P> <p> printf (" % d bytes returned from % s :", inet_ntoa (from. sin_addr), nret); <br/> printf ("packet serial number = % d. /t ", precvicmp-> icmp_sequence); <br/> printf (" latency: % d ms ", ntick-precvicmp-> icmp_timestamp ); <br/> printf ("/N"); </P> <p> // The message is sent once every second. <br/>: Sleep (1000 ); <br/>}< br/> return 0; <br/>}</P> <p>

 

2. Open omnipeek, run the program, and capture the package as follows:

 

3. Source Code:

 

Network Disk download: http://www.rayfile.com/files/d828bc5e-9120-11de-bb76-0014221b798a/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.