/// <summary>
        ///		Serlialize this icmp message into an IcmpPacket which can
        ///		then be serialized further.
        /// </summary>
        /// <returns>
        ///		An IcmpPacket class.
        ///	</returns>
        public override IcmpPacket Serialize()
        {
            IcmpPacket packet = base.Serialize();

            packet.MessageType = IcmpMessageType.SourceQuench;

            return(packet);
        }
        /// <summary>
        ///		Create a new source quench ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Source Quench type packet.
        ///	</exception>
        public IcmpSourceQuench(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.SourceQuench)
            {
                throw new ArgumentException("The packet was not a Source Quench type packet", "packet");
            }

            base.Constructor(packet);
        }
Пример #3
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>
        ///		Create a new time exceeded ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Time Exceeded type packet.
        ///	</exception>
        public IcmpTimeExceeded(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.TimeExceeded)
            {
                throw new ArgumentException("The packet was not a Time Exceeded type packet", "packet");
            }

            base.Constructor(packet);
            m_code = (CodeType)packet.Code;
        }
        /// <summary>
        ///		Create a new destination unreachable ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Destination Unreachable type packet.
        ///	</exception>
        public IcmpDestinationUnreachable(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.DestinationUnreachable)
            {
                throw new ArgumentException("The packet was not a Destination Unreachable type packet", "packet");
            }

            base.Constructor(packet);
            m_code = (CodeType)packet.Code;
        }
        /// <summary>
        ///		Serlialize this icmp message into an IcmpPacket which can
        ///		then be serialized further.
        /// </summary>
        /// <returns>
        ///		An IcmpPacket class.
        ///	</returns>
        public override IcmpPacket Serialize()
        {
            IcmpPacket packet = base.Serialize();

            packet.MessageType = IcmpMessageType.ParameterProblem;

            // copy in the pointer
            packet.Data[0] = m_pointer;

            return(packet);
        }
        /// <summary>
        ///		Serlialize this icmp message into an IcmpPacket which can
        ///		then be serialized further.
        /// </summary>
        /// <returns>
        ///		An IcmpPacket class.
        ///	</returns>
        public override IcmpPacket Serialize()
        {
            IcmpPacket packet = base.Serialize();

            packet.MessageType = IcmpMessageType.TimeExceeded;

            // copy in the code
            packet.Code = (byte)m_code;

            return(packet);
        }
        /// <summary>
        ///		Serlialize this icmp message into an IcmpPacket which can
        ///		then be serialized further.
        /// </summary>
        /// <returns>
        ///		An IcmpPacket class.
        ///	</returns>
        public override IcmpPacket Serialize()
        {
            IcmpPacket packet = base.Serialize();

            packet.MessageType = IcmpMessageType.DestinationUnreachable;

            // copy in the code
            packet.Code = (byte)m_code;

            return(packet);
        }
        /// <summary>
        ///		Create a new parameter problem ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Parameter Problem type packet.
        ///	</exception>
        public IcmpParameterProblem(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.ParameterProblem)
            {
                throw new ArgumentException("The packet was not a Time Parameter Problem packet", "packet");
            }

            base.Constructor(packet);

            // extract the pointer
            m_pointer = packet.Data[0];
        }
Пример #10
0
        /// <summary>
        ///		Create a new redirect ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Redirect type packet.
        ///	</exception>
        public IcmpRedirect(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.Redirect)
            {
                throw new ArgumentException("The packet was not a Redirect type packet", "packet");
            }

            base.Constructor(packet);
            m_code = (CodeType)packet.Code;

            // copy out the address
            m_gatewayAddress = new IPAddress((long)BitConverter.ToInt32(packet.Data, 4));
        }
Пример #11
0
        /// <summary>
        ///		Serlialize this icmp message into an IcmpPacket which can
        ///		then be serialized further.
        /// </summary>
        /// <returns>
        ///		An IcmpPacket class.
        ///	</returns>
        public virtual IcmpPacket Serialize()
        {
            IcmpPacket packet = new IcmpPacket();

            // serialize the bad packet and allocate enough space in the buffer
            // for it
            byte[] badPacket = m_badPacket.Serialize();
            byte[] buffer    = new byte[4 + badPacket.Length];

            // copy in the bad packet just after the unused field
            Array.Copy(badPacket, 0, buffer, 4, badPacket.Length);

            return(packet);
        }
