1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

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