Commit 8dcb5280 authored by Brickner_cp's avatar Brickner_cp

Fixed ICMP message types values for AddressMaskRequest and AddressMaskReply.

Added IGMP message type MulticastTracerouteResponse.
Added automatic IP ethernet type if IPv4 layer comes after Ethernet layer.
Code Coverage 95.25%
parent 3c7a3d78
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace PcapDotNet.Base.Test
{
/// Summary description for DictionaryExtensionsTests
/// </summary>
[TestClass]
// ReSharper disable InconsistentNaming
public class IDictionaryExtensionsTests
// ReSharper restore InconsistentNaming
{
/// <summary>
/// Gets or sets the test context which provides
/// information about and functionality for the current test run.
/// </summary>
public TestContext TestContext { get; set; }
#region Additional test attributes
//
// You can use the following additional attributes as you write your tests:
//
// Use ClassInitialize to run code before running the first test in the class
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext testContext) { }
//
// Use ClassCleanup to run code after all tests in a class have run
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// Use TestInitialize to run code before running each test
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// Use TestCleanup to run code after each test has run
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion
[TestMethod]
public void DictionaryEqualsTest()
{
// Both null
Dictionary<int, int> dic1 = null;
Dictionary<int, int> dic2 = null;
Assert.IsTrue(dic1.DictionaryEquals(dic2));
Assert.IsTrue(dic2.DictionaryEquals(dic1));
// One null
dic1 = new Dictionary<int, int>();
Assert.IsFalse(dic1.DictionaryEquals(dic2));
Assert.IsFalse(dic2.DictionaryEquals(dic1));
// Both empty
dic2 = new Dictionary<int, int>();
Assert.IsTrue(dic1.DictionaryEquals(dic2));
Assert.IsTrue(dic2.DictionaryEquals(dic1));
// Different count
dic1.Add(1,1);
Assert.IsFalse(dic1.DictionaryEquals(dic2));
Assert.IsFalse(dic2.DictionaryEquals(dic1));
// Different key
dic2.Add(2, 1);
Assert.IsFalse(dic1.DictionaryEquals(dic2));
Assert.IsFalse(dic2.DictionaryEquals(dic1));
// Different value
dic1.Add(2, 1);
dic2.Add(1, 2);
Assert.IsFalse(dic1.DictionaryEquals(dic2));
Assert.IsFalse(dic2.DictionaryEquals(dic1));
}
}
}
\ No newline at end of file
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
<Reference Include="System.Numerics" /> <Reference Include="System.Numerics" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="IDictionaryExtensionsTests.cs" />
<Compile Include="FuncExtensionsTest.cs" /> <Compile Include="FuncExtensionsTest.cs" />
<Compile Include="IEnumerableExtensionsTests.cs" /> <Compile Include="IEnumerableExtensionsTests.cs" />
<Compile Include="MemberInfoExtensionsTests.cs" /> <Compile Include="MemberInfoExtensionsTests.cs" />
......
...@@ -6,8 +6,11 @@ namespace PcapDotNet.Base ...@@ -6,8 +6,11 @@ namespace PcapDotNet.Base
{ {
public static bool DictionaryEquals<TKey, TValue>(this IDictionary<TKey, TValue> dictionary1, IDictionary<TKey, TValue> dictionary2, IEqualityComparer<TValue> valueComparer) public static bool DictionaryEquals<TKey, TValue>(this IDictionary<TKey, TValue> dictionary1, IDictionary<TKey, TValue> dictionary2, IEqualityComparer<TValue> valueComparer)
{ {
if (ReferenceEquals(dictionary1, dictionary2))
return true;
if (dictionary1 == null || dictionary2 == null) if (dictionary1 == null || dictionary2 == null)
return dictionary1 == null && dictionary2 == null; return false;
if (dictionary1.Count != dictionary2.Count) if (dictionary1.Count != dictionary2.Count)
return false; return false;
......
...@@ -158,7 +158,7 @@ namespace PcapDotNet.Core.Test ...@@ -158,7 +158,7 @@ namespace PcapDotNet.Core.Test
TestReceivePackets(NumPacketsToSend, NumPacketsToSend, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.063); TestReceivePackets(NumPacketsToSend, NumPacketsToSend, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend, 0, 0.063);
// Wait for less packets // Wait for less packets
TestReceivePackets(NumPacketsToSend, NumPacketsToSend / 2, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend / 2, 0, 0.02); TestReceivePackets(NumPacketsToSend, NumPacketsToSend / 2, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.Ok, NumPacketsToSend / 2, 0, 0.027);
// Wait for more packets // Wait for more packets
TestReceivePackets(NumPacketsToSend, 0, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.None, NumPacketsToSend, 2, 2.14); TestReceivePackets(NumPacketsToSend, 0, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.None, NumPacketsToSend, 2, 2.14);
......
...@@ -35,7 +35,7 @@ namespace PcapDotNet.Core.Test ...@@ -35,7 +35,7 @@ namespace PcapDotNet.Core.Test
private const bool IsRetry private const bool IsRetry
// = true; // = true;
= false; = false;
private const byte RetryNumber = 101; private const byte RetryNumber = 61;
/// <summary> /// <summary>
/// Gets or sets the test context which provides /// Gets or sets the test context which provides
...@@ -68,10 +68,17 @@ namespace PcapDotNet.Core.Test ...@@ -68,10 +68,17 @@ namespace PcapDotNet.Core.Test
[TestMethod] [TestMethod]
public void ComparePacketsToWiresharkTest() public void ComparePacketsToWiresharkTest()
{ {
if (IsRetry)
{
ComparePacketsToWireshark(null);
return;
}
Random random = new Random();
for (int i = 0; i != 10; ++i) for (int i = 0; i != 10; ++i)
{ {
// Create packets // Create packets
List<Packet> packets = new List<Packet>(CreateRandomPackets(200)); List<Packet> packets = new List<Packet>(CreateRandomPackets(random, 200));
// Compare packets to wireshark // Compare packets to wireshark
ComparePacketsToWireshark(packets); ComparePacketsToWireshark(packets);
...@@ -125,6 +132,7 @@ namespace PcapDotNet.Core.Test ...@@ -125,6 +132,7 @@ namespace PcapDotNet.Core.Test
Ethernet, Ethernet,
Arp, Arp,
IpV4, IpV4,
IpV4OverIpV4,
Igmp, Igmp,
Icmp, Icmp,
Gre, Gre,
...@@ -145,18 +153,25 @@ namespace PcapDotNet.Core.Test ...@@ -145,18 +153,25 @@ namespace PcapDotNet.Core.Test
PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100)); PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100));
switch (random.NextEnum<PacketType>()) switch (random.NextEnum<PacketType>())
// switch (PacketType.Http) // switch (PacketType.IpV4OverIpV4)
{ {
case PacketType.Ethernet: case PacketType.Ethernet:
return PacketBuilder.Build(DateTime.Now, ethernetLayer, payloadLayer); return PacketBuilder.Build(DateTime.Now, ethernetLayer, payloadLayer);
case PacketType.Arp: case PacketType.Arp:
ethernetLayer.EtherType = EthernetType.None;
ethernetLayer.Destination = MacAddress.Zero; ethernetLayer.Destination = MacAddress.Zero;
return PacketBuilder.Build(packetTimestamp, ethernetLayer, random.NextArpLayer()); return PacketBuilder.Build(packetTimestamp, ethernetLayer, random.NextArpLayer());
case PacketType.IpV4: case PacketType.IpV4:
ethernetLayer.EtherType = EthernetType.None;
return PacketBuilder.Build(packetTimestamp, ethernetLayer, ipV4Layer, payloadLayer); return PacketBuilder.Build(packetTimestamp, ethernetLayer, ipV4Layer, payloadLayer);
case PacketType.IpV4OverIpV4:
ethernetLayer.EtherType = EthernetType.None;
ipV4Layer.Protocol = null;
return PacketBuilder.Build(packetTimestamp, ethernetLayer, ipV4Layer, random.NextIpV4Layer(), payloadLayer);
case PacketType.Igmp: case PacketType.Igmp:
ethernetLayer.EtherType = EthernetType.None; ethernetLayer.EtherType = EthernetType.None;
ipV4Layer.Protocol = null; ipV4Layer.Protocol = null;
...@@ -208,9 +223,8 @@ namespace PcapDotNet.Core.Test ...@@ -208,9 +223,8 @@ namespace PcapDotNet.Core.Test
} }
} }
private static IEnumerable<Packet> CreateRandomPackets(int numPackets) private static IEnumerable<Packet> CreateRandomPackets(Random random, int numPackets)
{ {
Random random = new Random();
for (int i = 0; i != numPackets; ++i) for (int i = 0; i != numPackets; ++i)
yield return CreateRandomPacket(random); yield return CreateRandomPacket(random);
} }
...@@ -770,6 +784,10 @@ namespace PcapDotNet.Core.Test ...@@ -770,6 +784,10 @@ namespace PcapDotNet.Core.Test
// todo support IGMP version 0 and IGMP identifier. // todo support IGMP version 0 and IGMP identifier.
break; break;
case "igmp.mtrace.max_hops":
// todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
break;
default: default:
throw new InvalidOperationException("Invalid igmp field " + field.Name()); throw new InvalidOperationException("Invalid igmp field " + field.Name());
} }
...@@ -1052,18 +1070,24 @@ namespace PcapDotNet.Core.Test ...@@ -1052,18 +1070,24 @@ namespace PcapDotNet.Core.Test
else if (field.Show().StartsWith("Address family: ")) else if (field.Show().StartsWith("Address family: "))
{ {
++currentEntry; ++currentEntry;
if (currentEntry != greDatagram.Routing.Count) if (currentEntry < greDatagram.Routing.Count)
field.AssertValue((ushort)greDatagram.Routing[currentEntry].AddressFamily); field.AssertValue((ushort)greDatagram.Routing[currentEntry].AddressFamily);
else if (currentEntry > greDatagram.Routing.Count)
Assert.IsFalse(greDatagram.IsValid);
} }
else if (field.Show().StartsWith("SRE offset: ")) else if (field.Show().StartsWith("SRE offset: "))
{ {
if (currentEntry != greDatagram.Routing.Count) if (currentEntry < greDatagram.Routing.Count)
field.AssertValue(greDatagram.Routing[currentEntry].PayloadOffset); field.AssertValue(greDatagram.Routing[currentEntry].PayloadOffset);
else if (currentEntry > greDatagram.Routing.Count)
Assert.IsFalse(greDatagram.IsValid);
} }
else if (field.Show().StartsWith("SRE length: ")) else if (field.Show().StartsWith("SRE length: "))
{ {
if (currentEntry != greDatagram.Routing.Count) if (currentEntry < greDatagram.Routing.Count)
field.AssertValue(greDatagram.Routing[currentEntry].PayloadLength); field.AssertValue(greDatagram.Routing[currentEntry].PayloadLength);
else if (currentEntry > greDatagram.Routing.Count)
Assert.IsFalse(greDatagram.IsValid);
} }
else else
{ {
...@@ -1175,7 +1199,14 @@ namespace PcapDotNet.Core.Test ...@@ -1175,7 +1199,14 @@ namespace PcapDotNet.Core.Test
switch (field.Name()) switch (field.Name())
{ {
case "tcp.len": case "tcp.len":
field.AssertShowDecimal(tcpDatagram.Payload.Length); if (tcpDatagram.Payload == null)
{
// todo seems like a bug in tshark https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5235
break;
field.AssertShowDecimal(tcpDatagram.Length);
}
else
field.AssertShowDecimal(tcpDatagram.Payload.Length);
break; break;
case "tcp.srcport": case "tcp.srcport":
...@@ -1297,12 +1328,8 @@ namespace PcapDotNet.Core.Test ...@@ -1297,12 +1328,8 @@ namespace PcapDotNet.Core.Test
if (currentOptionIndex >= options.Count) if (currentOptionIndex >= options.Count)
{ {
Assert.IsFalse(options.IsValid, "Options IsValid"); Assert.IsFalse(options.IsValid, "Options IsValid");
// if (field.Show().StartsWith("Unknown ("))
// {
// int.Parse()
// }
Assert.IsTrue( Assert.IsTrue(
// field.Show().StartsWith("Unknown (") || // Unknown in Wireshark but known (and invalid) in Pcap.Net field.Show().StartsWith("Unknown (0x0a) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net
field.Show().Contains("bytes says option goes past end of options"), "Options show: " + field.Show()); field.Show().Contains("bytes says option goes past end of options"), "Options show: " + field.Show());
Assert.AreEqual(options.Count, currentOptionIndex, "Options Count"); Assert.AreEqual(options.Count, currentOptionIndex, "Options Count");
return; return;
......
...@@ -97,12 +97,12 @@ namespace PcapDotNet.Packets.Test ...@@ -97,12 +97,12 @@ namespace PcapDotNet.Packets.Test
if (httpLayer.Header != null) if (httpLayer.Header != null)
{ {
foreach (var field in httpLayer.Header) foreach (var field in httpLayer.Header)
Assert.AreNotEqual<object>("abc", field); Assert.IsFalse(field.Equals("abc"));
if (httpLayer.Header.ContentType != null) if (httpLayer.Header.ContentType != null)
{ {
var parameters = httpLayer.Header.ContentType.Parameters; var parameters = httpLayer.Header.ContentType.Parameters;
Assert.AreEqual(parameters.Count, parameters.OfType<KeyValuePair<string, string>>().Count()); Assert.IsNotNull(((IEnumerable)parameters).GetEnumerator());
Assert.AreEqual<object>(parameters, httpDatagram.Header.ContentType.Parameters); Assert.AreEqual<object>(parameters, httpDatagram.Header.ContentType.Parameters);
int maxParameterNameLength = parameters.Any() ? parameters.Max(pair => pair.Key.Length) : 0; int maxParameterNameLength = parameters.Any() ? parameters.Max(pair => pair.Key.Length) : 0;
Assert.IsNull(parameters[new string('a', maxParameterNameLength + 1)]); Assert.IsNull(parameters[new string('a', maxParameterNameLength + 1)]);
...@@ -495,6 +495,23 @@ namespace PcapDotNet.Packets.Test ...@@ -495,6 +495,23 @@ namespace PcapDotNet.Packets.Test
Assert.AreEqual(Datagram.Empty, ((HttpResponseDatagram)packet.Ethernet.IpV4.Tcp.Http).ReasonPhrase, "ReasonPhrase"); Assert.AreEqual(Datagram.Empty, ((HttpResponseDatagram)packet.Ethernet.IpV4.Tcp.Http).ReasonPhrase, "ReasonPhrase");
} }
[TestMethod]
public void HttpRequestWithoutUriTest()
{
PacketBuilder builder = new PacketBuilder(new EthernetLayer(),
new IpV4Layer(),
new TcpLayer(),
new HttpRequestLayer
{
Method = new HttpRequestMethod("UnknownMethod")
});
Packet packet = builder.Build(DateTime.Now);
Assert.IsNotNull(((HttpRequestDatagram)packet.Ethernet.IpV4.Tcp.Http).Method);
Assert.AreEqual(HttpRequestKnownMethod.Unknown, ((HttpRequestDatagram)packet.Ethernet.IpV4.Tcp.Http).Method.KnownMethod);
Assert.AreEqual(string.Empty, ((HttpRequestDatagram)packet.Ethernet.IpV4.Tcp.Http).Uri, "Uri");
}
[TestMethod] [TestMethod]
public void HttpBadTransferCodingsRegexTest() public void HttpBadTransferCodingsRegexTest()
{ {
......
...@@ -171,5 +171,12 @@ namespace PcapDotNet.Packets.Test ...@@ -171,5 +171,12 @@ namespace PcapDotNet.Packets.Test
Assert.IsNotNull(new TcpOptionMd5Signature(null)); Assert.IsNotNull(new TcpOptionMd5Signature(null));
Assert.Fail(); Assert.Fail();
} }
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void TcpOptionMoodBadEmotionStringTest()
{
Assert.IsNotNull(new TcpOptionMood((TcpOptionMoodEmotion)202).EmotionString);
}
} }
} }
\ No newline at end of file
...@@ -533,7 +533,8 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -533,7 +533,8 @@ namespace PcapDotNet.Packets.TestUtils
IgmpMessageType.CreateGroupReplyVersion0, IgmpMessageType.JoinGroupRequestVersion0, IgmpMessageType.CreateGroupReplyVersion0, IgmpMessageType.JoinGroupRequestVersion0,
IgmpMessageType.JoinGroupReplyVersion0, IgmpMessageType.LeaveGroupRequestVersion0, IgmpMessageType.JoinGroupReplyVersion0, IgmpMessageType.LeaveGroupRequestVersion0,
IgmpMessageType.LeaveGroupReplyVersion0, IgmpMessageType.ConfirmGroupRequestVersion0, IgmpMessageType.LeaveGroupReplyVersion0, IgmpMessageType.ConfirmGroupRequestVersion0,
IgmpMessageType.ConfirmGroupReplyVersion0); IgmpMessageType.ConfirmGroupReplyVersion0,
IgmpMessageType.MulticastTracerouteResponse); // todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
IgmpQueryVersion igmpQueryVersion = IgmpQueryVersion.None; IgmpQueryVersion igmpQueryVersion = IgmpQueryVersion.None;
TimeSpan igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1), TimeSpan.FromSeconds(256 * 0.1) - TimeSpan.FromTicks(1)); TimeSpan igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1), TimeSpan.FromSeconds(256 * 0.1) - TimeSpan.FromTicks(1));
IpV4Address igmpGroupAddress = random.NextIpV4Address(); IpV4Address igmpGroupAddress = random.NextIpV4Address();
......
...@@ -659,12 +659,12 @@ namespace PcapDotNet.Packets ...@@ -659,12 +659,12 @@ namespace PcapDotNet.Packets
buffer.Write(ref offset, value.MillisecondsSinceMidnightUniversalTime, endianity); buffer.Write(ref offset, value.MillisecondsSinceMidnightUniversalTime, endianity);
} }
public static void WriteCarriageReturnLineFeed(this byte[] buffer, int offset) // public static void WriteCarriageReturnLineFeed(this byte[] buffer, int offset)
{ // {
buffer.Write(ref offset, AsciiBytes.CarriageReturn); // buffer.Write(ref offset, AsciiBytes.CarriageReturn);
buffer.Write(offset, AsciiBytes.LineFeed); // buffer.Write(offset, AsciiBytes.LineFeed);
} // }
//
public static void WriteCarriageReturnLineFeed(this byte[] buffer, ref int offset) public static void WriteCarriageReturnLineFeed(this byte[] buffer, ref int offset)
{ {
buffer.Write(ref offset, AsciiBytes.CarriageReturn); buffer.Write(ref offset, AsciiBytes.CarriageReturn);
......
...@@ -5,6 +5,24 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,6 +5,24 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public enum IcmpMessageType : byte public enum IcmpMessageType : byte
{ {
/// <summary>
/// RFC 792.
/// <para>
/// The data received in the echo message must be returned in the echo reply message.
/// </para>
///
/// <para>
/// The identifier and sequence number may be used by the echo sender to aid in matching the replies with the echo requests.
/// For example, the identifier might be used like a port in TCP or UDP to identify a session, and the sequence number might be incremented on each echo request sent.
/// The echoer returns these same values in the echo reply.
/// </para>
///
/// <para>
/// Code 0 may be received from a gateway or a host.
/// </para>
/// </summary>
EchoReply = 0x00,
/// <summary> /// <summary>
/// RFC 792 /// RFC 792
/// ///
...@@ -33,43 +51,6 @@ namespace PcapDotNet.Packets.Icmp ...@@ -33,43 +51,6 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
DestinationUnreachable = 0x03, DestinationUnreachable = 0x03,
/// <summary>
/// RFC 792.
///
/// <para>
/// If the gateway processing a datagram finds the time to live field is zero it must discard the datagram.
/// The gateway may also notify the source host via the time exceeded message.
/// </para>
///
/// <para>
/// If a host reassembling a fragmented datagram cannot complete the reassembly due to missing fragments within its time limit it discards the datagram,
/// and it may send a time exceeded message.
/// If fragment zero is not available then no time exceeded need be sent at all.
/// </para>
///
/// <para>
/// Code 0 may be received from a gateway.
/// Code 1 may be received from a host.
/// </para>
/// </summary>
TimeExceeded = 0x0B,
/// <summary>
/// RFC 792.
///
/// <para>
/// If the gateway or host processing a datagram finds a problem with the header parameters such that it cannot complete processing the datagram it must discard the datagram.
/// One potential source of such a problem is with incorrect arguments in an option.
/// The gateway or host may also notify the source host via the parameter problem message.
/// This message is only sent if the error caused the datagram to be discarded.
/// </para>
///
/// <para>
/// Code 0 may be received from a gateway or a host.
/// </para>
/// </summary>
ParameterProblem = 0x0C,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// ///
...@@ -136,23 +117,52 @@ namespace PcapDotNet.Packets.Icmp ...@@ -136,23 +117,52 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
Echo = 0x08, Echo = 0x08,
/// <summary>
/// RFC 1256.
/// </summary>
RouterAdvertisement = 0x09,
/// <summary>
/// RFC 1256.
/// </summary>
RouterSolicitation = 0x0A,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
///
/// <para> /// <para>
/// The data received in the echo message must be returned in the echo reply message. /// If the gateway processing a datagram finds the time to live field is zero it must discard the datagram.
/// The gateway may also notify the source host via the time exceeded message.
/// </para> /// </para>
/// ///
/// <para> /// <para>
/// The identifier and sequence number may be used by the echo sender to aid in matching the replies with the echo requests. /// If a host reassembling a fragmented datagram cannot complete the reassembly due to missing fragments within its time limit it discards the datagram,
/// For example, the identifier might be used like a port in TCP or UDP to identify a session, and the sequence number might be incremented on each echo request sent. /// and it may send a time exceeded message.
/// The echoer returns these same values in the echo reply. /// If fragment zero is not available then no time exceeded need be sent at all.
/// </para>
///
/// <para>
/// Code 0 may be received from a gateway.
/// Code 1 may be received from a host.
/// </para>
/// </summary>
TimeExceeded = 0x0B,
/// <summary>
/// RFC 792.
///
/// <para>
/// If the gateway or host processing a datagram finds a problem with the header parameters such that it cannot complete processing the datagram it must discard the datagram.
/// One potential source of such a problem is with incorrect arguments in an option.
/// The gateway or host may also notify the source host via the parameter problem message.
/// This message is only sent if the error caused the datagram to be discarded.
/// </para> /// </para>
/// ///
/// <para> /// <para>
/// Code 0 may be received from a gateway or a host. /// Code 0 may be received from a gateway or a host.
/// </para> /// </para>
/// </summary> /// </summary>
EchoReply = 0x00, ParameterProblem = 0x0C,
/// <summary> /// <summary>
/// RFC 792 /// RFC 792
...@@ -242,16 +252,6 @@ namespace PcapDotNet.Packets.Icmp ...@@ -242,16 +252,6 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
InformationReply = 0x10, InformationReply = 0x10,
/// <summary>
/// RFC 1256.
/// </summary>
RouterAdvertisement = 0x09,
/// <summary>
/// RFC 1256.
/// </summary>
RouterSolicitation = 0x0A,
/// <summary> /// <summary>
/// RFC 950. /// RFC 950.
/// ///
...@@ -267,7 +267,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -267,7 +267,7 @@ namespace PcapDotNet.Packets.Icmp
/// The "Identifier" and "Sequence Number" fields can be ignored. /// The "Identifier" and "Sequence Number" fields can be ignored.
/// </para> /// </para>
/// </summary> /// </summary>
AddressMaskRequest = 0xA1, AddressMaskRequest = 0x11,
/// <summary> /// <summary>
/// RFC 950. /// RFC 950.
...@@ -284,7 +284,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -284,7 +284,7 @@ namespace PcapDotNet.Packets.Icmp
/// The "Identifier" and "Sequence Number" fields can be ignored. /// The "Identifier" and "Sequence Number" fields can be ignored.
/// </para> /// </para>
/// </summary> /// </summary>
AddressMaskReply = 0xA2, AddressMaskReply = 0x12,
/// <summary> /// <summary>
/// RFC 1393. /// RFC 1393.
...@@ -310,7 +310,6 @@ namespace PcapDotNet.Packets.Icmp ...@@ -310,7 +310,6 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
DomainNameReply = 0x26, DomainNameReply = 0x26,
/// <summary> /// <summary>
/// RFC 2521. /// RFC 2521.
/// </summary> /// </summary>
......
...@@ -439,7 +439,8 @@ namespace PcapDotNet.Packets.Igmp ...@@ -439,7 +439,8 @@ namespace PcapDotNet.Packets.Igmp
{ {
if (_sourceAddresses == null) if (_sourceAddresses == null)
{ {
IpV4Address[] sourceAddresses = new IpV4Address[NumberOfSources]; int actualNumberOfSources = Math.Min(NumberOfSources, (Length - Offset.SourceAddresses) / IpV4Address.SizeOf);
IpV4Address[] sourceAddresses = new IpV4Address[actualNumberOfSources];
for (int i = 0; i != sourceAddresses.Length; ++i) for (int i = 0; i != sourceAddresses.Length; ++i)
sourceAddresses[i] = ReadIpV4Address(Offset.SourceAddresses + IpV4Address.SizeOf * i, Endianity.Big); sourceAddresses[i] = ReadIpV4Address(Offset.SourceAddresses + IpV4Address.SizeOf * i, Endianity.Big);
_sourceAddresses = new ReadOnlyCollection<IpV4Address>(sourceAddresses); _sourceAddresses = new ReadOnlyCollection<IpV4Address>(sourceAddresses);
......
...@@ -73,6 +73,8 @@ namespace PcapDotNet.Packets.Igmp ...@@ -73,6 +73,8 @@ namespace PcapDotNet.Packets.Igmp
/// <summary> /// <summary>
/// Version 2 Leave Group (RFC2236). /// Version 2 Leave Group (RFC2236).
/// </summary> /// </summary>
LeaveGroupVersion2 = 0x17 LeaveGroupVersion2 = 0x17,
MulticastTracerouteResponse = 0x1E,
} }
} }
\ No newline at end of file
...@@ -7,7 +7,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -7,7 +7,7 @@ namespace PcapDotNet.Packets.IpV4
/// Represents IPv4 layer. /// Represents IPv4 layer.
/// <seealso cref="IpV4Datagram"/> /// <seealso cref="IpV4Datagram"/>
/// </summary> /// </summary>
public class IpV4Layer : Layer, IEthernetNextLayer public class IpV4Layer : Layer, IEthernetNextLayer, IIpV4NextLayer
{ {
/// <summary> /// <summary>
/// Creates an IPv4 layer with all zero values. /// Creates an IPv4 layer with all zero values.
...@@ -80,6 +80,11 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -80,6 +80,11 @@ namespace PcapDotNet.Packets.IpV4
get { return EthernetType.IpV4; } get { return EthernetType.IpV4; }
} }
public IpV4Protocol PreviousLayerProtocol
{
get { return IpV4Protocol.Ip; }
}
/// <summary> /// <summary>
/// The default MAC Address value when this layer is the Ethernet payload. /// The default MAC Address value when this layer is the Ethernet payload.
/// null means there is no default value. /// null means there is no default value.
......
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