/// <summary>
		/// Reads an IcmpPacket from the wire using the specified socket from the specified end point
		/// </summary>
		/// <param name="socket">The socket to read</param>
		/// <param name="packet">The packet read</param>
		/// <param name="ep">The end point read from</param>
		/// <returns></returns>
		public virtual bool Read(Socket socket, EndPoint ep, int timeout, out IcmpPacket packet, out int bytesReceived)
		{
			const int MAX_PATH = 256;
			packet = null;
			bytesReceived = 0;

			/*
			 * check the parameters
			 * */

			if (socket == null)
				throw new ArgumentNullException("socket");
			
			if (socket == null)
				throw new ArgumentNullException("ep");		
						
			// see if any data is readable on the socket
			bool success = socket.Poll(timeout * 1000, SelectMode.SelectRead);

			// if there is data waiting to be read
			if (success)
			{
				// prepare to receive data
				byte[] bytes = new byte[MAX_PATH];
				
				bytesReceived = socket.ReceiveFrom(bytes, bytes.Length, SocketFlags.None, ref ep);

				/*
				 * convert the bytes to an icmp packet
				 * */
//				packet = IcmpPacket.FromBytes(bytes);
			}						

			return success;
		}
예제 #2
0
        /// <summary>
        /// Writes the IcmpPacket to the wire over the specified socket to the specified end point
        /// </summary>
        /// <param name="socket">The socket to write to</param>
        /// <param name="packet">The packet to write</param>
        /// <param name="ep">The end point to write to</param>
        /// <returns></returns>
        public virtual int Write(Socket socket, IcmpPacket packet, EndPoint ep)
        {
            /*
             * check the parameters
             * */

            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }

            if (socket == null)
            {
                throw new ArgumentNullException("packet");
            }

            if (socket == null)
            {
                throw new ArgumentNullException("ep");
            }

            // convert the packet to a byte array
            byte[] bytes = IcmpPacket.GetBytes(packet);

            // send the data using the specified socket, returning the number of bytes sent
            int bytesSent = socket.SendTo(bytes, bytes.Length, SocketFlags.None, ep);

            /*
             * validate bytes sent
             * */

            return(bytesSent);
        }
		/// <summary>
		/// Writes the IcmpPacket to the wire over the specified socket to the specified end point
		/// </summary>
		/// <param name="socket">The socket to write to</param>
		/// <param name="packet">The packet to write</param>
		/// <param name="ep">The end point to write to</param>
		/// <returns></returns>
		public virtual int Write(Socket socket, IcmpPacket packet, EndPoint ep)
		{
			/*
			 * check the parameters
			 * */

			if (socket == null)
				throw new ArgumentNullException("socket");

			if (socket == null)
				throw new ArgumentNullException("packet");

			if (socket == null)
				throw new ArgumentNullException("ep");

			// convert the packet to a byte array
			byte[] bytes = IcmpPacket.GetBytes(packet);

			// send the data using the specified socket, returning the number of bytes sent
			int bytesSent = socket.SendTo(bytes, bytes.Length, SocketFlags.None, ep);

			/*
			 * validate bytes sent
			 * */

			return bytesSent;
		}
예제 #4
0
        /// <summary>
        /// Returns an IcmpPacket from an array of bytes
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static IcmpPacket FromBytes(byte[] bytes)
        {
            Debug.Assert(bytes != null);

            IcmpPacket packet = new IcmpPacket();

            packet.Type           = bytes[0];
            packet.Code           = bytes[1];
            packet.Checksum       = BitConverter.ToUInt16(bytes, 2);
            packet.Identifier     = BitConverter.ToUInt16(bytes, 4);
            packet.SequenceNumber = BitConverter.ToUInt16(bytes, 6);
            packet.Payload        = new byte[bytes.Length - (bytes.Length - 8)];
            Array.Copy(bytes, 8, packet.Payload, bytes.Length - 8, packet.Payload.Length);

            return(packet);
        }
예제 #5
0
        /// <summary>
        /// Returns an array of bytes from an IcmpPacket
        /// </summary>
        /// <returns></returns>
        public static byte[] GetBytes(IcmpPacket packet)
        {
            Debug.Assert(packet != null);

            int index = 0;

            byte[] bytes = new byte[packet.Payload.Length + 8];

            byte[] typeBytes     = new byte[] { packet.Type };
            byte[] codeBytes     = new byte[] { packet.Code };
            byte[] checksumBytes = BitConverter.GetBytes(packet.Checksum);
            byte[] idBytes       = BitConverter.GetBytes(packet.Identifier);
            byte[] sequenceBytes = BitConverter.GetBytes(packet.SequenceNumber);

            // type
            Array.Copy(typeBytes, 0, bytes, index, typeBytes.Length);
            index += typeBytes.Length;

            // code
            Array.Copy(codeBytes, 0, bytes, index, codeBytes.Length);
            index += codeBytes.Length;

            // checksum
            Array.Copy(checksumBytes, 0, bytes, index, checksumBytes.Length);
            index += checksumBytes.Length;

            // identifier
            Array.Copy(idBytes, 0, bytes, index, idBytes.Length);
            index += idBytes.Length;

            // sequence number
            Array.Copy(sequenceBytes, 0, bytes, index, sequenceBytes.Length);
            index += sequenceBytes.Length;

            // payload
            Array.Copy(packet.Payload, 0, bytes, index, packet.Payload.Length);
            index += packet.Payload.Length;

            return(bytes);
        }
예제 #6
0
        /// <summary>
        /// Reads an IcmpPacket from the wire using the specified socket from the specified end point
        /// </summary>
        /// <param name="socket">The socket to read</param>
        /// <param name="packet">The packet read</param>
        /// <param name="ep">The end point read from</param>
        /// <returns></returns>
        public virtual bool Read(Socket socket, EndPoint ep, int timeout, out IcmpPacket packet, out int bytesReceived)
        {
            const int MAX_PATH = 256;

            packet        = null;
            bytesReceived = 0;

            /*
             * check the parameters
             * */

            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }

            if (socket == null)
            {
                throw new ArgumentNullException("ep");
            }

            // see if any data is readable on the socket
            bool success = socket.Poll(timeout * 1000, SelectMode.SelectRead);

            // if there is data waiting to be read
            if (success)
            {
                // prepare to receive data
                byte[] bytes = new byte[MAX_PATH];

                bytesReceived = socket.ReceiveFrom(bytes, bytes.Length, SocketFlags.None, ref ep);

                /*
                 * convert the bytes to an icmp packet
                 * */
//				packet = IcmpPacket.FromBytes(bytes);
            }

            return(success);
        }
예제 #7
0
		/// <summary>
		/// Returns an array of bytes from an IcmpPacket
		/// </summary>
		/// <returns></returns>
		public static byte[] GetBytes(IcmpPacket packet)
		{
			Debug.Assert(packet != null);

			int index = 0;
			byte[] bytes = new byte[packet.Payload.Length + 8];
			
			byte[] typeBytes = new byte[] {packet.Type};
			byte[] codeBytes = new byte[] {packet.Code};
			byte[] checksumBytes = BitConverter.GetBytes(packet.Checksum);
			byte[] idBytes = BitConverter.GetBytes(packet.Identifier);
			byte[] sequenceBytes = BitConverter.GetBytes(packet.SequenceNumber);

			// type
			Array.Copy(typeBytes, 0, bytes, index, typeBytes.Length);
			index += typeBytes.Length;

			// code
			Array.Copy(codeBytes, 0, bytes, index, codeBytes.Length);
			index += codeBytes.Length;

			// checksum
			Array.Copy(checksumBytes, 0, bytes, index, checksumBytes.Length);
			index += checksumBytes.Length;

			// identifier
			Array.Copy(idBytes, 0, bytes, index, idBytes.Length);
			index += idBytes.Length;

			// sequence number
			Array.Copy(sequenceBytes, 0, bytes, index, sequenceBytes.Length);
			index += sequenceBytes.Length;
			
			// payload
			Array.Copy(packet.Payload, 0, bytes, index, packet.Payload.Length);
			index += packet.Payload.Length;

			return bytes;
		}
예제 #8
0
		/// <summary>
		/// Returns an IcmpPacket from an array of bytes
		/// </summary>
		/// <param name="bytes"></param>
		/// <returns></returns>
		public static IcmpPacket FromBytes(byte[] bytes)
		{
			Debug.Assert(bytes != null);

			IcmpPacket packet = new IcmpPacket();
			
			packet.Type = bytes[0];
			packet.Code = bytes[1];
			packet.Checksum = BitConverter.ToUInt16(bytes, 2);
			packet.Identifier = BitConverter.ToUInt16(bytes, 4);
			packet.SequenceNumber = BitConverter.ToUInt16(bytes, 6);
			packet.Payload = new byte[bytes.Length - (bytes.Length - 8)];
			Array.Copy(bytes, 8, packet.Payload, bytes.Length - 8, packet.Payload.Length);
			
			return packet;
		}
