在 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_TCP
或IPPROTO_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