简体   繁体   中英

IP checksum calculation incorrect

im having trouble with computing the correct ip checksum of my packets. Here is the code and i will explain what im doing and what is going wrong..

u_short checkSum(u_short *data, int byteCount){
int i, sum = 0;

for(i = 0; i < byteCount/2; i++){
    if(i == 5) continue;
    sum += *data++;
}

while(sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
return (u_short)~sum;
}

First of all, my function is general for computing 16-bit checksum of the data sent. The bytecount is assumed to be even just for testing purposes. sum is the variable where i keep my 32-bit sum (when 16-bit sums overflow i can keep the overflow in the high 16-bit half). With the for i loop through the 16-bit blocks of the data and sum them up, incrementing the data pointer (by 16bits it's u_short), there is one if test to skip the checksum part of the header.. As it can be seen in the rfc 791 the checksum part is 6-th 16-bit block in the header (5 in my case because i start counting from 0). After the data is summed, i add the high 16-bits to the low 16-bits and fold the 32-bit int into 16-bit short. At the end i invert the bits (one's complement) and shorten the 32-bit in 16-bit and return it to the caller function.

This is not providing the correct checksum that is sent to me from pcap (i use it for sniffing packets). this is how i call my function to compare the results..

if(etherHdr->ether_type == 8){
    ipHdr = (struct ip*) (packet + sizeof(struct ether_header));
    printf("chck: %04x mychck: %04x\n\n", ipHdr->ip_sum, checkSum((u_short*)ipHdr, sizeof(struct ip)));
}

The if is filtering out only IP packets (code 8 in the ethernet header type field)..

and this is the output when i run my program..

chck: ef66 mychck: 06ee

chck: 3db8 mychck: 0264

chck: 9615 mychck: 0000

chck: edef mychck: ff64

chck: 59f1 mychck: 0164

chck: 49f1 mychck: 0264

chck: a3d4 mychck: 0c77

chck: e36b mychck: 0264

chck: aad4 mychck: 0c77

chck: 46d1 mychck: 0c77

chck: f40b mychck: 0264

chck: a8d4 mychck: 0c77

I downloaded other code examples running around on the net and neither of those gives the result that every IP header contains with in it when pcap forwards the packet to my code..

please help if you can, thanks.

The correct way to do it is given in RFC 1071 . You're close, but no cigar yet.

Maybe try this source code for calculating checksum, I'm using it and it works great for my softwares.

            int
checksum
            (unsigned short *   data,
            int         length)
{
    register int                nleft   = length;
    register unsigned short     *   w   = data;
    register int                sum = 0;
    unsigned short              answer  = 0;

    while (nleft > 1)
    {
        sum     += *w++;
        nleft   -= 2;
    }

    if (nleft == 1)
    {
        *(unsigned char *)(&answer) = *(unsigned char *)w;
        sum+=answer;
    }

    sum = (sum>>16) + (sum & 0xffff);
    sum += (sum>>16);
    answer = ~sum;

    return answer;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM