Traceroute and Ping in C#

TraceRoute and Ping in C#

Although the Base Class Library includes Ping, the BCL does not include any tracert functionality.

However, a quick search reveals two open-source attempts, the first in C# the second in C++:

  • http://www.codeproject.com/KB/IP/tracert.aspx
  • http://www.codeguru.com/Cpp/I-N/network/basicnetworkoperations/article.php/c5457/

Traceroute Results

The name of the method (TryTraceRouteInternalAsync) actually gives a hint that something is being done in an incorrect manner.

This method invokes only one ping and that's why you get just one result.

The actual method you need to invoke is TryTraceRouteAsync but I have a strong feeling that you had chosen the other one because it returns an accessible object, with a string Message property.

If you do the following, the TryTraceRouteAsync method will asynchronously invoke TryTraceRouteInternalAsync (MAX_HOPS = 15) times simultaneously and write all the results into the streamWriter.

You can just call this method and get all the results you are looking for:

    private async Task<string> TraceRt()
{
MemoryStream memoryStream = new MemoryStream();
StreamWriter streamWriter = new StreamWriter(memoryStream);
await TraceRoute.TryTraceRouteAsync("google.com.tr", streamWriter);
streamWriter.Flush();
memoryStream.Position = 0;
StreamReader stringReader = new StreamReader(memoryStream);
return stringReader.ReadToEnd();
}

TCP Traceroute in C#

You will need raw ethernet frames to generate TCP packets by hand as Windows won't let you send TCP packets over raw sockets.

See how nmap gets raw ethernet frames. Repeat it.

Find Packet Loss and Trace Route in .NET

Not sure if this is what you're looking for, but have you taken a look at the Ping class?

Edit: Actually for TraceRoute, take a look at the answers here: TraceRoute and Ping in C#.

For Netstat, take a look at http://towardsnext.wordpress.com/2009/02/09/netstat-in-c/.

How to implement PsPing TCP ping in C#

I have tried several approaches, first thinking I had to use raw sockets or at least use native calls, but a simple TCP connect and close seems to create exactly the same results as the psping utility:

var times = new List<double>();
for (int i = 0; i < 4; i++)
{
var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Blocking = true;

var stopwatch = new Stopwatch();

// Measure the Connect call only
stopwatch.Start();
sock.Connect(endPoint);
stopwatch.Stop();

double t = stopwatch.Elapsed.TotalMilliseconds;
Console.WriteLine("{0:0.00}ms", t);
times.Add(t);

sock.Close();

Thread.Sleep(1000);
}
Console.WriteLine("{0:0.00} {1:0.00} {2:0.00}", times.Min(), times.Max(), times.Average());

Inspecting the traffic using Wireshark, I can confirm both psping and the snippet above are creating exactly the same sequence of packets.

-> [SYN]
<- [SYN,ACK]
-> [ACK]
-> [FIN,ACK]
<- [FIN,ACK]
-> [ACK]

Output from psping with no warm-up and using TCP ping:

C:\>psping -w 0 stackoverflow.com:80

PsPing v2.01 - PsPing - ping, latency, bandwidth measurement utility
Copyright (C) 2012-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

TCP connect to 198.252.206.16:80:
4 iterations (warmup 0) connecting test:
Connecting to 198.252.206.16:80: 92.30ms
Connecting to 198.252.206.16:80: 83.16ms
Connecting to 198.252.206.16:80: 83.29ms
Connecting to 198.252.206.16:80: 82.98ms

TCP connect statistics for 198.252.206.16:80:
Sent = 4, Received = 4, Lost = 0 (0% loss),
Minimum = 82.98ms, Maximum = 92.30ms, Average = 85.43ms

Output from the program above:

C:\>TcpPing.exe stackoverflow.com 80
88.60ms
83.65ms
84.05ms
84.05ms
83.65 88.60 85.09

As for measurements, I must say, sometimes there are quite a few different results at different runs, but overall they seemed pretty close: kind of proves measuring the Connect() call is good enough. I'm thinking, taking a median of a few hundred results might prove it with a bit more confidence.



Related Topics



Leave a reply



Submit