在 ICMP 套接字上接收数据

Posted

技术标签:

【中文标题】在 ICMP 套接字上接收数据【英文标题】:Receiving Data on an ICMP socket 【发布时间】:2010-11-10 20:36:55 【问题描述】:

在 ICMP 套接字上接收时(SOCK_RAW 和 IPPROTO_ICMP),因为 ICMP协议中没有“端口”的概念,怎么能 应用程序确定接收到的数据包不是其他数据包的一部分 TCP/UDP/任何套接字传输也发生在 同一时间?

例如,假设您有一个具有 2 个线程的应用程序。线程 1 建立一个 TCP 服务器套接字,并不断地从一个 连接的客户端。线程 2 不断发送回显请求包 使用 ICMP 套接字 (ping) 到同一个客户端,然后接收回显 回复。什么是阻止线程 2 接收 TCP 之一 数据包代替?

【问题讨论】:

【参考方案1】:

ICMP 是不同于 TCP 和 UDP 的协议,由 IP header 中的协议字段确定。当您使用IPPROTO_ICMP 打开套接字时,您是在告诉套接字仅传输和接收带有协议字段设置为 ICMP 的 IP 标头的数据包。

同样,使用IPPROTO_TCPIPPROTO_UDP 打开的套接字仅响应其IP 标头包含分别设置为TCP 或UDP 的协议字段的数据包。

【讨论】:

【参考方案2】:

您可以检查 ICMP 标头的类型并查看其 ICMP Echo Response (Type 0)。同样在 ICMP 中,响应将包含您首先发送的请求。

【讨论】:

【参考方案3】:

收到的 UDP 和 TCP 数据包从未传递到原始套接字。如果一个进程想要读取包含 UDP 或 TCP 数据包的 IP 数据报,则必须在数据链路层读取数据包。检查此链接

http://aschauf.landshut.org/fh/linux/udp_vs_raw/ch01s03.html

如果数据包没有在第 2 层缓存,则它由内核处理。 如果数据包是 icmp 协议并且它是回显请求或时间戳请求或地址掩码请求类型,则它完全由内核处理,否则它将传递给 RAW SOCKETS。

另一个,所有带有内核不理解的协议字段的数据报都被传递到原始套接字,只对它们进行基本的ip处理

最后,如果数据报以片段的形式到达,那么在所有片段都到达并重新组装之前,什么都不会传递给原始套接字。

如果您想了解更多信息,请阅读this book。

【讨论】:

警告任何偶然发现此问题的人:关于此答案的几乎所有内容都是不正确的。这里关于原始套接字如何工作的每个断言都是错误的或被误解的。

以上是关于在 ICMP 套接字上接收数据的主要内容,如果未能解决你的问题,请参考以下文章

Python Raw Socket 无法接收 ICMP 消息;出现在 Wireshark 中

c_cpp 使用原始套接字发送和接收带有ICMP协议的OUTPUT的数据包的小程序是六进制格式的数据包。可以打印为%c来查看数据。 IP heade

原始套接字的学习和问题

使用数据包套接字在同一网络接口上发送和接收时无法接收包

Python套接字:错误接收数据

opengl 应用程序从套接字连接监听/接收数据? [关闭]