Commit 7bf4249c authored by Brickner_cp's avatar Brickner_cp

ICMP

parent 47ed4887
......@@ -68,85 +68,48 @@ namespace PcapDotNet.Packets.Test
[TestMethod]
public void RandomIcmpTest()
{
MacAddress ethernetSource = new MacAddress("00:01:02:03:04:05");
MacAddress ethernetDestination = new MacAddress("A0:A1:A2:A3:A4:A5");
EthernetLayer ethernetLayer = new EthernetLayer
{
Source = new MacAddress("00:01:02:03:04:05"),
Destination = new MacAddress("A0:A1:A2:A3:A4:A5")
};
Random random = new Random();
byte ipV4TypeOfService = random.NextByte();
ushort ipV4Identification = random.NextUShort();
byte ipV4Ttl = random.NextByte();
IpV4Fragmentation ipV4Fragmentation = random.NextIpV4Fragmentation();
IpV4Address ipV4Source = new IpV4Address(random.NextUInt());
IpV4Address ipV4Destination = new IpV4Address(random.NextUInt());
IpV4Options ipV4Options = random.NextIpV4Options();
IpV4Layer ipV4Layer = new IpV4Layer
{
TypeOfService = random.NextByte(),
Identification = random.NextUShort(),
Ttl = random.NextByte(),
Fragmentation = random.NextIpV4Fragmentation(),
Source = random.NextIpV4Address(),
Destination = random.NextIpV4Address(),
Options = random.NextIpV4Options()
};
for (int i = 0; i != 1000; ++i)
{
IcmpMessageType icmpMessageType = random.NextEnum<IcmpMessageType>();
Packet packet;
byte icmpIpV4TypeOfService = random.NextByte();
ushort icmpIpV4Identification = random.NextUShort();
byte icmpIpV4Ttl = random.NextByte();
IpV4Fragmentation icmpIpV4Fragmentation = random.NextIpV4Fragmentation();
IpV4Protocol icmpIpV4Protocol = random.NextEnum<IpV4Protocol>();
IpV4Address icmpIpV4Source = new IpV4Address(random.NextUInt());
IpV4Address icmpIpV4Destination = new IpV4Address(random.NextUInt());
IpV4Options icmpIpV4Options = random.NextIpV4Options();
Datagram icmpIpV4Payload = random.NextDatagram(random.Next(200));
switch (icmpMessageType)
{
case IcmpMessageType.DestinationUnreachable:
IcmpCodeDestinationUnrechable code = random.NextEnum<IcmpCodeDestinationUnrechable>();
IpV4Layer icmpIpV4Layer = new IpV4Layer
{
TypeOfService = random.NextByte(),
Identification = random.NextUShort(),
Fragmentation = random.NextIpV4Fragmentation(),
Ttl = random.NextByte(),
Protocol = random.NextEnum<IpV4Protocol>(),
Source = random.NextIpV4Address(),
Destination = random.NextIpV4Address(),
Options = random.NextIpV4Options(),
};
packet = PacketBuilder.EthernetIpV4IcmpDestinationUnreachable(DateTime.Now,
ethernetSource, ethernetDestination,
ipV4TypeOfService, ipV4Identification, ipV4Fragmentation,
ipV4Ttl,
ipV4Source, ipV4Destination, ipV4Options,
code,
icmpIpV4TypeOfService, icmpIpV4Identification,
icmpIpV4Fragmentation,
icmpIpV4Ttl, icmpIpV4Protocol, icmpIpV4Source,
icmpIpV4Destination,
icmpIpV4Options, icmpIpV4Payload);
break;
PayloadLayer icmpIpV4PayloadLayer = new PayloadLayer
{
Data = random.NextDatagram(random.Next(200))
};
// case IcmpMessageType.TimeExceeded:
// PacketBuilder.EthernetIpV4IcmpTimeExceeded(DateTime.Now,
// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation,
// ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options,
// code,
// icmpIpV4TypeOfService, icmpIpV4Identification,
// icmpIpV4Fragmentation,
// icmpIpV4Ttl, icmpIpV4Protocol, icmpIpV4Source,
// icmpIpV4Destination,
// icmpIpV4Options, icmpIpV4Payload);
// case IcmpMessageType.ParameterProblem:
// case IcmpMessageType.SourceQuench:
// case IcmpMessageType.Redirect:
// case IcmpMessageType.Echo:
// case IcmpMessageType.EchoReply:
// case IcmpMessageType.Timestamp:
// case IcmpMessageType.TimestampReply:
// case IcmpMessageType.InformationRequest:
// case IcmpMessageType.InformationReply:
// case IcmpMessageType.RouterAdvertisement:
// case IcmpMessageType.RouterSolicitation:
// case IcmpMessageType.AddressMaskRequest:
// case IcmpMessageType.AddressMaskReply:
// case IcmpMessageType.Traceroute:
// case IcmpMessageType.ConversionFailed:
// case IcmpMessageType.DomainNameRequest:
// case IcmpMessageType.DomainNameReply:
// case IcmpMessageType.SecurityFailures:
IcmpLayer icmpLayer = random.NextIcmpLayer();
default:
throw new InvalidOperationException("Invalid icmpMessageType " + icmpMessageType);
}
Packet packet = new PacketBuilder2(ethernetLayer, ipV4Layer, icmpLayer, icmpIpV4Layer, icmpIpV4PayloadLayer).Build(DateTime.Now);
Assert.IsTrue(packet.IsValid, "IsValid");
}
......
......@@ -89,140 +89,140 @@ namespace PcapDotNet.Packets.Test
for (int i = 0; i != 1000; ++i)
{
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;
IgmpLayer igmpLayer;
switch (igmpMessageType)
{
case IgmpMessageType.MembershipQuery:
igmpQueryVersion = random.NextEnum(IgmpQueryVersion.None, IgmpQueryVersion.Unknown);
switch (igmpQueryVersion)
{
case IgmpQueryVersion.Version1:
igmpMaxResponseTime = TimeSpan.Zero;
igmpLayer = new IgmpQueryVersion1Layer
{
GroupAddress = igmpGroupAddress
};
// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion1(DateTime.Now,
// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options,
// igmpGroupAddress);
break;
case IgmpQueryVersion.Version2:
igmpLayer = new IgmpQueryVersion2Layer
{
MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress
};
// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion2(DateTime.Now,
// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options,
// igmpMaxResponseTime, igmpGroupAddress);
break;
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));
igmpLayer = new IgmpQueryVersion3Layer
{
MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress,
IsSuppressRouterSideProcessing = igmpIsSuppressRouterSideProcessing.Value,
QueryRobustnessVariable = igmpQueryRobustnessVariable.Value,
QueryInterval = igmpQueryInterval.Value,
SourceAddresses = igmpSourceAddresses
};
// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion3(DateTime.Now,
// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options,
// igmpMaxResponseTime, igmpGroupAddress,
// igmpIsSuppressRouterSideProcessing.Value,
// igmpQueryRobustnessVariable.Value, igmpQueryInterval.Value,
// igmpSourceAddresses);
break;
default:
continue;
}
break;
case IgmpMessageType.MembershipReportVersion1:
igmpMaxResponseTime = TimeSpan.Zero;
igmpLayer = new IgmpReportVersion1Layer
{
GroupAddress = igmpGroupAddress
};
// packet = PacketBuilder.EthernetIpV4IgmpReportVersion1(DateTime.Now,
// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options,
// igmpGroupAddress);
break;
case IgmpMessageType.MembershipReportVersion2:
igmpLayer = new IgmpReportVersion2Layer
{
MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress
};
// packet = PacketBuilder.EthernetIpV4IgmpReportVersion2(DateTime.Now,
// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options,
// igmpMaxResponseTime, igmpGroupAddress);
break;
case IgmpMessageType.LeaveGroupVersion2:
igmpLayer = new IgmpLeaveGroupVersion2Layer
{
MaxResponseTime = igmpMaxResponseTime,
GroupAddress = igmpGroupAddress
};
// packet = PacketBuilder.EthernetIpV4IgmpLeaveGroupVersion2(DateTime.Now,
// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options,
// igmpMaxResponseTime, igmpGroupAddress);
break;
case IgmpMessageType.MembershipReportVersion3:
igmpMaxResponseTime = TimeSpan.Zero;
igmpGroupRecords = random.NextIgmpGroupRecords(random.Next(100));
igmpLayer = new IgmpReportVersion3Layer
{
GroupRecords = igmpGroupRecords
};
// packet = PacketBuilder.EthernetIpV4IgmpReportVersion3(DateTime.Now,
// ethernetSource, ethernetDestination,
// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
// ipV4Source, ipV4Destination, ipV4Options,
// igmpGroupRecords);
break;
default:
continue;
}
// 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;
IgmpLayer igmpLayer = random.NextIgmpLayer();
// switch (igmpMessageType)
// {
// case IgmpMessageType.MembershipQuery:
// igmpQueryVersion = random.NextEnum(IgmpQueryVersion.None, IgmpQueryVersion.Unknown);
// switch (igmpQueryVersion)
// {
// case IgmpQueryVersion.Version1:
// igmpMaxResponseTime = TimeSpan.Zero;
// igmpLayer = new IgmpQueryVersion1Layer
// {
// GroupAddress = igmpGroupAddress
// };
//
//// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion1(DateTime.Now,
//// ethernetSource, ethernetDestination,
//// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
//// ipV4Source, ipV4Destination, ipV4Options,
//// igmpGroupAddress);
// break;
//
// case IgmpQueryVersion.Version2:
// igmpLayer = new IgmpQueryVersion2Layer
// {
// MaxResponseTime = igmpMaxResponseTime,
// GroupAddress = igmpGroupAddress
// };
//// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion2(DateTime.Now,
//// ethernetSource, ethernetDestination,
//// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
//// ipV4Source, ipV4Destination, ipV4Options,
//// igmpMaxResponseTime, igmpGroupAddress);
// break;
//
// 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));
// igmpLayer = new IgmpQueryVersion3Layer
// {
// MaxResponseTime = igmpMaxResponseTime,
// GroupAddress = igmpGroupAddress,
// IsSuppressRouterSideProcessing = igmpIsSuppressRouterSideProcessing.Value,
// QueryRobustnessVariable = igmpQueryRobustnessVariable.Value,
// QueryInterval = igmpQueryInterval.Value,
// SourceAddresses = igmpSourceAddresses
// };
//
//// packet = PacketBuilder.EthernetIpV4IgmpQueryVersion3(DateTime.Now,
//// ethernetSource, ethernetDestination,
//// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
//// ipV4Source, ipV4Destination, ipV4Options,
//// igmpMaxResponseTime, igmpGroupAddress,
//// igmpIsSuppressRouterSideProcessing.Value,
//// igmpQueryRobustnessVariable.Value, igmpQueryInterval.Value,
//// igmpSourceAddresses);
// break;
//
// default:
// continue;
// }
// break;
//
// case IgmpMessageType.MembershipReportVersion1:
// igmpMaxResponseTime = TimeSpan.Zero;
// igmpLayer = new IgmpReportVersion1Layer
// {
// GroupAddress = igmpGroupAddress
// };
//
//// packet = PacketBuilder.EthernetIpV4IgmpReportVersion1(DateTime.Now,
//// ethernetSource, ethernetDestination,
//// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
//// ipV4Source, ipV4Destination, ipV4Options,
//// igmpGroupAddress);
// break;
//
// case IgmpMessageType.MembershipReportVersion2:
// igmpLayer = new IgmpReportVersion2Layer
// {
// MaxResponseTime = igmpMaxResponseTime,
// GroupAddress = igmpGroupAddress
// };
//
//// packet = PacketBuilder.EthernetIpV4IgmpReportVersion2(DateTime.Now,
//// ethernetSource, ethernetDestination,
//// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
//// ipV4Source, ipV4Destination, ipV4Options,
//// igmpMaxResponseTime, igmpGroupAddress);
// break;
//
// case IgmpMessageType.LeaveGroupVersion2:
// igmpLayer = new IgmpLeaveGroupVersion2Layer
// {
// MaxResponseTime = igmpMaxResponseTime,
// GroupAddress = igmpGroupAddress
// };
// // packet = PacketBuilder.EthernetIpV4IgmpLeaveGroupVersion2(DateTime.Now,
//// ethernetSource, ethernetDestination,
//// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
//// ipV4Source, ipV4Destination, ipV4Options,
//// igmpMaxResponseTime, igmpGroupAddress);
// break;
//
// case IgmpMessageType.MembershipReportVersion3:
// igmpMaxResponseTime = TimeSpan.Zero;
// igmpGroupRecords = random.NextIgmpGroupRecords(random.Next(100));
// igmpLayer = new IgmpReportVersion3Layer
// {
// GroupRecords = igmpGroupRecords
// };
// // packet = PacketBuilder.EthernetIpV4IgmpReportVersion3(DateTime.Now,
//// ethernetSource, ethernetDestination,
//// ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl,
//// ipV4Source, ipV4Destination, ipV4Options,
//// igmpGroupRecords);
// break;
//
// default:
// throw new InvalidOperationException("Invalid message type " + igmpMessageType);
// }
Packet packet = new PacketBuilder2(ethernetLayer, ipV4Layer, igmpLayer).Build(DateTime.Now);
......@@ -230,30 +230,32 @@ namespace PcapDotNet.Packets.Test
// IGMP
Assert.IsTrue(packet.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.AreEqual(igmpMessageType, packet.Ethernet.IpV4.Igmp.MessageType);
Assert.AreEqual(igmpQueryVersion, packet.Ethernet.IpV4.Igmp.QueryVersion);
MoreAssert.IsInRange(igmpMaxResponseTime.Divide(2), igmpMaxResponseTime,
Assert.AreEqual(igmpLayer.MessageType, packet.Ethernet.IpV4.Igmp.MessageType);
Assert.AreEqual(igmpLayer.QueryVersion, packet.Ethernet.IpV4.Igmp.QueryVersion);
MoreAssert.IsInRange(igmpLayer.MaxResponseTimeValue.Divide(2), igmpLayer.MaxResponseTimeValue,
packet.Ethernet.IpV4.Igmp.MaxResponseTime, "MaxResponseTime");
if (igmpMessageType != IgmpMessageType.MembershipReportVersion3)
Assert.AreEqual(igmpGroupAddress, packet.Ethernet.IpV4.Igmp.GroupAddress, "GroupAddress");
if (igmpLayer.MessageType != IgmpMessageType.MembershipReportVersion3)
Assert.AreEqual(((IIgmpLayerWithGroupAddress)igmpLayer).GroupAddress, packet.Ethernet.IpV4.Igmp.GroupAddress, "GroupAddress");
// 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");
MoreAssert.IsInRange(igmpQueryInterval.Value.Divide(2), igmpQueryInterval.Value, packet.Ethernet.IpV4.Igmp.QueryInterval);
Assert.AreEqual(igmpQueryRobustnessVariable, packet.Ethernet.IpV4.Igmp.QueryRobustnessVariable);
Assert.AreEqual(igmpSourceAddresses.Length, packet.Ethernet.IpV4.Igmp.NumberOfSources);
MoreAssert.AreSequenceEqual(igmpSourceAddresses, packet.Ethernet.IpV4.Igmp.SourceAddresses);
MoreAssert.IsInRange(igmpQueryVersion3Layer.QueryInterval.Divide(2), igmpQueryVersion3Layer.QueryInterval, packet.Ethernet.IpV4.Igmp.QueryInterval);
Assert.AreEqual(igmpQueryVersion3Layer.QueryRobustnessVariable, packet.Ethernet.IpV4.Igmp.QueryRobustnessVariable);
Assert.AreEqual(igmpQueryVersion3Layer.SourceAddresses.Length, packet.Ethernet.IpV4.Igmp.NumberOfSources);
MoreAssert.AreSequenceEqual(igmpQueryVersion3Layer.SourceAddresses, packet.Ethernet.IpV4.Igmp.SourceAddresses);
}
// Report Version 3
if (igmpMessageType == IgmpMessageType.MembershipReportVersion3)
if (igmpLayer.MessageType == IgmpMessageType.MembershipReportVersion3)
{
Assert.AreEqual(igmpGroupRecords.Length, packet.Ethernet.IpV4.Igmp.NumberOfGroupRecords);
MoreAssert.AreSequenceEqual(igmpGroupRecords, packet.Ethernet.IpV4.Igmp.GroupRecords.Select(record => record.ToGroupRecord()));
Assert.IsTrue(igmpGroupRecords.All(record => record.ToString() != null));
IgmpReportVersion3Layer igmpReportVersion3Layer= (IgmpReportVersion3Layer)igmpLayer;
Assert.AreEqual(igmpReportVersion3Layer.GroupRecords.Length, packet.Ethernet.IpV4.Igmp.NumberOfGroupRecords);
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 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MoreRandomPackets.cs" />
<Compile Include="RandomPacketsExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
......
......@@ -5,6 +5,7 @@ using System.Text;
using PcapDotNet.Base;
using PcapDotNet.Packets;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Icmp;
using PcapDotNet.Packets.Igmp;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Transport;
......@@ -12,7 +13,7 @@ using PcapDotNet.TestUtils;
namespace PcapDotNet.Packets.TestUtils
{
public static class MoreRandomPackets
public static class RandomPacketsExtensions
{
public static Datagram NextDatagram(this Random random, int length)
{
......@@ -89,7 +90,7 @@ namespace PcapDotNet.Packets.TestUtils
return new IpV4Fragmentation(ipV4FragmentationFlags, ipV4FragmentationOffset);
}
public static IpV4TimeOfDay NextIpV4OptionTimeOfDay(this Random random)
public static IpV4TimeOfDay NextIpV4TimeOfDay(this Random random)
{
return new IpV4TimeOfDay(random.NextUInt());
}
......@@ -197,7 +198,7 @@ namespace PcapDotNet.Packets.TestUtils
{
case IpV4OptionTimestampType.TimestampOnly:
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);
case IpV4OptionTimestampType.AddressAndTimestamp:
......@@ -205,7 +206,7 @@ namespace PcapDotNet.Packets.TestUtils
int numPairs = random.Next((maximumOptionLength - IpV4OptionTimestamp.OptionMinimumLength) / 8 + 1);
IpV4OptionTimedAddress[] pairs = new IpV4OptionTimedAddress[numPairs];
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);
......@@ -387,6 +388,254 @@ namespace PcapDotNet.Packets.TestUtils
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
public static TcpOptions NextTcpOptions(this Random random)
......
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
......@@ -16,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpAddressMaskDatagram : IcmpIdentifiedDatagram
{
public const int HeaderLength = HeaderMinimumLength + HeaderAdditionalLength;
public const int HeaderAdditionalLength = 4;
private class Offset
{
public const int AddressMask = 4;
......@@ -33,5 +37,10 @@ namespace PcapDotNet.Packets.Icmp
: base(buffer, offset, length)
{
}
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4Address addressMask)
{
buffer.Write(offset + Offset.AddressMask, addressMask, Endianity.Big);
}
}
}
\ No newline at end of file
......@@ -11,39 +11,246 @@ namespace PcapDotNet.Packets.Icmp
/// 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.
/// </summary>
DestinationUnreachableNetUnreachable = 0x00,
NetUnreachable = 0x00,
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
DestinationUnreachableHostUnreachable = 0x01,
HostUnreachable = 0x01,
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
DestinationUnreachableProtocolUnreachable = 0x02,
ProtocolUnreachable = 0x02,
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
DestinationUnreachablePortUnreachable = 0x03,
PortUnreachable = 0x03,
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
DestinationUnreachableFragmentationNeededAndDontFragmentSet = 0x04,
FragmentationNeededAndDontFragmentSet = 0x04,
/// <summary>
/// RFC 792.
/// </summary>
DestinationUnreachableSourceRouteFailed = 0x05,
SourceRouteFailed = 0x05,
}
}
\ No newline at end of file
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;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// Generic
/// <pre>
/// +-----+------+------+-----------+
/// | Bit | 0-7 | 8-15 | 16-31 |
......@@ -23,6 +24,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public const int HeaderLength = 8;
public const int HeaderWithoutValueLength = HeaderLength - sizeof(uint);
private static class Offset
{
public const int Type = 0;
......
......@@ -24,8 +24,8 @@ namespace PcapDotNet.Packets.Icmp
{
get
{
if (_ipV4 == null && Length >= HeaderLength)
_ipV4 = new IpV4Datagram(Buffer, StartOffset + HeaderLength, Length - HeaderLength);
if (_ipV4 == null && Length >= HeaderMinimumLength)
_ipV4 = new IpV4Datagram(Buffer, StartOffset + HeaderMinimumLength, Length - HeaderMinimumLength);
return _ipV4;
}
}
......
......@@ -9,47 +9,47 @@ namespace PcapDotNet.Packets.Icmp
/// 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.
/// </summary>
DestinationUnreachableNetUnreachable = 0x0300,
DestinationUnreachableNetUnreachable = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.NetUnreachable,
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
DestinationUnreachableHostUnreachable = 0x0301,
DestinationUnreachableHostUnreachable = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.HostUnreachable,
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
DestinationUnreachableProtocolUnreachable = 0x0302,
DestinationUnreachableProtocolUnreachable = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.ProtocolUnreachable,
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
DestinationUnreachablePortUnreachable = 0x0303,
DestinationUnreachablePortUnreachable = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.PortUnreachable,
/// <summary>
/// RFC 792.
/// 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.
/// </summary>
DestinationUnreachableFragmentationNeededAndDontFragmentSet = 0x0304,
DestinationUnreachableFragmentationNeededAndDontFragmentSet = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.FragmentationNeededAndDontFragmentSet,
/// <summary>
/// RFC 792.
/// </summary>
DestinationUnreachableSourceRouteFailed = 0x0305,
DestinationUnreachableSourceRouteFailed = (IcmpMessageType.DestinationUnreachable << 8) | IcmpCodeDestinationUnrechable.SourceRouteFailed,
/// <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>
TimeExceededTimeToLive = 0x0B00,
TimeExceededTimeToLive = (IcmpMessageType.TimeExceeded << 8) | IcmpCodeTimeExceeded.TimeToLive,
/// <summary>
/// RFC 792.
......@@ -57,7 +57,7 @@ namespace PcapDotNet.Packets.Icmp
/// and it may send a time exceeded message.
/// If fragment zero is not available then no time exceeded need be sent at all.
/// </summary>
TimeExceededFragmentReassembly = 0x0B01,
TimeExceededFragmentReassembly = (IcmpMessageType.TimeExceeded << 8) | IcmpCodeTimeExceeded.FragmentReassembly,
/// <summary>
/// RFC 792.
......@@ -66,7 +66,7 @@ namespace PcapDotNet.Packets.Icmp
/// 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.
/// </summary>
ParameterProblemPointerIndicatesTheError = 0x0C00,
ParameterProblemPointerIndicatesTheError = (IcmpMessageType.ParameterProblem << 8),
/// <summary>
/// RFC 792.
......@@ -87,27 +87,27 @@ namespace PcapDotNet.Packets.Icmp
/// This means that the data datagram which triggered the source quench message may be delivered.
/// </para>
/// </summary>
SourceQuench = 0x0400,
SourceQuench = (IcmpMessageType.SourceQuench << 8),
/// <summary>
/// RFC 792.
/// </summary>
RedirectDatagramsForTheNetwork = 0x0500,
RedirectDatagramsForTheNetwork = (IcmpMessageType.Redirect << 8) | IcmpCodeRedirect.ForTheNetwork,
/// <summary>
/// RFC 792.
/// </summary>
RedirectDatagramsForTheHost = 0x0501,
RedirectDatagramsForTheHost = (IcmpMessageType.Redirect << 8) | IcmpCodeRedirect.ForTheHost,
/// <summary>
/// RFC 792.
/// </summary>
RedirectDatagramsForTheTypeOfServiceAndNetwork = 0x0502,
RedirectDatagramsForTheTypeOfServiceAndNetwork = (IcmpMessageType.Redirect << 8) | IcmpCodeRedirect.ForTheTypeOfServiceAndNetwork,
/// <summary>
/// RFC 792.
/// </summary>
RedirectDatagramsForTheTypeOfServiceAndHost = 0x0503,
RedirectDatagramsForTheTypeOfServiceAndHost = (IcmpMessageType.Redirect << 8) | IcmpCodeRedirect.ForTheTypeOfServiceAndHost,
/// <summary>
/// RFC 792.
......@@ -125,7 +125,7 @@ namespace PcapDotNet.Packets.Icmp
/// Code 0 may be received from a gateway or a host.
/// </para>
/// </summary>
Echo = 0x0800,
Echo = (IcmpMessageType.Echo << 8),
/// <summary>
/// RFC 792.
......@@ -143,7 +143,7 @@ namespace PcapDotNet.Packets.Icmp
/// Code 0 may be received from a gateway or a host.
/// </para>
/// </summary>
EchoReply = 0x0000,
EchoReply = (IcmpMessageType.EchoReply << 8),
/// <summary>
/// RFC 792
......@@ -167,7 +167,7 @@ namespace PcapDotNet.Packets.Icmp
/// Code 0 may be received from a gateway or a host.
/// </para>
/// </summary>
Timestamp = 0x0D00,
Timestamp = (IcmpMessageType.Timestamp << 8),
/// <summary>
/// RFC 792
......@@ -191,7 +191,7 @@ namespace PcapDotNet.Packets.Icmp
/// Code 0 may be received from a gateway or a host.
/// </para>
/// </summary>
TimestampReply = 0x0E00,
TimestampReply = (IcmpMessageType.TimestampReply << 8),
/// <summary>
/// RFC 792.
......@@ -211,7 +211,7 @@ namespace PcapDotNet.Packets.Icmp
/// Code 0 may be received from a gateway or a host.
/// </para>
/// </summary>
InformationRequest = 0x0F00,
InformationRequest = (IcmpMessageType.InformationRequest << 8),
/// <summary>
/// RFC 792.
......@@ -231,17 +231,17 @@ namespace PcapDotNet.Packets.Icmp
/// Code 0 may be received from a gateway or a host.
/// </para>
/// </summary>
InformationReply = 0x1000,
InformationReply = (IcmpMessageType.InformationReply << 8),
/// <summary>
/// RFC 1256.
/// </summary>
RouterAdvertisement = 0x0900,
RouterAdvertisement = (IcmpMessageType.RouterAdvertisement << 8),
/// <summary>
/// RFC 1256.
/// </summary>
RouterSolicitation = 0x0A00,
RouterSolicitation = (IcmpMessageType.RouterSolicitation << 8),
/// <summary>
/// RFC 950.
......@@ -258,7 +258,7 @@ namespace PcapDotNet.Packets.Icmp
/// The "Identifier" and "Sequence Number" fields can be ignored.
/// </para>
/// </summary>
AddressMaskRequest = 0xA100,
AddressMaskRequest = (IcmpMessageType.AddressMaskRequest << 8),
/// <summary>
/// RFC 950.
......@@ -275,17 +275,17 @@ namespace PcapDotNet.Packets.Icmp
/// The "Identifier" and "Sequence Number" fields can be ignored.
/// </para>
/// </summary>
AddressMaskReply = 0xA200,
AddressMaskReply = (IcmpMessageType.AddressMaskReply << 8),
/// <summary>
/// RFC 1393.
/// </summary>
TracerouteOutboundPacketSuccessfullyForwarded = 0x1E00,
TracerouteOutboundPacketSuccessfullyForwarded = (IcmpMessageType.Traceroute << 8) | IcmpCodeTraceroute.OutboundPacketSuccessfullyForwarded,
/// <summary>
/// RFC 1393.
/// </summary>
TracerouteNoRouteForOutboundPacketDiscarded = 0x1E01,
TracerouteNoRouteForOutboundPacketDiscarded = (IcmpMessageType.Traceroute << 8) | IcmpCodeTraceroute.NoRouteForOutboundPacketDiscarded,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedUnknownOrUnspecifiedError = 0x1F00,
ConversionFailedUnknownOrUnspecifiedError = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.UnknownOrUnspecifiedError,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedDontConvertOptionPresent = 0x1F01,
ConversionFailedDontConvertOptionPresent = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.DontConvertOptionPresent,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedUnknownMandatoryOptionPresent = 0x1F02,
ConversionFailedUnknownMandatoryOptionPresent = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.UnknownMandatoryOptionPresent,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedKnownUnsupportedOptionPresent = 0x1F03,
ConversionFailedKnownUnsupportedOptionPresent = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.KnownUnsupportedOptionPresent,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedUnsupportedTransportProtocol = 0x1F04,
ConversionFailedUnsupportedTransportProtocol = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.UnsupportedTransportProtocol,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedOverallLengthExceeded = 0x1F05,
ConversionFailedOverallLengthExceeded = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.OverallLengthExceeded,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedIpHeaderLengthExceeded = 0x1F06,
ConversionFailedIpHeaderLengthExceeded = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.IpHeaderLengthExceeded,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedTransportProtocolIsBiggerThan255 = 0x1F07,
ConversionFailedTransportProtocolIsBiggerThan255 = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.TransportProtocolIsBiggerThan255,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedPortConversionOutOfRange = 0x1F08,
ConversionFailedPortConversionOutOfRange = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.PortConversionOutOfRange,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedTransportHeaderLengthExceeded = 0x1F09,
ConversionFailedTransportHeaderLengthExceeded = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.TransportHeaderLengthExceeded,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailed32BitRolloverMissingAndAckSet = 0x1F0A,
ConversionFailed32BitRolloverMissingAndAckSet = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.Code32BitRolloverMissingAndAckSet,
/// <summary>
/// RFC 1475.
......@@ -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.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
ConversionFailedUnknownMandatoryTransportOptionPresent = 0x1F0B,
ConversionFailedUnknownMandatoryTransportOptionPresent = (IcmpMessageType.ConversionFailed << 8) | IcmpCodeConversionFailed.UnknownMandatoryTransportOptionPresent,
/// <summary>
/// RFC 1788.
/// </summary>
DomainNameRequest = 0x2500,
DomainNameRequest = (IcmpMessageType.DomainNameRequest << 8),
/// <summary>
/// RFC 1788.
/// Parsing of this datagram isn't supported because its parsing is not clear from the RFC.
/// </summary>
DomainNameReply = 0x2600,
DomainNameReply = (IcmpMessageType.DomainNameReply << 8),
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram includes a Security Parameters Index (SPI) that is invalid or has expired.
/// </summary>
SecurityFailuresBadSpi = 0x2800,
SecurityFailuresBadSpi = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.BadSpi,
/// <summary>
/// RFC 2521.
......@@ -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.
/// </para>
/// </summary>
SecurityFailuresAuthenticationFailed = 0x2801,
SecurityFailuresAuthenticationFailed = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.AuthenticationFailed,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed a decompression check for a given SPI.
/// </summary>
SecurityFailuresDecompressionFailed = 0x2802,
SecurityFailuresDecompressionFailed = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.DecompressionFailed,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed a decryption check for a given SPI.
/// </summary>
SecurityFailuresDecryptionFailed = 0x2803,
SecurityFailuresDecryptionFailed = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.DecryptionFailed,
/// <summary>
/// RFC 2521.
......@@ -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.
/// </para>
/// </summary>
SecurityFailuresNeedAuthentication = 0x2804,
SecurityFailuresNeedAuthentication = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.NeedAuthentication,
/// <summary>
/// RFC 2521.
......@@ -443,6 +443,6 @@ namespace PcapDotNet.Packets.Icmp
/// For example, the party is authorized for Telnet access, but not for FTP access.
/// </para>
/// </summary>
SecurityFailuresNeedAuthorization = 0x2805,
SecurityFailuresNeedAuthorization = (IcmpMessageType.SecurityFailures << 8) | IcmpCodeSecurityFailures.NeedAuthorization,
}
}
\ No newline at end of file
......@@ -5,6 +5,28 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
public class IcmpRouterAdvertisementEntry
{
public IcmpRouterAdvertisementEntry(IpV4Address routerAddress, int routerAddressPreference)
{
_routerAddress = routerAddress;
_routerAddressPreference = routerAddressPreference;
}
public IpV4Address RouterAddress
{
get { return _routerAddress;}
}
public int RouterAddressPreference
{
get {return _routerAddressPreference; }
}
private readonly IpV4Address _routerAddress;
private readonly int _routerAddressPreference;
}
/// <summary>
/// RFC 1256.
/// <pre>
......@@ -28,6 +50,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpRouterAdvertisementDatagram : IcmpTypedDatagram
{
public const int DefaultAddressEntrySize = 2;
private class Offset
{
public const int NumAddresses = 0;
......@@ -69,58 +93,51 @@ namespace PcapDotNet.Packets.Icmp
}
/// <summary>
/// The sending router's IP address(es) on the interface from which this message is sent.
/// The pairs of sending router's IP address(es) on the interface from which this message is sent
/// and the preferability of each Router Address[i] as a default router address, relative to other router addresses on the same subnet.
/// A signed, twos-complement value; higher values mean more preferable.
/// </summary>
public ReadOnlyCollection<IpV4Address> RouterAddresses
public ReadOnlyCollection<IcmpRouterAdvertisementEntry> Entries
{
get
{
if (_routerAddresses == null)
if (_entries == null)
{
IpV4Address[] addresses = new IpV4Address[NumAddresses];
IcmpRouterAdvertisementEntry[] entries = new IcmpRouterAdvertisementEntry[NumAddresses];
int currentOffset = Offset.Addresses;
for (int i = 0; i != addresses.Length && currentOffset + IpV4Address.SizeOf <= Length; ++i)
for (int i = 0; i != entries.Length && currentOffset + IpV4Address.SizeOf <= Length; ++i)
{
addresses[i] = ReadIpV4Address(currentOffset, Endianity.Big);
entries[i] = new IcmpRouterAdvertisementEntry(ReadIpV4Address(currentOffset, Endianity.Big),
ReadInt(currentOffset + IpV4Address.SizeOf, Endianity.Big));
currentOffset += AddressEntrySize * IpV4Address.SizeOf;
}
_routerAddresses = new ReadOnlyCollection<IpV4Address>(addresses);
_entries = new ReadOnlyCollection<IcmpRouterAdvertisementEntry>(entries);
}
return _routerAddresses;
return _entries;
}
}
/// <summary>
/// The preferability of each Router Address[i] as a default router address, relative to other router addresses on the same subnet.
/// A signed, twos-complement value; higher values mean more preferable.
/// </summary>
public ReadOnlyCollection<int> RouterAddressesPreferences
internal IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
get
{
if (_routerAddressesPreferences == null)
{
int[] addressesPreferences = new int[NumAddresses];
int currentOffset = Offset.Addresses;
for (int i = 0; i != addressesPreferences.Length && currentOffset + sizeof(int) <= Length; ++i)
{
addressesPreferences[i] = ReadInt(currentOffset, Endianity.Big);
currentOffset += AddressEntrySize * IpV4Address.SizeOf;
}
_routerAddressesPreferences = new ReadOnlyCollection<int>(addressesPreferences);
}
}
return _routerAddressesPreferences;
}
internal static int GetHeaderAdditionalLength(int numEntries)
{
return numEntries * DefaultAddressEntrySize * IpV4Address.SizeOf;
}
internal IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
internal static void WriteHeaderAdditional(byte[] buffer, int offset,
IEnumerable<IcmpRouterAdvertisementEntry> entries)
{
foreach (IcmpRouterAdvertisementEntry entry in entries)
{
buffer.Write(ref offset, entry.RouterAddress, Endianity.Big);
buffer.Write(ref offset, entry.RouterAddressPreference, Endianity.Big);
}
}
private ReadOnlyCollection<IpV4Address> _routerAddresses;
private ReadOnlyCollection<int> _routerAddressesPreferences;
private ReadOnlyCollection<IcmpRouterAdvertisementEntry> _entries;
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
......@@ -20,6 +21,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTimestampDatagram : IcmpIdentifiedDatagram
{
public const int HeaderLength = HeaderMinimumLength + HeaderAdditionalLength;
public const int HeaderAdditionalLength = 12;
private class Offset
{
public const int OriginateTimestamp = 4;
......@@ -55,5 +59,12 @@ namespace PcapDotNet.Packets.Icmp
: base(buffer, offset, length)
{
}
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4TimeOfDay originateTimestamp, IpV4TimeOfDay receiveTimestamp, IpV4TimeOfDay transmitTimestamp)
{
buffer.Write(ref offset, originateTimestamp, Endianity.Big);
buffer.Write(ref offset, receiveTimestamp, Endianity.Big);
buffer.Write(offset, transmitTimestamp, Endianity.Big);
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
......@@ -18,6 +20,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTracerouteDatagram : IcmpTypedDatagram
{
public const int HeaderAdditionalLength = 12;
private class Offset
{
public const int Identifier = 0;
......@@ -76,5 +80,13 @@ namespace PcapDotNet.Packets.Icmp
: base(buffer, offset, length)
{
}
internal static void WriteHeaderAdditional(byte[] buffer, int offset, ushort outboundHopCount, ushort returnHopCount, uint outputLinkSpeed, uint outputLinkMtu)
{
buffer.Write(ref offset, outboundHopCount, Endianity.Big);
buffer.Write(ref offset, returnHopCount, Endianity.Big);
buffer.Write(ref offset, outputLinkSpeed, Endianity.Big);
buffer.Write(offset, outputLinkMtu, Endianity.Big);
}
}
}
\ No newline at end of file
......@@ -2,7 +2,7 @@ namespace PcapDotNet.Packets.Icmp
{
public class IcmpTypedDatagram : Datagram
{
public const int HeaderLength = 4;
public const int HeaderMinimumLength = 4;
internal IcmpTypedDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
......
using System;
using PcapDotNet.Packets.Icmp;
namespace PcapDotNet.Packets
{
public class IcmpTracerouteLayer : IcmpLayer
{
public IcmpCodeTraceroute Code { get; set; }
public ushort Identification{get;set;}
public ushort OutboundHopCount{get;set;}
public ushort ReturnHopCount{get;set;}
public uint OutputLinkSpeed{get;set;}
public uint OutputLinkMtu{get;set;}
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.Traceroute; }
}
public override int Length
{
get
{
return base.Length + IcmpTracerouteDatagram.HeaderAdditionalLength;
}
}
public override byte CodeValue
{
get
{
return (byte)Code;
}
}
protected override uint Value
{
get
{
return (uint)(Identification << 16);
}
}
protected override void WriteHeaderAdditional(byte[] buffer, int offset)
{
IcmpTracerouteDatagram.WriteHeaderAdditional(buffer, offset, OutboundHopCount, ReturnHopCount, OutputLinkSpeed, OutputLinkMtu);
}
}
}
\ No newline at end of file
......@@ -412,6 +412,12 @@ namespace PcapDotNet.Packets
Write(buffer, offset, value);
}
public static void Write(this byte[] buffer, ref int offset, int value, Endianity endianity)
{
Write(buffer, offset, value, endianity);
offset += sizeof(int);
}
/// <summary>
/// Writes the given value to the buffer using the given endianity.
/// </summary>
......@@ -535,6 +541,11 @@ namespace PcapDotNet.Packets
buffer.Write(ref offset, value.ToValue(), endianity);
}
public static void Write(this byte[] buffer, int offset, IpV4TimeOfDay value, Endianity endianity)
{
buffer.Write(offset, value.MillisecondsSinceMidnightUniversalTime, endianity);
}
/// <summary>
/// Writes the given value to the buffer using the given endianity and increments the offset by the number of bytes written.
/// </summary>
......
......@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using PcapDotNet.Packets.Arp;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Icmp;
using PcapDotNet.Packets.Igmp;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Transport;
......@@ -368,17 +369,27 @@ namespace PcapDotNet.Packets
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
{
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 abstract IgmpMessageType MessageType { get; }
public abstract TimeSpan MaxResponseTimeValue { get; }
public override int Length
{
get { return IgmpDatagram.HeaderLength; }
......@@ -414,6 +425,14 @@ namespace PcapDotNet.Packets
{
get { return IgmpMessageType.MembershipQuery; }
}
public override IgmpQueryVersion QueryVersion
{
get
{
return IgmpQueryVersion.Version1;
}
}
}
public class IgmpQueryVersion2Layer : IgmpVersion2Layer
......@@ -422,9 +441,17 @@ namespace PcapDotNet.Packets
{
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 IpV4Address GroupAddress { get; set; }
......@@ -447,6 +474,24 @@ namespace PcapDotNet.Packets
MaxResponseTime, GroupAddress, IsSuppressRouterSideProcessing, QueryRobustnessVariable,
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
......@@ -486,6 +531,347 @@ namespace PcapDotNet.Packets
{
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
......@@ -530,13 +916,13 @@ namespace PcapDotNet.Packets
private void FinalizeLayers(byte[] buffer, int length)
{
int offset = 0;
for (int i = 0; i != _layers.Length; ++i)
int offset = length;
for (int i = _layers.Length - 1; i >= 0; --i)
{
ILayer layer = _layers[i];
ILayer nextLayer = i == _layers.Length - 1 ? null : _layers[i + 1];
offset -= layer.Length;
layer.Finalize(buffer, offset, length - offset - layer.Length, nextLayer);
offset += layer.Length;
}
}
......
......@@ -70,6 +70,7 @@
<Compile Include="Ethernet\EthernetDatagram.cs" />
<Compile Include="Ethernet\EthernetType.cs" />
<Compile Include="Ethernet\MacAddress.cs" />
<Compile Include="IcmpTracerouteLayer.cs" />
<Compile Include="Icmp\IcmpAddressMaskDatagram.cs" />
<Compile Include="Icmp\IcmpCodeDestinationUnrechable.cs" />
<Compile Include="Icmp\IcmpConversionFailedDatagram.cs" />
......
......@@ -124,7 +124,7 @@ namespace PcapDotNet.TestUtils
return random.NextEnum((IEnumerable<T>)valuesToIgnore);
}
public static object NextValue<T>(this Random random, IList<T> values)
public static T NextValue<T>(this Random random, IList<T> values)
{
return values[random.Next(values.Count)];
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment