Commit 7ea0becf authored by Brickner_cp's avatar Brickner_cp

ICMP wireshark tests

parent 2eef92c2
...@@ -111,6 +111,11 @@ namespace PcapDotNet.Base ...@@ -111,6 +111,11 @@ namespace PcapDotNet.Base
}); });
} }
public static string BytesSequenceToHexadecimalString(this IEnumerable<byte> sequence)
{
return sequence.BytesSequenceToHexadecimalString(string.Empty);
}
/// <summary> /// <summary>
/// Creates a hash code by xoring the hash codes of the elements in the sequence. /// Creates a hash code by xoring the hash codes of the elements in the sequence.
/// </summary> /// </summary>
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
<Compile Include="LivePacketDeviceTests.cs" /> <Compile Include="LivePacketDeviceTests.cs" />
<Compile Include="MoreIpV4Option.cs" /> <Compile Include="MoreIpV4Option.cs" />
<Compile Include="MoreTcpOption.cs" /> <Compile Include="MoreTcpOption.cs" />
<Compile Include="MoreXElement.cs" /> <Compile Include="XElementExtensions.cs" />
<Compile Include="PacketDumpFileTests.cs" /> <Compile Include="PacketDumpFileTests.cs" />
<Compile Include="PacketHandler.cs" /> <Compile Include="PacketHandler.cs" />
<Compile Include="OfflinePacketDeviceTests.cs" /> <Compile Include="OfflinePacketDeviceTests.cs" />
......
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Base;
namespace PcapDotNet.Core.Test namespace PcapDotNet.Core.Test
{ {
internal static class MoreXElement internal static class XElementExtensions
{ {
public static IEnumerable<XElement> Fields(this XElement element) public static IEnumerable<XElement> Fields(this XElement element)
{ {
return element.Elements("field"); 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) public static string Name(this XElement element)
{ {
return element.Attribute("name").Value; return element.GetAttributeValue("name");
} }
public static string Show(this XElement element) public static string Show(this XElement element)
{ {
return element.Attribute("show").Value; return element.GetAttributeValue("show");
} }
public static string Value(this XElement element) 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) 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) public static void AssertShowDecimal(this XElement element, bool value)
...@@ -38,72 +59,82 @@ namespace PcapDotNet.Core.Test ...@@ -38,72 +59,82 @@ namespace PcapDotNet.Core.Test
public static void AssertShowDecimal(this XElement element, byte value) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) ...@@ -28,6 +28,7 @@ void PacketCommunicator::DataLink::set(PcapDataLink value)
ReadOnlyCollection<PcapDataLink>^ PacketCommunicator::SupportedDataLinks::get() ReadOnlyCollection<PcapDataLink>^ PacketCommunicator::SupportedDataLinks::get()
{ {
throw gcnew NotSupportedException("Supported DataLinks is unsupported to avoid winpcap memory leak"); throw gcnew NotSupportedException("Supported DataLinks is unsupported to avoid winpcap memory leak");
// pcap_free_datalinks(NULL);
/* /*
int* dataLinks; int* dataLinks;
int numDatalinks = pcap_list_datalinks(_pcapDescriptor, &dataLinks); int numDatalinks = pcap_list_datalinks(_pcapDescriptor, &dataLinks);
......
...@@ -83,103 +83,28 @@ namespace PcapDotNet.Packets.Test ...@@ -83,103 +83,28 @@ namespace PcapDotNet.Packets.Test
{ {
IcmpLayer icmpLayer = random.NextIcmpLayer(); IcmpLayer icmpLayer = random.NextIcmpLayer();
icmpLayer.Checksum = null; icmpLayer.Checksum = null;
if (icmpLayer.MessageType == IcmpMessageType.DestinationUnreachable &&
IpV4Layer icmpIpV4Layer = null; icmpLayer.MessageTypeAndCode != IcmpMessageTypeAndCode.DestinationUnreachableFragmentationNeededAndDontFragmentSet)
IEnumerable<ILayer> icmpIpV4PayloadLayers = null;
switch (icmpLayer.MessageType)
{ {
case IcmpMessageType.DestinationUnreachable: ((IcmpDestinationUnreachableLayer)icmpLayer).NextHopMtu = 0;
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
{
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;
}
}
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);
} }
int icmpPayloadLength = (icmpIpV4Layer != null ? icmpIpV4Layer.Length + icmpIpV4PayloadLayers.Select(layer => layer.Length).Sum() : 0); IEnumerable<ILayer> icmpPayloadLayers = random.NextIcmpPayloadLayers(icmpLayer);
int icmpPayloadLength = icmpPayloadLayers.Select(layer => layer.Length).Sum();
switch (icmpLayer.MessageType) switch (icmpLayer.MessageType)
{ {
// case IcmpMessageType.DestinationUnreachable:
// case IcmpMessageType.TimeExceeded:
case IcmpMessageType.ParameterProblem: case IcmpMessageType.ParameterProblem:
((IcmpParameterProblemLayer)icmpLayer).Pointer %= (byte)icmpPayloadLength; ((IcmpParameterProblemLayer)icmpLayer).Pointer %= (byte)icmpPayloadLength;
break; break;
// case IcmpMessageType.SourceQuench:
// case IcmpMessageType.Redirect:
case IcmpMessageType.SecurityFailures: case IcmpMessageType.SecurityFailures:
((IcmpSecurityFailuresLayer)icmpLayer).Pointer %= (ushort)icmpPayloadLength; ((IcmpSecurityFailuresLayer)icmpLayer).Pointer %= (ushort)icmpPayloadLength;
// icmpIpV4Layer = random.NextIpV4Layer();
// icmpIpV4PayloadLayers = new[] {random.NextPayloadLayer(IcmpIpV4HeaderPlus64BitsPayloadDatagram.OriginalDatagramPayloadLength)};
break; break;
// case IcmpMessageType.ConversionFailed:
} }
PacketBuilder packetBuilder; PacketBuilder packetBuilder = new PacketBuilder(new ILayer[] { ethernetLayer, ipV4Layer, icmpLayer }.Concat(icmpPayloadLayers));
if (icmpIpV4Layer != null)
packetBuilder = new PacketBuilder(new ILayer[] {ethernetLayer, ipV4Layer, icmpLayer, icmpIpV4Layer}.Concat(icmpIpV4PayloadLayers));
else
packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer);
Packet packet = packetBuilder.Build(DateTime.Now); Packet packet = packetBuilder.Build(DateTime.Now);
Assert.IsTrue(packet.IsValid, "IsValid"); Assert.IsTrue(packet.IsValid, "IsValid");
...@@ -221,7 +146,8 @@ namespace PcapDotNet.Packets.Test ...@@ -221,7 +146,8 @@ namespace PcapDotNet.Packets.Test
IcmpLayer actualIcmpLayer = (IcmpLayer)actualIcmp.ExtractLayer(); IcmpLayer actualIcmpLayer = (IcmpLayer)actualIcmp.ExtractLayer();
icmpLayer.Checksum = actualIcmpLayer.Checksum; icmpLayer.Checksum = actualIcmpLayer.Checksum;
Assert.AreEqual(icmpLayer, actualIcmpLayer); Assert.AreEqual(icmpLayer, actualIcmpLayer);
Assert.AreNotEqual(random.NextIcmpLayer(), actualIcmpLayer); if (actualIcmpLayer.MessageType != IcmpMessageType.RouterSolicitation)
Assert.AreNotEqual(random.NextIcmpLayer(), actualIcmpLayer);
Assert.IsTrue(actualIcmp.IsChecksumCorrect); Assert.IsTrue(actualIcmp.IsChecksumCorrect);
Assert.AreEqual(icmpLayer.MessageType, actualIcmp.MessageType); Assert.AreEqual(icmpLayer.MessageType, actualIcmp.MessageType);
Assert.AreEqual(icmpLayer.CodeValue, actualIcmp.Code); Assert.AreEqual(icmpLayer.CodeValue, actualIcmp.Code);
...@@ -231,13 +157,13 @@ namespace PcapDotNet.Packets.Test ...@@ -231,13 +157,13 @@ namespace PcapDotNet.Packets.Test
switch (packet.Ethernet.IpV4.Icmp.MessageType) switch (packet.Ethernet.IpV4.Icmp.MessageType)
{ {
case IcmpMessageType.DestinationUnreachable:
case IcmpMessageType.RouterSolicitation: case IcmpMessageType.RouterSolicitation:
case IcmpMessageType.SourceQuench: case IcmpMessageType.SourceQuench:
case IcmpMessageType.TimeExceeded: case IcmpMessageType.TimeExceeded:
Assert.AreEqual<uint>(0, actualIcmp.Variable); Assert.AreEqual<uint>(0, actualIcmp.Variable);
break; break;
case IcmpMessageType.DestinationUnreachable:
case IcmpMessageType.ParameterProblem: case IcmpMessageType.ParameterProblem:
case IcmpMessageType.Redirect: case IcmpMessageType.Redirect:
case IcmpMessageType.ConversionFailed: case IcmpMessageType.ConversionFailed:
...@@ -257,7 +183,6 @@ namespace PcapDotNet.Packets.Test ...@@ -257,7 +183,6 @@ namespace PcapDotNet.Packets.Test
case IcmpMessageType.DomainNameRequest: case IcmpMessageType.DomainNameRequest:
case IcmpMessageType.SecurityFailures: case IcmpMessageType.SecurityFailures:
break; break;
break;
case IcmpMessageType.DomainNameReply: case IcmpMessageType.DomainNameReply:
default: default:
......
...@@ -4,37 +4,55 @@ using PcapDotNet.Base; ...@@ -4,37 +4,55 @@ using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary> /// <summary>
/// RFC 792. /// RFC 792 and RFC 1191.
/// <pre> /// <pre>
/// +-----+------+------+-----------+ /// +-----+------+------+--------------+
/// | Bit | 0-7 | 8-15 | 16-31 | /// | Bit | 0-7 | 8-15 | 16-31 |
/// +-----+------+------+-----------+ /// +-----+------+------+--------------+
/// | 0 | Type | Code | Checksum | /// | 0 | Type | Code | Checksum |
/// +-----+------+------+-----------+ /// +-----+------+------+--------------+
/// | 32 | unused | /// | 32 | unused | Next-Hop MTU |
/// +-----+-------------------------+ /// +-----+-------------+--------------+
/// | 64 | Internet Header | /// | 64 | Internet Header |
/// | | + 64 bits of | /// | | + 64 bits of |
/// | | Original Data Datagram | /// | | Original Data Datagram |
/// +-----+-------------------------+ /// +-----+----------------------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
public class IcmpDestinationUnreachableDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram public class IcmpDestinationUnreachableDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{ {
private static class Offset
{
public const int NextHopMtu = 6;
}
public IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length) public IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length) : base(buffer, offset, length)
{ {
} }
public ushort NextHopMtu
{
get { return ReadUShort(Offset.NextHopMtu, Endianity.Big); }
}
public override ILayer ExtractLayer() public override ILayer ExtractLayer()
{ {
return new IcmpDestinationUnreachableLayer return new IcmpDestinationUnreachableLayer
{ {
Code = (IcmpCodeDestinationUnrechable)Code, 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 protected override byte MinCodeValue
{ {
get { return _minCode; } get { return _minCode; }
......
...@@ -13,5 +13,23 @@ namespace PcapDotNet.Packets.Icmp ...@@ -13,5 +13,23 @@ namespace PcapDotNet.Packets.Icmp
{ {
get { return (byte)Code; } 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 ...@@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Icmp
{ {
} }
protected IpV4Datagram IpV4 public IpV4Datagram IpV4
{ {
get get
{ {
......
...@@ -28,7 +28,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -28,7 +28,7 @@ namespace PcapDotNet.Packets.Icmp
/// Codes 2 and 3 may be received from a host. /// Codes 2 and 3 may be received from a host.
/// </para> /// </para>
/// </summary> /// </summary>
DestinationUnreachable = 3, DestinationUnreachable = 0x03,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
......
...@@ -11,6 +11,11 @@ namespace PcapDotNet.Packets ...@@ -11,6 +11,11 @@ namespace PcapDotNet.Packets
return new PacketBuilder(layers).Build(timestamp); 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) public PacketBuilder(params ILayer[] layers)
{ {
if (layers.Length == 0) 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