1. We have moved from vBulletin to XenForo and you are viewing the site in the middle of the move. Though the functional aspect of everything is working fine, we are still working on other changes including the new design on Xenforo.
    Dismiss Notice

Help WITH PING PROGRAM

Discussion in 'C' started by en_7123, Mar 27, 2010.

  1. en_7123

    en_7123 New Member

    Joined:
    Feb 11, 2010
    Messages:
    105
    Likes Received:
    0
    Trophy Points:
    0
    Hi this is a simple program that sends an echo request and recieves an echo reply.The problem is in the recieved packet

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <linux/ip.h>
    #include <linux/icmp.h>
    #include <string.h>
    #include <unistd.h>
    
    unsigned short in_cksum(unsigned short *, int);
    int main()
    {
    int addrlen;
    
    char d_addr[17];
    struct iphdr *ip;
    struct icmphdr *icmp;
    struct iphdr *ipreply;
    char *packet;
    char *buffer;
    int raw;
    char *n;
    struct sockaddr_in serv;
    int optval=1;
    int sent;
    
    printf("Enter the destination address : ");
    fgets(d_addr,17,stdin);
    
    n= strchr(d_addr, '\n'); /* search for newline character */
    
    if ( n != NULL )
    
    {
    
    *n = '\0'; /* overwrite trailing newline */
    
    }
    
    
    // Allocate space 
    
    packet=malloc(sizeof(struct iphdr)+sizeof(struct icmphdr));
    buffer=malloc(sizeof(struct iphdr)+sizeof(struct icmphdr));
    
    
    //setting up the ip header
    
    ip=(struct iphdr *)packet;
    
    //Setting the values for the ip header
    
    ip->ihl=5;  //header length
    ip->version=4; //version 
    ip->tos=0;    //type of service
    ip->tot_len=sizeof(struct iphdr)+sizeof(struct icmphdr); //toatal length
    ip->id=htons(random()); //Assign id as a random number
    ip->ttl=255; //time to live;
    ip->protocol=IPPROTO_ICMP;//ICMP header follow next to the ip header
    ip->check=0; //Assign checksum as zero for now
    ip->saddr=    INADDR_ANY;
    ip->daddr=inet_addr(d_addr);
    
    //Creating a raw socket
    
    if((raw=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))==-1)
    {
    perror("Something wrong with socket call :");
    }
    
    //setting the iphdrincl option
    
    setsockopt(raw, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int));
     
    //creating the icmp header
    icmp=(struct icmphdr *)(packet+sizeof(struct iphdr));
    
    icmp->type=ICMP_ECHO;        
    icmp->code        = 0;
        icmp->un.echo.id        = 0;
        icmp->un.echo.sequence    = 0;
        icmp->checksum         = 0;
        icmp-> checksum        = in_cksum((unsigned short *)icmp, sizeof(struct icmphdr));
        
        ip->check            = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
    
    serv.sin_family=AF_INET;
    serv.sin_addr.s_addr=ip->daddr;
    
    sent=sendto(raw,packet,sizeof(packet),0,(struct sockaddr *)&serv,sizeof(struct sockaddr));
    
    
    
     /*
         *listen for response
         */
        addrlen = sizeof(serv);
        if (recvfrom(raw, buffer, sizeof(packet), 0, (struct sockaddr *)&serv, &addrlen) == -1)
        {
        perror("recv");
        }
        else
        {
        printf("Received %d byte reply from:\n", sizeof(buffer));
            ipreply = (struct iphdr*) buffer;
        printf("ID: %d\n", ntohs(ipreply->id));
        printf("TTL: %d\n", ipreply->ttl);
            
    }
        close(raw);
        free(packet);
        return 0;
    
    
    
    }
    /*
     * in_cksum --
     * Checksum routine for Internet Protocol
     * family headers (C Version)
     */
    
    unsigned short in_cksum(unsigned short *addr, int len)
    {
        register int sum = 0;
        u_short answer = 0;
        register u_short *w = addr;
        register int nleft = len;
        /*
         * Our algorithm is simple, using a 32 bit accumulator (sum), we add
         * sequential 16 bit words to it, and at the end, fold back all the
         * carry bits from the top 16 bits into the lower 16 bits.
         */
        while (nleft > 1)
        {
          sum += *w++;
          nleft -= 2;
        }
        /* mop up an odd byte, if necessary */
        if (nleft == 1)
        {
          *(u_char *) (&answer) = *(u_char *) w;
          sum += answer;
        }
        /* add back carry outs from top 16 bits to low 16 bits */
        sum = (sum >> 16) + (sum & 0xffff);        /* add hi 16 to low 16 */
        sum += (sum >> 16);                /* add carry */
        answer = ~sum;                /* truncate to 16 bits */
        return (answer);
    }
    
    
    HERE IS THE OUTPUT
    Enter the destination address : 209.85.231.104(ip of google)
    Received 4 byte reply from:
    ID: 0
    TTL: 0

    What is going wrong.Thanks
     

Share This Page