关于像本例中那样使用 ICMP 原始套接字
sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
有一些重要的问题我没有在文档中的任何地方找到答案。据我了解ICMP协议(protocol)已实现 在内核级别((通过 %SystemRoot%\System32\Drivers\Tcpip.sys 驱动程序窗口)。
那么这个内核逻辑如何与愿意发送和接收上面示例中定义的 ICMP 数据包的原始用户空间套接字交互?
由于 RAW 套接字打开并且操作系统赋予应用程序对 ICMP 的完全控制权,ICMP 逻辑是否被取消?或者他们并行工作(不可避免地在网络上造成困惑)。我可以告诉操作系统我想要准确处理哪些 ICMP 数据包吗?
欢迎针对 linux 和 windows 的回答。
最佳答案
通过将原始套接字与 IPPROTO_ICMP
一起使用,您只会获得到达主机的 ICMP 数据包的副本(请参阅 How to receive ICMP request in C with raw sockets )。网络堆栈中的 ICMP 逻辑仍然存在,并将处理 ICMP 消息。
因此您只需要在收到您感兴趣的 ICMP 数据包后选择它们(例如,在 ICMP header 中使用相应的 ID)。在接收缓冲区中,您可以通过调用 recv()
来填充您还可以获得完整的 IP header 。
在 Linux 下甚至有一个套接字选项 (ICMP_FILTER
),您可以使用它为不同的 ICMP 数据包设置接收过滤器。
关于linux - 原始 ICMP 套接字与内部堆栈 windows/linux 的交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48635930/