Commit 7bf4249c authored by Brickner_cp's avatar Brickner_cp

ICMP

parent 47ed4887
...@@ -68,85 +68,48 @@ namespace PcapDotNet.Packets.Test ...@@ -68,85 +68,48 @@ namespace PcapDotNet.Packets.Test
[TestMethod] [TestMethod]
public void RandomIcmpTest() public void RandomIcmpTest()
{ {
MacAddress ethernetSource = new MacAddress("00:01:02:03:04:05"); EthernetLayer ethernetLayer = new EthernetLayer
MacAddress ethernetDestination = new MacAddress("A0:A1:A2:A3:A4:A5"); {
Source = new MacAddress("00:01:02:03:04:05"),
Destination = new MacAddress("A0:A1:A2:A3:A4:A5")
};
Random random = new Random(); Random random = new Random();
byte ipV4TypeOfService = random.NextByte(); IpV4Layer ipV4Layer = new IpV4Layer
ushort ipV4Identification = random.NextUShort(); {
byte ipV4Ttl = random.NextByte(); TypeOfService = random.NextByte(),
IpV4Fragmentation ipV4Fragmentation = random.NextIpV4Fragmentation(); Identification = random.NextUShort(),
IpV4Address ipV4Source = new IpV4Address(random.NextUInt()); Ttl = random.NextByte(),
IpV4Address ipV4Destination = new IpV4Address(random.NextUInt()); Fragmentation = random.NextIpV4Fragmentation(),
IpV4Options ipV4Options = random.NextIpV4Options(); Source = random.NextIpV4Address(),
Destination = random.NextIpV4Address(),
Options = random.NextIpV4Options()
};
for (int i = 0; i != 1000; ++i) for (int i = 0; i != 1000; ++i)
{ {
IcmpMessageType icmpMessageType = random.NextEnum<IcmpMessageType>(); IpV4Layer icmpIpV4Layer = new IpV4Layer
Packet packet;
byte icmpIpV4TypeOfService = random.NextByte();
ushort icmpIpV4Identification = random.NextUShort();
byte icmpIpV4Ttl = random.NextByte();
IpV4Fragmentation icmpIpV4Fragmentation = random.NextIpV4Fragmentation();
IpV4Protocol icmpIpV4Protocol = random.NextEnum<IpV4Protocol>();
IpV4Address icmpIpV4Source = new IpV4Address(random.NextUInt());
IpV4Address icmpIpV4Destination = new IpV4Address(random.NextUInt());
IpV4Options icmpIpV4Options = random.NextIpV4Options();
Datagram icmpIpV4Payload = random.NextDatagram(random.Next(200));
switch (icmpMessageType)
{ {
case IcmpMessageType.DestinationUnreachable: TypeOfService = random.NextByte(),
IcmpCodeDestinationUnrechable code = random.NextEnum<IcmpCodeDestinationUnrechable>(); Identification = random.NextUShort(),
Fragmentation = random.NextIpV4Fragmentation(),
Ttl = random.NextByte(),
Protocol = random.NextEnum<IpV4Protocol>(),
Source = random.NextIpV4Address(),
Destination = random.NextIpV4Address(),
Options = random.NextIpV4Options(),
};
packet = PacketBuilder.EthernetIpV4IcmpDestinationUnreachable(DateTime.Now, PayloadLayer icmpIpV4PayloadLayer = new PayloadLayer
ethernetSource, ethernetDestination, {
ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, Data = random.NextDatagram(random.Next(200))
ipV4Ttl, };
ipV4Source, ipV4Destination, ipV4Options,
code,
icmpIpV4TypeOfService, icmpIpV4Identification,
icmpIpV4Fragmentation,
icmpIpV4Ttl, icmpIpV4Protocol, icmpIpV4Source,
icmpIpV4Destination,
icmpIpV4Options, icmpIpV4Payload);
break;
// case IcmpMessageType.TimeExceeded: IcmpLayer icmpLayer = random.NextIcmpLayer();
// PacketBuilder.EthernetIpV4IcmpTimeExceeded(DateTime.Now,
// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation,
// ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options,
// code,
// icmpIpV4TypeOfService, icmpIpV4Identification,
// icmpIpV4Fragmentation,
// icmpIpV4Ttl, icmpIpV4Protocol, icmpIpV4Source,
// icmpIpV4Destination,
// icmpIpV4Options, icmpIpV4Payload);
// case IcmpMessageType.ParameterProblem:
// case IcmpMessageType.SourceQuench:
// case IcmpMessageType.Redirect:
// case IcmpMessageType.Echo:
// case IcmpMessageType.EchoReply:
// case IcmpMessageType.Timestamp:
// case IcmpMessageType.TimestampReply:
// case IcmpMessageType.InformationRequest:
// case IcmpMessageType.InformationReply:
// case IcmpMessageType.RouterAdvertisement:
// case IcmpMessageType.RouterSolicitation:
// case IcmpMessageType.AddressMaskRequest:
// case IcmpMessageType.AddressMaskReply:
// case IcmpMessageType.Traceroute:
// case IcmpMessageType.ConversionFailed:
// case IcmpMessageType.DomainNameRequest:
// case IcmpMessageType.DomainNameReply:
// case IcmpMessageType.SecurityFailures:
default: Packet packet = new PacketBuilder2(ethernetLayer, ipV4Layer, icmpLayer, icmpIpV4Layer, icmpIpV4PayloadLayer).Build(DateTime.Now);
throw new InvalidOperationException("Invalid icmpMessageType " + icmpMessageType);
}
Assert.IsTrue(packet.IsValid, "IsValid"); Assert.IsTrue(packet.IsValid, "IsValid");
} }
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MoreRandomPackets.cs" /> <Compile Include="RandomPacketsExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
......
using System;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
...@@ -16,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -16,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpAddressMaskDatagram : IcmpIdentifiedDatagram public class IcmpAddressMaskDatagram : IcmpIdentifiedDatagram
{ {
public const int HeaderLength = HeaderMinimumLength + HeaderAdditionalLength;
public const int HeaderAdditionalLength = 4;
private class Offset private class Offset
{ {
public const int AddressMask = 4; public const int AddressMask = 4;
...@@ -33,5 +37,10 @@ namespace PcapDotNet.Packets.Icmp ...@@ -33,5 +37,10 @@ namespace PcapDotNet.Packets.Icmp
: base(buffer, offset, length) : base(buffer, offset, length)
{ {
} }
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4Address addressMask)
{
buffer.Write(offset + Offset.AddressMask, addressMask, Endianity.Big);
}
} }
} }
\ No newline at end of file
...@@ -3,6 +3,7 @@ using System; ...@@ -3,6 +3,7 @@ using System;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary> /// <summary>
/// Generic
/// <pre> /// <pre>
/// +-----+------+------+-----------+ /// +-----+------+------+-----------+
/// | Bit | 0-7 | 8-15 | 16-31 | /// | Bit | 0-7 | 8-15 | 16-31 |
...@@ -23,6 +24,8 @@ namespace PcapDotNet.Packets.Icmp ...@@ -23,6 +24,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public const int HeaderLength = 8; public const int HeaderLength = 8;
public const int HeaderWithoutValueLength = HeaderLength - sizeof(uint);
private static class Offset private static class Offset
{ {
public const int Type = 0; public const int Type = 0;
......
...@@ -24,8 +24,8 @@ namespace PcapDotNet.Packets.Icmp ...@@ -24,8 +24,8 @@ namespace PcapDotNet.Packets.Icmp
{ {
get get
{ {
if (_ipV4 == null && Length >= HeaderLength) if (_ipV4 == null && Length >= HeaderMinimumLength)
_ipV4 = new IpV4Datagram(Buffer, StartOffset + HeaderLength, Length - HeaderLength); _ipV4 = new IpV4Datagram(Buffer, StartOffset + HeaderMinimumLength, Length - HeaderMinimumLength);
return _ipV4; return _ipV4;
} }
} }
......
...@@ -5,6 +5,28 @@ using PcapDotNet.Packets.IpV4; ...@@ -5,6 +5,28 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
public class IcmpRouterAdvertisementEntry
{
public IcmpRouterAdvertisementEntry(IpV4Address routerAddress, int routerAddressPreference)
{
_routerAddress = routerAddress;
_routerAddressPreference = routerAddressPreference;
}
public IpV4Address RouterAddress
{
get { return _routerAddress;}
}
public int RouterAddressPreference
{
get {return _routerAddressPreference; }
}
private readonly IpV4Address _routerAddress;
private readonly int _routerAddressPreference;
}
/// <summary> /// <summary>
/// RFC 1256. /// RFC 1256.
/// <pre> /// <pre>
...@@ -28,6 +50,8 @@ namespace PcapDotNet.Packets.Icmp ...@@ -28,6 +50,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpRouterAdvertisementDatagram : IcmpTypedDatagram public class IcmpRouterAdvertisementDatagram : IcmpTypedDatagram
{ {
public const int DefaultAddressEntrySize = 2;
private class Offset private class Offset
{ {
public const int NumAddresses = 0; public const int NumAddresses = 0;
...@@ -69,58 +93,51 @@ namespace PcapDotNet.Packets.Icmp ...@@ -69,58 +93,51 @@ namespace PcapDotNet.Packets.Icmp
} }
/// <summary> /// <summary>
/// The sending router's IP address(es) on the interface from which this message is sent. /// The pairs of sending router's IP address(es) on the interface from which this message is sent
/// and 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> /// </summary>
public ReadOnlyCollection<IpV4Address> RouterAddresses public ReadOnlyCollection<IcmpRouterAdvertisementEntry> Entries
{ {
get get
{ {
if (_routerAddresses == null) if (_entries == null)
{ {
IpV4Address[] addresses = new IpV4Address[NumAddresses]; IcmpRouterAdvertisementEntry[] entries = new IcmpRouterAdvertisementEntry[NumAddresses];
int currentOffset = Offset.Addresses; int currentOffset = Offset.Addresses;
for (int i = 0; i != addresses.Length && currentOffset + IpV4Address.SizeOf <= Length; ++i) for (int i = 0; i != entries.Length && currentOffset + IpV4Address.SizeOf <= Length; ++i)
{ {
addresses[i] = ReadIpV4Address(currentOffset, Endianity.Big); entries[i] = new IcmpRouterAdvertisementEntry(ReadIpV4Address(currentOffset, Endianity.Big),
ReadInt(currentOffset + IpV4Address.SizeOf, Endianity.Big));
currentOffset += AddressEntrySize * IpV4Address.SizeOf; currentOffset += AddressEntrySize * IpV4Address.SizeOf;
} }
_routerAddresses = new ReadOnlyCollection<IpV4Address>(addresses); _entries = new ReadOnlyCollection<IcmpRouterAdvertisementEntry>(entries);
} }
return _routerAddresses; return _entries;
} }
} }
/// <summary> internal IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length)
/// The preferability of each Router Address[i] as a default router address, relative to other router addresses on the same subnet. : base(buffer, offset, length)
/// 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 static int GetHeaderAdditionalLength(int numEntries)
} {
return numEntries * DefaultAddressEntrySize * IpV4Address.SizeOf;
} }
internal IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length) internal static void WriteHeaderAdditional(byte[] buffer, int offset,
: base(buffer, offset, length) IEnumerable<IcmpRouterAdvertisementEntry> entries)
{ {
foreach (IcmpRouterAdvertisementEntry entry in entries)
{
buffer.Write(ref offset, entry.RouterAddress, Endianity.Big);
buffer.Write(ref offset, entry.RouterAddressPreference, Endianity.Big);
}
} }
private ReadOnlyCollection<IpV4Address> _routerAddresses; private ReadOnlyCollection<IcmpRouterAdvertisementEntry> _entries;
private ReadOnlyCollection<int> _routerAddressesPreferences;
} }
} }
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
...@@ -20,6 +21,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -20,6 +21,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpTimestampDatagram : IcmpIdentifiedDatagram public class IcmpTimestampDatagram : IcmpIdentifiedDatagram
{ {
public const int HeaderLength = HeaderMinimumLength + HeaderAdditionalLength;
public const int HeaderAdditionalLength = 12;
private class Offset private class Offset
{ {
public const int OriginateTimestamp = 4; public const int OriginateTimestamp = 4;
...@@ -55,5 +59,12 @@ namespace PcapDotNet.Packets.Icmp ...@@ -55,5 +59,12 @@ namespace PcapDotNet.Packets.Icmp
: base(buffer, offset, length) : base(buffer, offset, length)
{ {
} }
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4TimeOfDay originateTimestamp, IpV4TimeOfDay receiveTimestamp, IpV4TimeOfDay transmitTimestamp)
{
buffer.Write(ref offset, originateTimestamp, Endianity.Big);
buffer.Write(ref offset, receiveTimestamp, Endianity.Big);
buffer.Write(offset, transmitTimestamp, Endianity.Big);
}
} }
} }
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary> /// <summary>
...@@ -18,6 +20,8 @@ namespace PcapDotNet.Packets.Icmp ...@@ -18,6 +20,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpTracerouteDatagram : IcmpTypedDatagram public class IcmpTracerouteDatagram : IcmpTypedDatagram
{ {
public const int HeaderAdditionalLength = 12;
private class Offset private class Offset
{ {
public const int Identifier = 0; public const int Identifier = 0;
...@@ -76,5 +80,13 @@ namespace PcapDotNet.Packets.Icmp ...@@ -76,5 +80,13 @@ namespace PcapDotNet.Packets.Icmp
: base(buffer, offset, length) : base(buffer, offset, length)
{ {
} }
internal static void WriteHeaderAdditional(byte[] buffer, int offset, ushort outboundHopCount, ushort returnHopCount, uint outputLinkSpeed, uint outputLinkMtu)
{
buffer.Write(ref offset, outboundHopCount, Endianity.Big);
buffer.Write(ref offset, returnHopCount, Endianity.Big);
buffer.Write(ref offset, outputLinkSpeed, Endianity.Big);
buffer.Write(offset, outputLinkMtu, Endianity.Big);
}
} }
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -2,7 +2,7 @@ namespace PcapDotNet.Packets.Icmp
{ {
public class IcmpTypedDatagram : Datagram public class IcmpTypedDatagram : Datagram
{ {
public const int HeaderLength = 4; public const int HeaderMinimumLength = 4;
internal IcmpTypedDatagram(byte[] buffer, int offset, int length) internal IcmpTypedDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length) : base(buffer, offset, length)
......
using System;
using PcapDotNet.Packets.Icmp;
namespace PcapDotNet.Packets
{
public class IcmpTracerouteLayer : IcmpLayer
{
public IcmpCodeTraceroute Code { get; set; }
public ushort Identification{get;set;}
public ushort OutboundHopCount{get;set;}
public ushort ReturnHopCount{get;set;}
public uint OutputLinkSpeed{get;set;}
public uint OutputLinkMtu{get;set;}
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.Traceroute; }
}
public override int Length
{
get
{
return base.Length + IcmpTracerouteDatagram.HeaderAdditionalLength;
}
}
public override byte CodeValue
{
get
{
return (byte)Code;
}
}
protected override uint Value
{
get
{
return (uint)(Identification << 16);
}
}
protected override void WriteHeaderAdditional(byte[] buffer, int offset)
{
IcmpTracerouteDatagram.WriteHeaderAdditional(buffer, offset, OutboundHopCount, ReturnHopCount, OutputLinkSpeed, OutputLinkMtu);
}
}
}
\ No newline at end of file
...@@ -412,6 +412,12 @@ namespace PcapDotNet.Packets ...@@ -412,6 +412,12 @@ namespace PcapDotNet.Packets
Write(buffer, offset, value); Write(buffer, offset, value);
} }
public static void Write(this byte[] buffer, ref int offset, int value, Endianity endianity)
{
Write(buffer, offset, value, endianity);
offset += sizeof(int);
}
/// <summary> /// <summary>
/// Writes the given value to the buffer using the given endianity. /// Writes the given value to the buffer using the given endianity.
/// </summary> /// </summary>
...@@ -535,6 +541,11 @@ namespace PcapDotNet.Packets ...@@ -535,6 +541,11 @@ namespace PcapDotNet.Packets
buffer.Write(ref offset, value.ToValue(), endianity); buffer.Write(ref offset, value.ToValue(), endianity);
} }
public static void Write(this byte[] buffer, int offset, IpV4TimeOfDay value, Endianity endianity)
{
buffer.Write(offset, value.MillisecondsSinceMidnightUniversalTime, endianity);
}
/// <summary> /// <summary>
/// Writes the given value to the buffer using the given endianity and increments the offset by the number of bytes written. /// Writes the given value to the buffer using the given endianity and increments the offset by the number of bytes written.
/// </summary> /// </summary>
......
...@@ -70,6 +70,7 @@ ...@@ -70,6 +70,7 @@
<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="IcmpTracerouteLayer.cs" />
<Compile Include="Icmp\IcmpAddressMaskDatagram.cs" /> <Compile Include="Icmp\IcmpAddressMaskDatagram.cs" />
<Compile Include="Icmp\IcmpCodeDestinationUnrechable.cs" /> <Compile Include="Icmp\IcmpCodeDestinationUnrechable.cs" />
<Compile Include="Icmp\IcmpConversionFailedDatagram.cs" /> <Compile Include="Icmp\IcmpConversionFailedDatagram.cs" />
......
...@@ -124,7 +124,7 @@ namespace PcapDotNet.TestUtils ...@@ -124,7 +124,7 @@ namespace PcapDotNet.TestUtils
return random.NextEnum((IEnumerable<T>)valuesToIgnore); return random.NextEnum((IEnumerable<T>)valuesToIgnore);
} }
public static object NextValue<T>(this Random random, IList<T> values) public static T NextValue<T>(this Random random, IList<T> values)
{ {
return values[random.Next(values.Count)]; return values[random.Next(values.Count)];
} }
......
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