# include & lt; Iomanip>
# include & lt; Winsock2. H>
# include & lt; Ws2tcpip. H>
# include & lt; Stdio. H>
using namespace std;
//IP datagram
Typedef struct
{
Unsigned char hdr_len: 4;//the length of the header
Unsigned char version: 4;//version of IP
Unsigned char tos.//the type of service
Unsigned short total_len;//the total length of the packet
Unsigned short identifier;//unique identifier
Unsigned short frag_and_flags;//flags
Unsigned char TTL.//time to live
Unsigned char protocol;//protocol (TCP, UDP etc)
Unsigned short checksum.//IP checksum
Unsigned long sourceIP;//the source IP address
Unsigned long destIP;//destination IP address
} IP_HEADER;
//ICMP header data
Typedef struct
{
Unsigned char type;//8-bit type
Unsigned char code;//8 bits of code
Unsigned short cksum;//16 bits checksum
Unsigned short id;//16 bit identifier
Unsigned short seq.//16 bits serial number
} ICMP_HEADER;
//decoding results
Typedef struct
{
Unsigned short usSeqNo;//package serial number
Unsigned long dwRoundTripTime;//round-trip time
In_addr dwIPaddr;//to end IP address
} DECODE_RESULT;
//the ICMP type fields
Const char ICMP_ECHO_REQUEST=8;//echo request
Const char ICMP_ECHO_REPLY=0;//echo reply
Const char ICMP_TIMEOUT=11;//transmission timeout
Const long DEF_ICMP_TIMEOUT=3000;//the default timeout, the unit ms
Const int DEF_ICMP_DATA_SIZE=32;//the default ICMP data section length
Const int MAX_ICMP_PACKET_SIZE=1024;//ICMP data submitted to the size of the largest
Const int DEF_MAX_HOP=30;//the biggest jump station number
//produce the checksum
Unsigned short GenerateChecksum (unsigned short * pbufs, int iSize)
{
Unsigned long cksum=0;
While (iSize> 1)
{
Cksum +=* pBuf++;
ISize -=sizeof (unsigned short);
}
If (iSize)
Pbufs cksum +=* (unsigned char *);
Cksum=(cksum & gt;> 16) + (cksum & amp; 0 XFFFF);
Cksum +=(cksum & gt;> 16);
Return (unsigned short) (~ cksum);
}
//decode the data submitted to the
BOOL DecodeIcmpResponse (char * pbufs, int iPacketSize, DECODE_RESULT & amp; StDecodeResult)
{
//check the legitimacy of the datagram size
Pbufs IP_HEADER * pIpHdr=(IP_HEADER *);
Int iIpHdrLen=pIpHdr - & gt; Hdr_len * 4;
If (iPacketSize & lt; (int) (iIpHdrLen + sizeof (ICMP_HEADER)))
return -1;
//check id field by ICMP packet type and serial number to determine whether the program should be received ICMP packet
ICMP_HEADER * pIcmpHdr=(ICMP_HEADER *) (pbufs + iIpHdrLen);
Unsigned short usID usSquNo;
If (pIcmpHdr - & gt; Type==ICMP_ECHO_REPLY)
{
UsID=pIcmpHdr - & gt; id;
UsSquNo=pIcmpHdr - & gt; Seq.
}
Else if (pIcmpHdr - & gt; Type==ICMP_TIMEOUT)
{
Char * pInnerIpHdr=pbufs + iIpHdrLen + sizeof (ICMP_HEADER);//load in the IP header
Int iInnerIPHdrLen=((IP_HEADER *) pInnerIpHdr) - & gt; Hdr_len * 4;//load the IP head length
ICMP_HEADER * pInnerIcmpHdr=(ICMP_HEADER *) (pInnerIpHdr + iInnerIPHdrLen);//load in ICMP header
UsID=pInnerIcmpHdr - & gt; id;
UsSquNo=pInnerIcmpHdr - & gt; Seq.
}
The else
return -1;
If (usID!=(USHORT) GetCurrentProcessId () | | usSquNo!=stDecodeResult. UsSeqNo)
return -1;
//handle correctly received ICMP datagram
If (pIcmpHdr - & gt; Type==ICMP_ECHO_REPLY | |
PIcmpHdr - & gt; Type==ICMP_TIMEOUT)
{
//return the decoding result
StDecodeResult. DwIPaddr. S_addr=pIpHdr - & gt; SourceIP;
StDecodeResult. DwRoundTripTime=GetTickCount () - stDecodeResult. DwRoundTripTime;
//print screen information
If (stDecodeResult. DwRoundTripTime)
Cout & lt;
Cout & lt;
}
return -1;
}
Unsigned long gethostname (char name [])
{
Unsigned long ulDestIP=inet_addr (name);
If (ulDestIP==INADDR_NONE)
{
//conversion is not successful in the DNS
Hostent * pHostent=gethostbyname (name);
If (pHostent)
{
(in_addr ulDestIP=(* *) pHostent - & gt; H_addr). S_addr;
//output screen information
Cout & lt; <"\ nTracing route to" & lt;
<"With a" maximum of & lt;
The else//failed to resolve hostnames
{
Cout & lt; <"/nCould not resolve the host name" & lt;
}
}
The else
{
//output screen information
Cout & lt; <"\ nTracing route to" & lt;
Return ulDestIP;
}
ICMP_HEADER * packetICMP (char IcmpSendBuf [], an unsigned short usSeqNo)
{
IcmpSendBuf ICMP_HEADER * pIcmpHeader=(ICMP_HEADER *);
PIcmpHeader - & gt; Type=ICMP_ECHO_REQUEST;
PIcmpHeader - & gt; Code=0;
PIcmpHeader - & gt; Id=(USHORT) GetCurrentProcessId ();
Memset (IcmpSendBuf + sizeof (ICMP_HEADER), 'E', DEF_ICMP_DATA_SIZE);
((ICMP_HEADER *) IcmpSendBuf) - & gt; Cksum=0;
((ICMP_HEADER *) IcmpSendBuf) - & gt; Seq=htons (usSeqNo);
((ICMP_HEADER *) IcmpSendBuf) - & gt; nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull