/// <summary>
        ///
        /// </summary>
        /// <param name="data">
        ///
        ///	</param>
        private void NewPacket(byte[] data)
        {
            // store the time the packet arrived
            m_stop = Environment.TickCount;

            // parse out the ip header
            IpV4Packet ipPacket = new IpV4Packet(data);

            // double check to make sure this is an icmp packet
            if (ipPacket.TransportProtocol != ProtocolType.Icmp)
            {
                return;
            }

            // parse out the icmp packet
            IcmpPacket icmpPacket = new IcmpPacket(ipPacket.Data);

            // if this is an echo reply
            if (icmpPacket.MessageType == IcmpMessageType.EchoReply)
            {
                // deserialize the packet
                IcmpEcho echo = new IcmpEcho(icmpPacket);

                // if this packet matches our identifier, and destination address
                if (echo.Identifier == m_id &&
                    ipPacket.SourceAddress.Equals(m_remoteAddress))
                {
                    // disable the timeout timer
                    m_timer.Enabled = false;

                    // raise the event
                    if (PingReply != null)
                    {
                        PingReply(ipPacket, icmpPacket, (int)((uint)m_stop - (uint)m_start));
                    }

                    // reset the id back to 0 so we can resume sending packets.
                    m_id = 0;

                    // signal the wait event
                    m_waitObject.Set();
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///		Log a new ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The packet to log.
        ///	</param>
        public void LogPacket(IcmpPacket packet)
        {
            lock (m_logger.XmlWriter)
            {
                // <IcmpHeader>
                m_logger.XmlWriter.WriteStartElement ("IcmpHeader");

                    m_logger.XmlWriter.WriteElementString ("Type",		packet.MessageType.ToString());
                    m_logger.XmlWriter.WriteElementString ("Checksum",	packet.Checksum.ToString());

                    #region Specific ICMP Types

                    switch (packet.MessageType)
                    {
                        case IcmpMessageType.DestinationUnreachable:
                            IcmpDestinationUnreachable option1 = new IcmpDestinationUnreachable (packet);
                            m_logger.XmlWriter.WriteElementString ("Code",	 option1.Code.ToString());
                            break;
                        case IcmpMessageType.Echo:
                            IcmpEcho option2 = new IcmpEcho (packet);
                            m_logger.XmlWriter.WriteElementString ("Identifier",		option2.Identifier.ToString());
                            m_logger.XmlWriter.WriteElementString ("SequenceNumber",	option2.SequenceNumber.ToString());
                            m_logger.XmlWriter.WriteElementString ("DataLength",		(option2.Data != null ? option2.Data.Length : 0) + " bytes");
                            m_logger.XmlWriter.WriteElementString ("Data",				(option2.Data != null ? System.Text.ASCIIEncoding.ASCII.GetString (option2.Data) : string.Empty));
                            break;
                        case IcmpMessageType.EchoReply:
                            IcmpEcho option3 = new IcmpEcho (packet);
                            m_logger.XmlWriter.WriteElementString ("Identifier",		option3.Identifier.ToString());
                            m_logger.XmlWriter.WriteElementString ("SequenceNumber",	option3.SequenceNumber.ToString());
                            m_logger.XmlWriter.WriteElementString ("DataLength",		(option3.Data != null ? option3.Data.Length : 0) + " bytes");
                            m_logger.XmlWriter.WriteElementString ("Data",				(option3.Data != null ? System.Text.ASCIIEncoding.ASCII.GetString (option3.Data) : string.Empty));
                            break;
                        case IcmpMessageType.ParameterProblem:
                            IcmpParameterProblem option4 = new IcmpParameterProblem (packet);
                            m_logger.XmlWriter.WriteElementString ("Pointer",			option4.ErrorPointer.ToString());
                            break;
                        case IcmpMessageType.Redirect:
                            IcmpRedirect option5 = new IcmpRedirect (packet);
                            m_logger.XmlWriter.WriteElementString ("Gateway",			option5.GatewayAddress.ToString());
                            break;
                        case IcmpMessageType.SourceQuench:
                            break;
                        case IcmpMessageType.TimeExceeded:
                            break;
                        case IcmpMessageType.TimeStamp:
                            break;
                        case IcmpMessageType.TimestampReply:
                            break;
                    }

                    #endregion

                m_logger.XmlWriter.WriteEndElement ();
                // </IcmpHeader>

            }
        }
        /// <summary>
        ///		Send a new ping packet.
        /// </summary>
        /// <param name="destination">
        ///		The address to send the packet to.
        ///	</param>
        /// <param name="payload">
        ///		The data to send in the ping.
        ///	</param>
        /// <param name="async">
        ///		If this is true, SendPing will return immediately otherwise it will wait
        ///	</param>
        /// <param name="timeOutTime">
        ///		The number of milliseconds before the reply times out.
        ///	</param>
        /// <exception cref="ObjectDisposedException">
        ///		If the class has been disposed then an ObjectDisposedException will be thrown.
        ///	</exception>
        /// <exception cref="Exception">
        ///		If the class is already waiting for a ping reply then an exception will be thrown.
        ///		Use the CancelPing method first.
        ///	</exception>
        public void SendPing(IPAddress destination, byte[] payload, bool async, double timeOutTime)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException(this.ToString(), "This object has already been disposed");
            }

            // check if a ping is already in process
            if (m_id != 0)
            {
                throw new Exception("A ping request is already in process. Either wait for the reply, or cancel the request first");
            }

            Random   random = new Random();
            IcmpEcho echo   = new IcmpEcho();

            // generate random identifier and sequence number
            echo.Identifier     = (ushort)random.Next(ushort.MaxValue);
            echo.SequenceNumber = (ushort)random.Next(ushort.MaxValue);

            m_id             = echo.Identifier;
            m_remoteAddress  = destination;
            m_timer.Interval = timeOutTime;

            // store the payload
            echo.Data = payload;

            // build the icmp header
            IcmpPacket icmpHeader = echo.Serialize(false);

            // build the ip header
            IpV4Packet ipHeader = new IpV4Packet();

            ipHeader.TransportProtocol  = ProtocolType.Icmp;
            ipHeader.SourceAddress      = m_networkInterface;
            ipHeader.DestinationAddress = destination;
            ipHeader.Data = icmpHeader.Serialize();

            if (m_fragment)
            {
                IpV4Packet[] fragments = ipHeader.Fragment(8);

                // send each fragment
                for (int i = 0; i < fragments.Length; i++)
                {
                    byte[] packet = fragments[i].Serialize();
                    m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(fragments[i].DestinationAddress, 0));
                }
            }
            else
            {
                // send the packet
                byte[] packet = ipHeader.Serialize();
                m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(ipHeader.DestinationAddress, 0));
            }

            // save the time and  start the timeout timer
            m_start         = Environment.TickCount;
            m_timer.Enabled = true;

            // wait for the reply
            m_waitObject.Reset();

            if (!async)
            {
                m_waitObject.WaitOne();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="data">
        ///	
        ///	</param>
        private void NewPacket(byte[] data)
        {
            // store the time the packet arrived
            m_stop = Environment.TickCount;

            // parse out the ip header
            IpV4Packet ipPacket = new IpV4Packet (data);

            // double check to make sure this is an icmp packet
            if (ipPacket.TransportProtocol != ProtocolType.Icmp)
            {
                return;
            }

            // parse out the icmp packet
            IcmpPacket icmpPacket = new IcmpPacket (ipPacket.Data);

            // if this is an echo reply
            if (icmpPacket.MessageType == IcmpMessageType.EchoReply)
            {
                // deserialize the packet
                IcmpEcho echo = new IcmpEcho (icmpPacket);

                // if this packet matches our identifier, and destination address
                if (echo.Identifier == m_id &&
                    ipPacket.SourceAddress.Equals (m_remoteAddress))
                {
                    // disable the timeout timer
                    m_timer.Enabled = false;

                    // raise the event
                    if (PingReply != null)
                    {
                        PingReply (ipPacket, icmpPacket, (int)((uint)m_stop - (uint)m_start));
                    }

                    // reset the id back to 0 so we can resume sending packets.
                    m_id = 0;

                    // signal the wait event
                    m_waitObject.Set ();
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        ///		Send a new ping packet.
        /// </summary>
        /// <param name="destination">
        ///		The address to send the packet to.
        ///	</param>	
        /// <param name="payload">
        ///		The data to send in the ping.
        ///	</param>
        /// <param name="async">
        ///		If this is true, SendPing will return immediately otherwise it will wait
        ///	</param>
        /// <param name="timeOutTime">
        ///		The number of milliseconds before the reply times out.
        ///	</param>
        /// <exception cref="ObjectDisposedException">
        ///		If the class has been disposed then an ObjectDisposedException will be thrown.
        ///	</exception>
        /// <exception cref="Exception">
        ///		If the class is already waiting for a ping reply then an exception will be thrown.
        ///		Use the CancelPing method first.
        ///	</exception>
        public void SendPing(IPAddress destination, byte[] payload, bool async, double timeOutTime)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException (this.ToString(), "This object has already been disposed");
            }

            // check if a ping is already in process
            if (m_id != 0)
            {
                throw new Exception ("A ping request is already in process. Either wait for the reply, or cancel the request first");
            }

            Random random = new Random ();
            IcmpEcho echo = new IcmpEcho ();

            // generate random identifier and sequence number
            echo.Identifier			= (ushort)random.Next (ushort.MaxValue);
            echo.SequenceNumber		= (ushort)random.Next (ushort.MaxValue);

            m_id = echo.Identifier;
            m_remoteAddress = destination;
            m_timer.Interval = timeOutTime;

            // store the payload
            echo.Data = payload;

            // build the icmp header
            IcmpPacket icmpHeader = echo.Serialize (false);

            // build the ip header
            IpV4Packet ipHeader = new IpV4Packet ();

            ipHeader.TransportProtocol	= ProtocolType.Icmp;
            ipHeader.SourceAddress		= m_networkInterface;
            ipHeader.DestinationAddress	= destination;
            ipHeader.Data				= icmpHeader.Serialize ();

            if (m_fragment)
            {
                IpV4Packet[] fragments = ipHeader.Fragment (8);

                // send each fragment
                for (int i = 0; i < fragments.Length; i++)
                {
                    byte[] packet = fragments[i].Serialize ();
                    m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (fragments[i].DestinationAddress, 0));
                }
            }
            else
            {
                // send the packet
                byte[] packet = ipHeader.Serialize ();
                m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (ipHeader.DestinationAddress, 0));
            }

            // save the time and  start the timeout timer
            m_start = Environment.TickCount;
            m_timer.Enabled = true;

            // wait for the reply
            m_waitObject.Reset ();

            if (!async)
            {
                m_waitObject.WaitOne ();
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        ///		Send the next request in order to find the next hop.
        /// </summary>
        private void SendRequest()
        {
            // generate a 32 byte payload
            string data = new string ('x', 32);
            byte[] payload = System.Text.ASCIIEncoding.ASCII.GetBytes (data);

            // fill in ip header fields
            IpV4Packet ipPacket = new IpV4Packet ();
            ipPacket.DestinationAddress = m_remoteAddress;
            ipPacket.SourceAddress		= m_localAddress;
            ipPacket.TransportProtocol	= ProtocolType.Icmp;
            ipPacket.TimeToLive = m_ttl;

            // save the identification
            m_ipId = ipPacket.Identification;

            // add routing options if any
            if (m_route != null)
            {
                ipPacket.Options = new IpV4Option[2];

                ipPacket.Options[0] = m_route.Serialize (m_strictRouting ? IpV4OptionNumber.StrictSourceRouting : IpV4OptionNumber.LooseSourceRouting);

                ipPacket.Options[1] = new IpV4Option ();
                ipPacket.Options[1].OptionType = IpV4OptionNumber.EndOfOptions;
                ipPacket.Options[1].IsCopied = false;
                ipPacket.Options[1].Length = 1;
                ipPacket.Options[1].Class = IpV4OptionClass.Control;
                ipPacket.Options[1].Data = null;
            }

            // create a new echo packet
            IcmpEcho echo = new IcmpEcho ();
            echo.Identifier = m_id;
            echo.Data = payload;

            // serialize the icmp packet
            IcmpPacket icmpPacket = echo.Serialize (false);
            ipPacket.Data = icmpPacket.Serialize ();

            if (m_fragment)
            {
                IpV4Packet[] fragments = ipPacket.Fragment (8);

                // send each fragment
                for (int i = 0; i < fragments.Length; i++)
                {
                    byte[] packet = fragments[i].Serialize ();
                    m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (fragments[i].DestinationAddress, 0));
                }
            }
            else
            {
                // send the ip packet
                byte[] packet = ipPacket.Serialize ();
                m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (ipPacket.DestinationAddress, 0));
            }

            // grab the current time
            m_start = Environment.TickCount;

            // start the timeout timer
            m_timer.Enabled = true;
        }
