IP 片段的 UDP 校验和如何变化?

use*_*386 3 c sockets networking udp

我需要用 c 语言编写一个基本的网络堆栈,但对正确的做法有一些疑问。假设我只需要在 L4 上支持 UDP,在 L3 上支持 IP。

当我想发送一条需要分段的大消息时。处理这个问题的正确顺序是什么?

1)初始化udp头并计算整个数据字段(加上udp和伪头)的校验和然后对数据字段进行分段,为每个分段构建IP头,然后发送分段。

2) 对数据字段进行分段,然后构建一个 udp 标头,并在每个分段的前面添加不同的校验和。然后构建一个 IP 标头,将每个片段添加到该标头之前。然后发送我们的片段。

我的困惑源于 udp 校验和是否应该包含整个组装的数据报,或者只是单个片段。我非常感谢您提供的任何帮助。

ind*_*div 5

网络层彼此独立工作。当 IP 层对数据包进行分段时,UDP 层对此一无所知。当应用层 UDP 监听器收到数据包时,它将被重新组装,并且不知道数据包曾经被分段。

有了这些知识,我们可以说 UDP 校验和必须覆盖完全组装的数据包,并且在分段期间不必更改。事实上,UDP 标头中没有任何变化。

要对分段数据包进行错误检查,请使用 IPv4 校验和标头字段。IPv6 标头没有校验和字段,因为较低层预计具有无差错的数据包传送。

当您对 IPv4 数据包进行分段时,必须重新计算分段的 IPv4 标头。IPv4 维基百科条目告诉我们在对数据包进行分段时必须更改哪些内容:

  • 总长度字段是段大小。
  • 除了最后一个段之外,所有段都设置了更多片段 (MF) 标志,最后一个段设置为 0。
  • 片段偏移字段是根据原始数据有效负载中片段的偏移来设置的。这是以八字节块为单位测量的。
  • [IPv4] 标头校验和字段被重新计算。

总之,您执行以下操作:

  1. 获取应用程序级数据并将其包装在 UDP 标头中。
  2. 将带有 UDP 标头的数据包交给 IP 层。
  3. 将数据分成碎片。
  4. 对于每个片段,在其上放置一个 IPv4 片段标头。
    • 将片段交给第 2 层,并将第 2 层标头放在上面。
    • 发送片段。