Have been stuck in this problem for several days :-(
Can anyone help me please..?
the core code:
IP header
typedef struct ip_hdr
{
unsigned char h_ver;
unsigned char tos;
unsigned short tot_len;
unsigned short id;
unsigned short
zero:1,
frag:1,
more_frag:1,
frag_off:13;
unsigned char ttl;
unsigned char protocol;
unsigned short checkSum;
unsigned long saddr;
unsigned long daddr;
}IP_HEADER;
oh and I really worried about the problem of big/small endian,is this header correct?I type it with the reference of RFC791.Internet Protocol
Generate an IP datagram
int IPGen(ip_hdr *hdr,unsigned long srcIP,unsigned long dstIP)
{
hdr->h_ver=(4<<4 | sizeof(ip_hdr)/sizeof(unsigned int));
hdr->tos=0;
hdr->tot_len=sizeof(ip_hdr)+sizeof(tcp_hdr);
hdr->id=0;
hdr->zero=0;
hdr->frag=0;
hdr->more_frag=0;
hdr->frag_off=0;
hdr->ttl=64;
hdr->protocol=IP_TCP;
hdr->saddr=srcIP;
hdr->daddr=dstIP;
hdr->saddr=htonl(hdr->saddr);
hdr->daddr=htonl(hdr->daddr);
hdr->tot_len=htons(hdr->tot_len);
hdr->checkSum=0;
hdr->checkSum=checkSum((char*)hdr,sizeof(ip_hdr);
return 0;
}
the checkSum
function
I copied it from the source code of linux thus I assume that the function works properly,but just in case;-)
unsigned short checkSum(unsigned char * buff, int wlen)
{
unsigned long sum = 0;
if (wlen) {
unsigned long bogus;
__asm__("clc\n"
"1:\t"
"lodsl\n\t"
"adcl %3, %0\n\t"
"decl %2\n\t"
"jne 1b\n\t"
"adcl $0, %0\n\t"
"movl %0, %3\n\t"
"shrl $16, %3\n\t"
"addw %w3, %w0\n\t"
"adcw $0, %w0"
: "=r" (sum), "=S" (buff), "=r" (wlen), "=a" (bogus)
: "0" (sum), "1" (buff), "2" (wlen))
}
return (~sum) & 0xffff;
}
the warning from
G++ 4.7.1(MinGW)
In function 'int IPGen(ip_hdr*, long unsigned int, long unsigned int)':
[Warning] invalid conversion from 'char*' to 'unsigned char*' [-fpermissive]
[Warning] initializing argument 1 of 'short unsigned int checkSum(unsigned char*, int)' [-fpermissive]
and than Wireshark told me that all packet I sent has an wrong IP checkSum :-(
but the really weird thing is I save a normal packet's bytes,and calculate its IP checksum with following code:
(ip_hdr*)(pktbytes+sizeof(eth_hdr))->checkSum=0;
unsigned short checkSum2=checkSum(pktbytes+sizeof(eth_hdr),sizeof(ip_hdr));
I FOUND THAT
checkSum2
is unequal to the original checksum!!!
Please,help.