Network programming: A simple multithreaded ping implementation in C

Here it is the simplePing, it is a simple multithreaded ping implementation coded from scratch.

First of all we need some requirements to satisfy:

 

REQ_OS_01

simplePing shall run on Linux Systems.

 

REQ_OS_03

simplePing shall be invoked using the shell an it shall receive (from the shell) the following arguments:

1. The destination IP address

2. An optional flag to setup the verbose mode

 

REQ_OS_04

simplePing shall use the standard posix threads to implement:

a. the pinger part 

b. the listener part.

 

REQ_OS_05

simplePing shall return EXIT_FAILURE in case of failure or EXIT_SUCCESS in case of success (when the user hits CTRL-C).

 

REQ_COM_02

simplePing shall use the standard ICMP protocol.

 

REQ_COM_03

simplePing shall send an ECHO request every seconds.

 

REQ_COM_04

The ECHO request shall be non blocking.

 

Just a little code…

 

 

int main(int argc, char **argv) /* REQ_OS_03 CLI arguments.   */

{

 

…….

 

…….

/* Trapping the CTRL-C                                        */

signal(SIGINT, quitProgram);

    if ((argc<2)||(argc>3))     /* REQ_OS_03 CLI arguments.   */

        Usage(argv);

 

…….

…….

/* REQ_OS_04.a                                            */

/* Create the listener thread                             */

pthread_create(&listenerThreadId, NULL, listener, NULL);

 

sleep(1);

/* REQ_OS_04.b                                            */

/* Create the pinger thread                               */

pthread_create(&pingerThreadId, NULL, ping, addr);

 

/* Wait for the end of both threads.                      */

pthread_join(pingerThreadId, NULL);

pthread_join(listenerThreadId, NULL);

 

…….

}

 

 

/*+——————————————————+

  | Function name : listener                             |

  +——————————————————+*/

void *listener(void *par)

{

 

…….

                  /* using the IGMP protocol */

sd   =  socket(PF_INET, SOCK_RAW, globalData.protocol->p_proto);

 

…….

while(!donel)

{

 

 

…….

/* waiting for data */

bytes = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);

if (bytes > 0)

printInfo(buf, bytes);

 

…….

 

…….

return(NULL);

}

 

/*+——————————————————+

  | Function name : ping                                 |

  | Parameters    :                                      |

  |        in     : The destination IP address.          |

  | Return  value : NULL or EXIT_FAILURE.                |

  | Description   : The pinger function.                 |

  +——————————————————+*/

void *ping(void *par)

{

 

…….

                  /* using the IGMP protocol */

sd    =  socket(PF_INET, SOCK_RAW, globalData.protocol->p_proto);

 

…….

                  /* Setting TTL to 255*/

if (setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0)

{

perror("Set TTL option");

exit(EXIT_FAILURE);

}

 

                  /* Requesting non blocking I/O */

if (fcntl(sd, F_SETFL, O_NONBLOCK) != 0)

{

perror("Request nonblocking I/O");

exit(EXIT_FAILURE);

}

while(!done)

{

 

…….

 

                  /* Sending one message per second until CTRL-C will be pushed and then "done"==true */

 

                  /* Preparing the packet to send */

pckt.hdr.type               =  ICMP_ECHO;

pckt.hdr.un.echo.id         =  globalData.pid;

for (i = 0; i < sizeof(pckt.msg)-1; i++)

pckt.msg[i] = i+'0';

pckt.msg[i]                 =  0;

pckt.hdr.un.echo.sequence   =  packetsSent++;

pckt.hdr.checksum           =  checksum(&pckt, sizeof(pckt));

 

                  /* Sending the packet */

if (sendto(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*)addr, sizeof(*addr)) <= 0)

{

perror("sendto");

}

sleep(1);

}

return(NULL);

}

 

 

 

You can download the simplePing here. simplePing

To compile simplePing just run the "make" command.

To run simplePing you must be root.

Gg1

You may also like...

5 Responses

  1. S_i_g_n_e_D says:

    The link with simplePing.zip is not working. I was kind of hoping to revise the code.

  2. admin says:

    @S_i_g_n_e_D Thank you for reporting the non working link.

    Now it should work fine.

  3. S_i_g_n_e_D says:

    Quite a fast response 😉 Thank you. By the way I'll implement Emery Berger's dthreads … just for the sport 😉 It's interesting for me to measure the performance of both implementations because of a future project decision.

  4. admin says:

    Emery Berger’s dthreads? Interesting! Please let me know if you will post your results. Good Luck!

  5. http://www.bing.com/ says:

    That was enjoyable to read, thanks for posting it.

Leave a Reply

Your email address will not be published. Required fields are marked *