参考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;
}发布于 2015-09-30 12:29:43
ICMP和ICMPv6是两种不同的协议。有关ICMPv6校验和调用,请参阅RFC2463第2.3节,文档在此查询。
发布于 2015-09-30 13:29:48
谢谢詹斯的帮助。在寻找RFC2463之后。我预先为伪头追加了以下数据。
unsigned short src_ip[8] = {0} //fill the source IP
unsigned short dst_ip[8] = {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所以把所有这些数据连在一起,发送给check_sum算法本部分与icmp相同.,我们就可以得到正确的校验和了!
https://networkengineering.stackexchange.com/questions/22933
复制相似问题