【问题标题】:Why is the IP layer not removed by the kernel in the ping program为什么在ping程序中内核没有去掉IP层
【发布时间】:2015-05-16 21:21:39
【问题描述】:

我正在研究标准 ping 实现。这里创建了icmp结构并填充了数据。IP层是内核添加的。但是,当我们使用函数http://linux.die.net/man/2/recvfrom 收到消息时,我观察到他们首先解析 IP 数据包,然后再解析 ICMp 数据包。为什么会这样。我所指的代码是在线提供的标准 ping 实现。

【问题讨论】:

    标签: c linux ip ping icmp


    【解决方案1】:

    这是因为在原始套接字上接收 IPv4 数据包时始终包含标头。请注意raw(7) 中的以下内容(强调我的):

    除非在套接字上启用了IP_HDRINCL 套接字选项,否则 IPv4 层会在发送数据包时生成 IP 标头。启用后,数据包必须包含 IP 标头。 用于接收的 IP 头总是包含在数据包中。

    由于始终包含标头和has variable length(对于 IPv4),因此必须对其进行解析以找出 ICMP 数据的开始位置。

    至于 为什么 标题没有被删除(对不起,如果这是您唯一想知道的事情),我不知道。我的疯狂猜测是,处理原始 IPv4 的足够多的程序想要查看标头,似乎不值得将剥离它作为选项包括在内。快速浏览一下,似乎标题 已为 IPv6 剥离。

    标准的pingping6顺便说一下来自iputils,其中ping_common.cping.cping6.c 是最相关的源文件。

    【讨论】:

    • 非常感谢。这就是我一直在寻找的。我还观察到他们将 ip 数据包的长度右移了 2。这是为什么呢?
    • @GatsbyGreat:你在看哪个 ping 实现?右移 2 会除以 4,但我不确定他们为什么要这样做。
    • 这是因为 IP 头中的 IHL 字段指定了 32 位(4 字节)字的数量。将其乘以四(与<< 2 相同)得到字节数。
    • 顺便说一下,原始套接字的某些行为可能是系统特定的,但似乎 Linux 和 OS X 在这里的行为相似。
    猜你喜欢
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 2015-05-15
    • 2014-07-23
    • 2022-01-15
    • 2014-12-20
    • 1970-01-01
    • 2014-03-12
    相关资源
    最近更新 更多