听在C#中的ICMP报文 [英] Listen for ICMP packets in C#

查看:225
本文介绍了听在C#中的ICMP报文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有需要发送UDP数据包来建立SIP呼叫的SIP应用程序。 SIP有超时机制,以应付传送失败。我想另外一个事情能够做的是检测一个UDP套接字是否关闭在不必等待了32秒的时间间隔重新发送SIP使用顺序。

I have a SIP application that needs to send UDP packets to set up the SIP calls. SIP has a timeout mechanism to cope with delivery failures. An additional thing I would like to be able to do is detect whether a UDP socket is closed in order having to wait the 32s retransmit interval SIP uses.

我指的案件时试图发送到一个ICMP目的不可达报UDP套接字结果被远程主机正在生成。如果我尝试将UDP数据包发送到主机的上升,但该端口不听我可以看到一个数据包追踪到达后面的ICMP消息,但问题是我怎么得到我的C#code访问该?

The cases I am referring to are when an attempt to send to a UDP socket results in an ICMP Destination Unreachable packet being generated by the remote host. If I attempt to send a UDP packet to a host that's up but that the port is not listening I can see the ICMP message arriving back with a packet tracer but the question is how do I get access to that from my C# code?

我在玩弄原始套接字但至今一直没能得到通过我的程序接收的ICMP数据包。下面从来没有样品接收,即使ICMP信息被我的电脑上到达的数据包。

I'm playing around with raw sockets but as yet have not been able to get the ICMP packets to be received by my program. The sample below never receives a packet even though ICMP messages are arriving on my PC.

Socket icmpListener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
icmpListener.Bind(new IPEndPoint(IPAddress.Any, 0));

byte[] buffer = new byte[4096];
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
int bytesRead = icmpListener.ReceiveFrom(buffer, ref remoteEndPoint);
logger.Debug("ICMPListener received " + bytesRead + " from " + remoteEndPoint.ToString());

下面是表示从10.0.0.100(我的电脑),我知道这不是监听的端口发送一个UDP包,10.0.0.138(我的路由器)上的ICMP响应进入我的电脑从一个企图一丝Wireshark的。我的问题是如何利用这些ICMP数据包,实现了UDP发送失败,而不仅仅是等待应用程序中的任意时间之后超时?

Below is a wireshark trace showing the ICMP responses coming into my PC from an attempt to send a UDP packet from 10.0.0.100 (my PC) to 10.0.0.138 (my router) on a port I know it's not listening on. My problem is how to make use of those ICMP packets to realise the UDP send has failed rather than just waiting for the application to timeout after an arbitrary period?

推荐答案

近3年后,我穿过<一个偶然href=\"http://www.$c$cproject.com/Articles/17031/A-Network-Sniffer-in-C\">http://www.$c$cproject.com/Articles/17031/A-Network-Sniffer-in-C这给了我足够的提示,以帮助我找到一个解决方案,在Windows 7上接收ICMP数据包(不知道Vista中,其中原来的问题是关于,但我怀疑这个解决方案将工作)。

Nearly 3 years later and I stumbled across http://www.codeproject.com/Articles/17031/A-Network-Sniffer-in-C which gave me enough of a hint to help me find a solution to receiving ICMP packets on Windows 7 (don't know about Vista, which the original question was about but I suspect this solution would work).

的两个关键点是所述插座具有被绑定到单个特定的IP地址,而不是IPAddress.Any和的IOControl呼叫它设置SIO_RCVALL标志

The two key points are that the socket has to be bound to a single specific IP address rather than IPAddress.Any and the IOControl call which sets the SIO_RCVALL flag.

Socket icmpListener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
icmpListener.Bind(new IPEndPoint(IPAddress.Parse("10.1.1.2"), 0));
icmpListener.IOControl(IOControlCode.ReceiveAll, new byte[] { 1, 0, 0, 0 }, new byte[] { 1, 0, 0, 0 });

byte[] buffer = new byte[4096];
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
int bytesRead = icmpListener.ReceiveFrom(buffer, ref remoteEndPoint);
Console.WriteLine("ICMPListener received " + bytesRead + " from " + remoteEndPoint);
Console.ReadLine();

我也必须设置防火墙规则,以允许收到的ICMP端口不可达报文。

I also had to set a firewall rule to allow ICMP Port Unreachable packets to be received.

netsh advfirewall firewall add rule name="All ICMP v4" dir=in action=allow protocol=icmpv4:any,any

这篇关于听在C#中的ICMP报文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