digigrupp.com       Home  Downloads  Support  About  Contact  Search 

PING / Trace Route - Open Source - C# (C-sharp)

Downloadmain.csip.csicmp.csicmpsocket.cscompile.cmd  

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