Commit 7ea0becf authored by Brickner_cp's avatar Brickner_cp

ICMP wireshark tests

parent 2eef92c2
......@@ -111,6 +111,11 @@ namespace PcapDotNet.Base
});
}
public static string BytesSequenceToHexadecimalString(this IEnumerable<byte> sequence)
{
return sequence.BytesSequenceToHexadecimalString(string.Empty);
}
/// <summary>
/// Creates a hash code by xoring the hash codes of the elements in the sequence.
/// </summary>
......
......@@ -50,7 +50,7 @@
<Compile Include="LivePacketDeviceTests.cs" />
<Compile Include="MoreIpV4Option.cs" />
<Compile Include="MoreTcpOption.cs" />
<Compile Include="MoreXElement.cs" />
<Compile Include="XElementExtensions.cs" />
<Compile Include="PacketDumpFileTests.cs" />
<Compile Include="PacketHandler.cs" />
<Compile Include="OfflinePacketDeviceTests.cs" />
......
......@@ -5,6 +5,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
......@@ -12,6 +13,7 @@ using PcapDotNet.Base;
using PcapDotNet.Packets;
using PcapDotNet.Packets.Arp;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Icmp;
using PcapDotNet.Packets.Igmp;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.TestUtils;
......@@ -108,6 +110,7 @@ namespace PcapDotNet.Core.Test
Arp,
IpV4,
Igmp,
Icmp,
Udp,
Tcp
}
......@@ -138,6 +141,13 @@ namespace PcapDotNet.Core.Test
ipV4Layer.Protocol = null;
return PacketBuilder.Build(packetTimestamp, ethernetLayer, ipV4Layer, random.NextIgmpLayer());
case PacketType.Icmp:
ethernetLayer.EtherType = EthernetType.None;
ipV4Layer.Protocol = null;
IcmpLayer icmpLayer = random.NextIcmpLayer();
IEnumerable<ILayer> icmpPayloadLayers = random.NextIcmpPayloadLayers(icmpLayer);
return PacketBuilder.Build(packetTimestamp, new ILayer[]{ethernetLayer, ipV4Layer, icmpLayer}.Concat(icmpPayloadLayers));
case PacketType.Udp:
ethernetLayer.EtherType = EthernetType.None;
ipV4Layer.Protocol = null;
......@@ -220,7 +230,14 @@ namespace PcapDotNet.Core.Test
packetEnumerator.MoveNext();
Packet packet = packetEnumerator.Current;
try
{
ComparePacket(packet, documentPacket);
}
catch (Exception e)
{
throw new AssertFailedException("Failed comparing packet " + i + ". " + e.Message, e);
}
++i;
}
}
......@@ -228,7 +245,12 @@ namespace PcapDotNet.Core.Test
private static void ComparePacket(Packet packet, XElement documentPacket)
{
object currentDatagram = packet;
foreach (var layer in documentPacket.Elements("proto"))
CompareProtocols(currentDatagram, documentPacket);
}
private static void CompareProtocols(object currentDatagram, XElement layersContainer)
{
foreach (var layer in layersContainer.Protocols())
{
switch (layer.Name())
{
......@@ -236,7 +258,7 @@ namespace PcapDotNet.Core.Test
break;
case "frame":
CompareFrame(layer, packet);
CompareFrame(layer, (Packet)currentDatagram);
break;
case "eth":
......@@ -271,6 +293,14 @@ namespace PcapDotNet.Core.Test
CompareIgmp(layer, (IgmpDatagram)currentDatagram);
break;
case "icmp":
PropertyInfo icmpProperty = currentDatagram.GetType().GetProperty("Icmp");
if (icmpProperty == null)
break;
currentDatagram = icmpProperty.GetValue(currentDatagram);
CompareIcmp(layer, (IcmpDatagram)currentDatagram);
break;
case "udp":
PropertyInfo udpProperty = currentDatagram.GetType().GetProperty("Udp");
if (udpProperty == null)
......@@ -379,12 +409,12 @@ namespace PcapDotNet.Core.Test
case "arp.src.hw":
case "arp.src.hw_mac":
field.AssertShow(arpDatagram.SenderHardwareAddress.BytesSequenceToHexadecimalString(":"));
field.AssertShow(arpDatagram.SenderHardwareAddress);
break;
case "arp.src.proto":
field.AssertShow(arpDatagram.SenderProtocolAddress.BytesSequenceToHexadecimalString(":"));
field.AssertShow(arpDatagram.SenderProtocolAddress);
break;
case "arp.src.proto_ipv4":
......@@ -393,11 +423,11 @@ namespace PcapDotNet.Core.Test
case "arp.dst.hw":
case "arp.dst.hw_mac":
field.AssertShow(arpDatagram.TargetHardwareAddress.BytesSequenceToHexadecimalString(":"));
field.AssertShow(arpDatagram.TargetHardwareAddress);
break;
case "arp.dst.proto":
field.AssertShow(arpDatagram.TargetProtocolAddress.BytesSequenceToHexadecimalString(":"));
field.AssertShow(arpDatagram.TargetProtocolAddress);
break;
case "arp.dst.proto_ipv4":
......@@ -607,7 +637,12 @@ namespace PcapDotNet.Core.Test
break;
default:
if (typeof(IgmpMessageType).GetEnumValues<IgmpMessageType>().Contains(igmpDatagram.MessageType))
throw new InvalidOperationException("Invalid message type " + igmpDatagram.MessageType);
field.AssertValue(igmpDatagram.Skip(1));
// field.AssertShow(igmpDatagram.Skip(1));
break;
}
break;
......@@ -666,7 +701,7 @@ namespace PcapDotNet.Core.Test
break;
case "igmp.aux_data":
field.AssertShow(groupRecordDatagram.AuxiliaryData.BytesSequenceToHexadecimalString(":"));
field.AssertShow(groupRecordDatagram.AuxiliaryData);
break;
default:
......@@ -675,6 +710,147 @@ namespace PcapDotNet.Core.Test
}
}
private static void CompareIcmp(XElement icmp, IcmpDatagram icmpDatagram)
{
int routerIndex = 0;
foreach (var field in icmp.Fields())
{
switch (field.Name())
{
case "icmp.type":
field.AssertShowDecimal((byte)icmpDatagram.MessageType);
break;
case "icmp.code":
field.AssertShowHex(icmpDatagram.Code);
break;
case "icmp.checksum_bad":
field.AssertShowDecimal(!icmpDatagram.IsChecksumCorrect);
break;
case "icmp.checksum":
field.AssertShowHex(icmpDatagram.Checksum);
break;
case "data":
field.AssertValue(((IcmpIpV4HeaderPlus64BitsPayloadDatagram)icmpDatagram).IpV4.Payload);
break;
case "data.data":
field.AssertShow(((IcmpIpV4HeaderPlus64BitsPayloadDatagram)icmpDatagram).IpV4.Payload);
break;
case "data.len":
field.AssertShowDecimal(((IcmpIpV4HeaderPlus64BitsPayloadDatagram)icmpDatagram).IpV4.Payload.Length);
break;
case "":
switch (icmpDatagram.MessageType)
{
case IcmpMessageType.ParameterProblem:
if (field.Show() != "Unknown session type")
field.AssertShow("Pointer: " + ((IcmpParameterProblemDatagram)icmpDatagram).Pointer);
break;
case IcmpMessageType.RouterAdvertisement:
IcmpRouterAdvertisementDatagram routerAdvertisementDatagram = (IcmpRouterAdvertisementDatagram)icmpDatagram;
string fieldName = field.Show().Split(':')[0];
switch (fieldName)
{
case "Number of addresses":
field.AssertShow(fieldName + ": " + routerAdvertisementDatagram.NumAddresses);
break;
case "Address entry size":
field.AssertShow(fieldName + ": " + routerAdvertisementDatagram.AddressEntrySize);
break;
case "Lifetime":
TimeSpan actualLifetime = routerAdvertisementDatagram.Lifetime;
StringBuilder actualLifetimeString = new StringBuilder(fieldName + ": ");
if (actualLifetime.Hours != 0)
{
actualLifetimeString.Append(actualLifetime.Hours + " hour");
if (actualLifetime.Hours != 1)
actualLifetimeString.Append('s');
}
if (actualLifetime.Minutes != 0)
{
if (actualLifetime.Hours != 0)
actualLifetimeString.Append(", ");
actualLifetimeString.Append(actualLifetime.Minutes + " minute");
if (actualLifetime.Minutes != 1)
actualLifetimeString.Append('s');
}
if (actualLifetime.Seconds != 0)
{
if (actualLifetime.Hours != 0 || actualLifetime.Minutes != 0)
actualLifetimeString.Append(", ");
actualLifetimeString.Append(actualLifetime.Seconds + " second");
if (actualLifetime.Seconds != 1)
actualLifetimeString.Append('s');
}
break;
case "Router address":
field.AssertShow(fieldName + ": " + routerAdvertisementDatagram.Entries[routerIndex].RouterAddress);
break;
case "Preference level":
field.AssertShow(fieldName + ": " + routerAdvertisementDatagram.Entries[routerIndex++].RouterAddressPreference);
break;
default:
throw new InvalidOperationException("Invalid icmp " + icmpDatagram.MessageType + " field " + fieldName);
}
break;
}
break;
case "icmp.ident":
field.AssertShowHex(((IcmpIdentifiedDatagram)icmpDatagram).Identifier);
break;
case "icmp.seq":
field.AssertShowDecimal(((IcmpIdentifiedDatagram)icmpDatagram).SequenceNumber);
break;
case "icmp.redir_gw":
field.AssertShow(((IcmpRedirectDatagram)icmpDatagram).GatewayInternetAddress.ToString());
break;
case "icmp.mtu":
field.AssertShowDecimal(((IcmpDestinationUnreachableDatagram)icmpDatagram).NextHopMtu);
break;
default:
if (!field.Name().StartsWith("lt2p."))
throw new InvalidOperationException("Invalid icmp field " + field.Name());
break;
}
}
CompareProtocols(icmpDatagram, icmp);
// object currentDatagram = icmpDatagram;
// foreach (var layer in icmp.Protocols())
// {
// switch (layer.Name())
// {
// case "ip":
// PropertyInfo ipV4Property = currentDatagram.GetType().GetProperty("IpV4");
// if (ipV4Property == null)
// break;
// currentDatagram = ipV4Property.GetValue(currentDatagram);
// CompareIpV4(layer, (IpV4Datagram)currentDatagram);
// break;
//
// default:
// throw new InvalidOperationException("unexpected layer under icmp: " + layer.Name());
// }
// }
}
private static void CompareUdp(XElement udpElement, IpV4Datagram ipV4Datagram)
{
UdpDatagram udpDatagram = ipV4Datagram.Udp;
......@@ -713,7 +889,10 @@ namespace PcapDotNet.Core.Test
break;
case "udp.checksum_bad":
checksumField.AssertShowDecimal(!ipV4Datagram.IsTransportChecksumCorrect);
if (checksumField.Show() == "1")
Assert.IsFalse(ipV4Datagram.IsTransportChecksumCorrect);
else
checksumField.AssertShowDecimal(0);
break;
}
}
......
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Base;
namespace PcapDotNet.Core.Test
{
internal static class MoreXElement
internal static class XElementExtensions
{
public static IEnumerable<XElement> Fields(this XElement element)
{
return element.Elements("field");
}
public static IEnumerable<XElement> Protocols(this XElement element)
{
return element.Elements("proto");
}
public static string GetAttributeValue(this XElement element, string attributeName)
{
XAttribute attribute = element.Attribute(attributeName);
if (attribute == null)
throw new ArgumentException("element " + element.Name + " doesn't contain attribute " + attributeName, "attributeName");
return attribute.Value;
}
public static string Name(this XElement element)
{
return element.Attribute("name").Value;
return element.GetAttributeValue("name");
}
public static string Show(this XElement element)
{
return element.Attribute("show").Value;
return element.GetAttributeValue("show");
}
public static string Value(this XElement element)
{
return element.Attribute("value").Value;
return element.GetAttributeValue("value");
}
public static void AssertShow(this XElement element, string value)
{
Assert.AreEqual(element.Show(), value);
Assert.AreEqual(element.Show(), value, element.Name());
}
public static void AssertShow(this XElement element, IEnumerable<byte> value)
{
element.AssertShow(value.BytesSequenceToHexadecimalString(":"));
}
public static void AssertShowDecimal(this XElement element, bool value)
......@@ -38,72 +59,82 @@ namespace PcapDotNet.Core.Test
public static void AssertShowDecimal(this XElement element, byte value)
{
Assert.AreEqual(element.Show(), value.ToString());
element.AssertShow(value.ToString());
}
public static void AssertShowDecimal(this XElement element, short value)
{
Assert.AreEqual(element.Show(), value.ToString());
element.AssertShow(value.ToString());
}
public static void AssertShowDecimal(this XElement element, ushort value)
{
Assert.AreEqual(element.Show(), value.ToString());
element.AssertShow(value.ToString());
}
public static void AssertShowDecimal(this XElement element, int value)
{
Assert.AreEqual(element.Show(), value.ToString(), element.Name());
element.AssertShow(value.ToString());
}
public static void AssertShowDecimal(this XElement element, uint value)
{
Assert.AreEqual(element.Show(), value.ToString());
element.AssertShow(value.ToString());
}
public static void AssertShowDecimal(this XElement element, long value)
{
Assert.AreEqual(element.Show(), value.ToString());
element.AssertShow(value.ToString());
}
public static void AssertShowDecimal(this XElement element, ulong value)
{
Assert.AreEqual(element.Show(), value.ToString());
element.AssertShow(value.ToString());
}
public static void AssertShowHex(this XElement element, byte value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(byte)));
element.AssertShow("0x" + value.ToString("x" + 2 * sizeof(byte)));
}
public static void AssertShowHex(this XElement element, short value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(ushort)));
element.AssertShow("0x" + value.ToString("x" + 2 * sizeof(short)));
}
public static void AssertShowHex(this XElement element, ushort value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(ushort)));
element.AssertShow("0x" + value.ToString("x" + 2 * sizeof(ushort)));
}
public static void AssertShowHex(this XElement element, int value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(int)));
element.AssertShow("0x" + value.ToString("x" + 2 * sizeof(int)));
}
public static void AssertShowHex(this XElement element, uint value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(uint)));
element.AssertShow("0x" + value.ToString("x" + 2 * sizeof(uint)));
}
public static void AssertShowHex(this XElement element, long value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(long)));
element.AssertShow("0x" + value.ToString("x" + 2 * sizeof(long)));
}
public static void AssertShowHex(this XElement element, ulong value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(ulong)));
element.AssertShow("0x" + value.ToString("x" + 2 * sizeof(ulong)));
}
public static void AssertValue(this XElement element, string value)
{
Assert.AreEqual(element.Value(), value, element.Name());
}
public static void AssertValue(this XElement element, IEnumerable<byte> bytes)
{
element.AssertValue(bytes.BytesSequenceToHexadecimalString());
}
}
}
\ No newline at end of file
......@@ -28,6 +28,7 @@ void PacketCommunicator::DataLink::set(PcapDataLink value)
ReadOnlyCollection<PcapDataLink>^ PacketCommunicator::SupportedDataLinks::get()
{
throw gcnew NotSupportedException("Supported DataLinks is unsupported to avoid winpcap memory leak");
// pcap_free_datalinks(NULL);
/*
int* dataLinks;
int numDatalinks = pcap_list_datalinks(_pcapDescriptor, &dataLinks);
......
......@@ -83,103 +83,28 @@ namespace PcapDotNet.Packets.Test
{
IcmpLayer icmpLayer = random.NextIcmpLayer();
icmpLayer.Checksum = null;
IpV4Layer icmpIpV4Layer = null;
IEnumerable<ILayer> icmpIpV4PayloadLayers = null;
switch (icmpLayer.MessageType)
{
case IcmpMessageType.DestinationUnreachable:
case IcmpMessageType.TimeExceeded:
case IcmpMessageType.ParameterProblem:
case IcmpMessageType.SourceQuench:
case IcmpMessageType.Redirect:
case IcmpMessageType.SecurityFailures:
icmpIpV4Layer = random.NextIpV4Layer();
icmpIpV4PayloadLayers = new[] {random.NextPayloadLayer(IcmpIpV4HeaderPlus64BitsPayloadDatagram.OriginalDatagramPayloadLength)};
break;
case IcmpMessageType.ConversionFailed:
icmpIpV4Layer = random.NextIpV4Layer();
if (icmpLayer.MessageTypeAndCode == IcmpMessageTypeAndCode.ConversionFailedUnsupportedTransportProtocol)
icmpIpV4PayloadLayers = new[]
{
random.NextPayloadLayer(
IcmpConversionFailedDatagram.OriginalDatagramLengthForUnsupportedTransportProtocol -
icmpIpV4Layer.Length)
};
else
if (icmpLayer.MessageType == IcmpMessageType.DestinationUnreachable &&
icmpLayer.MessageTypeAndCode != IcmpMessageTypeAndCode.DestinationUnreachableFragmentationNeededAndDontFragmentSet)
{
switch (icmpIpV4Layer.Protocol)
{
case IpV4Protocol.Udp:
icmpIpV4PayloadLayers = new ILayer[]
{
random.NextUdpLayer(),
random.NextPayloadLayer(random.Next(100))
};
break;
case IpV4Protocol.Tcp:
icmpIpV4PayloadLayers = new ILayer[]
{
random.NextTcpLayer(),
random.NextPayloadLayer(random.Next(100))
};
break;
default:
icmpIpV4PayloadLayers = new[]
{
random.NextPayloadLayer(random.Next(200))
};
break;
((IcmpDestinationUnreachableLayer)icmpLayer).NextHopMtu = 0;
}
}
break;
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.DomainNameRequest:
break;
case IcmpMessageType.DomainNameReply:
default:
throw new InvalidOperationException("Invalid icmpMessageType " + icmpLayer.MessageType);
}
IEnumerable<ILayer> icmpPayloadLayers = random.NextIcmpPayloadLayers(icmpLayer);
int icmpPayloadLength = (icmpIpV4Layer != null ? icmpIpV4Layer.Length + icmpIpV4PayloadLayers.Select(layer => layer.Length).Sum() : 0);
int icmpPayloadLength = icmpPayloadLayers.Select(layer => layer.Length).Sum();
switch (icmpLayer.MessageType)
{
// case IcmpMessageType.DestinationUnreachable:
// case IcmpMessageType.TimeExceeded:
case IcmpMessageType.ParameterProblem:
((IcmpParameterProblemLayer)icmpLayer).Pointer %= (byte)icmpPayloadLength;
break;
// case IcmpMessageType.SourceQuench:
// case IcmpMessageType.Redirect:
case IcmpMessageType.SecurityFailures:
((IcmpSecurityFailuresLayer)icmpLayer).Pointer %= (ushort)icmpPayloadLength;
// icmpIpV4Layer = random.NextIpV4Layer();
// icmpIpV4PayloadLayers = new[] {random.NextPayloadLayer(IcmpIpV4HeaderPlus64BitsPayloadDatagram.OriginalDatagramPayloadLength)};
break;
// case IcmpMessageType.ConversionFailed:
}
PacketBuilder packetBuilder;
if (icmpIpV4Layer != null)
packetBuilder = new PacketBuilder(new ILayer[] {ethernetLayer, ipV4Layer, icmpLayer, icmpIpV4Layer}.Concat(icmpIpV4PayloadLayers));
else
packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer);
PacketBuilder packetBuilder = new PacketBuilder(new ILayer[] { ethernetLayer, ipV4Layer, icmpLayer }.Concat(icmpPayloadLayers));
Packet packet = packetBuilder.Build(DateTime.Now);
Assert.IsTrue(packet.IsValid, "IsValid");
......@@ -221,6 +146,7 @@ namespace PcapDotNet.Packets.Test
IcmpLayer actualIcmpLayer = (IcmpLayer)actualIcmp.ExtractLayer();
icmpLayer.Checksum = actualIcmpLayer.Checksum;
Assert.AreEqual(icmpLayer, actualIcmpLayer);
if (actualIcmpLayer.MessageType != IcmpMessageType.RouterSolicitation)
Assert.AreNotEqual(random.NextIcmpLayer(), actualIcmpLayer);
Assert.IsTrue(actualIcmp.IsChecksumCorrect);
Assert.AreEqual(icmpLayer.MessageType, actualIcmp.MessageType);
......@@ -231,13 +157,13 @@ namespace PcapDotNet.Packets.Test
switch (packet.Ethernet.IpV4.Icmp.MessageType)
{
case IcmpMessageType.DestinationUnreachable:
case IcmpMessageType.RouterSolicitation:
case IcmpMessageType.SourceQuench:
case IcmpMessageType.TimeExceeded:
Assert.AreEqual<uint>(0, actualIcmp.Variable);
break;
case IcmpMessageType.DestinationUnreachable:
case IcmpMessageType.ParameterProblem:
case IcmpMessageType.Redirect:
case IcmpMessageType.ConversionFailed:
......@@ -257,7 +183,6 @@ namespace PcapDotNet.Packets.Test
case IcmpMessageType.DomainNameRequest:
case IcmpMessageType.SecurityFailures:
break;
break;
case IcmpMessageType.DomainNameReply:
default:
......
......@@ -128,8 +128,8 @@ namespace PcapDotNet.Packets.TestUtils
Identification = random.NextUShort(),
Ttl = random.NextByte(),
Protocol = protocol,
HeaderChecksum = random.NextUShort(),
Fragmentation = random.NextIpV4Fragmentation(),
HeaderChecksum = random.NextBool() ? (ushort?)random.NextUShort() : null,
Fragmentation = random.NextBool() ? random.NextIpV4Fragmentation() : IpV4Fragmentation.None,
Source = random.NextIpV4Address(),
Destination = random.NextIpV4Address(),
Options = random.NextIpV4Options()
......@@ -576,6 +576,7 @@ namespace PcapDotNet.Packets.TestUtils
public static IcmpLayer NextIcmpLayer(this Random random)
{
IcmpMessageType icmpMessageType = random.NextEnum(IcmpMessageType.DomainNameReply);
ushort? checksum = random.NextBool() ? (ushort?)random.NextUShort() : null;
switch (icmpMessageType)
{
......@@ -583,41 +584,42 @@ namespace PcapDotNet.Packets.TestUtils
return new IcmpDestinationUnreachableLayer
{
Code = random.NextEnum<IcmpCodeDestinationUnrechable>(),
Checksum = random.NextUShort(),
Checksum = checksum,
NextHopMtu = random.NextUShort(),
};
case IcmpMessageType.TimeExceeded:
return new IcmpTimeExceededLayer
{
Code = random.NextEnum<IcmpCodeTimeExceeded>(),
Checksum = random.NextUShort(),
Checksum = checksum,
};
case IcmpMessageType.ParameterProblem:
return new IcmpParameterProblemLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Pointer = random.NextByte()
};
case IcmpMessageType.SourceQuench:
return new IcmpSourceQuenchLayer
{
Checksum = random.NextUShort(),
Checksum = checksum
};
case IcmpMessageType.Redirect:
return new IcmpRedirectLayer
{
Code = random.NextEnum<IcmpCodeRedirect>(),
Checksum = random.NextUShort(),
Checksum = checksum,
GatewayInternetAddress = random.NextIpV4Address()
};
case IcmpMessageType.Echo:
return new IcmpEchoLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort()
};
......@@ -625,7 +627,7 @@ namespace PcapDotNet.Packets.TestUtils
case IcmpMessageType.EchoReply:
return new IcmpEchoReplyLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort()
};
......@@ -634,7 +636,7 @@ namespace PcapDotNet.Packets.TestUtils
case IcmpMessageType.Timestamp:
return new IcmpTimestampLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
OriginateTimestamp = random.NextIpV4TimeOfDay(),
......@@ -645,7 +647,7 @@ namespace PcapDotNet.Packets.TestUtils
case IcmpMessageType.TimestampReply:
return new IcmpTimestampReplyLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
OriginateTimestamp = random.NextIpV4TimeOfDay(),
......@@ -656,7 +658,7 @@ namespace PcapDotNet.Packets.TestUtils
case IcmpMessageType.InformationRequest:
return new IcmpInformationRequestLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
};
......@@ -664,7 +666,7 @@ namespace PcapDotNet.Packets.TestUtils
case IcmpMessageType.InformationReply:
return new IcmpInformationReplyLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
};
......@@ -673,7 +675,7 @@ namespace PcapDotNet.Packets.TestUtils
case IcmpMessageType.RouterAdvertisement:
return new IcmpRouterAdvertisementLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Lifetime = random.NextTimeSpan(TimeSpan.Zero, TimeSpan.FromSeconds(ushort.MaxValue)),
Entries = random.NextIcmpRouterAdvertisementEntries(random.Next(10)).ToList()
};
......@@ -681,13 +683,13 @@ namespace PcapDotNet.Packets.TestUtils
case IcmpMessageType.RouterSolicitation:
return new IcmpRouterSolicitationLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
};
case IcmpMessageType.AddressMaskRequest:
return new IcmpAddressMaskRequestLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
AddressMask = random.NextIpV4Address()
......@@ -696,7 +698,7 @@ namespace PcapDotNet.Packets.TestUtils
case IcmpMessageType.AddressMaskReply:
return new IcmpAddressMaskReplyLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
AddressMask = random.NextIpV4Address()
......@@ -706,7 +708,7 @@ namespace PcapDotNet.Packets.TestUtils
return new IcmpTracerouteLayer
{
Code = random.NextEnum<IcmpCodeTraceroute>(),
Checksum = random.NextUShort(),
Checksum = checksum,
Identification = random.NextUShort(),
OutboundHopCount = random.NextUShort(),
ReturnHopCount = random.NextUShort(),
......@@ -718,14 +720,14 @@ namespace PcapDotNet.Packets.TestUtils
return new IcmpConversionFailedLayer
{
Code = random.NextEnum<IcmpCodeConversionFailed>(),
Checksum = random.NextUShort(),
Checksum = checksum,
Pointer = random.NextUInt(),
};
case IcmpMessageType.DomainNameRequest:
return new IcmpDomainNameRequestLayer
{
Checksum = random.NextUShort(),
Checksum = checksum,
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
};
......@@ -737,7 +739,7 @@ namespace PcapDotNet.Packets.TestUtils
return new IcmpSecurityFailuresLayer
{
Code = random.NextEnum<IcmpCodeSecurityFailures>(),
Checksum = random.NextUShort(),
Checksum = checksum,
Pointer = random.NextUShort()
};
......@@ -747,6 +749,73 @@ namespace PcapDotNet.Packets.TestUtils
}
public static IEnumerable<ILayer> NextIcmpPayloadLayers(this Random random, IcmpLayer icmpLayer)
{
IEnumerable<ILayer> icmpPayloadLayers = new List<ILayer>();
switch (icmpLayer.MessageType)
{
case IcmpMessageType.DestinationUnreachable:
case IcmpMessageType.TimeExceeded:
case IcmpMessageType.ParameterProblem:
case IcmpMessageType.SourceQuench:
case IcmpMessageType.Redirect:
case IcmpMessageType.SecurityFailures:
icmpPayloadLayers = icmpPayloadLayers.Concat(random.NextIpV4Layer(), random.NextPayloadLayer(IcmpIpV4HeaderPlus64BitsPayloadDatagram.OriginalDatagramPayloadLength));
break;
case IcmpMessageType.ConversionFailed:
IpV4Layer icmpIpV4Layer = random.NextIpV4Layer();
icmpPayloadLayers = icmpPayloadLayers.Concat(icmpIpV4Layer);
if (icmpLayer.MessageTypeAndCode == IcmpMessageTypeAndCode.ConversionFailedUnsupportedTransportProtocol)
{
icmpPayloadLayers =
icmpPayloadLayers.Concat(random.NextPayloadLayer(
IcmpConversionFailedDatagram.OriginalDatagramLengthForUnsupportedTransportProtocol -
icmpIpV4Layer.Length));
}
else
{
switch (icmpIpV4Layer.Protocol)
{
case IpV4Protocol.Udp:
icmpPayloadLayers = icmpPayloadLayers.Concat(random.NextUdpLayer(),
random.NextPayloadLayer(random.Next(100)));
break;
case IpV4Protocol.Tcp:
icmpPayloadLayers = icmpPayloadLayers.Concat(random.NextTcpLayer(),
random.NextPayloadLayer(random.Next(100)));
break;
default:
icmpPayloadLayers = icmpPayloadLayers.Concat(random.NextPayloadLayer(random.Next(200)));
break;
}
}
break;
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.DomainNameRequest:
break;
case IcmpMessageType.DomainNameReply:
default:
throw new InvalidOperationException("Invalid icmpMessageType " + icmpLayer.MessageType);
}
return icmpPayloadLayers;
}
public static IEnumerable<IcmpRouterAdvertisementEntry> NextIcmpRouterAdvertisementEntries(this Random random, int numEntries)
{
for (int i = 0; i != numEntries; ++i)
......
......@@ -4,37 +4,55 @@ using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792.
/// RFC 792 and RFC 1191.
/// <pre>
/// +-----+------+------+-----------+
/// +-----+------+------+--------------+
/// | Bit | 0-7 | 8-15 | 16-31 |
/// +-----+------+------+-----------+
/// +-----+------+------+--------------+
/// | 0 | Type | Code | Checksum |
/// +-----+------+------+-----------+
/// | 32 | unused |
/// +-----+-------------------------+
/// +-----+------+------+--------------+
/// | 32 | unused | Next-Hop MTU |
/// +-----+-------------+--------------+
/// | 64 | Internet Header |
/// | | + 64 bits of |
/// | | Original Data Datagram |
/// +-----+-------------------------+
/// +-----+----------------------------+
/// </pre>
/// </summary>
public class IcmpDestinationUnreachableDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
private static class Offset
{
public const int NextHopMtu = 6;
}
public IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
public ushort NextHopMtu
{
get { return ReadUShort(Offset.NextHopMtu, Endianity.Big); }
}
public override ILayer ExtractLayer()
{
return new IcmpDestinationUnreachableLayer
{
Code = (IcmpCodeDestinationUnrechable)Code,
Checksum = Checksum
Checksum = Checksum,
NextHopMtu = NextHopMtu,
};
}
protected override bool CalculateIsValid()
{
return base.CalculateIsValid() &&
(((IcmpCodeDestinationUnrechable)Code == IcmpCodeDestinationUnrechable.FragmentationNeededAndDontFragmentSet) ||
NextHopMtu == 0);
}
protected override byte MinCodeValue
{
get { return _minCode; }
......
......@@ -13,5 +13,23 @@ namespace PcapDotNet.Packets.Icmp
{
get { return (byte)Code; }
}
public ushort NextHopMtu { get; set; }
public bool Equals(IcmpDestinationUnreachableLayer other)
{
return other != null &&
NextHopMtu == other.NextHopMtu;
}
public override sealed bool Equals(IcmpLayer other)
{
return base.Equals(other) && Equals(other as IcmpDestinationUnreachableLayer);
}
protected override uint Value
{
get { return NextHopMtu; }
}
}
}
\ No newline at end of file
......@@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Icmp
{
}
protected IpV4Datagram IpV4
public IpV4Datagram IpV4
{
get
{
......
......@@ -28,7 +28,7 @@ namespace PcapDotNet.Packets.Icmp
/// Codes 2 and 3 may be received from a host.
/// </para>
/// </summary>
DestinationUnreachable = 3,
DestinationUnreachable = 0x03,
/// <summary>
/// RFC 792.
......
......@@ -11,6 +11,11 @@ namespace PcapDotNet.Packets
return new PacketBuilder(layers).Build(timestamp);
}
public static Packet Build(DateTime timestamp, IEnumerable<ILayer> layers)
{
return new PacketBuilder(layers).Build(timestamp);
}
public PacketBuilder(params ILayer[] layers)
{
if (layers.Length == 0)
......
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