Example #1
0
        //    this ping class can be disposed



        /// <summary>

        /// Base constructor that initializes the member variables to default values. It also

        /// creates the events used and initializes the async callback function.

        /// </summary>

        public RawSocketPing()

        {
            pingSocket = null;

            pingFamily = AddressFamily.InterNetwork;

            pingTtl = 8;

            pingPayloadLength = 8;

            pingSequence = 0;

            pingReceiveTimeout = 4000;

            pingOutstandingReceives = 0;

            destEndPoint = new IPEndPoint(IPAddress.Loopback, 0);

            protocolHeaderList = new ArrayList();

            pingReceiveEvent = new ManualResetEvent(false);

            pingDoneEvent = new ManualResetEvent(false);

            receiveCallback = new AsyncCallback(PingReceiveCallback);

            icmpHeader = null;
        }
Example #2
0
        /// <summary>

        /// This routine creates an instance of the IcmpHeader class from a byte

        /// array that is a received IGMP packet. This is useful when a packet

        /// is received from the network and the header object needs to be

        /// constructed from those values.

        /// </summary>

        /// <param name="icmpPacket">Byte array containing the binary ICMP header</param>

        /// <param name="bytesCopied">Number of bytes used in header</param>

        /// <returns>Returns the IcmpHeader object created from the byte array</returns>

        static public IcmpHeader Create(byte[] icmpPacket, ref int bytesCopied)

        {
            IcmpHeader icmpHeader = new IcmpHeader();

            int offset = 0;



            // Make sure byte array is large enough to contain an ICMP header

            if (icmpPacket.Length < IcmpHeader.IcmpHeaderLength)
            {
                return(null);
            }



            icmpHeader.icmpType = icmpPacket[offset++];

            icmpHeader.icmpCode = icmpPacket[offset++];

            icmpHeader.icmpChecksum = BitConverter.ToUInt16(icmpPacket, offset);

            offset += 2;

            icmpHeader.icmpId = BitConverter.ToUInt16(icmpPacket, offset);

            offset += 2;

            icmpHeader.icmpSequence = BitConverter.ToUInt16(icmpPacket, offset);

            bytesCopied = IcmpHeader.IcmpHeaderLength;

            return(icmpHeader);
        }
Example #3
0
        /// <summary>

        /// This is the asynchronous callback that is fired when an async ReceiveFrom.

        /// An asynchronous ReceiveFrom is posted by calling BeginReceiveFrom. When this

        /// function is invoked, it calculates the elapsed time between when the ping

        /// packet was sent and when it was completed.

        /// </summary>

        /// <param name="ar">Asynchronous context for operation that completed</param>

        static void PingReceiveCallback(IAsyncResult ar)

        {
            RawSocketPing rawSock = (RawSocketPing)ar.AsyncState;

            TimeSpan elapsedTime;

            int bytesReceived = 0;

            ushort receivedId = 0;



            try

            {
                // Keep a count of how many async operations are outstanding -- one just completed

                //    so decrement the count.

                Interlocked.Decrement(ref rawSock.pingOutstandingReceives);



                // If we're done because ping is exiting and the socket has been closed,

                //    set the done event

                if (rawSock.pingSocket == null)

                {
                    if (rawSock.pingOutstandingReceives == 0)
                    {
                        rawSock.pingDoneEvent.Set();
                    }

                    return;
                }



                // Complete the receive op by calling EndReceiveFrom. This will return the number

                //    of bytes received as well as the source address of who sent this packet.

                bytesReceived = rawSock.pingSocket.EndReceiveFrom(ar, ref rawSock.castResponseEndPoint);



                // Calculate the elapsed time from when the ping request was sent and a response was

                //    received.

                elapsedTime = DateTime.Now - rawSock.pingSentTime;



                rawSock.responseEndPoint = (IPEndPoint)rawSock.castResponseEndPoint;



                // Here we unwrap the data received back into the respective protocol headers such

                //    that we can find the ICMP ID in the ICMP or ICMPv6 packet to verify that

                //    the echo response we received was really a response to our request.

                if (rawSock.pingSocket.AddressFamily == AddressFamily.InterNetwork)

                {
                    Ipv4Header v4Header;

                    IcmpHeader icmpv4Header;

                    byte[] pktIcmp;

                    int offset = 0;



                    // Remember, raw IPv4 sockets will return the IPv4 header along with all

                    //    subsequent protocol headers

                    v4Header = Ipv4Header.Create(rawSock.receiveBuffer, ref offset);

                    pktIcmp = new byte[bytesReceived - offset];

                    Array.Copy(rawSock.receiveBuffer, offset, pktIcmp, 0, pktIcmp.Length);

                    icmpv4Header = IcmpHeader.Create(pktIcmp, ref offset);



                    /*Console.WriteLine("Icmp.Id = {0}; Icmp.Sequence = {1}",
                     *
                     *  icmpv4Header.Id,
                     *
                     *  icmpv4Header.Sequence
                     *
                     *  );*/



                    receivedId = icmpv4Header.Id;
                }



                if (receivedId == rawSock.pingId)

                {
                    string elapsedString;



                    // Print out the usual statistics for ping

                    if (elapsedTime.Milliseconds < 1)
                    {
                        elapsedString = "<1";
                    }

                    else
                    {
                        elapsedString = "=" + elapsedTime.Milliseconds.ToString();
                    }
                }



                // Post another async receive if the count indicates for us to do so.

                if (rawSock.pingCount > 0)

                {
                    rawSock.pingSocket.BeginReceiveFrom(

                        rawSock.receiveBuffer,

                        0,

                        rawSock.receiveBuffer.Length,

                        SocketFlags.None,

                        ref rawSock.castResponseEndPoint,

                        rawSock.receiveCallback,

                        rawSock

                        );



                    // Keep track of outstanding async operations

                    Interlocked.Increment(ref rawSock.pingOutstandingReceives);
                }

                else

                {
                    // If we're done then set the done event

                    if (rawSock.pingOutstandingReceives == 0)
                    {
                        rawSock.pingDoneEvent.Set();
                    }
                }

                // If this is indeed the response to our echo request then signal the main thread

                //    that we received the response so it can send additional echo requests if

                //    necessary. This is done after another async ReceiveFrom is already posted.

                if (receivedId == rawSock.pingId)

                {
                    rawSock.pingReceiveEvent.Set();
                }
            }

            catch (SocketException err)

            {
                Console.WriteLine("Socket error occurred in async callback: {0}", err.Message);
            }
        }
Example #4
0
        /// <summary>

        /// This routine builds the appropriate ICMP echo packet depending on the

        /// protocol family requested.

        /// </summary>

        public void BuildPingPacket()

        {
            // Initialize the socket if it hasn't already been done



            if (pingSocket == null)

            {
                InitializeSocket();
            }



            // Clear any existing headers in the list


            protocolHeaderList.Clear();



            if (destEndPoint.AddressFamily == AddressFamily.InterNetwork)

            {
                // Create the ICMP header and initialize the members


                icmpHeader = new IcmpHeader();



                icmpHeader.Id = pingId;

                icmpHeader.Sequence = pingSequence;

                icmpHeader.Type = IcmpHeader.EchoRequestType;

                icmpHeader.Code = IcmpHeader.EchoRequestCode;



                // Build the data payload of the ICMP echo request


                pingPayload = new byte[pingPayloadLength];



                for (int i = 0; i < pingPayload.Length; i++)

                {
                    pingPayload[i] = (byte)'e';
                }

                // Add ICMP header to the list of headers


                protocolHeaderList.Add(icmpHeader);
            }
        }