Ejemplo n.º 7
0
        /// <summary>
        ///		This event occurs whenever a new packet arrives.
        /// </summary>
        /// <param name="data">
        ///		The data in the packet.
        ///	</param>
        private void NewPacket(byte[] data)
        {
            if (!m_working)
            {
                return;
            }

            // store the time the packet arrived
            m_stop = Environment.TickCount;

            // parse out the ip header
            IpV4Packet ipPacket = new IpV4Packet (data);

            // double check to make sure this is an icmp packet
            if (ipPacket.TransportProtocol != ProtocolType.Icmp)
            {
                return;
            }

            // parse out the icmp packet
            IcmpPacket icmpPacket = new IcmpPacket (ipPacket.Data);

            // if this is an echo reply
            if (icmpPacket.MessageType == IcmpMessageType.EchoReply)
            {
                #region Reply From Destination

                // deserialize the packet
                IcmpEcho echo = new IcmpEcho (icmpPacket);

                // if this packet matches our identifier, and destination address
                if (echo.Identifier == m_id)
                {
                    // disable the timeout timer
                    m_timer.Enabled = false;

                    // raise the event
                    if (RouteUpdate != null)
                    {
                        RouteUpdate (ipPacket.SourceAddress, (int)((uint)m_stop - (uint)m_start), m_ttl);
                    }

                    // raise the event
                    if (TraceFinished != null)
                    {
                        TraceFinished ();
                    }

                    // signal the wait event
                    m_waitObject.Set ();

                    // allow new trace routes
                    m_working = false;
                }

                #endregion
            }

            // if the time to live exceeded then we have a new hop
            else if (icmpPacket.MessageType == IcmpMessageType.TimeExceeded)
            {
                #region Reply From Router

                IcmpTimeExceeded icmpTimeExceeded = new IcmpTimeExceeded (icmpPacket);

                // make sure this packet is for us
                if (m_ipId != icmpTimeExceeded.BadPacket.Identification)
                {
                    return;
                }

                // disable the timeout timer
                m_timer.Enabled = false;

                // raise the event
                if (RouteUpdate != null && m_working)
                {
                    RouteUpdate (ipPacket.SourceAddress, (int)((uint)m_stop - (uint)m_start), m_ttl);
                }

                // increment the time to live.
                m_ttl++;

                // if the max hop count is exceeded
                if (m_ttl > m_maxHops)
                {
                    // disable the timeout timer
                    m_timer.Enabled = false;

                    // allow new trace routes
                    m_working = false;

                    // raise the event
                    if (MaxHopsExceeded != null)
                    {
                        MaxHopsExceeded ();
                    }

                    // signal the wait event
                    m_waitObject.Set ();
                }
                else
                {
                    // send the next request
                    SendRequest ();
                }

                #endregion
            }
        }
        /// <summary>
        ///		This event occurs whenever a new packet arrives.
        /// </summary>
        /// <param name="data">
        ///		The data in the packet.
        ///	</param>
        private void NewPacket(byte[] data)
        {
            if (!m_working)
            {
                return;
            }

            // store the time the packet arrived
            m_stop = Environment.TickCount;

            // parse out the ip header
            IpV4Packet ipPacket = new IpV4Packet(data);

            // double check to make sure this is an icmp packet
            if (ipPacket.TransportProtocol != ProtocolType.Icmp)
            {
                return;
            }

            // parse out the icmp packet
            IcmpPacket icmpPacket = new IcmpPacket(ipPacket.Data);

            // if this is an echo reply
            if (icmpPacket.MessageType == IcmpMessageType.EchoReply)
            {
                #region Reply From Destination

                // deserialize the packet
                IcmpEcho echo = new IcmpEcho(icmpPacket);

                // if this packet matches our identifier, and destination address
                if (echo.Identifier == m_id)
                {
                    // disable the timeout timer
                    m_timer.Enabled = false;

                    // raise the event
                    if (RouteUpdate != null)
                    {
                        RouteUpdate(ipPacket.SourceAddress, (int)((uint)m_stop - (uint)m_start), m_ttl);
                    }

                    // raise the event
                    if (TraceFinished != null)
                    {
                        TraceFinished();
                    }

                    // signal the wait event
                    m_waitObject.Set();

                    // allow new trace routes
                    m_working = false;
                }

                #endregion
            }

            // if the time to live exceeded then we have a new hop
            else if (icmpPacket.MessageType == IcmpMessageType.TimeExceeded)
            {
                #region Reply From Router

                IcmpTimeExceeded icmpTimeExceeded = new IcmpTimeExceeded(icmpPacket);

                // make sure this packet is for us
                if (m_ipId != icmpTimeExceeded.BadPacket.Identification)
                {
                    return;
                }

                // disable the timeout timer
                m_timer.Enabled = false;

                // raise the event
                if (RouteUpdate != null && m_working)
                {
                    RouteUpdate(ipPacket.SourceAddress, (int)((uint)m_stop - (uint)m_start), m_ttl);
                }

                // increment the time to live.
                m_ttl++;

                // if the max hop count is exceeded
                if (m_ttl > m_maxHops)
                {
                    // disable the timeout timer
                    m_timer.Enabled = false;

                    // allow new trace routes
                    m_working = false;

                    // raise the event
                    if (MaxHopsExceeded != null)
                    {
                        MaxHopsExceeded();
                    }

                    // signal the wait event
                    m_waitObject.Set();
                }
                else
                {
                    // send the next request
                    SendRequest();
                }

                #endregion
            }
        }
        /// <summary>
        ///		Send the next request in order to find the next hop.
        /// </summary>
        private void SendRequest()
        {
            // generate a 32 byte payload
            string data = new string ('x', 32);

            byte[] payload = System.Text.ASCIIEncoding.ASCII.GetBytes(data);

            // fill in ip header fields
            IpV4Packet ipPacket = new IpV4Packet();

            ipPacket.DestinationAddress = m_remoteAddress;
            ipPacket.SourceAddress      = m_localAddress;
            ipPacket.TransportProtocol  = ProtocolType.Icmp;
            ipPacket.TimeToLive         = m_ttl;

            // save the identification
            m_ipId = ipPacket.Identification;

            // add routing options if any
            if (m_route != null)
            {
                ipPacket.Options = new IpV4Option[2];

                ipPacket.Options[0] = m_route.Serialize(m_strictRouting ? IpV4OptionNumber.StrictSourceRouting : IpV4OptionNumber.LooseSourceRouting);

                ipPacket.Options[1]            = new IpV4Option();
                ipPacket.Options[1].OptionType = IpV4OptionNumber.EndOfOptions;
                ipPacket.Options[1].IsCopied   = false;
                ipPacket.Options[1].Length     = 1;
                ipPacket.Options[1].Class      = IpV4OptionClass.Control;
                ipPacket.Options[1].Data       = null;
            }

            // create a new echo packet
            IcmpEcho echo = new IcmpEcho();

            echo.Identifier = m_id;
            echo.Data       = payload;

            // serialize the icmp packet
            IcmpPacket icmpPacket = echo.Serialize(false);

            ipPacket.Data = icmpPacket.Serialize();


            if (m_fragment)
            {
                IpV4Packet[] fragments = ipPacket.Fragment(8);

                // send each fragment
                for (int i = 0; i < fragments.Length; i++)
                {
                    byte[] packet = fragments[i].Serialize();
                    m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(fragments[i].DestinationAddress, 0));
                }
            }
            else
            {
                // send the ip packet
                byte[] packet = ipPacket.Serialize();
                m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(ipPacket.DestinationAddress, 0));
            }


            // grab the current time
            m_start = Environment.TickCount;

            // start the timeout timer
            m_timer.Enabled = true;
        }