如何使用 UDP 实现 Traceroute?
显然 ICMP 不是创建 Traceroute 的唯一方法。 此和这个答案表明可以发送具有低 TTL 的 UDP 数据包(或任何其他数据包)并等待 ICMP 消息。
我将如何在 C# 中实现这个?系统.IO.套接字? TCP 对象?有人知道简单/最好的方法吗?
更新 1:
以下代码似乎在达到 TTL 时正确引发异常。如何从返回的UDP数据包中提取信息?
我如何知道我收到的 UDP 数据包是给我的(而不是我主机上的其他应用程序?)
public void PingUDPAsync(IPAddress _destination, short ttl)
{
// This constructor arbitrarily assigns the local port number.
UdpClient udpClient = new UdpClient(21000);
udpClient.Ttl = ttl;
// udpClient.DontFragment = true;
try
{
udpClient.Connect(_destination, 21000);
// Sends a message to the host to which you have connected.
Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody there?");
udpClient.Send(sendBytes, sendBytes.Length);
//IPEndPoint object will allow us to read datagrams sent from any source.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
// Uses the IPEndPoint object to determine which of these two hosts responded.
Console.WriteLine("This is the message you received " +
returnData.ToString());
Console.WriteLine("This message was sent from " +
RemoteIpEndPoint.Address.ToString() +
" on their port number " +
RemoteIpEndPoint.Port.ToString());
udpClient.Close();
}
catch (SocketException socketException)
{
Console.WriteLine(socketException.ToString());
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Apparently ICMP isn't the only way to create a Traceroute. This and this answer indicates it's possible to send a UDP packet (or any other) with a low TTL and wait for the ICMP message.
How would I go about implementing this in C#? System.IO.Sockets? The TCP objects? Anyone know of an easy/best way?
Update 1:
The following code seems to correctly throw an exception when the TTL is hit. How do I extract information from the returned UDP Packet?
How do I know that the UDP packet I'm receiving is intended for me (and not some other application on my host?)
public void PingUDPAsync(IPAddress _destination, short ttl)
{
// This constructor arbitrarily assigns the local port number.
UdpClient udpClient = new UdpClient(21000);
udpClient.Ttl = ttl;
// udpClient.DontFragment = true;
try
{
udpClient.Connect(_destination, 21000);
// Sends a message to the host to which you have connected.
Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody there?");
udpClient.Send(sendBytes, sendBytes.Length);
//IPEndPoint object will allow us to read datagrams sent from any source.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
// Uses the IPEndPoint object to determine which of these two hosts responded.
Console.WriteLine("This is the message you received " +
returnData.ToString());
Console.WriteLine("This message was sent from " +
RemoteIpEndPoint.Address.ToString() +
" on their port number " +
RemoteIpEndPoint.Port.ToString());
udpClient.Close();
}
catch (SocketException socketException)
{
Console.WriteLine(socketException.ToString());
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,System.Net.Sockets 应该为您提供发送/接收 UDP/TCP 数据包所需的所有原始对象。网上有大量文档和示例,您问题中包含的两篇文章非常有趣,是一个很好的起点:)
Yes, System.Net.Sockets should provide you all the primitive objects you would need to send/receive UDP/TCP packets. Plenty of documentation and samples online, the two articles you included in your question are very interesting and a good starting point :)
https://learningnetwork.cisco.com/thread/87497
您可以在此处查看答案,其中详细介绍了 Cisco 的 UPD 跟踪路由实施。它相当全面,可以轻松适应特定的 UDP 端口。您不会从目标处收到 UDP 数据包。相反,您会收到 ICMP 回复,表明未收到流量。您发起的 UDP 数据包包含随机响应端口号,您的主机会跟踪哪些应用程序使用哪些端口。当ICMP响应被发送回来时,它被发送到包含在UDP标头中的主机IP和响应端口。然后,您的主机将看到该端口并知道它绑定到您的应用程序。然后它将数据包传送到您的应用程序。
https://learningnetwork.cisco.com/thread/87497
You can check out the answer here that goes into detail on Cisco's UPD traceroute implementation. It is rather comprehensive and can easily adapted to target a specific UDP port. You do not get a UDP packet back from the target. Rather, you get an ICMP reply to indicate the traffic was not received. The UDP packet that you originate has a random response port number included and your host tracks what ports are used by what applications. When the ICMP response is sent back, it is sent to the host IP and the response port included in the UDP header. Your host will then see the port and know it is bound to your application. It then delivers the packet to your application.