【问题标题】:Why ping receives another ping command packet?为什么 ping 会收到另一个 ping 命令包?
【发布时间】:2016-05-05 06:37:50
【问题描述】:

我正在学习 C 中的 ping 实现。 问题是,我使用原始套接字来接收数据包。对于所有数据包,我们在ICMP header 中都有一个标识值。

我在多个终端中运行ping

例如,我在三个终端中运行了三个ping google.com

第一次ping识别值为23456,第二次ping识别值为34564,第三次ping识别值为98763。

我的问题是第二次 ping 必须接收到 34564 数据包的标识,但它接收到的标识值为 23456。

对于每个 ping,新的原始套接字正在创建。但它收到另一个 ping 数据包。

谁能解释一下,为什么它会收到另一个 ping 数据包?

更新:-

我还有一个疑问。怀疑是,

原始套接字从何处以及如何识别此原始套接字的数据包?

更新 1:-

这是代码的链接。

ping_common.c

ping.c

ping.h

【问题讨论】:

  • 虽然我试过了,但我在你运行的未发布代码中找不到问题。
  • 它发生在回复数据包中。使用 recvmsg 我正在接收数据包。在我验证数据包的 recvmsg 之后,在验证过程中,标识值发生了变化。
  • @suresh:感谢您的信息。现在请给我们一些代码..
  • @suresh 您链接的代码是linux ping 命令的来源,他们没有您描述的问题。你需要展示你自己的代码。
  • 我只是在学习这段代码。他们跳过了这些数据包。我怀疑这是原始套接字。为什么它会收到另一个套接字数据包?

标签: c linux ping raw-sockets


【解决方案1】:

您看到的是原始套接字的设计,因为原始套接字旨在接收所有原始数据包。因此,要仅接收对某些 ICMP 数据包的回复,您需要在套接字上应用过滤器。首先,您可以使用ICMP_FILTER 套接字选项来限制接收某些 ICMP 类型:

struct icmp_filter filter;
filter.data = <bit mask of ICMP types, like ICMP_REPLY>;
setsockopt(sock, SOL_RAW, ICMP_FILTER, &filter, sizeof filter)

其次,您可以附加套接字过滤器以强制只接收具有给定 ICMP ID 的包:

struct sock_fprog filter;
// set filter to check ID with your own ID
setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof filter);

【讨论】:

  • @suresh 为两个 ping 创建了两个原始套接字。
  • 原始套接字不检查任何条件,例如仅读取此套接字的数据包?
  • @suresh 我们说的是 raw 套接字,没有仅此套接字的数据包之类的东西,原始套接字适用于所有数据包,您可以做的是过滤靠自己。
【解决方案2】:

回答您的其他疑问:

  • 原始套接字从何处以及如何识别此原始套接字的数据包?

原始套接字位于 IP 层之后的其他协议处理程序旁边。摘自《理解 Linux 网络内部原理》第 25.5 章:

以下是协议之间交互的一些示例:

IP协议

第 24 章中描述的 ip_local_deliver_finish 例程提供 将 ICMP 消息输入到由注册的接收例程 icmp_rcv ICMP 协议,但它也将它们传送到原始 IP 套接字 根据 ICMP 协议注册的 (raw_v4_input)。

【讨论】:

    猜你喜欢
    • 2021-01-06
    • 2020-12-04
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 2015-06-05
    • 2023-02-12
    • 2016-12-19
    • 2017-12-05
    相关资源
    最近更新 更多