不正确填充数据包的 UDP 校验和计算

网络工程 以太网 IPv4 UDP 射频 校验和
2022-02-13 14:45:53

假设我正在接收有效载荷小于 18 个八位字节的 IPv4 UDP 数据包,因此当它们通过以太网传输时,它们有一些尾随填充。在数据包的源和我的接收器之间有一个自定义设备,除其他外,它会修改 IP 标头,以便其总长度字段将包括以太网填充。因此,例如,具有 7 个八位字节长的有效载荷的数据包的 IP 总长度不会是 35,而是 46。这是错误的行为,但我无法摆脱设备或修改它,所以我必须处理它。

小问题:我是否正确理解根据RFC 894,这样的数据包一开始就被认为是无效的?

无论如何,Windows 和 Linux 都不会丢弃此类数据包,因此询问如何为它们计算 UDP 校验和是有意义的。

如果我正确理解RFC 768,则伪标头中的长度应该是 UDP 长度,因此 15 表示 7 个八位字节长的有效负载 - 就像实际 UDP 标头中的长度字段一样。这也是 Wireshark 的 UDP 解析器所做的。

另一方面,Windows 和 Linux 的网络堆栈都做了其他事情。当他们验证校验和时,他们将伪标头的长度设置为 IP 标头的总长度减去其大小。对于普通数据包,这与 UDP 标头中的长度字段的净值相同,因此没关系。但是,对于我的数据包,结果显然不同。

谁有错?这是 Wireshark 和我对RFC 768的理解中的错误吗?它是 Windows/Linux 中的错误吗?这个问题是否没有实际意义,因为这些数据包一开始就是非法的,在这种情况下,Wireshark 应该将它们标记为这样,而 Windows/Linux 无论如何都应该丢弃它们?

1个回答

假设我正在接收有效载荷小于 18 个八位字节的 IPv4 UDP 数据包,因此当它们通过以太网传输时,它们有一些尾随填充。生成所述数据包的设备在IP头的总长度字段中包含填充的长度。因此,例如,具有 7 个八位字节长的有效载荷的数据包的 IP 总长度不会是 35,而是 46。

你从哪里得到这个想法的?

以太网是二层协议,它不知道三层协议。以太网可以承载任意数量的第 3 层协议(IPv4、IPX、IPv6、AppleTalk 等),它对第 3 层协议或第 3 层协议的标头一无所知,因此无法更改第 3 层标头中的字段。

相反,第 3 层协议不知道哪个第 2 层协议(以太网、Wi-Fi、令牌环、帧中继、ATM、PPP 等)承载其数据包。

以太网填充用于第 2 层的以太网帧,而不是第 3 层数据包。


编辑:

您完全改变了问题的含义,这是非常糟糕的形式,尤其是当您已经得到原始问题的答案时。您应该针对不同的问题开始一个新问题,而不是更改原始问题。

中间改变IPv4头总长度字段的设备必须改变IPv4头校验和,并且UDP校验和(如果使用,但对于IPv4是可选的,并且经常不使用)不使用IPv4总计算长度字段或校验和,所以它不会改变。

如果 IPv4 总长度字段发生更改,则 IPv4 将其原始有效负载(UDP 数据报)和填充发送到 UDP。

UDP 标头有自己的长度字段。如果设备不修改此字段,则 UDP 将正确,并且 UDP 将向应用程序发送正确数量的八位字节(不包括填充),但如果设备更改 UDP 长度字段,则 UDP 校验和将为重新计算后,UDP 将发送原始的 UDP 有效负载以及填充到应用程序,这可能会导致应用程序出现问题。