Commit 7bf4249c authored by Brickner_cp's avatar Brickner_cp

ICMP

parent 47ed4887
......@@ -68,85 +68,48 @@ namespace PcapDotNet.Packets.Test
[TestMethod]
public void RandomIcmpTest()
{
MacAddress ethernetSource = new MacAddress("00:01:02:03:04:05");
MacAddress ethernetDestination = new MacAddress("A0:A1:A2:A3:A4:A5");
EthernetLayer ethernetLayer = new EthernetLayer
{
Source = new MacAddress("00:01:02:03:04:05"),
Destination = new MacAddress("A0:A1:A2:A3:A4:A5")
};
Random random = new Random();
byte ipV4TypeOfService = random.NextByte();
ushort ipV4Identification = random.NextUShort();
byte ipV4Ttl = random.NextByte();
IpV4Fragmentation ipV4Fragmentation = random.NextIpV4Fragmentation();
IpV4Address ipV4Source = new IpV4Address(random.NextUInt());
IpV4Address ipV4Destination = new IpV4Address(random.NextUInt());
IpV4Options ipV4Options = random.NextIpV4Options();
IpV4Layer ipV4Layer = new IpV4Layer
{
TypeOfService = random.NextByte(),
Identification = random.NextUShort(),
Ttl = random.NextByte(),
Fragmentation = random.NextIpV4Fragmentation(),
Source = random.NextIpV4Address(),
Destination = random.NextIpV4Address(),
Options = random.NextIpV4Options()
};
for (int i = 0; i != 1000; ++i)
{
IcmpMessageType icmpMessageType = random.NextEnum<IcmpMessageType>();
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:
IcmpCodeDestinationUnrechable code = random.NextEnum<IcmpCodeDestinationUnrechable>();
IpV4Layer icmpIpV4Layer = new IpV4Layer
{
TypeOfService = random.NextByte(),
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,
ethernetSource, ethernetDestination,
ipV4TypeOfService, ipV4Identification, ipV4Fragmentation,
ipV4Ttl,
ipV4Source, ipV4Destination, ipV4Options,
code,
icmpIpV4TypeOfService, icmpIpV4Identification,
icmpIpV4Fragmentation,
icmpIpV4Ttl, icmpIpV4Protocol, icmpIpV4Source,
icmpIpV4Destination,
icmpIpV4Options, icmpIpV4Payload);
break;
PayloadLayer icmpIpV4PayloadLayer = new PayloadLayer
{
Data = random.NextDatagram(random.Next(200))
};
// case IcmpMessageType.TimeExceeded:
// 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:
IcmpLayer icmpLayer = random.NextIcmpLayer();
default:
throw new InvalidOperationException("Invalid icmpMessageType " + icmpMessageType);
}
Packet packet = new PacketBuilder2(ethernetLayer, ipV4Layer, icmpLayer, icmpIpV4Layer, icmpIpV4PayloadLayer).Build(DateTime.Now);
Assert.IsTrue(packet.IsValid, "IsValid");
}
......
......@@ -49,7 +49,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MoreRandomPackets.cs" />
<Compile Include="RandomPacketsExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
......
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
......@@ -16,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpAddressMaskDatagram : IcmpIdentifiedDatagram
{
public const int HeaderLength = HeaderMinimumLength + HeaderAdditionalLength;
public const int HeaderAdditionalLength = 4;
private class Offset
{
public const int AddressMask = 4;
......@@ -33,5 +37,10 @@ namespace PcapDotNet.Packets.Icmp
: 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;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// Generic
/// <pre>
/// +-----+------+------+-----------+
/// | Bit | 0-7 | 8-15 | 16-31 |
......@@ -23,6 +24,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public const int HeaderLength = 8;
public const int HeaderWithoutValueLength = HeaderLength - sizeof(uint);
private static class Offset
{
public const int Type = 0;
......
......@@ -24,8 +24,8 @@ namespace PcapDotNet.Packets.Icmp
{
get
{
if (_ipV4 == null && Length >= HeaderLength)
_ipV4 = new IpV4Datagram(Buffer, StartOffset + HeaderLength, Length - HeaderLength);
if (_ipV4 == null && Length >= HeaderMinimumLength)
_ipV4 = new IpV4Datagram(Buffer, StartOffset + HeaderMinimumLength, Length - HeaderMinimumLength);
return _ipV4;
}
}
......
......@@ -5,6 +5,28 @@ using PcapDotNet.Packets.IpV4;
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>
/// RFC 1256.
/// <pre>
......@@ -28,6 +50,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpRouterAdvertisementDatagram : IcmpTypedDatagram
{
public const int DefaultAddressEntrySize = 2;
private class Offset
{
public const int NumAddresses = 0;
......@@ -69,58 +93,51 @@ namespace PcapDotNet.Packets.Icmp
}
/// <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>
public ReadOnlyCollection<IpV4Address> RouterAddresses
public ReadOnlyCollection<IcmpRouterAdvertisementEntry> Entries
{
get
{
if (_routerAddresses == null)
if (_entries == null)
{
IpV4Address[] addresses = new IpV4Address[NumAddresses];
IcmpRouterAdvertisementEntry[] entries = new IcmpRouterAdvertisementEntry[NumAddresses];
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;
}
_routerAddresses = new ReadOnlyCollection<IpV4Address>(addresses);
_entries = new ReadOnlyCollection<IcmpRouterAdvertisementEntry>(entries);
}
return _routerAddresses;
return _entries;
}
}
/// <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
internal IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
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)
: base(buffer, offset, length)
internal static void WriteHeaderAdditional(byte[] buffer, int offset,
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<int> _routerAddressesPreferences;
private ReadOnlyCollection<IcmpRouterAdvertisementEntry> _entries;
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
......@@ -20,6 +21,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTimestampDatagram : IcmpIdentifiedDatagram
{
public const int HeaderLength = HeaderMinimumLength + HeaderAdditionalLength;
public const int HeaderAdditionalLength = 12;
private class Offset
{
public const int OriginateTimestamp = 4;
......@@ -55,5 +59,12 @@ namespace PcapDotNet.Packets.Icmp
: 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
{
/// <summary>
......@@ -18,6 +20,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTracerouteDatagram : IcmpTypedDatagram
{
public const int HeaderAdditionalLength = 12;
private class Offset
{
public const int Identifier = 0;
......@@ -76,5 +80,13 @@ namespace PcapDotNet.Packets.Icmp
: 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
{
public class IcmpTypedDatagram : Datagram
{
public const int HeaderLength = 4;
public const int HeaderMinimumLength = 4;
internal IcmpTypedDatagram(byte[] buffer, int offset, int 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
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>
/// Writes the given value to the buffer using the given endianity.
/// </summary>
......@@ -535,6 +541,11 @@ namespace PcapDotNet.Packets
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>
/// Writes the given value to the buffer using the given endianity and increments the offset by the number of bytes written.
/// </summary>
......
......@@ -70,6 +70,7 @@
<Compile Include="Ethernet\EthernetDatagram.cs" />
<Compile Include="Ethernet\EthernetType.cs" />
<Compile Include="Ethernet\MacAddress.cs" />
<Compile Include="IcmpTracerouteLayer.cs" />
<Compile Include="Icmp\IcmpAddressMaskDatagram.cs" />
<Compile Include="Icmp\IcmpCodeDestinationUnrechable.cs" />
<Compile Include="Icmp\IcmpConversionFailedDatagram.cs" />
......
......@@ -124,7 +124,7 @@ namespace PcapDotNet.TestUtils
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)];
}
......
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