参考 http://www.faqs.org/rfcs/rfc1071.html,我尝试推导出用于计算 ICMPv6 校验和的 c 代码。但是通过wireshark检查校验和解析,我发现从我的代码中得到的答案是错误的......
由wireshark解析的校验和是0x8e73。
以下是我的代码,与 RFC 中提到的完全相同。注意:数组数据是从 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;
}