1
votes

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());
        }

    }
2

2 Answers

1
votes

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 :)

0
votes

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.