【问题标题】:AF_PACKET raw IP packets with SOCK_DGRAM require fragmenting?带有 SOCK_DGRAM 的 AF_PACKET 原始 IP 数据包需要分段吗?
【发布时间】:2019-11-06 01:03:27
【问题描述】:

我看到的在 linux 中使用 AF_PACKET 套接字的大多数示例代码都使用 SOCK_RAW 版本来发送以太网数据包。我希望使用带有第 3 层 SOCK_DGRAM 选项的 AF_PACKET 套接字来发送带有自定义 IP 标头的自定义 UDP 数据包。我的问题是,我是否必须在用户空间处理 IP 分片并将多个分片的 IP 数据包写入 AF_PACKET 套接字,或者我可以写一个 30K 数据的 UDP 数据包,内核将为我分片?

【问题讨论】:

  • "一个自定义的IP头" 以什么方式自定义?过于自定义,它将被下一个 IP 进程(路由器或目标,如果在同一网络上)丢弃。如果您需要在 IP 中打包之前分解 UDP 数据报(不是数据包;毕竟,UDP 中的“D”用于数据报;数据链路上的帧、网络上的数据包、UDP 的数据报和 TCP 的段) ,那么这不是 IPv4 分片,您应该尽可能避免 IPv4 分片,因为当今许多路由器和防火墙都会丢弃分片以防止分片攻击。
  • 无论如何,您确实希望将 UDP 数据报的大小限制在 576 字节左右,因为 UDP 不可靠,并且您丢失数据报。数据报中的数据越少,丢失时丢失的数据就越少。让您的应用层协议将数据分成小块以进行 UDP 传输。
  • 感谢您的建议。这是嵌入式 linux 设备上的自定义应用程序,在封闭的无线电网络中处理多播,没有路由器或防火墙,我无法控制应用程序层,也不知道数据报有多大。我想确保它在大于 1500 的情况下是健壮的,但不确定我是否必须在 AF_PACKET 套接字的用户空间部分实现分段。
  • 不是分片,而是发生在网络层。您想在传输层之前对数据进行分段。当数据包通过中间设备时,IPv4 会发生分段,例如路由器,其中 IPv4 数据包对于退出接口的 MTU 来说太大了。分片实际上非常困难,随着我们转向 IPv6,它已被弃用。在任何情况下,您都会在网络上丢失数据包,因此您要限制 UDP 数据报中包含的数据。 TCP 会重新发送丢失的数据,但 UDP 不会。
  • 我在网络层操作。来自 man packet(7):“数据包套接字用于在设备驱动程序(OSI 第 2 层)级别接收或发送原始数据包。”有 SOCK_RAW,您可以在其中读取和写入以太网数据包,并且必须构建和解析以太网标头。然后是 SOCK_DGRAM,它“在稍高的级别上运行”,您不必担心以太网标头,但您必须构建自己的 IP 标头。我不清楚的是“略高一点”是否包括处理碎片。

标签: linux networking raw-sockets


【解决方案1】:

开发后,我可以确认,如果您使用带有 SOCK_DGRAM 的 AF_PACKET 套接字来处理 IP 数据包,则必须手动处理分段。我尝试编写一个 4000 字节的 UDP 数据报,并收到“消息大小太长”错误。

【讨论】:

    猜你喜欢
    • 2013-01-16
    • 2011-05-10
    • 2021-06-05
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 2019-12-04
    相关资源
    最近更新 更多