0

当我们从 udp 端口​​发送数据包时,如果网络返回无法访问的 ICMP 主机,我们会收到异常。该异常没有告诉我们任何有用的信息(例如 ICMP 数据包的内容)。

没问题,我们将只监听 ICMP,这将为我们提供所需的信息,同时忽略 UDP 端口上的异常。因此,打开一个原始套接字,侦听 ICMP 数据包并从那里开始。

在开发(Win XP)中工作正常,但在服务器 2008 上的生产中,似乎运行 exe 的安全上下文必须具有管理员权限才能打开原始套接字。这对于服务是没有用的。如果我理解微软在说什么,那么我们可以做我们想做的唯一方法就是在具有管理员权限的帐户下运行我们的服务。感觉有点像花生的大锤,更不用说在管理员帐户下运行面向网络的服务带来的潜在安全漏洞。

我真的希望我在这里错了,但我似乎找不到任何与上述内容相矛盾的东西。

有人有任何意见/提示或同情吗?

4

3 回答 3

1

与其监听对失败的 UDP 发送的 ICMP 响应,不如发送一个全新的 ICMP 回显请求?

当您收到异常时,您可以 PInvokeIcmpSendEcho()函数(来自 Win32 IP Helper API)以自己生成新的 ICMP 回显请求。关键是该函数返回一个带有回显回复的缓冲区,包括状态代码,例如IP_DEST_HOST_UNREACHABLE

我认为您不需要任何特权来执行此操作,因此它应该比使用原始套接字侦听 ICMP 回复更容易。

您将需要三个函数:IcmpCreateFile()IcmpSendEcho()- IcmpCloseHandle()PInvoke.net 具有必要的互操作详细信息:

http://www.pinvoke.net/default.aspx/icmp/IcmpCreateFile.html http://www.pinvoke.net/default.aspx/icmp/IcmpSendEcho.html http://www.pinvoke.net/default。 aspx/icmp/IcmpCloseHandle.html

于 2009-04-14T12:48:15.133 回答
0

我自己也遇到了完全相同的问题Listen for ICMP packet in C#。实际上,您的问题似乎是 Windows 权限,因此该帖子无济于事。

我计划进一步研究的一个领域是检查 UdpListener 生成的 SocketException 中是否还有信息。由于 Windows 使用 ICMP 数据包来生成异常,它不会在某个地方记录该数据包中的信息,这似乎是不合理的。

像您一样,我无法从.Net级别的异常信息中获取ICMP信息,但我想看看是否可以通过Win32 API(例如GetLastError或其他一些)获得更多信息专门为 WinSock32 调用。

于 2009-03-31T04:00:18.250 回答
0

从 MSDN网站

要使用 SOCK_RAW 类型的套接字需要管理权限。运行使用原始套接字的 Winsock 应用程序的用户必须是本地计算机上管理员组的成员,否则原始套接字调用将失败并返回错误代码 WSAEACCES。在 Windows Vista 和更高版本上,对原始套接字的访问是在创建套接字时强制执行的。在早期版本的 Windows 中,对原始套接字的访问是在其他套接字操作期间强制执行的。

为了在我的项目中解决这个问题,我创建了一个 Windows 服务,作为我们 UI 应用程序的网络代理。Windows 服务在本地管理员帐户下运行,以绕过限制。应用程序使用 WCF 连接到服务,告诉它要打开什么样的套接字以及要应用什么过滤器。然后使用协议缓冲区通过回调将数据发送回进行编码(至少这是计划 - 回调部分仍在进行中)。

于 2009-03-31T05:07:46.950 回答