예제 #9
0
        private void OnThreadRun(object sender, BackgroundThreadStartEventArgs e)
        {
//			const int SOCKET_ERROR = -1;

            try
            {
                string address     = (string)e.Args[0];
                int    timesToPing = (int)e.Args[1];

                #region Address Resolution

                bool      isHostName = false;
                IPAddress ipAddress  = null;
                try
                {
                    ipAddress = IPAddress.Parse(address);
                }
                catch (Exception)
                {
                    try
                    {
                        ipAddress  = Dns.GetHostEntry(address).AddressList[0];
                        isHostName = true;
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }

                #endregion

                // create the source and destination end points
                IPEndPoint sourceIPEP      = new IPEndPoint(IPAddress.Any, 0);
                IPEndPoint destinationIPEP = new IPEndPoint(ipAddress, 0);

                EndPoint source      = sourceIPEP;
                EndPoint destination = destinationIPEP;

                // create an icmp socket
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);

                // create an icmp echo packet
                IcmpEchoPacket packet = new IcmpEchoPacket();

                // serialize the packet to a byte array
                byte[] bytes = IcmpPacket.GetBytes(packet);

                // create the checksum for the packet based on it's data
                packet.Checksum = IcmpPacket.CreateChecksum(bytes);

                // create a packet reader and writer
                IcmpPacketReader reader = new IcmpPacketReader();
                IcmpPacketWriter writer = new IcmpPacketWriter();

                // raise the ping started event
                this.OnPingStarted(this, new PingerEventArgs(address, isHostName, ipAddress, timesToPing));

                // ping statistics
                int   packetsSent     = 0;
                int   packetsReceived = 0;
                int[] elapsedTimes    = new int[timesToPing];

                // now ping the destination X number of times as instructed
                for (int i = 0; i < timesToPing; i++)
                {
                    int start   = System.Environment.TickCount;
                    int end     = 0;
                    int elapsed = 0;

                    try
                    {
                        // send the icmp echo request
                        int bytesSent = writer.Write(socket, packet, destination);

                        packetsSent++;

                        // wait for a response
                        IcmpPacket response;
                        int        bytesReceived;
                        bool       receivedResponse = reader.Read(socket, source, 1000 /* 1 second timeout */, out response, out bytesReceived);

                        // calculate the end and elapsed time in milliseconds
                        end     = System.Environment.TickCount;
                        elapsed = end - start;

                        elapsedTimes[i] = elapsed;

                        if (receivedResponse)
                        {
                            packetsReceived++;
                        }

                        // raise the ping result event
                        this.OnPingResult(this, new PingerResultEventArgs(address, isHostName, ipAddress, timesToPing, !receivedResponse, bytesReceived, elapsed));
                    }
                    catch (Exception ex)
                    {
                        /*
                         * this should never hit
                         *
                         * raw sockets shouldn't pose a problem when targeting icmp
                         * */
                        this.OnException(this, new ExceptionEventArgs(ex));
                    }
                }

                // calculate the percentage lost
                int percentLost = (int)(((double)(packetsSent - packetsReceived) / (double)packetsSent) * 100d);
                int min         = int.MaxValue;
                int max         = int.MinValue;
                int average     = 0;
                int total       = 0;
                for (int i = 0; i < timesToPing; i++)
                {
                    if (elapsedTimes[i] < min)
                    {
                        min = elapsedTimes[i];
                    }

                    if (elapsedTimes[i] > max)
                    {
                        max = elapsedTimes[i];
                    }

                    total += elapsedTimes[i];
                }

                average = (int)((double)total / (double)timesToPing);

                PingerStatisticsEventArgs ea = new PingerStatisticsEventArgs(
                    address, isHostName, ipAddress, timesToPing,
                    packetsSent,
                    packetsReceived,
                    packetsSent - packetsReceived,
                    percentLost,
                    min,
                    max,
                    average);

                this.OnPingStatistics(this, ea);
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                this.OnException(this, new ExceptionEventArgs(ex));
            }
            finally
            {
            }
        }