当接收到“目的地不可达”数据包时,ICMP回显请求不会被发送。

3
我正在开发一个网络管理应用程序,使用原始BSD套接字(sendto)通过ICMP ping托管主机。
我的问题不是如何实现ping,事实上它已经很好地工作了。只有当目标主机在尝试发送ICMP echo请求时向管理服务器发送“Destination unreachable”消息时,我才会遇到问题。
当主机被添加到管理应用程序中时,将使用所述的ICMP ping进行测试,并同时启动“发现”,测试主机上的各种端口,例如SNMP(161)等,使用所需的协议来执行此操作。
现在,我知道在不知道主机是否存在或响应(即它发送了ICMP echo回复)的情况下执行该“发现”没有多大意义,但对于这个问题来说,这是至关重要的。让我们还假设这里的主机实际上是可达的并且确实响应ICMP ping,例如通过命令行ping
最终,“发现”会导致一些ICMP“Destination unreachable:Port unreachable”数据包发送回管理服务器,例如当目标主机上没有运行SNMP代理且端口161实际上无法到达时。
这是完全可以的,但由于某种原因,这似乎妨碍了ICMP套接字向该主机发送ICMP echo请求,而这对于ICMP ping是必需的。由于该请求从未发送,我的应用程序没有收到回复,并且在一段时间后(超时)将被视为“不可达”。
我使用Wireshark分析了网络流量,因此我可以告诉您实际上没有将ICMP echo请求发送到目标主机。我正在处理的应用程序还具有“状态轮询”功能,可用于在该主机上“手动”执行另一个ICMP ping。如果在添加主机之后使用它(即不再收到Destination unreachable数据包),则echo请求将被正常发送。
我对上述情况下未发送ICMP echo请求感到困惑。我确实有另一个接收所有传入ICMP数据包的ICMP套接字(以便响应回复),但它不应该影响发送套接字,对吧?在我的代码中,未定义任何针对Destination unreachable消息的反应,它们只是被忽略了,因此我非常确定不是我的代码禁用了请求发送。
事实上,负责发送请求的sendto函数已经执行(通过调试确保),并且甚至返回成功(发送的字节数),但数据包实际上并没有被发送。我可以在Windows和Linux系统上重现这个问题,因此我不认为这是任何操作系统问题。
禁用导致发送“目标不可达”消息的“发现”功能后,一切都恢复正常了,因此我相当确定是这些消息阻碍了ICMP回显请求的发送。我无法找到答案的重要问题是:为什么会这样呢?
如果需要更多信息,我可以提供,但是我担心我不被允许在这里发布任何代码,因为这是商业产品。代码并不特别,只是使用原始ICMP套接字发送和接收ICMP(IPv4)数据包,TOS = 0,TTL = 64。
1个回答

1

目标不可达是由路由器生成的,或者如果您在本地网络内进行ping操作,则会由本地主机生成。

我猜您的观察结果是因为您正在本地网络内进行ping操作。事实上,ICMP-3被生成意味着ARP查找失败,没有ARP查找,您实际上无法发送数据包,因为您不知道目标MAC地址。这解释了一切。

所以,无论如何,您应该等待一个固定的时间,比如一秒钟,并声明主机不存在,无论是否发送数据包都无关紧要。


ARP查找没有问题,问题出现在明显可达和可用的主机上(例如使用ping命令行)。我已经使用Wireshark进行了分析并得到确认。ICMP-3数据包涉及测试监听SNMP服务的端口。我非常确定Dest Unreachable不是由本地主机生成的,但是否真的如此,只有路由器才能生成它们吗?因为如果是这样,它会将目标主机设置为发送方。接收到的ICMP-3数据包在发送者字段中具有目标主机,而不是路由器。 - pdinklag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接