/// <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); }
/// <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]; }
/// <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)); }
/// <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); }
/// <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); }
/// <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); }
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(); } } }
/// <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); }
/// <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); }
/// <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> /// 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 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); }
/// <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)); }
/// <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]; }
/// <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); }
/// <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; }
/// <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); }
/// <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 (); } } }
/// <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; }
/// <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; }