【发布时间】:2015-05-16 21:21:39
【问题描述】:
我正在研究标准 ping 实现。这里创建了icmp结构并填充了数据。IP层是内核添加的。但是,当我们使用函数http://linux.die.net/man/2/recvfrom 收到消息时,我观察到他们首先解析 IP 数据包,然后再解析 ICMp 数据包。为什么会这样。我所指的代码是在线提供的标准 ping 实现。
【问题讨论】:
我正在研究标准 ping 实现。这里创建了icmp结构并填充了数据。IP层是内核添加的。但是,当我们使用函数http://linux.die.net/man/2/recvfrom 收到消息时,我观察到他们首先解析 IP 数据包,然后再解析 ICMp 数据包。为什么会这样。我所指的代码是在线提供的标准 ping 实现。
【问题讨论】:
这是因为在原始套接字上接收 IPv4 数据包时始终包含标头。请注意raw(7) 中的以下内容(强调我的):
除非在套接字上启用了
IP_HDRINCL套接字选项,否则 IPv4 层会在发送数据包时生成 IP 标头。启用后,数据包必须包含 IP 标头。 用于接收的 IP 头总是包含在数据包中。
由于始终包含标头和has variable length(对于 IPv4),因此必须对其进行解析以找出 ICMP 数据的开始位置。
至于 为什么 标题没有被删除(对不起,如果这是您唯一想知道的事情),我不知道。我的疯狂猜测是,处理原始 IPv4 的足够多的程序想要查看标头,似乎不值得将剥离它作为选项包括在内。快速浏览一下,似乎标题 已为 IPv6 剥离。
标准的ping和ping6顺便说一下来自iputils,其中ping_common.c、ping.c和ping6.c 是最相关的源文件。
【讨论】:
<< 2 相同)得到字节数。