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");
} }
......
...@@ -89,140 +89,140 @@ namespace PcapDotNet.Packets.Test ...@@ -89,140 +89,140 @@ namespace PcapDotNet.Packets.Test
for (int i = 0; i != 1000; ++i) for (int i = 0; i != 1000; ++i)
{ {
IgmpMessageType igmpMessageType = random.NextEnum(IgmpMessageType.None); // IgmpMessageType igmpMessageType = random.NextEnum(IgmpMessageType.None);
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();
bool? igmpIsSuppressRouterSideProcessing = null; // bool? igmpIsSuppressRouterSideProcessing = null;
byte? igmpQueryRobustnessVariable = null; // byte? igmpQueryRobustnessVariable = null;
TimeSpan? igmpQueryInterval = null; // TimeSpan? igmpQueryInterval = null;
IpV4Address[] igmpSourceAddresses = null; // IpV4Address[] igmpSourceAddresses = null;
IgmpGroupRecord[] igmpGroupRecords = null; // IgmpGroupRecord[] igmpGroupRecords = null;
IgmpLayer igmpLayer; IgmpLayer igmpLayer = random.NextIgmpLayer();
switch (igmpMessageType) // switch (igmpMessageType)
{ // {
case IgmpMessageType.MembershipQuery: // case IgmpMessageType.MembershipQuery:
igmpQueryVersion = random.NextEnum(IgmpQueryVersion.None, IgmpQueryVersion.Unknown); // igmpQueryVersion = random.NextEnum(IgmpQueryVersion.None, IgmpQueryVersion.Unknown);
switch (igmpQueryVersion) // switch (igmpQueryVersion)
{ // {
case IgmpQueryVersion.Version1: // case IgmpQueryVersion.Version1:
igmpMaxResponseTime = TimeSpan.Zero; // igmpMaxResponseTime = TimeSpan.Zero;
igmpLayer = new IgmpQueryVersion1Layer // igmpLayer = new IgmpQueryVersion1Layer
{ // {
GroupAddress = igmpGroupAddress // GroupAddress = igmpGroupAddress
}; // };
//
// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion1(DateTime.Now, //// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion1(DateTime.Now,
// ethernetSource, ethernetDestination, //// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl, //// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options, //// ipV4Source, ipV4Destination, ipV4Options,
// igmpGroupAddress); //// igmpGroupAddress);
break; // break;
//
case IgmpQueryVersion.Version2: // case IgmpQueryVersion.Version2:
igmpLayer = new IgmpQueryVersion2Layer // igmpLayer = new IgmpQueryVersion2Layer
{ // {
MaxResponseTime = igmpMaxResponseTime, // MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress // GroupAddress = igmpGroupAddress
}; // };
// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion2(DateTime.Now, //// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion2(DateTime.Now,
// ethernetSource, ethernetDestination, //// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl, //// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options, //// ipV4Source, ipV4Destination, ipV4Options,
// igmpMaxResponseTime, igmpGroupAddress); //// igmpMaxResponseTime, igmpGroupAddress);
break; // break;
//
case IgmpQueryVersion.Version3: // case IgmpQueryVersion.Version3:
igmpIsSuppressRouterSideProcessing = random.NextBool(); // igmpIsSuppressRouterSideProcessing = random.NextBool();
igmpQueryRobustnessVariable = random.NextByte(8); // igmpQueryRobustnessVariable = random.NextByte(8);
igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1), // igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1),
IgmpDatagram.MaxVersion3MaxResponseTime - TimeSpan.FromTicks(1)); // IgmpDatagram.MaxVersion3MaxResponseTime - TimeSpan.FromTicks(1));
igmpQueryInterval = random.NextTimeSpan(TimeSpan.Zero, IgmpDatagram.MaxQueryInterval - TimeSpan.FromTicks(1)); // igmpQueryInterval = random.NextTimeSpan(TimeSpan.Zero, IgmpDatagram.MaxQueryInterval - TimeSpan.FromTicks(1));
igmpSourceAddresses = random.NextIpV4Addresses(random.Next(1000)); // igmpSourceAddresses = random.NextIpV4Addresses(random.Next(1000));
igmpLayer = new IgmpQueryVersion3Layer // igmpLayer = new IgmpQueryVersion3Layer
{ // {
MaxResponseTime = igmpMaxResponseTime, // MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress, // GroupAddress = igmpGroupAddress,
IsSuppressRouterSideProcessing = igmpIsSuppressRouterSideProcessing.Value, // IsSuppressRouterSideProcessing = igmpIsSuppressRouterSideProcessing.Value,
QueryRobustnessVariable = igmpQueryRobustnessVariable.Value, // QueryRobustnessVariable = igmpQueryRobustnessVariable.Value,
QueryInterval = igmpQueryInterval.Value, // QueryInterval = igmpQueryInterval.Value,
SourceAddresses = igmpSourceAddresses // SourceAddresses = igmpSourceAddresses
}; // };
//
// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion3(DateTime.Now, //// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion3(DateTime.Now,
// ethernetSource, ethernetDestination, //// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl, //// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options, //// ipV4Source, ipV4Destination, ipV4Options,
// igmpMaxResponseTime, igmpGroupAddress, //// igmpMaxResponseTime, igmpGroupAddress,
// igmpIsSuppressRouterSideProcessing.Value, //// igmpIsSuppressRouterSideProcessing.Value,
// igmpQueryRobustnessVariable.Value, igmpQueryInterval.Value, //// igmpQueryRobustnessVariable.Value, igmpQueryInterval.Value,
// igmpSourceAddresses); //// igmpSourceAddresses);
break; // break;
//
default: // default:
continue; // continue;
} // }
break; // break;
//
case IgmpMessageType.MembershipReportVersion1: // case IgmpMessageType.MembershipReportVersion1:
igmpMaxResponseTime = TimeSpan.Zero; // igmpMaxResponseTime = TimeSpan.Zero;
igmpLayer = new IgmpReportVersion1Layer // igmpLayer = new IgmpReportVersion1Layer
{ // {
GroupAddress = igmpGroupAddress // GroupAddress = igmpGroupAddress
}; // };
//
// packet = PacketBuilder.EthernetIpV4IgmpReportVersion1(DateTime.Now, //// packet = PacketBuilder.EthernetIpV4IgmpReportVersion1(DateTime.Now,
// ethernetSource, ethernetDestination, //// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl, //// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options, //// ipV4Source, ipV4Destination, ipV4Options,
// igmpGroupAddress); //// igmpGroupAddress);
break; // break;
//
case IgmpMessageType.MembershipReportVersion2: // case IgmpMessageType.MembershipReportVersion2:
igmpLayer = new IgmpReportVersion2Layer // igmpLayer = new IgmpReportVersion2Layer
{ // {
MaxResponseTime = igmpMaxResponseTime, // MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress // GroupAddress = igmpGroupAddress
}; // };
//
// packet = PacketBuilder.EthernetIpV4IgmpReportVersion2(DateTime.Now, //// packet = PacketBuilder.EthernetIpV4IgmpReportVersion2(DateTime.Now,
// ethernetSource, ethernetDestination, //// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl, //// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options, //// ipV4Source, ipV4Destination, ipV4Options,
// igmpMaxResponseTime, igmpGroupAddress); //// igmpMaxResponseTime, igmpGroupAddress);
break; // break;
//
case IgmpMessageType.LeaveGroupVersion2: // case IgmpMessageType.LeaveGroupVersion2:
igmpLayer = new IgmpLeaveGroupVersion2Layer // igmpLayer = new IgmpLeaveGroupVersion2Layer
{ // {
MaxResponseTime = igmpMaxResponseTime, // MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress // GroupAddress = igmpGroupAddress
}; // };
// packet = PacketBuilder.EthernetIpV4IgmpLeaveGroupVersion2(DateTime.Now, // // packet = PacketBuilder.EthernetIpV4IgmpLeaveGroupVersion2(DateTime.Now,
// ethernetSource, ethernetDestination, //// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl, //// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options, //// ipV4Source, ipV4Destination, ipV4Options,
// igmpMaxResponseTime, igmpGroupAddress); //// igmpMaxResponseTime, igmpGroupAddress);
break; // break;
//
case IgmpMessageType.MembershipReportVersion3: // case IgmpMessageType.MembershipReportVersion3:
igmpMaxResponseTime = TimeSpan.Zero; // igmpMaxResponseTime = TimeSpan.Zero;
igmpGroupRecords = random.NextIgmpGroupRecords(random.Next(100)); // igmpGroupRecords = random.NextIgmpGroupRecords(random.Next(100));
igmpLayer = new IgmpReportVersion3Layer // igmpLayer = new IgmpReportVersion3Layer
{ // {
GroupRecords = igmpGroupRecords // GroupRecords = igmpGroupRecords
}; // };
// packet = PacketBuilder.EthernetIpV4IgmpReportVersion3(DateTime.Now, // // packet = PacketBuilder.EthernetIpV4IgmpReportVersion3(DateTime.Now,
// ethernetSource, ethernetDestination, //// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl, //// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options, //// ipV4Source, ipV4Destination, ipV4Options,
// igmpGroupRecords); //// igmpGroupRecords);
break; // break;
//
default: // default:
continue; // throw new InvalidOperationException("Invalid message type " + igmpMessageType);
} // }
Packet packet = new PacketBuilder2(ethernetLayer, ipV4Layer, igmpLayer).Build(DateTime.Now); Packet packet = new PacketBuilder2(ethernetLayer, ipV4Layer, igmpLayer).Build(DateTime.Now);
...@@ -230,30 +230,32 @@ namespace PcapDotNet.Packets.Test ...@@ -230,30 +230,32 @@ namespace PcapDotNet.Packets.Test
// IGMP // IGMP
Assert.IsTrue(packet.Ethernet.IpV4.Igmp.IsChecksumCorrect); Assert.IsTrue(packet.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.AreEqual(igmpMessageType, packet.Ethernet.IpV4.Igmp.MessageType); Assert.AreEqual(igmpLayer.MessageType, packet.Ethernet.IpV4.Igmp.MessageType);
Assert.AreEqual(igmpQueryVersion, packet.Ethernet.IpV4.Igmp.QueryVersion); Assert.AreEqual(igmpLayer.QueryVersion, packet.Ethernet.IpV4.Igmp.QueryVersion);
MoreAssert.IsInRange(igmpMaxResponseTime.Divide(2), igmpMaxResponseTime, MoreAssert.IsInRange(igmpLayer.MaxResponseTimeValue.Divide(2), igmpLayer.MaxResponseTimeValue,
packet.Ethernet.IpV4.Igmp.MaxResponseTime, "MaxResponseTime"); packet.Ethernet.IpV4.Igmp.MaxResponseTime, "MaxResponseTime");
if (igmpMessageType != IgmpMessageType.MembershipReportVersion3) if (igmpLayer.MessageType != IgmpMessageType.MembershipReportVersion3)
Assert.AreEqual(igmpGroupAddress, packet.Ethernet.IpV4.Igmp.GroupAddress, "GroupAddress"); Assert.AreEqual(((IIgmpLayerWithGroupAddress)igmpLayer).GroupAddress, packet.Ethernet.IpV4.Igmp.GroupAddress, "GroupAddress");
// Query Version 3 // Query Version 3
if (igmpQueryVersion == IgmpQueryVersion.Version3) if (igmpLayer.QueryVersion == IgmpQueryVersion.Version3)
{ {
Assert.AreEqual(igmpIsSuppressRouterSideProcessing.Value, packet.Ethernet.IpV4.Igmp.IsSuppressRouterSideProcessing, IgmpQueryVersion3Layer igmpQueryVersion3Layer = (IgmpQueryVersion3Layer)igmpLayer;
Assert.AreEqual(igmpQueryVersion3Layer.IsSuppressRouterSideProcessing, packet.Ethernet.IpV4.Igmp.IsSuppressRouterSideProcessing,
"IsSuppressRouterSideProcessing"); "IsSuppressRouterSideProcessing");
MoreAssert.IsInRange(igmpQueryInterval.Value.Divide(2), igmpQueryInterval.Value, packet.Ethernet.IpV4.Igmp.QueryInterval); MoreAssert.IsInRange(igmpQueryVersion3Layer.QueryInterval.Divide(2), igmpQueryVersion3Layer.QueryInterval, packet.Ethernet.IpV4.Igmp.QueryInterval);
Assert.AreEqual(igmpQueryRobustnessVariable, packet.Ethernet.IpV4.Igmp.QueryRobustnessVariable); Assert.AreEqual(igmpQueryVersion3Layer.QueryRobustnessVariable, packet.Ethernet.IpV4.Igmp.QueryRobustnessVariable);
Assert.AreEqual(igmpSourceAddresses.Length, packet.Ethernet.IpV4.Igmp.NumberOfSources); Assert.AreEqual(igmpQueryVersion3Layer.SourceAddresses.Length, packet.Ethernet.IpV4.Igmp.NumberOfSources);
MoreAssert.AreSequenceEqual(igmpSourceAddresses, packet.Ethernet.IpV4.Igmp.SourceAddresses); MoreAssert.AreSequenceEqual(igmpQueryVersion3Layer.SourceAddresses, packet.Ethernet.IpV4.Igmp.SourceAddresses);
} }
// Report Version 3 // Report Version 3
if (igmpMessageType == IgmpMessageType.MembershipReportVersion3) if (igmpLayer.MessageType == IgmpMessageType.MembershipReportVersion3)
{ {
Assert.AreEqual(igmpGroupRecords.Length, packet.Ethernet.IpV4.Igmp.NumberOfGroupRecords); IgmpReportVersion3Layer igmpReportVersion3Layer= (IgmpReportVersion3Layer)igmpLayer;
MoreAssert.AreSequenceEqual(igmpGroupRecords, packet.Ethernet.IpV4.Igmp.GroupRecords.Select(record => record.ToGroupRecord())); Assert.AreEqual(igmpReportVersion3Layer.GroupRecords.Length, packet.Ethernet.IpV4.Igmp.NumberOfGroupRecords);
Assert.IsTrue(igmpGroupRecords.All(record => record.ToString() != null)); MoreAssert.AreSequenceEqual(igmpReportVersion3Layer.GroupRecords, packet.Ethernet.IpV4.Igmp.GroupRecords.Select(record => record.ToGroupRecord()));
Assert.IsTrue(igmpReportVersion3Layer.GroupRecords.All(record => record.ToString() != null));
} }
} }
} }
......
...@@ -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>
......
...@@ -5,6 +5,7 @@ using System.Text; ...@@ -5,6 +5,7 @@ using System.Text;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets; using PcapDotNet.Packets;
using PcapDotNet.Packets.Ethernet; using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Icmp;
using PcapDotNet.Packets.Igmp; using PcapDotNet.Packets.Igmp;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Transport; using PcapDotNet.Packets.Transport;
...@@ -12,7 +13,7 @@ using PcapDotNet.TestUtils; ...@@ -12,7 +13,7 @@ using PcapDotNet.TestUtils;
namespace PcapDotNet.Packets.TestUtils namespace PcapDotNet.Packets.TestUtils
{ {
public static class MoreRandomPackets public static class RandomPacketsExtensions
{ {
public static Datagram NextDatagram(this Random random, int length) public static Datagram NextDatagram(this Random random, int length)
{ {
...@@ -89,7 +90,7 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -89,7 +90,7 @@ namespace PcapDotNet.Packets.TestUtils
return new IpV4Fragmentation(ipV4FragmentationFlags, ipV4FragmentationOffset); return new IpV4Fragmentation(ipV4FragmentationFlags, ipV4FragmentationOffset);
} }
public static IpV4TimeOfDay NextIpV4OptionTimeOfDay(this Random random) public static IpV4TimeOfDay NextIpV4TimeOfDay(this Random random)
{ {
return new IpV4TimeOfDay(random.NextUInt()); return new IpV4TimeOfDay(random.NextUInt());
} }
...@@ -197,7 +198,7 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -197,7 +198,7 @@ namespace PcapDotNet.Packets.TestUtils
{ {
case IpV4OptionTimestampType.TimestampOnly: case IpV4OptionTimestampType.TimestampOnly:
int numTimestamps = random.Next((maximumOptionLength - IpV4OptionTimestamp.OptionMinimumLength) / 4 + 1); int numTimestamps = random.Next((maximumOptionLength - IpV4OptionTimestamp.OptionMinimumLength) / 4 + 1);
IpV4TimeOfDay[] timestamps = ((Func<IpV4TimeOfDay>)random.NextIpV4OptionTimeOfDay).GenerateArray(numTimestamps); IpV4TimeOfDay[] timestamps = ((Func<IpV4TimeOfDay>)random.NextIpV4TimeOfDay).GenerateArray(numTimestamps);
return new IpV4OptionTimestampOnly(overflow, pointedIndex, timestamps); return new IpV4OptionTimestampOnly(overflow, pointedIndex, timestamps);
case IpV4OptionTimestampType.AddressAndTimestamp: case IpV4OptionTimestampType.AddressAndTimestamp:
...@@ -205,7 +206,7 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -205,7 +206,7 @@ namespace PcapDotNet.Packets.TestUtils
int numPairs = random.Next((maximumOptionLength - IpV4OptionTimestamp.OptionMinimumLength) / 8 + 1); int numPairs = random.Next((maximumOptionLength - IpV4OptionTimestamp.OptionMinimumLength) / 8 + 1);
IpV4OptionTimedAddress[] pairs = new IpV4OptionTimedAddress[numPairs]; IpV4OptionTimedAddress[] pairs = new IpV4OptionTimedAddress[numPairs];
for (int i = 0; i != numPairs; ++i) for (int i = 0; i != numPairs; ++i)
pairs[i] = new IpV4OptionTimedAddress(random.NextIpV4Address(), random.NextIpV4OptionTimeOfDay()); pairs[i] = new IpV4OptionTimedAddress(random.NextIpV4Address(), random.NextIpV4TimeOfDay());
return new IpV4OptionTimestampAndAddress(timestampType, overflow, pointedIndex, pairs); return new IpV4OptionTimestampAndAddress(timestampType, overflow, pointedIndex, pairs);
...@@ -387,6 +388,254 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -387,6 +388,254 @@ namespace PcapDotNet.Packets.TestUtils
return ((Func<IgmpGroupRecord>)random.NextIgmpGroupRecord).GenerateArray(count); return ((Func<IgmpGroupRecord>)random.NextIgmpGroupRecord).GenerateArray(count);
} }
public static IgmpLayer NextIgmpLayer(this Random random)
{
IgmpMessageType igmpMessageType = random.NextEnum(IgmpMessageType.None);
IgmpQueryVersion igmpQueryVersion = IgmpQueryVersion.None;
TimeSpan igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1), TimeSpan.FromSeconds(256 * 0.1) - TimeSpan.FromTicks(1));
IpV4Address igmpGroupAddress = random.NextIpV4Address();
bool? igmpIsSuppressRouterSideProcessing = null;
byte? igmpQueryRobustnessVariable = null;
TimeSpan? igmpQueryInterval = null;
IpV4Address[] igmpSourceAddresses = null;
IgmpGroupRecord[] igmpGroupRecords = null;
switch (igmpMessageType)
{
case IgmpMessageType.MembershipQuery:
igmpQueryVersion = random.NextEnum(IgmpQueryVersion.None, IgmpQueryVersion.Unknown);
switch (igmpQueryVersion)
{
case IgmpQueryVersion.Version1:
return new IgmpQueryVersion1Layer
{
GroupAddress = igmpGroupAddress
};
case IgmpQueryVersion.Version2:
return new IgmpQueryVersion2Layer
{
MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress
};
case IgmpQueryVersion.Version3:
igmpIsSuppressRouterSideProcessing = random.NextBool();
igmpQueryRobustnessVariable = random.NextByte(8);
igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1),
IgmpDatagram.MaxVersion3MaxResponseTime - TimeSpan.FromTicks(1));
igmpQueryInterval = random.NextTimeSpan(TimeSpan.Zero, IgmpDatagram.MaxQueryInterval - TimeSpan.FromTicks(1));
igmpSourceAddresses = random.NextIpV4Addresses(random.Next(1000));
return new IgmpQueryVersion3Layer
{
MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress,
IsSuppressRouterSideProcessing = igmpIsSuppressRouterSideProcessing.Value,
QueryRobustnessVariable = igmpQueryRobustnessVariable.Value,
QueryInterval = igmpQueryInterval.Value,
SourceAddresses = igmpSourceAddresses
};
default:
throw new InvalidOperationException("Invalid Query Version " + igmpQueryVersion);
}
case IgmpMessageType.MembershipReportVersion1:
return new IgmpReportVersion1Layer
{
GroupAddress = igmpGroupAddress
};
case IgmpMessageType.MembershipReportVersion2:
return new IgmpReportVersion2Layer
{
MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress
};
case IgmpMessageType.LeaveGroupVersion2:
return new IgmpLeaveGroupVersion2Layer
{
MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress
};
case IgmpMessageType.MembershipReportVersion3:
igmpGroupRecords = random.NextIgmpGroupRecords(random.Next(100));
return new IgmpReportVersion3Layer
{
GroupRecords = igmpGroupRecords
};
default:
throw new InvalidOperationException("Invalid message type " + igmpMessageType);
}
}
// ICMP
public static IcmpLayer NextIcmpLayer(this Random random)
{
IcmpMessageType icmpMessageType = random.NextValue(new[]
{
IcmpMessageType.DestinationUnreachable,
IcmpMessageType.TimeExceeded
});
//random.NextEnum<IcmpMessageType>();
switch (icmpMessageType)
{
case IcmpMessageType.DestinationUnreachable:
return new IcmpDestinationUnreachableLayer
{
Code = random.NextEnum<IcmpCodeDestinationUnrechable>()
};
case IcmpMessageType.TimeExceeded:
return new IcmpTimeExceededLayer
{
Code = random.NextEnum<IcmpCodeTimeExceeded>()
};
case IcmpMessageType.ParameterProblem:
return new IcmpParameterProblemLayer
{
Pointer = random.NextUShort()
};
case IcmpMessageType.SourceQuench:
return new IcmpSourceQuenchLayer();
case IcmpMessageType.Redirect:
return new IcmpRedirectLayer
{
Code = random.NextEnum<IcmpCodeRedirect>(),
GatewayInternetAddress = random.NextIpV4Address()
};
case IcmpMessageType.Echo:
return new IcmpEchoLayer
{
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort()
};
case IcmpMessageType.EchoReply:
return new IcmpEchoReplyLayer
{
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort()
};
case IcmpMessageType.Timestamp:
return new IcmpTimestampLayer
{
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
OriginateTimestamp = random.NextIpV4TimeOfDay(),
ReceiveTimestamp = random.NextIpV4TimeOfDay(),
TransmitTimestamp = random.NextIpV4TimeOfDay()
};
case IcmpMessageType.TimestampReply:
return new IcmpTimestampReplyLayer
{
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
OriginateTimestamp = random.NextIpV4TimeOfDay(),
ReceiveTimestamp = random.NextIpV4TimeOfDay(),
TransmitTimestamp = random.NextIpV4TimeOfDay()
};
case IcmpMessageType.InformationRequest:
return new IcmpInformationRequestLayer
{
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
};
case IcmpMessageType.InformationReply:
return new IcmpInformationReplyLayer
{
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
};
case IcmpMessageType.RouterAdvertisement:
return new IcmpRouterAdvertisementLayer
{
Lifetime = random.NextTimeSpan(TimeSpan.Zero, TimeSpan.FromSeconds(ushort.MaxValue)),
Entries = random.NextIcmpRouterAdvertisementEntries(random.Next(10)).ToList()
};
case IcmpMessageType.RouterSolicitation:
return new IcmpRouterSolicitationLayer();
case IcmpMessageType.AddressMaskRequest:
return new IcmpAddressMaskRequestLayer
{
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
AddressMask = random.NextIpV4Address()
};
case IcmpMessageType.AddressMaskReply:
return new IcmpAddressMaskReplyLayer
{
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
AddressMask = random.NextIpV4Address()
};
case IcmpMessageType.Traceroute:
return new IcmpTracerouteLayer
{
Code = random.NextEnum<IcmpCodeTraceroute>(),
Identification = random.NextUShort(),
OutboundHopCount = random.NextUShort(),
ReturnHopCount = random.NextUShort(),
OutputLinkSpeed = random.NextUInt(),
OutputLinkMtu = random.NextUInt(),
};
case IcmpMessageType.ConversionFailed:
return new IcmpConversionFailedLayer
{
Code = random.NextEnum<IcmpCodeConversionFailed>(),
Pointer = random.NextUInt(),
};
case IcmpMessageType.DomainNameRequest:
return new IcmpDomainNameRequestLayer
{
Identifier = random.NextUShort(),
SequenceNumber = random.NextUShort(),
};
case IcmpMessageType.DomainNameReply:
throw new NotSupportedException("Message Type " + icmpMessageType + " is not supported");
case IcmpMessageType.SecurityFailures:
return new IcmpSecurityFailuresLayer
{
Code = random.NextEnum<IcmpCodeSecurityFailures>(),
Pointer = random.NextUShort()
};
default:
throw new InvalidOperationException("Invalid icmpMessageType " + icmpMessageType);
}
}
public static IEnumerable<IcmpRouterAdvertisementEntry> NextIcmpRouterAdvertisementEntries(this Random random, int numEntries)
{
for (int i = 0; i != numEntries; ++i)
yield return new IcmpRouterAdvertisementEntry(random.NextIpV4Address(), random.Next());
}
// TCP // TCP
public static TcpOptions NextTcpOptions(this Random random) public static TcpOptions NextTcpOptions(this Random random)
......
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
...@@ -11,39 +11,246 @@ namespace PcapDotNet.Packets.Icmp ...@@ -11,39 +11,246 @@ namespace PcapDotNet.Packets.Icmp
/// e.g., the distance to the network is infinity, /// e.g., the distance to the network is infinity,
/// the gateway may send a destination unreachable message to the internet source host of the datagram. /// the gateway may send a destination unreachable message to the internet source host of the datagram.
/// </summary> /// </summary>
DestinationUnreachableNetUnreachable = 0x00, NetUnreachable = 0x00,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// In some networks, the gateway may be able to determine if the internet destination host is unreachable. /// In some networks, the gateway may be able to determine if the internet destination host is unreachable.
/// Gateways in these networks may send destination unreachable messages to the source host when the destination host is unreachable. /// Gateways in these networks may send destination unreachable messages to the source host when the destination host is unreachable.
/// </summary> /// </summary>
DestinationUnreachableHostUnreachable = 0x01, HostUnreachable = 0x01,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// If, in the destination host, the IP module cannot deliver the datagram because the indicated protocol module is not active, /// If, in the destination host, the IP module cannot deliver the datagram because the indicated protocol module is not active,
/// the destination host may send a destination unreachable message to the source host. /// the destination host may send a destination unreachable message to the source host.
/// </summary> /// </summary>
DestinationUnreachableProtocolUnreachable = 0x02, ProtocolUnreachable = 0x02,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// If, in the destination host, the IP module cannot deliver the datagram because the indicated process port is not active, /// If, in the destination host, the IP module cannot deliver the datagram because the indicated process port is not active,
/// the destination host may send a destination unreachable message to the source host. /// the destination host may send a destination unreachable message to the source host.
/// </summary> /// </summary>
DestinationUnreachablePortUnreachable = 0x03, PortUnreachable = 0x03,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// A datagram must be fragmented to be forwarded by a gateway yet the Don't Fragment flag is on. /// A datagram must be fragmented to be forwarded by a gateway yet the Don't Fragment flag is on.
/// In this case the gateway must discard the datagram and may return a destination unreachable message. /// In this case the gateway must discard the datagram and may return a destination unreachable message.
/// </summary> /// </summary>
DestinationUnreachableFragmentationNeededAndDontFragmentSet = 0x04, FragmentationNeededAndDontFragmentSet = 0x04,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// </summary> /// </summary>
DestinationUnreachableSourceRouteFailed = 0x05, SourceRouteFailed = 0x05,
}
public enum IcmpCodeTimeExceeded : byte
{
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
TimeToLive = 0x00,
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
FragmentReassembly = 0x01,
}
public enum IcmpCodeRedirect : byte
{
/// <summary>
/// RFC 792.
/// </summary>
ForTheNetwork = 0x00,
/// <summary>
/// RFC 792.
/// </summary>
ForTheHost = 0x01,
/// <summary>
/// RFC 792.
/// </summary>
ForTheTypeOfServiceAndNetwork = 0x02,
/// <summary>
/// RFC 792.
/// </summary>
ForTheTypeOfServiceAndHost = 0x03,
}
public enum IcmpCodeTraceroute : byte
{
/// <summary>
/// RFC 1393.
/// </summary>
OutboundPacketSuccessfullyForwarded = 0x00,
/// <summary>
/// RFC 1393.
/// </summary>
NoRouteForOutboundPacketDiscarded = 0x01,
}
public enum IcmpCodeConversionFailed : byte
{
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnknownOrUnspecifiedError = 0x00,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
DontConvertOptionPresent = 0x01,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnknownMandatoryOptionPresent = 0x02,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
KnownUnsupportedOptionPresent = 0x03,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnsupportedTransportProtocol = 0x04,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
OverallLengthExceeded = 0x05,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
IpHeaderLengthExceeded = 0x06,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
TransportProtocolIsBiggerThan255 = 0x07,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
PortConversionOutOfRange = 0x08,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
TransportHeaderLengthExceeded = 0x09,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
Code32BitRolloverMissingAndAckSet = 0x0A,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnknownMandatoryTransportOptionPresent = 0x0B,
}
public enum IcmpCodeSecurityFailures : byte
{
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram includes a Security Parameters Index (SPI) that is invalid or has expired.
/// </summary>
BadSpi = 0x00,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed the authenticity or integrity check for a given SPI.
///
/// <para>
/// Note that the SPI may indicate an outer Encapsulating Security Protocol when a separate Authentication Header SPI is hidden inside.
/// </para>
/// </summary>
AuthenticationFailed = 0x01,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed a decompression check for a given SPI.
/// </summary>
DecompressionFailed = 0x02,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed a decryption check for a given SPI.
/// </summary>
DecryptionFailed = 0x03,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram will not be accepted without additional authentication.
///
/// <para>
/// In this case, either no SPI is present, or an unsuitable SPI is present.
/// For example, an encryption SPI without integrity arrives from a secure operating system with mutually suspicious users.
/// </para>
/// </summary>
NeedAuthentication = 0x04,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram will not be accepted because it has insufficient authorization.
///
/// <para>
/// In this case, an authentication SPI is present that is inappropriate for the target transport or application.
/// The principle party denoted by the SPI does not have proper authorization for the facilities used by the datagram.
/// For example, the party is authorized for Telnet access, but not for FTP access.
/// </para>
/// </summary>
NeedAuthorization = 0x05,
} }
} }
...@@ -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;
} }
} }
......
...@@ -9,47 +9,47 @@ namespace PcapDotNet.Packets.Icmp ...@@ -9,47 +9,47 @@ namespace PcapDotNet.Packets.Icmp
/// e.g., the distance to the network is infinity, /// e.g., the distance to the network is infinity,
/// the gateway may send a destination unreachable message to the internet source host of the datagram. /// the gateway may send a destination unreachable message to the internet source host of the datagram.
/// </summary> /// </summary>
DestinationUnreachableNetUnreachable = 0x0300, DestinationUnreachableNetUnreachable = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.NetUnreachable,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// In some networks, the gateway may be able to determine if the internet destination host is unreachable. /// In some networks, the gateway may be able to determine if the internet destination host is unreachable.
/// Gateways in these networks may send destination unreachable messages to the source host when the destination host is unreachable. /// Gateways in these networks may send destination unreachable messages to the source host when the destination host is unreachable.
/// </summary> /// </summary>
DestinationUnreachableHostUnreachable = 0x0301, DestinationUnreachableHostUnreachable = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.HostUnreachable,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// If, in the destination host, the IP module cannot deliver the datagram because the indicated protocol module is not active, /// If, in the destination host, the IP module cannot deliver the datagram because the indicated protocol module is not active,
/// the destination host may send a destination unreachable message to the source host. /// the destination host may send a destination unreachable message to the source host.
/// </summary> /// </summary>
DestinationUnreachableProtocolUnreachable = 0x0302, DestinationUnreachableProtocolUnreachable = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.ProtocolUnreachable,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// If, in the destination host, the IP module cannot deliver the datagram because the indicated process port is not active, /// If, in the destination host, the IP module cannot deliver the datagram because the indicated process port is not active,
/// the destination host may send a destination unreachable message to the source host. /// the destination host may send a destination unreachable message to the source host.
/// </summary> /// </summary>
DestinationUnreachablePortUnreachable = 0x0303, DestinationUnreachablePortUnreachable = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.PortUnreachable,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// A datagram must be fragmented to be forwarded by a gateway yet the Don't Fragment flag is on. /// A datagram must be fragmented to be forwarded by a gateway yet the Don't Fragment flag is on.
/// In this case the gateway must discard the datagram and may return a destination unreachable message. /// In this case the gateway must discard the datagram and may return a destination unreachable message.
/// </summary> /// </summary>
DestinationUnreachableFragmentationNeededAndDontFragmentSet = 0x0304, DestinationUnreachableFragmentationNeededAndDontFragmentSet = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.FragmentationNeededAndDontFragmentSet,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// </summary> /// </summary>
DestinationUnreachableSourceRouteFailed = 0x0305, DestinationUnreachableSourceRouteFailed = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.SourceRouteFailed,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// If the gateway processing a datagram finds the time to live field is zero it must discard the datagram. /// 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. /// The gateway may also notify the source host via the time exceeded message.
/// </summary> /// </summary>
TimeExceededTimeToLive = 0x0B00, TimeExceededTimeToLive = (IcmpMessageType.TimeExceeded << 8) | IcmpCodeTimeExceeded.TimeToLive,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
...@@ -57,7 +57,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -57,7 +57,7 @@ namespace PcapDotNet.Packets.Icmp
/// and it may send a time exceeded message. /// and it may send a time exceeded message.
/// If fragment zero is not available then no time exceeded need be sent at all. /// If fragment zero is not available then no time exceeded need be sent at all.
/// </summary> /// </summary>
TimeExceededFragmentReassembly = 0x0B01, TimeExceededFragmentReassembly = (IcmpMessageType.TimeExceeded << 8) | IcmpCodeTimeExceeded.FragmentReassembly,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
...@@ -66,7 +66,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -66,7 +66,7 @@ namespace PcapDotNet.Packets.Icmp
/// The gateway or host may also notify the source host via the parameter problem message. /// 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. /// This message is only sent if the error caused the datagram to be discarded.
/// </summary> /// </summary>
ParameterProblemPointerIndicatesTheError = 0x0C00, ParameterProblemPointerIndicatesTheError = (IcmpMessageType.ParameterProblem << 8),
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
...@@ -87,27 +87,27 @@ namespace PcapDotNet.Packets.Icmp ...@@ -87,27 +87,27 @@ namespace PcapDotNet.Packets.Icmp
/// This means that the data datagram which triggered the source quench message may be delivered. /// This means that the data datagram which triggered the source quench message may be delivered.
/// </para> /// </para>
/// </summary> /// </summary>
SourceQuench = 0x0400, SourceQuench = (IcmpMessageType.SourceQuench << 8),
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// </summary> /// </summary>
RedirectDatagramsForTheNetwork = 0x0500, RedirectDatagramsForTheNetwork = (IcmpMessageType.Redirect << 8) | IcmpCodeRedirect.ForTheNetwork,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// </summary> /// </summary>
RedirectDatagramsForTheHost = 0x0501, RedirectDatagramsForTheHost = (IcmpMessageType.Redirect << 8) | IcmpCodeRedirect.ForTheHost,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// </summary> /// </summary>
RedirectDatagramsForTheTypeOfServiceAndNetwork = 0x0502, RedirectDatagramsForTheTypeOfServiceAndNetwork = (IcmpMessageType.Redirect << 8) | IcmpCodeRedirect.ForTheTypeOfServiceAndNetwork,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
/// </summary> /// </summary>
RedirectDatagramsForTheTypeOfServiceAndHost = 0x0503, RedirectDatagramsForTheTypeOfServiceAndHost = (IcmpMessageType.Redirect << 8) | IcmpCodeRedirect.ForTheTypeOfServiceAndHost,
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
...@@ -125,7 +125,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -125,7 +125,7 @@ namespace PcapDotNet.Packets.Icmp
/// 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>
Echo = 0x0800, Echo = (IcmpMessageType.Echo << 8),
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
...@@ -143,7 +143,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -143,7 +143,7 @@ namespace PcapDotNet.Packets.Icmp
/// 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 = 0x0000, EchoReply = (IcmpMessageType.EchoReply << 8),
/// <summary> /// <summary>
/// RFC 792 /// RFC 792
...@@ -167,7 +167,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -167,7 +167,7 @@ namespace PcapDotNet.Packets.Icmp
/// 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>
Timestamp = 0x0D00, Timestamp = (IcmpMessageType.Timestamp << 8),
/// <summary> /// <summary>
/// RFC 792 /// RFC 792
...@@ -191,7 +191,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -191,7 +191,7 @@ namespace PcapDotNet.Packets.Icmp
/// 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>
TimestampReply = 0x0E00, TimestampReply = (IcmpMessageType.TimestampReply << 8),
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
...@@ -211,7 +211,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -211,7 +211,7 @@ namespace PcapDotNet.Packets.Icmp
/// 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>
InformationRequest = 0x0F00, InformationRequest = (IcmpMessageType.InformationRequest << 8),
/// <summary> /// <summary>
/// RFC 792. /// RFC 792.
...@@ -231,17 +231,17 @@ namespace PcapDotNet.Packets.Icmp ...@@ -231,17 +231,17 @@ namespace PcapDotNet.Packets.Icmp
/// 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>
InformationReply = 0x1000, InformationReply = (IcmpMessageType.InformationReply << 8),
/// <summary> /// <summary>
/// RFC 1256. /// RFC 1256.
/// </summary> /// </summary>
RouterAdvertisement = 0x0900, RouterAdvertisement = (IcmpMessageType.RouterAdvertisement << 8),
/// <summary> /// <summary>
/// RFC 1256. /// RFC 1256.
/// </summary> /// </summary>
RouterSolicitation = 0x0A00, RouterSolicitation = (IcmpMessageType.RouterSolicitation << 8),
/// <summary> /// <summary>
/// RFC 950. /// RFC 950.
...@@ -258,7 +258,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -258,7 +258,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 = 0xA100, AddressMaskRequest = (IcmpMessageType.AddressMaskRequest << 8),
/// <summary> /// <summary>
/// RFC 950. /// RFC 950.
...@@ -275,17 +275,17 @@ namespace PcapDotNet.Packets.Icmp ...@@ -275,17 +275,17 @@ 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 = 0xA200, AddressMaskReply = (IcmpMessageType.AddressMaskReply << 8),
/// <summary> /// <summary>
/// RFC 1393. /// RFC 1393.
/// </summary> /// </summary>
TracerouteOutboundPacketSuccessfullyForwarded = 0x1E00, TracerouteOutboundPacketSuccessfullyForwarded = (IcmpMessageType.Traceroute << 8) | IcmpCodeTraceroute.OutboundPacketSuccessfullyForwarded,
/// <summary> /// <summary>
/// RFC 1393. /// RFC 1393.
/// </summary> /// </summary>
TracerouteNoRouteForOutboundPacketDiscarded = 0x1E01, TracerouteNoRouteForOutboundPacketDiscarded = (IcmpMessageType.Traceroute << 8) | IcmpCodeTraceroute.NoRouteForOutboundPacketDiscarded,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -293,7 +293,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -293,7 +293,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedUnknownOrUnspecifiedError = 0x1F00, ConversionFailedUnknownOrUnspecifiedError = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.UnknownOrUnspecifiedError,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -301,7 +301,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -301,7 +301,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedDontConvertOptionPresent = 0x1F01, ConversionFailedDontConvertOptionPresent = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.DontConvertOptionPresent,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -309,7 +309,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -309,7 +309,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedUnknownMandatoryOptionPresent = 0x1F02, ConversionFailedUnknownMandatoryOptionPresent = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.UnknownMandatoryOptionPresent,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -317,7 +317,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -317,7 +317,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedKnownUnsupportedOptionPresent = 0x1F03, ConversionFailedKnownUnsupportedOptionPresent = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.KnownUnsupportedOptionPresent,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -325,7 +325,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -325,7 +325,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedUnsupportedTransportProtocol = 0x1F04, ConversionFailedUnsupportedTransportProtocol = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.UnsupportedTransportProtocol,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -333,7 +333,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -333,7 +333,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedOverallLengthExceeded = 0x1F05, ConversionFailedOverallLengthExceeded = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.OverallLengthExceeded,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -341,7 +341,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -341,7 +341,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedIpHeaderLengthExceeded = 0x1F06, ConversionFailedIpHeaderLengthExceeded = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.IpHeaderLengthExceeded,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -349,7 +349,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -349,7 +349,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedTransportProtocolIsBiggerThan255 = 0x1F07, ConversionFailedTransportProtocolIsBiggerThan255 = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.TransportProtocolIsBiggerThan255,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -357,7 +357,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -357,7 +357,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedPortConversionOutOfRange = 0x1F08, ConversionFailedPortConversionOutOfRange = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.PortConversionOutOfRange,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -365,7 +365,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -365,7 +365,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedTransportHeaderLengthExceeded = 0x1F09, ConversionFailedTransportHeaderLengthExceeded = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.TransportHeaderLengthExceeded,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -373,7 +373,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -373,7 +373,7 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailed32BitRolloverMissingAndAckSet = 0x1F0A, ConversionFailed32BitRolloverMissingAndAckSet = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.Code32BitRolloverMissingAndAckSet,
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
...@@ -381,24 +381,24 @@ namespace PcapDotNet.Packets.Icmp ...@@ -381,24 +381,24 @@ namespace PcapDotNet.Packets.Icmp
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram. /// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted. /// This message is only sent when a valid datagram cannot be converted.
/// </summary> /// </summary>
ConversionFailedUnknownMandatoryTransportOptionPresent = 0x1F0B, ConversionFailedUnknownMandatoryTransportOptionPresent = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.UnknownMandatoryTransportOptionPresent,
/// <summary> /// <summary>
/// RFC 1788. /// RFC 1788.
/// </summary> /// </summary>
DomainNameRequest = 0x2500, DomainNameRequest = (IcmpMessageType.DomainNameRequest << 8),
/// <summary> /// <summary>
/// RFC 1788. /// RFC 1788.
/// Parsing of this datagram isn't supported because its parsing is not clear from the RFC. /// Parsing of this datagram isn't supported because its parsing is not clear from the RFC.
/// </summary> /// </summary>
DomainNameReply = 0x2600, DomainNameReply = (IcmpMessageType.DomainNameReply << 8),
/// <summary> /// <summary>
/// RFC 2521. /// RFC 2521.
/// Indicates that a received datagram includes a Security Parameters Index (SPI) that is invalid or has expired. /// Indicates that a received datagram includes a Security Parameters Index (SPI) that is invalid or has expired.
/// </summary> /// </summary>
SecurityFailuresBadSpi = 0x2800, SecurityFailuresBadSpi = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.BadSpi,
/// <summary> /// <summary>
/// RFC 2521. /// RFC 2521.
...@@ -408,19 +408,19 @@ namespace PcapDotNet.Packets.Icmp ...@@ -408,19 +408,19 @@ namespace PcapDotNet.Packets.Icmp
/// Note that the SPI may indicate an outer Encapsulating Security Protocol when a separate Authentication Header SPI is hidden inside. /// Note that the SPI may indicate an outer Encapsulating Security Protocol when a separate Authentication Header SPI is hidden inside.
/// </para> /// </para>
/// </summary> /// </summary>
SecurityFailuresAuthenticationFailed = 0x2801, SecurityFailuresAuthenticationFailed = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.AuthenticationFailed,
/// <summary> /// <summary>
/// RFC 2521. /// RFC 2521.
/// Indicates that a received datagram failed a decompression check for a given SPI. /// Indicates that a received datagram failed a decompression check for a given SPI.
/// </summary> /// </summary>
SecurityFailuresDecompressionFailed = 0x2802, SecurityFailuresDecompressionFailed = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.DecompressionFailed,
/// <summary> /// <summary>
/// RFC 2521. /// RFC 2521.
/// Indicates that a received datagram failed a decryption check for a given SPI. /// Indicates that a received datagram failed a decryption check for a given SPI.
/// </summary> /// </summary>
SecurityFailuresDecryptionFailed = 0x2803, SecurityFailuresDecryptionFailed = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.DecryptionFailed,
/// <summary> /// <summary>
/// RFC 2521. /// RFC 2521.
...@@ -431,7 +431,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -431,7 +431,7 @@ namespace PcapDotNet.Packets.Icmp
/// For example, an encryption SPI without integrity arrives from a secure operating system with mutually suspicious users. /// For example, an encryption SPI without integrity arrives from a secure operating system with mutually suspicious users.
/// </para> /// </para>
/// </summary> /// </summary>
SecurityFailuresNeedAuthentication = 0x2804, SecurityFailuresNeedAuthentication = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.NeedAuthentication,
/// <summary> /// <summary>
/// RFC 2521. /// RFC 2521.
...@@ -443,6 +443,6 @@ namespace PcapDotNet.Packets.Icmp ...@@ -443,6 +443,6 @@ namespace PcapDotNet.Packets.Icmp
/// For example, the party is authorized for Telnet access, but not for FTP access. /// For example, the party is authorized for Telnet access, but not for FTP access.
/// </para> /// </para>
/// </summary> /// </summary>
SecurityFailuresNeedAuthorization = 0x2805, SecurityFailuresNeedAuthorization = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.NeedAuthorization,
} }
} }
\ No newline at end of file
...@@ -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>
......
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using PcapDotNet.Packets.Arp; using PcapDotNet.Packets.Arp;
using PcapDotNet.Packets.Ethernet; using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Icmp;
using PcapDotNet.Packets.Igmp; using PcapDotNet.Packets.Igmp;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Transport; using PcapDotNet.Packets.Transport;
...@@ -368,17 +369,27 @@ namespace PcapDotNet.Packets ...@@ -368,17 +369,27 @@ namespace PcapDotNet.Packets
public abstract class IgmpLayer : SimpleLayer, IIpV4NextLayer public abstract class IgmpLayer : SimpleLayer, IIpV4NextLayer
{ {
public abstract IgmpMessageType MessageType { get; }
public virtual IgmpQueryVersion QueryVersion
{
get { return IgmpQueryVersion.None; }
}
public abstract TimeSpan MaxResponseTimeValue { get; }
public IpV4Protocol PreviousLayerProtocol public IpV4Protocol PreviousLayerProtocol
{ {
get { return IpV4Protocol.InternetGroupManagementProtocol; } get { return IpV4Protocol.InternetGroupManagementProtocol; }
} }
} }
public abstract class SimpleIgmpLayer : IgmpLayer public interface IIgmpLayerWithGroupAddress
{
IpV4Address GroupAddress { get; set; }
}
public abstract class SimpleIgmpLayer : IgmpLayer, IIgmpLayerWithGroupAddress
{ {
public IpV4Address GroupAddress { get; set; } public IpV4Address GroupAddress { get; set; }
public abstract IgmpMessageType MessageType { get; }
public abstract TimeSpan MaxResponseTimeValue { get; }
public override int Length public override int Length
{ {
get { return IgmpDatagram.HeaderLength; } get { return IgmpDatagram.HeaderLength; }
...@@ -414,6 +425,14 @@ namespace PcapDotNet.Packets ...@@ -414,6 +425,14 @@ namespace PcapDotNet.Packets
{ {
get { return IgmpMessageType.MembershipQuery; } get { return IgmpMessageType.MembershipQuery; }
} }
public override IgmpQueryVersion QueryVersion
{
get
{
return IgmpQueryVersion.Version1;
}
}
} }
public class IgmpQueryVersion2Layer : IgmpVersion2Layer public class IgmpQueryVersion2Layer : IgmpVersion2Layer
...@@ -422,9 +441,17 @@ namespace PcapDotNet.Packets ...@@ -422,9 +441,17 @@ namespace PcapDotNet.Packets
{ {
get { return IgmpMessageType.MembershipQuery; } get { return IgmpMessageType.MembershipQuery; }
} }
public override IgmpQueryVersion QueryVersion
{
get
{
return IgmpQueryVersion.Version2;
}
}
} }
public class IgmpQueryVersion3Layer : IgmpLayer public class IgmpQueryVersion3Layer : IgmpLayer, IIgmpLayerWithGroupAddress
{ {
public TimeSpan MaxResponseTime { get; set; } public TimeSpan MaxResponseTime { get; set; }
public IpV4Address GroupAddress { get; set; } public IpV4Address GroupAddress { get; set; }
...@@ -447,6 +474,24 @@ namespace PcapDotNet.Packets ...@@ -447,6 +474,24 @@ namespace PcapDotNet.Packets
MaxResponseTime, GroupAddress, IsSuppressRouterSideProcessing, QueryRobustnessVariable, MaxResponseTime, GroupAddress, IsSuppressRouterSideProcessing, QueryRobustnessVariable,
QueryInterval, SourceAddresses); QueryInterval, SourceAddresses);
} }
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.MembershipQuery; }
}
public override IgmpQueryVersion QueryVersion
{
get
{
return IgmpQueryVersion.Version3;
}
}
public override TimeSpan MaxResponseTimeValue
{
get { return MaxResponseTime; }
}
} }
public class IgmpReportVersion1Layer : IgmpVersion1Layer public class IgmpReportVersion1Layer : IgmpVersion1Layer
...@@ -486,6 +531,347 @@ namespace PcapDotNet.Packets ...@@ -486,6 +531,347 @@ namespace PcapDotNet.Packets
{ {
IgmpDatagram.WriteReportVersion3(buffer, offset, GroupRecords); IgmpDatagram.WriteReportVersion3(buffer, offset, GroupRecords);
} }
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.MembershipReportVersion3; }
}
public override TimeSpan MaxResponseTimeValue
{
get { return TimeSpan.Zero; }
}
}
public abstract class IcmpLayer : SimpleLayer, IIpV4NextLayer
{
public abstract IcmpMessageType MessageType { get; }
public virtual byte CodeValue
{
get { return 0; }
}
protected virtual uint Value
{
get { return 0; }
}
public override int Length
{
get { return IcmpDatagram.HeaderLength; }
}
protected override sealed void Write(byte[] buffer, int offset)
{
IcmpDatagram.WriteHeader(buffer, offset, MessageType, CodeValue, Value);
WriteHeaderAdditional(buffer, offset + IcmpDatagram.HeaderLength);
}
protected virtual void WriteHeaderAdditional(byte[] buffer, int offset)
{
}
public override void Finalize(byte[] buffer, int offset, int payloadLength, ILayer nextLayer)
{
IcmpDatagram.WriteChecksum(buffer, offset, Length + payloadLength);
}
public IpV4Protocol PreviousLayerProtocol
{
get { return IpV4Protocol.InternetControlMessageProtocol; }
}
}
public class IcmpDestinationUnreachableLayer : IcmpLayer
{
public IcmpCodeDestinationUnrechable Code { get; set; }
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.DestinationUnreachable; }
}
public override byte CodeValue
{
get { return (byte)Code; }
}
}
public class IcmpTimeExceededLayer : IcmpLayer
{
public IcmpCodeTimeExceeded Code { get; set; }
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.TimeExceeded; }
}
public override byte CodeValue
{
get { return (byte)Code; }
}
}
public class IcmpParameterProblemLayer : IcmpLayer
{
public ushort Pointer { get; set; }
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.ParameterProblem; }
}
protected override uint Value
{
get
{
return (uint)(Pointer << 16);
}
}
}
public class IcmpSourceQuenchLayer : IcmpLayer
{
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.SourceQuench; }
}
}
public class IcmpRedirectLayer : IcmpLayer
{
public IcmpCodeRedirect Code { get; set; }
public IpV4Address GatewayInternetAddress{get;set;}
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.Redirect; }
}
public override byte CodeValue
{
get
{
return (byte)Code;
}
}
protected override uint Value
{
get
{
return GatewayInternetAddress.ToValue();
}
}
}
public abstract class IcmpIdentifiedLayer : IcmpLayer
{
public ushort Identifier { get; set; }
public ushort SequenceNumber { get; set; }
protected override sealed uint Value
{
get
{
return (uint)((Identifier << 16) | SequenceNumber);
}
}
}
public class IcmpEchoLayer : IcmpIdentifiedLayer
{
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.Echo; }
}
}
public class IcmpEchoReplyLayer : IcmpIdentifiedLayer
{
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.EchoReply; }
}
}
public class IcmpTimestampLayer : IcmpIdentifiedLayer
{
public IpV4TimeOfDay OriginateTimestamp { get; set; }
public IpV4TimeOfDay ReceiveTimestamp { get; set; }
public IpV4TimeOfDay TransmitTimestamp { get; set; }
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.Timestamp; }
}
public override int Length
{
get
{
return base.Length + IcmpTimestampDatagram.HeaderAdditionalLength;
}
}
protected override void WriteHeaderAdditional(byte[] buffer, int offset)
{
IcmpTimestampDatagram.WriteHeaderAdditional(buffer, offset,
OriginateTimestamp, ReceiveTimestamp, TransmitTimestamp);
}
}
public class IcmpTimestampReplyLayer : IcmpTimestampLayer
{
public override IcmpMessageType MessageType
{
get
{
return IcmpMessageType.TimestampReply;
}
}
}
public class IcmpInformationRequestLayer : IcmpIdentifiedLayer
{
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.InformationRequest; }
}
}
public class IcmpInformationReplyLayer : IcmpIdentifiedLayer
{
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.InformationReply; }
}
}
public class IcmpRouterAdvertisementLayer : IcmpLayer
{
public TimeSpan Lifetime { get; set; }
public List<IcmpRouterAdvertisementEntry> Entries { get; set; }
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.RouterAdvertisement; }
}
protected override uint Value
{
get
{
return (uint)(((byte)Entries.Count << 24) |
(IcmpRouterAdvertisementDatagram.DefaultAddressEntrySize << 16) |
((ushort)Lifetime.TotalSeconds));
}
}
public override int Length
{
get
{
return base.Length + IcmpRouterAdvertisementDatagram.GetHeaderAdditionalLength(Entries.Count);
}
}
protected override void WriteHeaderAdditional(byte[] buffer, int offset)
{
IcmpRouterAdvertisementDatagram.WriteHeaderAdditional(buffer, offset, Entries);
}
}
public class IcmpRouterSolicitationLayer : IcmpLayer
{
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.RouterSolicitation; }
}
}
public class IcmpAddressMaskRequestLayer : IcmpIdentifiedLayer
{
public IpV4Address AddressMask { get; set; }
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.AddressMaskRequest; }
}
public override int Length
{
get
{
return base.Length + IcmpAddressMaskDatagram.HeaderAdditionalLength;
}
}
protected override void WriteHeaderAdditional(byte[] buffer, int offset)
{
IcmpAddressMaskDatagram.WriteHeaderAdditional(buffer, offset, AddressMask);
}
}
public class IcmpAddressMaskReplyLayer : IcmpAddressMaskRequestLayer
{
public override IcmpMessageType MessageType
{
get
{
return IcmpMessageType.AddressMaskReply;
}
}
}
public class IcmpConversionFailedLayer : IcmpLayer
{
public IcmpCodeConversionFailed Code { get; set; }
public uint Pointer { get; set; }
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.ConversionFailed; }
}
public override byte CodeValue
{
get
{
return (byte)Code;
}
}
}
public class IcmpDomainNameRequestLayer : IcmpIdentifiedLayer
{
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.DomainNameRequest; }
}
}
public class IcmpSecurityFailuresLayer : IcmpLayer
{
public IcmpCodeSecurityFailures Code{get; set ;}
public ushort Pointer{get; set ;}
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.SecurityFailures; }
}
public override byte CodeValue
{
get
{
return (byte)Code;
}
}
protected override uint Value
{
get
{
return Pointer;
}
}
} }
public class PacketBuilder2 public class PacketBuilder2
...@@ -530,13 +916,13 @@ namespace PcapDotNet.Packets ...@@ -530,13 +916,13 @@ namespace PcapDotNet.Packets
private void FinalizeLayers(byte[] buffer, int length) private void FinalizeLayers(byte[] buffer, int length)
{ {
int offset = 0; int offset = length;
for (int i = 0; i != _layers.Length; ++i) for (int i = _layers.Length - 1; i >= 0; --i)
{ {
ILayer layer = _layers[i]; ILayer layer = _layers[i];
ILayer nextLayer = i == _layers.Length - 1 ? null : _layers[i + 1]; ILayer nextLayer = i == _layers.Length - 1 ? null : _layers[i + 1];
offset -= layer.Length;
layer.Finalize(buffer, offset, length - offset - layer.Length, nextLayer); layer.Finalize(buffer, offset, length - offset - layer.Length, nextLayer);
offset += layer.Length;
} }
} }
......
...@@ -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