PING / Trace Route - Open Source - C# (C-sharp)
ICMP communication module
// Author: Toomas Kaljus
// http://www.digigrupp.com
namespace DG
{
public class ICMPSocket
{
public int SocketTimeout = 3000; // default to 3 seconds
private System.Net.Sockets.Socket Socket;
private System.Net.IPEndPoint IPEndPoint;
public System.Net.EndPoint EndPoint;
private string HostAddress;
public int TimeElapsed;
~ICMPSocket()
{
if (Socket != null) Socket.Close();
}
public IPPacket Send(string Host, ICMPPacket ICMP, int TTL)
{
// Resolve IP address (do it only once)
if (HostAddress != Host)
{
#if NET20
System.Net.IPAddress[] IPAddress = System.Net.Dns.GetHostAddresses(Host);
IPEndPoint = new System.Net.IPEndPoint(IPAddress[0], 0);
#else
System.Net.IPHostEntry IPHostEntry = System.Net.Dns.Resolve(Host);
IPEndPoint = new System.Net.IPEndPoint(IPHostEntry.AddressList[0], 0);
#endif
EndPoint = (System.Net.EndPoint)IPEndPoint;
HostAddress = Host;
}
// Create and initialize the socket (do it only once)
if (Socket == null)
{
Socket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Raw, System.Net.Sockets.ProtocolType.Icmp);
Socket.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket, System.Net.Sockets.SocketOptionName.SendTimeout, SocketTimeout);
Socket.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket, System.Net.Sockets.SocketOptionName.ReceiveTimeout, SocketTimeout);
}
Socket.SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP, System.Net.Sockets.SocketOptionName.IpTimeToLive, TTL);
// Save the time and send out the packet
TimeElapsed = System.Environment.TickCount;
Socket.SendTo(ICMP.GetBytes(), IPEndPoint);
IPPacket IPReply = null;
do
{
byte[] Packet = new byte[2048];
int ReceivedLenght = Socket.ReceiveFrom(Packet, ref EndPoint);
IPReply = new IPPacket(ref Packet);
// Time Exceeded, Destination Unreachable and other errors
if (IPReply.ICMP.Message is ICMPIPHeaderReply)
{
IPPacket IPAttached = ((ICMPIPHeaderReply)IPReply.ICMP.Message).IP;
if (IPEndPoint.Address.ToString() == IPAttached.DestinationAddress.ToString())
if (IPAttached.ICMP.Message is ICMPEchoReply)
break;
}
// Check if received packet is the one we expected, discard it if not
if ((IPReply.ICMP.Message is ICMPEchoReply) && (IPReply.ICMP.Code == 0) && (IPEndPoint.ToString() == EndPoint.ToString()) &&
(((ICMPEchoReply)IPReply.ICMP.Message).Identifier == ((ICMPEcho)ICMP.Message).Identifier) &&
(((ICMPEchoReply)IPReply.ICMP.Message).SequenceNumber == ((ICMPEcho)ICMP.Message).SequenceNumber)) break;
} while (true);
// calculate roundtrip time
TimeElapsed = System.Environment.TickCount - TimeElapsed;
return IPReply;
}
}
}