为什么ping接收另一个ping命令包?

时间:2016-05-05 06:37:51

标签: c linux ping raw-sockets

我正在学习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

2 个答案:

答案 0 :(得分:3)

您所看到的是原始套接字的设计,因为原始套接字旨在接收所有原始数据包。因此,要仅接收对某些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);

答案 1 :(得分:1)

回答你的其他疑问:

  • 原始套接字读取数据包从哪里以及如何识别该套接字的原始套接字?

原始套接字位于IP层之后的其他协议处理程序旁边。从“了解Linux网络内部”一书第25.5章:

  

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

     

IP协议

     

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

enter image description here