# Calculating checksum for ICMPv6

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;
}
``````

## 2 Answers

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

• I've check this RFC. So I should pre-appending the psedo layer before the icmp header? from the rfc I found the format of pseudo header is source-address/destination address/upperlayer packet length/zero/next header. source and destionation address will be occupied 16bytes, but how about other fields? – Anakin Tung Sep 30 '15 at 12:57

Thanks for Jens's help. After having look for RFC2463. I pre-append the following data for the pseudo header.

``````unsigned short src_ip = {0} //fill the source IP
unsigned short dst_ip = {0} //fill the destination IP
//0x0020 is the packet length of ICMPv6
//fill 3bytes of zero and 0x3a is the type of ICMPv6, so we have
//0x00, 0x003a
unsigned short remain[] = {0x0020, 0x0000, 0x003a}
unsigned short data[] = {} //as before
``````

So concatenate all this data, send it to the check_sum algorithm[this part is same as icmp], we can derive the correct checksum!