3

我正在开发一个网络管理应用程序,该应用程序使用 ICMP 通过原始 BSD 套接字 ( sendto) 对托管主机执行 ping 操作。

我的问题不是如何做到这一点,事实上它运作良好。我似乎只是在目标主机向管理服务器发送目的地不可达消息时遇到问题,而我正在尝试向该主机发送 ICMP 回显请求。

当在管理应用程序中添加主机时,将使用所述 ICMP ping 对其进行测试,同时启动“发现”,使用各自的协议测试主机上的各种端口,例如 SNMP (161) 等需要这样做。

现在,我知道在我不知道它是否存在或响应的主机上执行该“发现”没有多大意义(即它发送了 ICMP 回显回复),但对于这个问题,这是至关重要的。让我们还假设这里讨论的主机实际上是可访问的,并且确实响应 ICMP ping,例如通过命令行ping

“发现”最终会导致一些 ICMP “目标不可达:端口不可达”数据包被发送回管理服务器,例如,当目标主机上没有运行 SNMP 代理并且端口 161 实际上无法访问时。

这很好,但由于某种原因,这似乎阻碍了 ICMP 套接字向该主机发送 ICMP 回显请求,这是 ICMP ping 所必需的。由于该请求从未发送过,因此我的应用程序没有得到回复,并且主机将在一段时间后被视为“无法访问”(超时)。

我使用 Wireshark 分析了网络流量,因此我可以看出实际上没有发送到目标主机的 ICMP 回显请求。我工作的应用程序还有一个“状态轮询”功能,可用于“手动”在该主机上执行另一个 ICMP ping。如果在添加主机之后使用它(即不再有目的地不可达数据包传入),则发送回显请求没有任何问题。

我对在我上面解释的情况下没有发送 ICMP 回显请求感到困惑。我确实有另一个 ICMP 套接字接收所有传入的 ICMP 数据包(为了对回复做出反应),但它不应该影响发送套接字,不是吗?在我的代码中,没有为Destination unreachable消息定义任何反应,它们只是被忽略了,所以我非常确定不是我自己的代码禁用了请求发送。

事实上,sendto负责发送请求的函数已执行(通过调试确保这一点),甚至返回成功(发送的字节数),但实际上并未发送数据包。我可以在 Windows 和 Linux 系统上重现此问题,因此我不认为这是任何操作系统问题。

禁用导致那些无法到达的目的地消息被发回的“发现”可以让一切再次正常工作,所以我相当肯定是这些消息阻碍了 ICMP 回显请求的发送。我找不到答案的大问题是:为什么会这样?

如果需要,我可以提供更多信息,但是,我恐怕不允许在这里发布任何代码,因为这是一个商业产品。不过,代码并没有什么特别之处,只是使用原始 ICMP 套接字发送TOS=0和接收 ICMP (IPv4) 数据包。TTL=64

4

1 回答 1

1

Dest unreachable 由路由器生成,或者如果您在 localnet 内 ping,它将由 localhost 生成。

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

所以,无论如何,你应该等待一个固定的时间,比如一秒钟,然后声明主机不在那里,无论是否发送数据包都没有关系。

于 2012-06-06T06:10:04.590 回答