【发布时间】:2017-08-26 03:04:03
【问题描述】:
需要编写一个工具来构建整个 ICMPv6 数据包。我似乎无法获得生成正确 ICMPv6 校验和的代码。我已经尝试了下面的checksum(void * buffer, int bytes) 函数
Calculating checksum of ICMPv6 Packet in C
我有一个用于验证校验和的wireshark 捕获。原始数据包内容看起来像
0000 33 33 00 00 00 01 38 ea a7 89 be 59 86 dd 60 00
0010 00 00 00 20 3a ff fe 80 00 00 00 00 00 00 88 c5
0020 75 41 aa 0c 58 ee ff 02 00 00 00 00 00 00 00 00
0030 00 00 00 00 00 01 88 00 b8 cc 20 00 00 00 fe 80
0040 00 00 00 00 00 00 88 c5 75 41 aa 0c 58 ee 02 01
0050 38 ea a7 89 be 59
数据包中的正确校验和当然是0xb8cc。上面的数据包是整个 IPv6 数据包,但数据包的相关内容从源地址开始,即fe 80 00 00 00 00 00 00 88 c5 75 41 aa 0c 58 ee
. ICMPv6 标头从 88 00 开始。
我认为上面链接中的校验和函数可能是正确的,但我正在构建的用于计算校验和的缓冲区可能不正确。按照 RFC,我通过连接源地址、目的地地址、数据包长度 (32 = 00 20)、下一个标头 (58 = 3a)、ICMPv6 数据包的其余部分来构建缓冲区,这给了我最终的缓冲区
uint8_t packet[] = {
0xfe , 0x80 ,0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x00 ,
0x88 , 0xc5 ,0x75 , 0x41 ,0xaa , 0x0c ,0x58 , 0xee,
0xff , 0x02 ,0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x00,
0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x01,
0x00 , 0x20 ,0x3a , 0x88 ,0x00 , 0x00 ,0x00 ,
0x20 , 0x00 ,0x00 , 0x00 ,0xfe , 0x80 ,0x00 , 0x00 ,
0x00 , 0x00 ,0x00 , 0x00 ,0x88 , 0xc5 ,0x75 , 0x41 ,
0xaa , 0x0c ,0x58 , 0xee ,0x02 , 0x01 ,0x38 , 0xea ,
0xa7 , 0x89 ,0xbe , 0x59
};
我把校验和函数称为
fprintf(stdout, "%x\n", ~checksum(packet, sizeof(packet)));
但我得到的校验和值为ffffd174。忽略前 2 个字节,我得到 7510。
任何想法我做错了什么?我认为校验和函数中可能存在字节序问题,但我也可能错误地构造了伪标题。
【问题讨论】: