ICMPv6 – Calculating Checksum for ICMPv6

checksumicmpicmpv6protocol-theoryrfc

Referring http://www.faqs.org/rfcs/rfc1071.html, I try to deduce the c code for calculating the checksum for ICMPv6. But check with the checksum parse by wireshark, I find that the answer got from my code is wrong…

the checksum parsed by wireshark is 0x8e73.

the following is my code, that is exactly same as mentioned in RFC.
NOTE : the array data is the raw data got from the ICMPv6

unsigned short checksum(unsigned short *addr, unsigned short count)
{
    unsigned long sum;

    sum = 0;
    while (count > 1) {
            sum += *(unsigned short*)addr++;
            count -= 2;
            printf("sum is %x\n", sum);
    }

    /*  Add left-over byte, if any */
    if (count){
            sum += *(unsigned char *)addr;
            printf("in side left-over byte\n");
    }
    /*  Fold 32-bit sum to 16 bits */
    while (sum >> 16) {
            sum  = (sum & 0xffff) + (sum >> 16);
            printf("IN while:sum is %x\n", sum);
    }
    printf("sum is %x\n", sum);
    return (unsigned short)(~sum);
}

int main() {
    unsigned short count = 32;
    //data is the raw data for ICMPv6 got from wireshark, and I put the checksum field as 0x0000
    unsigned short data[] = {0x8800, 0x0000, 0x6000, 0x0000, 0xfe80, 0x0000, 0x0000, 0x0000, 0xb96b, 0x982f, 0x447a, 0x6a80, 0x0201, 0x6057, 0x187d, 0x7fad};


    printf("check sum is %x\n", checksum(data, 32));
    return 0;
}

Best Answer

ICMP and ICMPv6 are two different protocols. For ICMPv6 checksum callulation see RFC2463 section 2.3 and the documents reffered there.