Click here to Skip to main content
13,301,619 members (75,547 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


58 bookmarked
Posted 21 Feb 2008

Ping and Traceroute

, 21 Feb 2008
Rate this:
Please Sign up or sign in to vote.
In this article, we will see how Ping and Tracert networking tools work and we will create our own replicas for them.


Ping is an old Unix utility which is pretty useful even today. The basic idea behind Ping is to find out whether the network is reachable and alive or not. Ping basically sends an ICMP echo request and then waits for an ICMP echo response; the roundtrip time is calculated from the time at which the request was sent and the time at which a response is received. For more information on ICMP, please see RFC 792.

To send out ICMP requests, we create a socket which will use ICMP as the protocol:

SOCKET sock;

//Create a raw socket which will use ICMP
sock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);

Now to send an ICMP request, first of all we populate the ICMP header structure:

struct ICMPheader
    unsigned char    byType;
    unsigned char    byCode;
    unsigned short    nChecksum;
    unsigned short    nId;
    unsigned short    nSequence;

ICMPheader sendHdr;
sendHdr.byCode = 0;       //Zero for ICMP echo and reply messages

//Sequence number is incremented with each request, this should be different
//so we can match a response with a request
sendHdr.nSequence = htons (nSequence++);    
sendHdr.byType = 8;       //Eight for ICMP echo message
sendHdr.nChecksum = 0;    //Checksum is calculated later on

Next we fill the ICMP header and message data into a buffer to be sent out:

//Create the message buffer, which is big enough to store the header and the 
//message data
pSendBuffer = new char [sizeof (ICMPheader) + nMessageSize];

//Copy the message header in the buffer
memcpy_s (pSendBuffer, sizeof (ICMPheader), &sendHdr, sizeof (ICMPheader));

//Fill the message with some arbitrary value
memset (pSendBuffer + sizeof (ICMPheader), 'x', nMessageSize);

Now we calculate the checksum of the ICMP header and the message being sent with it. The checksum for ICMP messages is calculated in the same way as for IP headers.

//Calculate checksum over ICMP header and message data
sendHdr.nChecksum = 
    htons (CalcChecksum (pSendBuffer, sizeof (ICMPheader) + nMessageSize)); 
//Copy the message header back into the buffer
memcpy_s (pSendBuffer, sizeof (ICMPheader), &sendHdr, sizeof (ICMPheader));

We are all ready to send the ICMP echo request, so here we do that:

nResult = sendto (sock, pSendBuffer, sizeof (ICMPheader) + 
            nMessageSize, 0, (SOCKADDR *)&dest, sizeof (SOCKADDR_IN));

With an ICMP request sent out, we now wait for the timeout interval (default is 5 seconds) to get a response. We use I/O socket model for this.

timeval timeInterval = {0, 0};
//Set the timeout interval for the select call to expire
timeInterval.tv_usec = nTimeOut * 1000;

FD_ZERO (&fdRead);
FD_SET (sock, &fdRead);

select (0, &fdRead, NULL, NULL, &timeInterval);

If we get a response, then the response is parsed to see if it has the correct checksum, the sequence ID is the same as in the request which was sent out, etc. One point to note here is that the bytes received contain the IP header + ICMP header + message, so we need to take them out accordingly and then proceed. The following code explains it further:

//We got a response so we construct the ICMP header and message out of it
ICMPheader recvHdr;
char *pICMPbuffer = NULL;

//The response includes the IP header as well, so we move 20 bytes ahead to 
//read the ICMP header
pICMPbuffer = pRecvBuffer + sizeof(IPheader);

//ICMP message length is calculated by subtracting the IP header size from 
//the total bytes received
int nICMPMsgLen = nResult - sizeof(IPheader);

//Construct the ICMP header
memcpy_s (&recvHdr, sizeof (recvHdr), pICMPbuffer, sizeof (recvHdr));

//Construct the IP header from the response
IPheader ipHdr;
memcpy_s (&ipHdr, sizeof (ipHdr), pRecvBuffer, sizeof (ipHdr));

recvHdr.nId = recvHdr.nId;
recvHdr.nSequence = recvHdr.nSequence;
recvHdr.nChecksum = ntohs (recvHdr.nChecksum);

//Check if the response is an echo reply, transaction ID and sequence number 
//are same as for the request, and that the checksum is correct
if (recvHdr.byType == 0 &&
    recvHdr.nId == sendHdr.nId &&
    recvHdr.nSequence == sendHdr.nSequence &&
    ValidateChecksum (pICMPbuffer, nICMPMsgLen) && 
memcmp (pSendBuffer + sizeof(ICMPheader), pRecvBuffer + sizeof(ICMPheader) + 
        sizeof(IPheader), nResult - sizeof (ICMPheader) - sizeof(IPheader)) == 0)
    //All's OK
    //So just calculate the round trip time and print it

And lastly, we repeat the above process (sending ICMP echo request and receiving responses) three or four times, as asked by the user, to calculate Ping statistics.


Tracert is another networking utility which determines the route taken by packets across an IP network. The basic idea behind tracert is that it sends ICMP requests and increments their TTL value in the IP header by one on each request. The first request has a TTL of one, the next one two, and so on. When the first request reaches the next host, the host ignores the request and sends an ICMP time exceeded response. By seeing this response we are able to determine the host and thus able to produce a lists of hosts by sending incremented TTL values.

The code for Tracert is very similar to Ping. The only point of interest here is that we need to modify the IP header to change the TTL values. This is done using setsockopt with IPPROTO_IP and IP_TTL values as shown below:

setsockopt (sock, IPPROTO_IP, IP_TTL, (char *)&nTTL, sizeof (nTTL));


I mainly wrote this article for learning purposes and I hope that the code in this article is useful to others as well. Please be kind enough to notify me about any mistakes or a better way to do things.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Hitesh Sharma
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

Questionif run os'ping will be get error Pin
qingye200826-Jun-13 21:13
memberqingye200826-Jun-13 21:13 
Generalclosesocket(sock); missing! Pin
StoneHead7-Dec-10 14:59
memberStoneHead7-Dec-10 14:59 
GeneralNice article - one problem Pin
SamNorris15-Apr-10 10:18
memberSamNorris15-Apr-10 10:18 
GeneralNEED HELP! An Error has occur in gethostbyname operaion: WSAGetLastError <> = 11004 Pin
bkimp1-Mar-10 23:09
memberbkimp1-Mar-10 23:09 
GeneralAnother ICMP packet Pin
welcomyou4-Nov-09 23:14
memberwelcomyou4-Nov-09 23:14 
Questionregarding raw sockets Pin
N.siva subrahmanyam22-Oct-09 21:09
memberN.siva subrahmanyam22-Oct-09 21:09 
AnswerRe: regarding raw sockets Pin
welcomyou4-Nov-09 23:02
memberwelcomyou4-Nov-09 23:02 
Generalcompile error Pin
alaa naeem2-Aug-09 6:58
memberalaa naeem2-Aug-09 6:58 
thanks for this useful article, when I tried to compile the file an error of the function (memcpy_s) appeared, I use VC6.0, what does this function do?
QuestionI couldn't execute the project !!! Please Help! Pin
mecrop2-Dec-08 15:46
membermecrop2-Dec-08 15:46 
GeneralVista business version will fail Pin
owenskao25-Apr-08 3:35
memberowenskao25-Apr-08 3:35 
GeneralRe: Vista business version will fail Pin
youval vaknin28-Sep-08 6:20
memberyouval vaknin28-Sep-08 6:20 
QuestionNetwork ping ???? Pin
wege27-Feb-08 0:42
memberwege27-Feb-08 0:42 
AnswerRe: Network ping ???? Pin
Hitesh Sharma28-Feb-08 4:43
memberHitesh Sharma28-Feb-08 4:43 
AnswerRe: Network ping ???? Pin
emilio_grv10-Mar-08 8:47
member emilio_grv 10-Mar-08 8:47 
GeneralRe: Network ping ???? Pin
wege10-Mar-08 23:51
memberwege10-Mar-08 23:51 
GeneralRe: Network ping ???? Pin
emilio_grv12-Mar-08 1:48
member emilio_grv 12-Mar-08 1:48 
GeneralEmprovement suggestions Pin
emilio_grv22-Feb-08 3:02
member emilio_grv 22-Feb-08 3:02 
GeneralRe: Emprovement suggestions Pin
Hitesh Sharma22-Feb-08 3:25
memberHitesh Sharma22-Feb-08 3:25 
GeneralMessage Body Pin
Jeffrey Walton22-Feb-08 2:10
mvpJeffrey Walton22-Feb-08 2:10 
GeneralRe: Message Body Pin
Hitesh Sharma22-Feb-08 3:36
memberHitesh Sharma22-Feb-08 3:36 
GeneralRe: Message Body Pin
ThatsAlok10-Mar-08 6:28
member ThatsAlok 10-Mar-08 6:28 
GeneralRe: Message Body Pin
Hitesh Sharma10-Mar-08 8:29
memberHitesh Sharma10-Mar-08 8:29 
GeneralRe: Message Body Pin
ThatsAlok10-Mar-08 8:40
member ThatsAlok 10-Mar-08 8:40 
GeneralRe: Message Body Pin
Hitesh Sharma10-Mar-08 13:03
memberHitesh Sharma10-Mar-08 13:03 
GeneralRe: Message Body Pin
ThatsAlok10-Mar-08 17:55
member ThatsAlok 10-Mar-08 17:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171207.1 | Last Updated 21 Feb 2008
Article Copyright 2008 by Hitesh Sharma
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid