Commit 66338447 authored by Brickner_cp's avatar Brickner_cp

ICMP

parent eb8ebc4b
...@@ -176,6 +176,17 @@ namespace PcapDotNet.Packets ...@@ -176,6 +176,17 @@ namespace PcapDotNet.Packets
return Buffer.ReadUShort(StartOffset + offset, endianity); return Buffer.ReadUShort(StartOffset + offset, endianity);
} }
/// <summary>
/// Reads 4 bytes from a specific offset in the datagram as an int with a given endianity.
/// </summary>
/// <param name="offset">The offset in the datagram to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
protected int ReadInt(int offset, Endianity endianity)
{
return Buffer.ReadInt(StartOffset + offset, endianity);
}
/// <summary> /// <summary>
/// Reads 4 bytes from a specific offset in the datagram as a uint with a given endianity. /// Reads 4 bytes from a specific offset in the datagram as a uint with a given endianity.
/// </summary> /// </summary>
......
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 950.
/// <pre>
/// +-----+------------+-----------------+
/// | Bit | 0-15 | 16-31 |
/// +-----+------------+-----------------+
/// | 0 | Identifier | Sequence Number |
/// +-----+------------+-----------------+
/// | 32 | Address Mask |
/// +-----+------------------------------+
/// </pre>
/// </summary>
public class IcmpAddressMaskDatagram : IcmpIdentifiedDatagram
{
private class Offset
{
public const int AddressMask = 4;
}
/// <summary>
/// A 32-bit mask.
/// </summary>
public IpV4Address AddressMask
{
get { return ReadIpV4Address(Offset.AddressMask, Endianity.Big); }
}
internal IcmpAddressMaskDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 1475.
/// <pre>
/// +-----+-------------------------+
/// | Bit | 0-31 |
/// +-----+-------------------------+
/// | 0 | pointer to problem area |
/// +-----+-------------------------+
/// | 32 | copy of datagram that |
/// | | could not be converted |
/// | | ... |
/// +-----+-------------------------+
/// </pre>
/// </summary>
public class IcmpConversionFailedDatagram : IcmpIpV4PayloadDatagram
{
private class Offset
{
public const int Pointer = 0;
}
/// <summary>
/// An offset from the start of the original datagram to the beginning of the offending field.
/// </summary>
public uint Pointer
{
get { return ReadUInt(Offset.Pointer, Endianity.Big); }
}
/// <summary>
/// The data is part of the datagram that could not be converted.
/// It must be at least the IP and transport headers, and must include the field pointed to by the previous parameter.
/// For code 4, the transport header is probably not identifiable; the data should include 256 bytes of the original datagram.
/// </summary>
public IpV4Datagram IpV4
{
get { return IpV4Payload; }
}
internal IcmpConversionFailedDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
...@@ -77,14 +77,14 @@ namespace PcapDotNet.Packets.Icmp ...@@ -77,14 +77,14 @@ namespace PcapDotNet.Packets.Icmp
get { return new Datagram(Buffer, StartOffset + HeaderLength, Length - HeaderLength); } get { return new Datagram(Buffer, StartOffset + HeaderLength, Length - HeaderLength); }
} }
public IcmpIpV4PayloadDatagram DestinationUncreachable public IcmpIpV4HeaderPlus64BitsPayloadDatagram DestinationUncreachable
{ {
get { return IpV4Payload; } get { return IpV4HeaderPlus64BitsPayload; }
} }
public IcmpIpV4PayloadDatagram TimeExceeded public IcmpIpV4HeaderPlus64BitsPayloadDatagram TimeExceeded
{ {
get { return IpV4Payload; } get { return IpV4HeaderPlus64BitsPayload; }
} }
public IcmpParameterProblemDatagram ParameterProblem public IcmpParameterProblemDatagram ParameterProblem
...@@ -97,9 +97,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -97,9 +97,9 @@ namespace PcapDotNet.Packets.Icmp
} }
} }
public IcmpIpV4PayloadDatagram SourceQuench public IcmpIpV4HeaderPlus64BitsPayloadDatagram SourceQuench
{ {
get { return IpV4Payload; } get { return IpV4HeaderPlus64BitsPayload; }
} }
...@@ -144,18 +144,78 @@ namespace PcapDotNet.Packets.Icmp ...@@ -144,18 +144,78 @@ namespace PcapDotNet.Packets.Icmp
} }
public IcmpIdentifiedDatagram InformationRequest public IcmpIdentifiedDatagram InformationRequest
{
get { return Identified; }
}
public IcmpIdentifiedDatagram InformationReply
{
get { return Identified; }
}
public IcmpRouterAdvertisementDatagram RouterAdvertisement
{ {
get get
{ {
if (_identified == null && Length >= Offset.Variable) if (_routerAdvertisement == null && Length >= Offset.Variable)
_identified = new IcmpIdentifiedDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable); _routerAdvertisement = new IcmpRouterAdvertisementDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable);
return _identified; return _routerAdvertisement;
} }
} }
public IcmpIdentifiedDatagram InformationReply public IcmpTypedDatagram RouterSolicitation
{ {
get { return InformationRequest; } get { return Typed; }
}
public IcmpAddressMaskDatagram AddressMaskRequest
{
get
{
if (_addressMask == null && Length >= Offset.Variable)
_addressMask = new IcmpAddressMaskDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable);
return _addressMask;
}
}
public IcmpAddressMaskDatagram AddressMaskReply
{
get { return AddressMaskRequest; }
}
public IcmpTracerouteDatagram Traceroute
{
get
{
if (_traceroute == null && Length >= Offset.Variable)
_traceroute = new IcmpTracerouteDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable);
return _traceroute;
}
}
public IcmpConversionFailedDatagram ConversionFailed
{
get
{
if (_conversionFailed == null && Length >= Offset.Variable)
_conversionFailed = new IcmpConversionFailedDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable);
return _conversionFailed;
}
}
public IcmpIdentifiedDatagram DomainNameRequest
{
get { return Identified; }
}
public IcmpSecurityFailuresDatagram SecurityFailures
{
get
{
if (_securityFailures == null && Length >= Offset.Variable)
_securityFailures = new IcmpSecurityFailuresDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable);
return _securityFailures;
}
} }
internal IcmpDatagram(byte[] buffer, int offset, int length) internal IcmpDatagram(byte[] buffer, int offset, int length)
...@@ -183,22 +243,49 @@ namespace PcapDotNet.Packets.Icmp ...@@ -183,22 +243,49 @@ namespace PcapDotNet.Packets.Icmp
return Sum16BitsToChecksum(sum); return Sum16BitsToChecksum(sum);
} }
private IcmpIpV4PayloadDatagram IpV4Payload private IcmpTypedDatagram Typed
{
get
{
if (_typed == null && Length >= Offset.Variable)
_typed = new IcmpTypedDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable);
return _typed;
}
}
private IcmpIdentifiedDatagram Identified
{
get
{
if (_identified == null && Length >= Offset.Variable)
_identified = new IcmpIdentifiedDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable);
return _identified;
}
}
private IcmpIpV4HeaderPlus64BitsPayloadDatagram IpV4HeaderPlus64BitsPayload
{ {
get get
{ {
if (_ipV4Payload == null && Length >= Offset.Variable) if (_ipV4HeaderPlus64BitsPayload == null && Length >= Offset.Variable)
_ipV4Payload = new IcmpIpV4PayloadDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable); _ipV4HeaderPlus64BitsPayload = new IcmpIpV4HeaderPlus64BitsPayloadDatagram(Buffer, StartOffset + Offset.Variable, Length - Offset.Variable);
return _ipV4Payload; return _ipV4HeaderPlus64BitsPayload;
} }
} }
private bool? _isChecksumCorrect; private bool? _isChecksumCorrect;
private IcmpIpV4PayloadDatagram _ipV4Payload; private IcmpIpV4HeaderPlus64BitsPayloadDatagram _ipV4HeaderPlus64BitsPayload;
private IcmpParameterProblemDatagram _parameterProblem; private IcmpParameterProblemDatagram _parameterProblem;
private IcmpRedirectDatagram _redirect; private IcmpRedirectDatagram _redirect;
private IcmpEchoDatagram _echo; private IcmpEchoDatagram _echo;
private IcmpTimestampDatagram _timestamp; private IcmpTimestampDatagram _timestamp;
private IcmpIdentifiedDatagram _identified; private IcmpIdentifiedDatagram _identified;
private IcmpRouterAdvertisementDatagram _routerAdvertisement;
private IcmpTypedDatagram _typed;
private IcmpAddressMaskDatagram _addressMask;
private IcmpTracerouteDatagram _traceroute;
private IcmpConversionFailedDatagram _conversionFailed;
private IcmpSecurityFailuresDatagram _securityFailures;
} }
} }
\ No newline at end of file
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792.
/// <pre>
/// +-----+-------------------------+
/// | Bit | 0-31 |
/// +-----+-------------------------+
/// | 0 | unused |
/// +-----+-------------------------+
/// | 32 | Internet Header |
/// | | + 64 bits of |
/// | | Original Data Datagram |
/// +-----+-------------------------+
/// </pre>
/// </summary>
public class IcmpIpV4HeaderPlus64BitsPayloadDatagram : IcmpIpV4PayloadDatagram
{
internal IcmpIpV4HeaderPlus64BitsPayloadDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// The internet header plus the first 64 bits of the original datagram's data.
/// This data is used by the host to match the message to the appropriate process.
/// If a higher level protocol uses port numbers, they are assumed to be in the first 64 data bits of the original datagram's data.
/// </summary>
public IpV4Datagram IpV4
{
get { return IpV4Payload; }
}
}
}
\ No newline at end of file
...@@ -3,32 +3,24 @@ using PcapDotNet.Packets.IpV4; ...@@ -3,32 +3,24 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary> /// <summary>
/// RFC 792.
/// <pre> /// <pre>
/// +-----+-------------------------+ /// +-----+-------------------------+
/// | Bit | 0-31 | /// | Bit | 0-31 |
/// +-----+-------------------------+ /// +-----+-------------------------+
/// | 0 | unused | /// | 0 | unused |
/// +-----+-------------------------+ /// +-----+-------------------------+
/// | 32 | Internet Header | /// | 32 | IpV4 datagram |
/// | | + 64 bits of |
/// | | Original Data Datagram |
/// +-----+-------------------------+ /// +-----+-------------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public class IcmpIpV4PayloadDatagram : IcmpTypedDatagram public abstract class IcmpIpV4PayloadDatagram : IcmpTypedDatagram
{ {
internal IcmpIpV4PayloadDatagram(byte[] buffer, int offset, int length) internal IcmpIpV4PayloadDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length) : base(buffer, offset, length)
{ {
} }
/// <summary> protected IpV4Datagram IpV4Payload
/// The internet header plus the first 64 bits of the original datagram's data.
/// This data is used by the host to match the message to the appropriate process.
/// If a higher level protocol uses port numbers, they are assumed to be in the first 64 data bits of the original datagram's data.
/// </summary>
public IpV4Datagram IpV4
{ {
get get
{ {
......
...@@ -14,7 +14,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -14,7 +14,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------+ /// +-----+-------------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public class IcmpParameterProblemDatagram : IcmpIpV4PayloadDatagram public class IcmpParameterProblemDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{ {
private class Offset private class Offset
{ {
......
...@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -16,7 +16,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+--------------------------+ /// +-----+--------------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public class IcmpRedirectDatagram : IcmpIpV4PayloadDatagram public class IcmpRedirectDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{ {
private class Offset private class Offset
{ {
......
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 1256.
/// <pre>
/// +-----+-----------+-----------------+----------+
/// | Bit | 0-7 | 8-15 | 16-31 |
/// +-----+-----------+-----------------+----------+
/// | 0 | Num Addrs | Addr Entry Size | Lifetime |
/// +-----+-----------+-----------------+----------+
/// | 32 | Router Address[1] |
/// +-----+----------------------------------------+
/// | 64 | Preference Level[1] |
/// +-----+----------------------------------------+
/// | 96 | Router Address[2] |
/// +-----+----------------------------------------+
/// | 128 | Preference Level[2] |
/// +-----+----------------------------------------+
/// | . | . |
/// | . | . |
/// | . | . |
/// </pre>
/// </summary>
public class IcmpRouterAdvertisementDatagram : IcmpTypedDatagram
{
private class Offset
{
public const int NumAddresses = 0;
public const int AddressEntrySize = 1;
public const int Lifetime = 2;
public const int Addresses = 4;
}
/// <summary>
/// The number of router addresses advertised in this message.
/// </summary>
public byte NumAddresses
{
get { return this[Offset.NumAddresses]; }
}
/// <summary>
/// The number of 32-bit words of information per each router address (2, in the version of the protocol described here).
/// </summary>
public byte AddressEntrySize
{
get { return this[Offset.AddressEntrySize]; }
}
/// <summary>
/// The maximum number of seconds that the router addresses may be considered valid.
/// </summary>
public ushort LifetimeSeconds
{
get { return ReadUShort(Offset.Lifetime, Endianity.Big); }
}
/// <summary>
/// The maximum time that the router addresses may be considered valid.
/// </summary>
public TimeSpan Lifetime
{
get { return TimeSpan.FromSeconds(LifetimeSeconds); }
}
/// <summary>
/// The sending router's IP address(es) on the interface from which this message is sent.
/// </summary>
public ReadOnlyCollection<IpV4Address> RouterAddresses
{
get
{
if (_routerAddresses == null)
{
IpV4Address[] addresses = new IpV4Address[NumAddresses];
int currentOffset = Offset.Addresses;
for (int i = 0; i != addresses.Length && currentOffset + IpV4Address.SizeOf <= Length; ++i)
{
addresses[i] = ReadIpV4Address(currentOffset, Endianity.Big);
currentOffset += AddressEntrySize * IpV4Address.SizeOf;
}
_routerAddresses = new ReadOnlyCollection<IpV4Address>(addresses);
}
return _routerAddresses;
}
}
/// <summary>
/// The preferability of each Router Address[i] as a default router address, relative to other router addresses on the same subnet.
/// A signed, twos-complement value; higher values mean more preferable.
/// </summary>
public ReadOnlyCollection<int> RouterAddressesPreferences
{
get
{
if (_routerAddressesPreferences == null)
{
int[] addressesPreferences = new int[NumAddresses];
int currentOffset = Offset.Addresses;
for (int i = 0; i != addressesPreferences.Length && currentOffset + sizeof(int) <= Length; ++i)
{
addressesPreferences[i] = ReadInt(currentOffset, Endianity.Big);
currentOffset += AddressEntrySize * IpV4Address.SizeOf;
}
_routerAddressesPreferences = new ReadOnlyCollection<int>(addressesPreferences);
}
return _routerAddressesPreferences;
}
}
internal IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
private ReadOnlyCollection<IpV4Address> _routerAddresses;
private ReadOnlyCollection<int> _routerAddressesPreferences;
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 2521.
/// <pre>
/// +-----+----------+--------------+
/// | Bit | 0-15 | 16-31 |
/// +-----+----------+--------------+
/// | 0 | Reserved | Pointer |
/// +-----+----------+--------------+
/// | 32 | Internet Header |
/// | | + 64 bits of |
/// | | Original Data Datagram |
/// +-----+-------------------------+
/// </pre>
/// </summary>
public class IcmpSecurityFailuresDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
private class Offset
{
public const int Pointer = 2;
}
/// <summary>
/// An offset into the Original Internet Headers that locates the most significant octet of the offending SPI.
/// Will be zero when no SPI is present.
/// </summary>
public ushort Pointer
{
get { return ReadUShort(Offset.Pointer, Endianity.Big); }
}
internal IcmpSecurityFailuresDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 1393.
/// <pre>
/// +-----+--------------------+------------------+
/// | Bit | 0-15 | 16-31 |
/// +-----+--------------------+------------------+
/// | 0 | ID Number | unused |
/// +-----+--------------------+------------------+
/// | 32 | Outbound Hop Count | Return Hop Count |
/// +-----+--------------------+------------------+
/// | 64 | Output Link Speed |
/// +-----+---------------------------------------+
/// | 96 | Output Link MTU |
/// +-----+---------------------------------------+
/// </pre>
/// </summary>
public class IcmpTracerouteDatagram : IcmpTypedDatagram
{
private class Offset
{
public const int Identifier = 0;
public const int OutboundHopCount = 4;
public const int ReturnHopCount = 6;
public const int OutputLinkSpeed = 8;
public const int OutputLinkMtu = 12;
}
/// <summary>
/// The ID Number as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent.
/// This is NOT related to the ID number in the IP header.
/// </summary>
public ushort Identification
{
get { return ReadUShort(Offset.Identifier, Endianity.Big); }
}
/// <summary>
/// The Outbound Hop Count as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent.
/// </summary>
public ushort OutboundHopCount
{
get { return ReadUShort(Offset.OutboundHopCount, Endianity.Big); }
}
/// <summary>
/// The Return Hop Count as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent.
/// </summary>
public ushort ReturnHopCount
{
get { return ReadUShort(Offset.ReturnHopCount, Endianity.Big); }
}
/// <summary>
/// The speed, in OCTETS per second, of the link over which the Outbound/Return Packet will be sent.
/// Since it will not be long before network speeds exceed 4.3Gb/s, and since some machines deal poorly with fields longer than 32 bits, octets per second was chosen over bits per second.
/// If this value cannot be determined, the field should be set to zero.
/// </summary>
public uint OutputLinkSpeed
{
get { return ReadUInt(Offset.OutputLinkSpeed, Endianity.Big); }
}
/// <summary>
/// The MTU, in bytes, of the link over which the Outbound/Return Packet will be sent.
/// MTU refers to the data portion (includes IP header; excludes datalink header/trailer) of the packet.
/// If this value cannot be determined, the field should be set to zero.
/// </summary>
public uint OutputLinkMtu
{
get { return ReadUInt(Offset.OutputLinkMtu, Endianity.Big); }
}
internal IcmpTracerouteDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
...@@ -238,5 +238,80 @@ namespace PcapDotNet.Packets.Icmp ...@@ -238,5 +238,80 @@ namespace PcapDotNet.Packets.Icmp
/// </para> /// </para>
/// </summary> /// </summary>
InformationReply = 0x10, InformationReply = 0x10,
/// <summary>
/// RFC 1256.
/// </summary>
RouterAdvertisement = 0x09,
/// <summary>
/// RFC 1256.
/// </summary>
RouterSolicitation = 0x0A,
/// <summary>
/// RFC 950.
///
/// <para>
/// A gateway receiving an address mask request should return it with the address mask field set to the 32-bit mask of the bits identifying the subnet and network,
/// for the subnet on which the request was received.
/// </para>
///
/// <para>
/// If the requesting host does not know its own IP address, it may leave the source field zero; the reply should then be broadcast.
/// However, this approach should be avoided if at all possible, since it increases the superfluous broadcast load on the network.
/// Even when the replies are broadcast, since there is only one possible address mask for a subnet, there is no need to match requests with replies.
/// The "Identifier" and "Sequence Number" fields can be ignored.
/// </para>
/// </summary>
AddressMaskRequest = 0xA1,
/// <summary>
/// RFC 950.
///
/// <para>
/// A gateway receiving an address mask request should return it with the address mask field set to the 32-bit mask of the bits identifying the subnet and network,
/// for the subnet on which the request was received.
/// </para>
///
/// <para>
/// If the requesting host does not know its own IP address, it may leave the source field zero; the reply should then be broadcast.
/// However, this approach should be avoided if at all possible, since it increases the superfluous broadcast load on the network.
/// Even when the replies are broadcast, since there is only one possible address mask for a subnet, there is no need to match requests with replies.
/// The "Identifier" and "Sequence Number" fields can be ignored.
/// </para>
/// </summary>
AddressMaskReply = 0xA2,
/// <summary>
/// RFC 1393.
/// </summary>
Traceroute = 0x1E,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailed = 0x1F,
/// <summary>
/// RFC 1788.
/// </summary>
DomainNameRequest = 0x25,
/// <summary>
/// RFC 1788.
/// Parsing of this datagram isn't supported because its parsing is not clear from the RFC.
/// </summary>
DomainNameReply = 0x26,
/// <summary>
/// RFC 2521.
/// </summary>
SecurityFailures = 0x28,
} }
} }
\ No newline at end of file
...@@ -2,6 +2,7 @@ using System; ...@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Text;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ethernet; using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
......
...@@ -70,13 +70,19 @@ ...@@ -70,13 +70,19 @@
<Compile Include="Ethernet\EthernetDatagram.cs" /> <Compile Include="Ethernet\EthernetDatagram.cs" />
<Compile Include="Ethernet\EthernetType.cs" /> <Compile Include="Ethernet\EthernetType.cs" />
<Compile Include="Ethernet\MacAddress.cs" /> <Compile Include="Ethernet\MacAddress.cs" />
<Compile Include="Icmp\IcmpAddressMaskDatagram.cs" />
<Compile Include="Icmp\IcmpConversionFailedDatagram.cs" />
<Compile Include="Icmp\IcmpDatagram.cs" /> <Compile Include="Icmp\IcmpDatagram.cs" />
<Compile Include="Icmp\IcmpEchoDatagram.cs" /> <Compile Include="Icmp\IcmpEchoDatagram.cs" />
<Compile Include="Icmp\IcmpIdentifiedDatagram.cs" /> <Compile Include="Icmp\IcmpIdentifiedDatagram.cs" />
<Compile Include="Icmp\IcmpIpV4HeaderPlus64BitsPayloadDatagram.cs" />
<Compile Include="Icmp\IcmpIpV4PayloadDatagram.cs" /> <Compile Include="Icmp\IcmpIpV4PayloadDatagram.cs" />
<Compile Include="Icmp\IcmpParameterProblemDatagram.cs" /> <Compile Include="Icmp\IcmpParameterProblemDatagram.cs" />
<Compile Include="Icmp\IcmpRedirectDatagram.cs" /> <Compile Include="Icmp\IcmpRedirectDatagram.cs" />
<Compile Include="Icmp\IcmpRouterAdvertisementDatagram.cs" />
<Compile Include="Icmp\IcmpSecurityFailuresDatagram.cs" />
<Compile Include="Icmp\IcmpTimestampDatagram.cs" /> <Compile Include="Icmp\IcmpTimestampDatagram.cs" />
<Compile Include="Icmp\IcmpTracerouteDatagram.cs" />
<Compile Include="Icmp\IcmpType.cs" /> <Compile Include="Icmp\IcmpType.cs" />
<Compile Include="Icmp\IcmpTypeAndCode.cs" /> <Compile Include="Icmp\IcmpTypeAndCode.cs" />
<Compile Include="Icmp\IcmpTypedDatagram.cs" /> <Compile Include="Icmp\IcmpTypedDatagram.cs" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment