我正在开发一个网络管理应用程序,它通过原始BSD套接字(sendto
)使用ICMP ping托管主机。
我的问题不是如何做到这一点,事实上它的效果非常好。当我尝试向该主机发送ICMP回应请求时,目标主机向管理服务器发送目标无法访问消息时,我似乎只遇到了问题。
当在管理应用程序中添加主机时,将使用所述ICMP ping对其进行测试,同时启动“发现”,测试主机上的各种端口,如SNMP(161)等,使用这样做需要各自的协议。
现在,我知道在我不知道它是否存在或响应的主机上执行“发现”没有多大意义(即它发送了一个ICMP echo回复),但对于这个问题,这是关键。我们还假设这里讨论的主机实际上是可达的并且确实响应ICMP ping,例如通过命令行ping
。
“发现”最终导致一些ICMP “目的地不可达:端口不可达”数据包被发送回管理服务器,例如,当目标主机上没有运行SNMP代理且实际上端口161无法访问时。
这很好,但由于某种原因,这似乎阻碍了ICMP套接字向该主机发送ICMP回应请求,这是ICMP ping所必需的。由于该请求永远不会被发送,我的应用程序没有得到回复,一段时间(超时)后主机将被视为“无法访问”。
我使用Wireshark分析了网络流量,因此我可以看出实际上没有发送到目标主机的ICMP echo请求。我工作的应用程序还具有“状态轮询”功能,可用于“手动”在该主机上执行另一个ICMP ping。如果在添加主机后使用它(即不再有目的地不可达数据包传入),则发送回应请求时没有任何问题。
我很困惑在上面解释的情况下没有发送ICMP回应请求。我有另一个ICMP套接字接收所有传入的ICMP数据包(以便对回复作出反应),但它不应该影响发送套接字,如果它?在我的代码中,没有为目标无法访问的消息定义任何反应,它们被简单地忽略,所以我非常确定它不是我自己的代码来禁用请求发送。
实际上,负责发送请求的sendto
函数被执行(通过调试确保),甚至返回成功(发送的字节数),但数据包实际上并不存在发送。我可以在Windows和Linux系统上重现这一点,所以我不认为这是一种操作系统问题。
禁用导致这些目标无法访问消息的“发现”会使一切正常工作,所以我很确定这些消息阻碍了ICMP回应请求的发送。我无法找到答案的一个重要问题是:为什么?
如果需要,我可以提供更多信息,但是,我担心我不允许在此发布任何代码,因为这是商业产品。但是,代码没有什么特别之处,只是使用原始ICMP套接字发送和接收TOS=0
和TTL=64
的ICMP(IPv4)数据包。
答案 0 :(得分:1)
路由器生成Dest unreachable,或者如果您在localnet内ping,则它将由localhost生成。
我猜您的观察是因为您在本地网络中进行ping操作。正在生成ICMP-3意味着ARP查找失败,没有ARP查找,您实际上无法发送数据包,因为您不知道目标MAC地址。这表明了一切。
所以,无论如何,你应该等待一段固定的时间,并声明主机不存在,无论数据包是否发送都无关紧要。