Search code examples
csocketspingicmptraceroute

Why is my ICMP sequence number not incrementing? (C Socket Programming)


is it possible someone can help me workout why my ICMP sequence number isn't incrementing on every request, when this was used as a ping program it would increment the sequence number on each ping. Also does anyone have any idea why my Round Trip Times are displaying as negative numbers? This also worked fine when this was a ping program.

Please assume all the code 'works', i have removed some for easier reading.

void
respond (int signum) {
   struct sockaddr_storage peer_addr;
   socklen_t               peer_addrlen;
   struct sockaddr_in      addr;
   struct sockaddr_in      dstaddr;
   struct iphdr   *        ip;
   struct icmphdr *        icmp;
   struct timeval *        sent;
   int skt;
   int sequence = 0;
   long int length;
   fd_set rdfds;
   int ready;
   int rtt;
   char buff [BUF_SIZE];

   /* Create and check Socket Number */
   skt = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);


    int ttl = 0;
    setsockopt(skt, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) < 0;


       /* Check Socket */
       if (skt < 0) {
          perror ("socket()");
          exit (1);
       }

       /* Set IP Addresses */
       addr.sin_family      = AF_INET;
       addr.sin_port        = 0;
       addr.sin_addr.s_addr = INADDR_ANY;


       /* Check Socket Bind */
       if (bind (skt, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))) {
          perror ("Can't bind socket");
          exit (1);
       }

/* START SEND LOOP*/
int i;
for (i = 0; i < 7; i++){
        ttl+=1;
        setsockopt(skt, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));

        /* IP Buffer */
       ip = (struct iphdr *)buff;
       peer_addrlen = (socklen_t) sizeof (struct sockaddr_storage);
       memset (&dstaddr, 0, sizeof(struct sockaddr_in));
       dstaddr.sin_addr.s_addr = inet_addr(HOSTADDR);
       dstaddr.sin_family = AF_INET;

       /* ICMP Buffer */
       memset (buff, 0, sizeof(buff));
       icmp = (struct icmphdr *) buff;
       icmp->type   = ECHO_REQ;
       icmp->id     = htons(getpid( ) & 0xffff);
       icmp->seqNum = htons(sequence++);


       /* Check Send Time */
       if (gettimeofday ((struct timeval *)icmp->data, NULL)) {
          perror ("Can't establish send time");
          exit (1);
       }

       /*Calculating packet size*/
       length = sizeof(struct icmphdr) + sizeof(struct timeval);
       icmp->checksum = ~(sum (0, buff, length));



       /* Packet too small, ERROR
       SEND Request             */
       if (sendto (skt, buff, length, 0,
             (struct sockaddr *) &dstaddr, sizeof(struct sockaddr_in)) <= 0) {
          perror ("sendto()");
          exit (1);
        }

       /* Define File Descriptor */
       timeout.tv_sec  = 1;
       timeout.tv_usec = 1;
       FD_ZERO(&rdfds);
       FD_SET (skt, &rdfds);

       /* Select Data from File Descriptor */
       ready = select (skt + 1, &rdfds, NULL, NULL, &timeout);
       if (ready < 0) {
          perror ("Select()");
          exit (1);
       }

        /* Recieve Reply */
        memset (buff, 0, sizeof(buff));
       if (recvfrom (skt, buff, sizeof(buff), 0,
            (struct sockaddr *) &peer_addr, &peer_addrlen) <= 0) exit (1);



       /* Check Time Stamp */
       if (gettimeofday (&end, NULL)) {   // Timestamp reception
          perror ("Can't establish time of receipt");
          exit (1);
       }


       /* Check IP Protocol */
       if (ip->version != 4 ||
           sum (0, buff, sizeof(struct iphdr)) != 0xffff ||
           ip->protocol != ICMP)
          exit(1);


       /* Get IP Payload legth and ICMP Address*/
       length = ntohs(ip->length) - ip->hdrlen * 4;       // Length of IP payload
       icmp = (struct icmphdr *)((uint32_t *)ip + ip->hdrlen);   // Find ICMP hdr


       /* Check ICMP response type*/
       if (icmp->type == 11){
           printf("");
           }

      /* if (icmp->type != ECHO_REPL || sum (0, icmp, length) != 0xffff) {
          fprintf (stderr, "Received %s\n", messages[icmp->type]);
          //exit (1);
       } */

       /*   Find the difference between sent and end times in 10s of ms */
       sent = (struct timeval *)icmp->data;
       if ((rtt = (end.tv_usec - sent->tv_usec) / 10) < 0)
          rtt += 10000;  // We've cycled to a new second
       rtt += (end.tv_sec - sent->tv_sec) * 10000;  // Add any seconds

       /* PRINT ICMP REPLY*/
       printf ("%ld bytes from %s: icmp_req=%d ttl=%d time= %0.1f ms\n",
      length,
      iptos(ntohl(ip->srcip)),
      ntohs(icmp->seqNum),
      ip->ttl,
      ((float)rtt) / 10);


} /*END SEND LOOP


   /* 3 Second Probe */
   alarm (5);
}

Solution

  • You're never setting sequence to 0 in this code, only declaring that it's an int.