Пример #12
0
        /// <summary>
        ///		Serlialize this icmp message into an IcmpPacket which can
        ///		then be serialized further.
        /// </summary>
        /// <returns>
        ///		An IcmpPacket class.
        ///	</returns>
        public override IcmpPacket Serialize()
        {
            IcmpPacket packet = base.Serialize();

            packet.MessageType = IcmpMessageType.SourceQuench;

            // copy in the code
            packet.Code = (byte)m_code;

            // copy in the address
            Array.Copy(m_gatewayAddress.GetAddressBytes(), 0, packet.Data, 4, 4);

            return(packet);
        }
Пример #13
0
        /// <summary>
        ///		Create a new generic error ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        public void Constructor(IcmpPacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            // discard the unused field
            byte[] tempBuffer = new byte[packet.Data.Length - 4];
            Array.Copy(packet.Data, 4, tempBuffer, 0, tempBuffer.Length);

            // parse out the packet data
            m_badPacket = new IpV4Packet(tempBuffer);
        }
Пример #14
0
 void ping_PingReply(Metro.NetworkLayer.IpV4.IpV4Packet ipHeader, Metro.TransportLayer.Icmp.IcmpPacket icmpHeader, int roundTripTime)
 {
     lock (threadLocker)
     {
         PingUpdate pu = new PingUpdate();
         pu.ipHeader      = ipHeader;
         pu.icmpHeader    = icmpHeader;
         pu.RoundTripTime = roundTripTime;
         pu.dateReceived  = DateTime.Now;
         PingList.Add(pu);
         pingReady = true;
         this.Invoke(mivPing);
     }
 }
        /// <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();
                }
            }
        }
Пример #16
0
        /// <summary>
        ///		Serlialize this icmp message into an IcmpPacket which can
        ///		then be serialized further.
        /// </summary>
        /// <param name="reply">
        ///		If true, this packet is an echo reply, otherwise it is an echo request.
        ///	</param>
        /// <returns>
        ///		An IcmpPacket class.
        ///	</returns>
        public IcmpPacket Serialize(bool reply)
        {
            IcmpPacket packet = new IcmpPacket();

            packet.MessageType = (reply ? IcmpMessageType.EchoReply : IcmpMessageType.Echo);

            // allocate enough space for the data
            packet.Data = new byte[4 + (m_data != null ? m_data.Length : 0)];

            // copy in the identifier
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_identifier)), 0, packet.Data, 0, 2);

            // copy in the sequence number
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_sequenceNumber)), 0, packet.Data, 2, 2);

            // copy in the echo data
            Array.Copy(m_data, 0, packet.Data, 4, m_data.Length);

            return(packet);
        }
Пример #17
0
        /// <summary>
        ///		Create a new echo ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Echo packet.
        ///	</exception>
        public IcmpEcho(IcmpPacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            if (packet.MessageType != IcmpMessageType.Echo && packet.MessageType != IcmpMessageType.EchoReply)
            {
                throw new ArgumentException("The packet was not an Echo or Echo Reply type packet", "packet");
            }

            // extract the identifier
            m_identifier = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(packet.Data, 0));

            // extract the sequence number
            m_sequenceNumber = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(packet.Data, 2));

            // copy out the data
            m_data = new byte[packet.Data.Length - 4];
            Array.Copy(packet.Data, 4, m_data, 0, m_data.Length);
        }
Пример #18
0
        /// <summary>
        ///		Create a new destination unreachable ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Destination Unreachable type packet.
        ///	</exception>
        public IcmpDestinationUnreachable(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.DestinationUnreachable)
            {
                throw new ArgumentException ("The packet was not a Destination Unreachable type packet", "packet");
            }

            base.Constructor (packet);
            m_code = (CodeType)packet.Code;
        }
Пример #19
0
        /// <summary>
        ///		Create a new time exceeded ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Time Exceeded type packet.
        ///	</exception>
        public IcmpTimeExceeded(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.TimeExceeded)
            {
                throw new ArgumentException ("The packet was not a Time Exceeded type packet", "packet");
            }

            base.Constructor (packet);
            m_code = (CodeType)packet.Code;
        }
Пример #20
0
        /// <summary>
        ///		Create a new source quench ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Source Quench type packet.
        ///	</exception>
        public IcmpSourceQuench(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.SourceQuench)
            {
                throw new ArgumentException ("The packet was not a Source Quench type packet", "packet");
            }

            base.Constructor (packet);
        }
Пример #21
0
        /// <summary>
        ///		Create a new redirect ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Redirect type packet.
        ///	</exception>
        public IcmpRedirect(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.Redirect)
            {
                throw new ArgumentException ("The packet was not a Redirect type packet", "packet");
            }

            base.Constructor (packet);
            m_code = (CodeType)packet.Code;

            // copy out the address
            m_gatewayAddress = new IPAddress ((long)BitConverter.ToInt32 (packet.Data, 4));
        }
Пример #22
0
        /// <summary>
        ///		Create a new parameter problem ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Parameter Problem type packet.
        ///	</exception>
        public IcmpParameterProblem(IcmpPacket packet)
        {
            if (packet.MessageType != IcmpMessageType.ParameterProblem)
            {
                throw new ArgumentException ("The packet was not a Time Parameter Problem packet", "packet");
            }

            base.Constructor (packet);

            // extract the pointer
            m_pointer = packet.Data[0];
        }
Пример #23
0
        /// <summary>
        ///		Create a new generic error ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        public void Constructor(IcmpPacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException ("packet");
            }

            // discard the unused field
            byte[] tempBuffer = new byte[packet.Data.Length - 4];
            Array.Copy (packet.Data, 4, tempBuffer, 0, tempBuffer.Length);

            // parse out the packet data
            m_badPacket = new IpV4Packet (tempBuffer);
        }
Пример #24
0
        /// <summary>
        ///		Serlialize this icmp message into an IcmpPacket which can
        ///		then be serialized further.
        /// </summary>
        /// <param name="reply">
        ///		If true, this packet is an echo reply, otherwise it is an echo request.
        ///	</param>
        /// <returns>	
        ///		An IcmpPacket class.
        ///	</returns>
        public IcmpPacket Serialize(bool reply)
        {
            IcmpPacket packet = new IcmpPacket ();

            packet.MessageType = (reply ? IcmpMessageType.EchoReply : IcmpMessageType.Echo);

            // allocate enough space for the data
            packet.Data = new byte[4 + (m_data != null ? m_data.Length : 0)];

            // copy in the identifier
            Array.Copy (BitConverter.GetBytes (IPAddress.HostToNetworkOrder ((short)m_identifier)), 0, packet.Data, 0, 2);

            // copy in the sequence number
            Array.Copy (BitConverter.GetBytes (IPAddress.HostToNetworkOrder ((short)m_sequenceNumber)), 0, packet.Data, 2, 2);

            // copy in the echo data
            Array.Copy (m_data, 0, packet.Data, 4, m_data.Length);

            return packet;
        }
Пример #25
0
        /// <summary>
        ///		Create a new echo ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        /// <exception cref="ArgumentException">
        ///		The packet was not a Echo packet.
        ///	</exception>
        public IcmpEcho(IcmpPacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException ("packet");
            }

            if (packet.MessageType != IcmpMessageType.Echo && packet.MessageType != IcmpMessageType.EchoReply)
            {
                throw new ArgumentException ("The packet was not an Echo or Echo Reply type packet", "packet");
            }

            // extract the identifier
            m_identifier = (ushort)IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (packet.Data, 0));

            // extract the sequence number
            m_sequenceNumber = (ushort)IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (packet.Data, 2));

            // copy out the data
            m_data = new byte[packet.Data.Length - 4];
            Array.Copy (packet.Data, 4, m_data, 0, m_data.Length);
        }
Пример #26
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 ();
                }
            }
        }
Пример #27
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 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();
            }
        }
        /// <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;
        }
Пример #31
0
        /// <summary>
        ///		Serlialize this icmp message into an IcmpPacket which can
        ///		then be serialized further.
        /// </summary>
        /// <returns>	
        ///		An IcmpPacket class.
        ///	</returns>
        public virtual IcmpPacket Serialize()
        {
            IcmpPacket packet = new IcmpPacket ();

            // serialize the bad packet and allocate enough space in the buffer
            // for it
            byte[] badPacket = m_badPacket.Serialize ();
            byte[] buffer = new byte[4 + badPacket.Length];

            // copy in the bad packet just after the unused field
            Array.Copy (badPacket, 0, buffer, 4, badPacket.Length);

            return packet;
        }