简体   繁体   English

为什么ping会收到另一个ping命令数据包?

[英]Why ping receives another ping command packet?

I am learning about the ping implementation in C. The problem is, I was using a raw sockets to receive the packet. 我正在学习C语言中ping的实现。问题是,我使用的是原始套接字来接收数据包。 For all packets we have a identification value in ICMP header . 对于所有数据包,我们在ICMP header都有一个标识值。

I was running the ping in multiple terminal. 我在多个终端上运行ping

For example, I was running three ping google.com in three terminals. 例如,我在三个终端上运行三个ping google.com

For the first ping the identification value is 23456, the second ping identification value is 34564, and the third ping identification value is 98763. 对于第一次ping,标识值为23456,第二次ping标识值为34564,并且第三次ping标识值为98763。

My problem is the second ping have to receives the identification with 34564 packet, but it receives the identification value as 23456. 我的问题是第二个ping必须接收34564数据包的标识,但它接收的标识值为23456。

For each ping the new raw socket is creating. 对于每个ping,都会创建新的原始套接字。 But it receives another ping packet. 但是它收到另一个ping数据包。

Can anyone please explain me, why it receives another ping packet ? 谁能解释一下为什么收到另一个ping数据包?

UPDATE:- 更新: -

I have another one doubt. 我还有一个疑问。 The doubt is, 疑问是,

raw sockets reads the packet from where and how it identify the packet is for this raw socket ? raw套接字从何处读取数据包,以及如何识别此原始套接字的数据包?

UPDATE 1:- 更新1:-

Here is the link for the codes. 这是代码的链接。

ping_common.c ping_common.c

ping.c ping.c

ping.h ping.h

What's you are seeing is by design of the raw socket, because raw sockets are meant to receive all the raw packets. 您所看到的是原始套接字的设计,因为原始套接字是用来接收所有原始数据包的。 So to only receive the reply to certain ICMP packets, you need to apply filters on the socket. 因此,仅接收对某些ICMP数据包的答复,您需要在套接字上应用过滤器。 First you can use ICMP_FILTER socket options to restrict receiving of certain ICMP types: 首先,您可以使用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)

Second, you can attach socket filter to enforce only receive the package with the given ICMP ID: 其次,您可以附加套接字过滤器以仅接收具有给定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);

To answer your other doubt: 要回答您的其他疑问:

  • raw sockets reads the packet from where and how it identify the packet is for this raw socket ? raw套接字从何处读取数据包,以及如何识别此原始套接字的数据包?

Raw socket sit along side other protocol handlers after IP layer. 原始套接字与IP层之后的其他协议处理程序并排放置。 From book "Understanding Linux Network Internals" Chapter 25.5: 从《了解Linux网络内部知识》一书第25.5章中:

Here are some examples of interactions between protocols: 以下是协议之间交互的一些示例:

IP protocol IP协议

The ip_local_deliver_finish routine, described in Chapter 24, delivers ingress ICMP messages to the receive routine icmp_rcv registered by the ICMP protocol, but it also delivers them to the raw IP sockets that registered against the ICMP protocol (raw_v4_input). 第24章中描述的ip_local_deliver_finish例程将入口ICMP消息传递到由ICMP协议注册的接收例程icmp_rcv,但还将它们传递到针对ICMP协议注册的原始IP套接字(raw_v4_input)。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM