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