我有以下数据包(十六进制):
45 00 00 2C
14 3C 40 00
80 06 63 39
C0 A8 01 02
C0 A8 01 04
11 EF 00 7C
4F BF BB FE
18 DF 7A 77
50 18 00 40
02 41 00 00
78 70 00 01
我在其中确定了IP标头:
45 00 00 2C
14 3C 40 00
80 06 63 39
C0 A8 01 02
C0 A8 01 04
TCP标头:
11 EF 00 7C
4F BF BB FE
18 DF 7A 77
50 18 00 40
02 41 00 00
和数据
78 70 00 01
我正在尝试验证校验和。为此,我总结了TCP标题中除校验和字段之外的所有字段,这给了我201D6
然后我总结了数据字节,增加到7871
然后我添加计算的TCP长度(即24)协议,以及IP源和目标地址;总计:18380
添加最后三个标记的数量3FDC7
并将最有价值的数字与其余数字相加FDCA
,在计算其一个补码时变为0235
。然而,这与原始数据包的校验和不同。
我在哪里弄乱了什么?
答案 0 :(得分:1)
计算中有两个错误:
第一个是简单的,你总结24为TCP长度,但长度必须是十六进制,所以它是0x0018
。
第二个更棘手,RFC 793说:
校验和字段是 one 的16位补码 标题和文本中所有16位字的补码和。
所以它不仅仅是一个16位字的简单总和,而是一个一个补码和,这个forum answer解释了它是如何工作的:
添加16位值。每次产生一个进位(第17位)时,摆动那个位并将其添加回LSb(一个's) 数字)。这有点被错误地称为"补充 。此外"
- 醇>
以这种方式添加所有值后,反转结果中的所有位。包含另一个二进制文件的所有位的二进制值 价值倒置称为其补充,""或者只是它的 "补充"
这样做你会发现:
0x01D8
表示没有校验和的TCP标头
0x7871
获取数据
0x8375
用于伪标头
0x0018
表示TCP长度
0xC0A0102
用于IP src
C0A80104
获取IP dst
0x0006
16位的补码和所有这些的补码给出 0x0241
,这是正确的结果。