From 49164e48223f6d446dacb3edc6805115c8d137c0 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sun, 27 Nov 2016 17:42:38 +0100 Subject: [PATCH 01/19] add extension to create a random c-strings --- .../PcapDotNet.TestUtils/RandomExtensions.cs | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/PcapDotNet/src/PcapDotNet.TestUtils/RandomExtensions.cs b/PcapDotNet/src/PcapDotNet.TestUtils/RandomExtensions.cs index 4f2233d9..e13739bf 100644 --- a/PcapDotNet/src/PcapDotNet.TestUtils/RandomExtensions.cs +++ b/PcapDotNet/src/PcapDotNet.TestUtils/RandomExtensions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Text; using PcapDotNet.Base; namespace PcapDotNet.TestUtils @@ -207,5 +208,28 @@ public static T NextFlags(this Random random) T resultEnum = (T)Convert.ChangeType(resultValue, underlyingType); return resultEnum; } + + public static string NextCString(this Random random, int minLength, int maxLength) + { + if (minLength < 0) + throw new ArgumentOutOfRangeException(nameof(minLength), minLength, $"{nameof(minLength)} has to be greater than {nameof(maxLength)}"); + if (minLength > maxLength) + throw new ArgumentOutOfRangeException(nameof(minLength), minLength, $"{nameof(minLength)} has to be greater or equal than {nameof(maxLength)}"); + + return random.NextCString(random.NextInt(minLength, maxLength)); + } + + public static string NextCString(this Random random, int length) + { + if (length < 0) + throw new ArgumentOutOfRangeException(nameof(length), length, $"{nameof(length)} has to be greater than 0"); + + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < length; i++) + { + builder.Append(random.NextChar((char)1, (char)127)); + } + return builder.ToString(); + } } -} +} \ No newline at end of file From d2faae883e51ed65a4a2105e80cba1c5a33db930 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sun, 27 Nov 2016 17:43:29 +0100 Subject: [PATCH 02/19] add dhcp support --- .../src/PcapDotNet.Packets.Test/DhcpTests.cs | 84 ++ .../PcapDotNet.Packets.Test.csproj | 1 + .../PcapDotNet.Packets.TestUtils.csproj | 1 + .../RandomDhcpExtensions.cs | 333 +++++++ .../PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 309 ++++++ .../src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs | 37 + .../src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs | 136 +++ .../Dhcp/DhcpMessageType.cs | 27 + .../Dhcp/Options/DhcpARPCacheTimeoutOption.cs | 57 ++ .../Dhcp/Options/DhcpAddressListOption.cs | 73 ++ .../Options/DhcpAllSubnetsAreLocalOption.cs | 57 ++ .../Dhcp/Options/DhcpAnyOption.cs | 65 ++ .../Dhcp/Options/DhcpBootFileSizeOption.cs | 56 ++ .../Dhcp/Options/DhcpBootfileNameOption.cs | 66 ++ .../Options/DhcpBroadcastAddressOption.cs | 52 ++ .../Options/DhcpClientIdentifierOption.cs | 78 ++ .../Dhcp/Options/DhcpCookieServerOption.cs | 31 + .../Options/DhcpDefaultFingerServerOption.cs | 31 + .../Options/DhcpDefaultIPTimeToLiveOption.cs | 52 ++ ...hcpDefaultInternetRelayChatServerOption.cs | 31 + .../DhcpDefaultWorldWideWebServerOption.cs | 31 + .../Dhcp/Options/DhcpDomainNameOption.cs | 67 ++ .../Options/DhcpDomainNameServerOption.cs | 22 + .../Dhcp/Options/DhcpEndOption.cs | 39 + .../DhcpEthernetEncapsulationOption.cs | 57 ++ .../Dhcp/Options/DhcpExtensionsPathOption.cs | 66 ++ .../Dhcp/Options/DhcpHostNameOption.cs | 66 ++ .../Options/DhcpIPAddressLeaseTimeOption.cs | 52 ++ .../Options/DhcpIPForwardingEnableOption.cs | 58 ++ .../Dhcp/Options/DhcpImpressServerOption.cs | 22 + .../Dhcp/Options/DhcpInterfaceMTUOption.cs | 51 + .../Dhcp/Options/DhcpLPRServerOption.cs | 22 + .../Dhcp/Options/DhcpLogServerOption.cs | 22 + .../Dhcp/Options/DhcpMaskSupplierOption.cs | 57 ++ ...DhcpMaximumDatagramReassemblySizeOption.cs | 57 ++ .../DhcpMaximumDhcpMessageSizeOption.cs | 56 ++ .../Dhcp/Options/DhcpMeritDumpFileOption.cs | 66 ++ .../Dhcp/Options/DhcpMessageOption.cs | 66 ++ .../Dhcp/Options/DhcpMessageTypeOption.cs | 74 ++ .../Options/DhcpMobileIPHomeAgentOption.cs | 31 + .../Dhcp/Options/DhcpNameServerOption.cs | 22 + ...erTCPIPDatagramDistributionServerOption.cs | 31 + .../DhcpNetBIOSOverTCPIPNameServerOption.cs | 31 + .../DhcpNetBIOSOverTCPIPNodeTypeOption.cs | 81 ++ .../DhcpNetBIOSOverTCPIPScopeOption.cs | 70 ++ .../DhcpNetworkInformationServersOption.cs | 31 + ...cpNetworkInformationServiceDomainOption.cs | 67 ++ ...tworkInformationServicePlusDomainOption.cs | 66 ++ ...workInformationServicePlusServersOption.cs | 31 + ...etworkNewsTransportProtocolServerOption.cs | 31 + .../DhcpNetworkTimeProtocolServersOption.cs | 31 + .../DhcpNonLocalSourceRoutingEnableOption.cs | 57 ++ .../Dhcp/Options/DhcpOption.cs | 359 +++++++ .../Dhcp/Options/DhcpOptionCode.cs | 884 ++++++++++++++++++ .../Dhcp/Options/DhcpOptionOverloadOption.cs | 70 ++ .../Dhcp/Options/DhcpPadOption.cs | 39 + .../Options/DhcpParameterRequestListOption.cs | 65 ++ .../Options/DhcpPathMTUAgingTimeoutOption.cs | 57 ++ .../Options/DhcpPathMTUPlateauTableOption.cs | 76 ++ .../Options/DhcpPerformMaskDiscoveryOption.cs | 57 ++ .../DhcpPerformRouterDiscoveryOption.cs | 57 ++ .../Dhcp/Options/DhcpPolicyFilterOption.cs | 107 +++ .../DhcpPostOfficeProtocolServerOption.cs | 31 + .../Options/DhcpRebindingTimeValueOption.cs | 53 ++ .../Options/DhcpRenewalTimeValueOption.cs | 53 ++ .../Options/DhcpRequestedIPAddressOption.cs | 52 ++ .../DhcpResourceLocationServerOption.cs | 22 + .../Dhcp/Options/DhcpRootPathOption.cs | 66 ++ .../Dhcp/Options/DhcpRouterOption.cs | 22 + .../DhcpRouterSolicitationAddressOption.cs | 52 ++ .../Options/DhcpServerIdentifierOption.cs | 52 ++ ...SimpleMailTransportProtocolServerOption.cs | 31 + .../Dhcp/Options/DhcpStaticRouteOption.cs | 89 ++ ...reetTalkDirectoryAssistanceServerOption.cs | 31 + .../Options/DhcpStreetTalkServerOption.cs | 31 + .../Dhcp/Options/DhcpSubnetMaskOption.cs | 52 ++ .../Dhcp/Options/DhcpSwapServerOption.cs | 52 ++ .../Dhcp/Options/DhcpTCPDefaultTTLOption.cs | 58 ++ .../Options/DhcpTCPKeepaliveGarbageOption.cs | 58 ++ .../Options/DhcpTCPKeepaliveIntervalOption.cs | 53 ++ .../Dhcp/Options/DhcpTFTPServerNameOption.cs | 66 ++ .../Dhcp/Options/DhcpTimeOffsetOption.cs | 53 ++ .../Dhcp/Options/DhcpTimeServerOption.cs | 22 + .../Options/DhcpTrailerEncapsulationOption.cs | 58 ++ .../DhcpVendorClassidentifierOption.cs | 74 ++ .../DhcpVendorSpecificInformationOption.cs | 70 ++ .../DhcpXWindowSystemDisplayManagerOption.cs | 31 + .../DhcpXWindowSystemFontServerOption.cs | 31 + .../PcapDotNet.Packets.csproj | 84 ++ .../Transport/UdpDatagram.cs | 51 +- 90 files changed, 6260 insertions(+), 17 deletions(-) create mode 100644 PcapDotNet/src/PcapDotNet.Packets.Test/DhcpTests.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMTUOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLPRServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNameServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNodeTypeOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPScopeOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionCode.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUAgingTimeoutOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUPlateauTableOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPDefaultTTLOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveGarbageOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveIntervalOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFTPServerNameOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs diff --git a/PcapDotNet/src/PcapDotNet.Packets.Test/DhcpTests.cs b/PcapDotNet/src/PcapDotNet.Packets.Test/DhcpTests.cs new file mode 100644 index 00000000..81dc57f7 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets.Test/DhcpTests.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using PcapDotNet.Packets.Dhcp; +using PcapDotNet.Packets.Ethernet; +using PcapDotNet.Packets.IpV4; +using PcapDotNet.Packets.TestUtils; +using PcapDotNet.Packets.Transport; + +namespace PcapDotNet.Packets.Test +{ + /// + /// Summary description for ArpTests + /// + [TestClass] + [ExcludeFromCodeCoverage] + public class DhcpTests + { + /// + /// Gets or sets the test context which provides + /// information about and functionality for the current test run. + /// + public TestContext TestContext { get; set; } + + #region Additional test attributes + + // + // You can use the following additional attributes as you write your tests: + // + // Use ClassInitialize to run code before running the first test in the class + // [ClassInitialize()] + // public static void MyClassInitialize(TestContext testContext) { } + // + // Use ClassCleanup to run code after all tests in a class have run + // [ClassCleanup()] + // public static void MyClassCleanup() { } + // + // Use TestInitialize to run code before running each test + // [TestInitialize()] + // public void MyTestInitialize() { } + // + // Use TestCleanup to run code after each test has run + // [TestCleanup()] + // public void MyTestCleanup() { } + // + + #endregion Additional test attributes + + [TestMethod] + public void RandomDhcpTest() + { + int seed = new Random().Next(); + Console.WriteLine("Seed: " + seed); + Random random = new Random(seed); + + for (int i = 0; i != 1000; ++i) + { + EthernetLayer ethernetLayer = random.NextEthernetLayer(EthernetType.None); + + IpV4Layer ipV4Layer = random.NextIpV4Layer(null); + ipV4Layer.HeaderChecksum = null; + + UdpLayer udpLayer = random.NextUdpLayer(); + udpLayer.Checksum = null; + + DhcpLayer dhcpLayer = random.NextDhcpLayer(); + + Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, udpLayer, dhcpLayer); + + Assert.IsTrue(packet.IsValid, "IsValid"); + DhcpLayer actualLayer = (DhcpLayer)packet.Ethernet.Ip.Udp.Dhcp.ExtractLayer(); + if (!Object.Equals(dhcpLayer, actualLayer)) + { + Console.WriteLine(actualLayer); + } + Assert.AreEqual(dhcpLayer, actualLayer, "DHCP Layer"); + } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets.Test/PcapDotNet.Packets.Test.csproj b/PcapDotNet/src/PcapDotNet.Packets.Test/PcapDotNet.Packets.Test.csproj index 42728d0f..bf4214f1 100644 --- a/PcapDotNet/src/PcapDotNet.Packets.Test/PcapDotNet.Packets.Test.csproj +++ b/PcapDotNet/src/PcapDotNet.Packets.Test/PcapDotNet.Packets.Test.csproj @@ -75,6 +75,7 @@ + diff --git a/PcapDotNet/src/PcapDotNet.Packets.TestUtils/PcapDotNet.Packets.TestUtils.csproj b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/PcapDotNet.Packets.TestUtils.csproj index 50328411..f4d40d4b 100644 --- a/PcapDotNet/src/PcapDotNet.Packets.TestUtils/PcapDotNet.Packets.TestUtils.csproj +++ b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/PcapDotNet.Packets.TestUtils.csproj @@ -76,6 +76,7 @@ + diff --git a/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs new file mode 100644 index 00000000..f4939c7a --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs @@ -0,0 +1,333 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using PcapDotNet.Base; +using PcapDotNet.Packets.Arp; +using PcapDotNet.Packets.Dhcp; +using PcapDotNet.Packets.Dhcp.Options; +using PcapDotNet.Packets.IpV4; +using PcapDotNet.Packets.IpV6; +using PcapDotNet.TestUtils; + +namespace PcapDotNet.Packets.TestUtils +{ + [ExcludeFromCodeCoverage] + public static class RandomDhcpExtensions + { + public static DhcpLayer NextDhcpLayer(this Random random) + { + const int MaxOptions = 10; + + DhcpLayer dhcpLayer = new DhcpLayer(); + dhcpLayer.MessageType = random.NextEnum(); + dhcpLayer.HardwareType = random.NextEnum(Enum.GetValues(typeof(ArpHardwareType)).Cast().Where(p => ((short)p) > byte.MaxValue)); + dhcpLayer.HardwareAddressLength = random.NextByte(16); + dhcpLayer.Hops = random.NextByte(); + dhcpLayer.TransactionId = random.NextInt(); + dhcpLayer.SecondsElapsed = random.NextUShort(); + dhcpLayer.Flags = random.NextEnum(); + dhcpLayer.ClientIpAddress = random.NextIpV4Address(); + dhcpLayer.YourClientIpAddress = random.NextIpV4Address(); + dhcpLayer.NextServerIpAddress = random.NextIpV4Address(); + dhcpLayer.RelayAgentIpAddress = random.NextIpV4Address(); + dhcpLayer.RelayAgentIpAddress = random.NextIpV4Address(); + dhcpLayer.ClientHardwareAddress = random.NextDataSegment(16); + if (random.NextBool()) + { + dhcpLayer.ServerHostName = random.NextCString(1, 64); + } + else + { + dhcpLayer.ServerHostName = ""; + } + if (random.NextBool()) + { + dhcpLayer.BootFileName = random.NextCString(1, 128); + } + else + { + dhcpLayer.BootFileName = ""; + } + dhcpLayer.IsDhcp = random.NextBool(); + int numQueries = random.Next(MaxOptions + 1); + List options = new List(); + for (int i = 0; i != numQueries; ++i) + options.Add(random.NextDhcpOption()); + dhcpLayer.Options = options; + + return dhcpLayer; + } + + public static DhcpOption NextDhcpOption(this Random random) + { + switch (random.NextEnum()) + { + #region 3. RFC 1497 Vendor Extensions + + case DhcpOptionCode.Pad: + return new DhcpPadOption(); + + case DhcpOptionCode.End: + return new DhcpEndOption(); + + case DhcpOptionCode.SubnetMask: + return new DhcpSubnetMaskOption(random.NextIpV4Address()); + + case DhcpOptionCode.TimeOffset: + return new DhcpTimeOffsetOption(random.NextUInt()); + + case DhcpOptionCode.Router: + return new DhcpRouterOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.TimeServer: + return new DhcpTimeServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.NameServer: + return new DhcpNameServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.DomainNameServerServer: + return new DhcpDomainNameServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.LogServer: + return new DhcpLogServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.CookieServer: + return new DhcpCookieServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.LPRServer: + return new DhcpLPRServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.ImpressServer: + return new DhcpImpressServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.ResourceLocationServer: + return new DhcpResourceLocationServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.HostName: + return new DhcpHostNameOption(random.NextCString(1, 254)); + + case DhcpOptionCode.BootFileSize: + return new DhcpBootFileSizeOption(random.NextUShort()); + + case DhcpOptionCode.MeritDumpFile: + return new DhcpMeritDumpFileOption(random.NextCString(1, 254)); + + case DhcpOptionCode.DomainName: + return new DhcpDomainNameOption(random.NextCString(1, 254)); + + case DhcpOptionCode.SwapServer: + return new DhcpSwapServerOption(random.NextIpV4Address()); + + case DhcpOptionCode.RootPath: + return new DhcpRootPathOption(random.NextCString(1, 254)); + + case DhcpOptionCode.ExtensionsPath: + return new DhcpExtensionsPathOption(random.NextCString(1, 254)); + + #endregion 3. RFC 1497 Vendor Extensions + + #region 4. IP Layer Parameters per Host + + case DhcpOptionCode.IPForwardingEnable: + return new DhcpIPForwardingEnableOption(random.NextBool()); + + case DhcpOptionCode.NonLocalSourceRoutingEnable: + return new DhcpNonLocalSourceRoutingEnableOption(random.NextBool()); + + case DhcpOptionCode.PolicyFilter: + return new DhcpPolicyFilterOption(Enumerable.Range(0, random.NextByte() / DhcpPolicyFilterOption.IpV4AddressWithMask.SizeOf).Select(p => new DhcpPolicyFilterOption.IpV4AddressWithMask(random.NextIpV4Address(), random.NextIpV4Address())).ToList()); + + case DhcpOptionCode.MaximumDatagramReassemblySize: + return new DhcpMaximumDatagramReassemblySizeOption(random.NextUShort()); + + case DhcpOptionCode.DefaultIPTimeToLive: + return new DhcpDefaultIPTimeToLiveOption(random.NextByte()); + + case DhcpOptionCode.PathMTUAgingTimeout: + return new DhcpPathMTUAgingTimeoutOption(random.NextUInt()); + + case DhcpOptionCode.PathMTUPlateauTable: + return new DhcpPathMTUPlateauTableOption(Enumerable.Range(0, random.NextByte() / sizeof(ushort)).Select(p => random.NextUShort()).ToList()); + + #endregion 4. IP Layer Parameters per Host + + #region 5. IP Layer Parameters per Interface + + case DhcpOptionCode.InterfaceMTU: + return new DhcpInterfaceMTUOption(random.NextUShort()); + + case DhcpOptionCode.AllSubnetsAreLocal: + return new DhcpAllSubnetsAreLocalOption(random.NextBool()); + + case DhcpOptionCode.BroadcastAddress: + return new DhcpBroadcastAddressOption(random.NextIpV4Address()); + + case DhcpOptionCode.PerformMaskDiscovery: + return new DhcpPerformMaskDiscoveryOption(random.NextBool()); + + case DhcpOptionCode.MaskSupplier: + return new DhcpMaskSupplierOption(random.NextBool()); + + case DhcpOptionCode.PerformRouterDiscovery: + return new DhcpPerformRouterDiscoveryOption(random.NextBool()); + + case DhcpOptionCode.RouterSolicitationAddress: + return new DhcpRouterSolicitationAddressOption(random.NextIpV4Address()); + + case DhcpOptionCode.StaticRoute: + return new DhcpStaticRouteOption(Enumerable.Range(0, random.NextByte() / IpV4Address.SizeOf / 2).Select(p => new DhcpStaticRouteOption.IpV4AddressRoute(random.NextIpV4Address(), random.NextIpV4Address())).ToList()); + + #endregion 5. IP Layer Parameters per Interface + + #region 6. Link Layer Parameters per Interface + + case DhcpOptionCode.TrailerEncapsulation: + return new DhcpTrailerEncapsulationOption(random.NextBool()); + + case DhcpOptionCode.ARPCacheTimeout: + return new DhcpARPCacheTimeoutOption(random.NextUInt()); + + case DhcpOptionCode.EthernetEncapsulation: + return new DhcpEthernetEncapsulationOption(random.NextBool()); + + #endregion 6. Link Layer Parameters per Interface + + #region 7. TCP Parameters + + case DhcpOptionCode.TCPDefaultTTL: + return new DhcpTCPDefaultTTLOption(random.NextBool()); + + case DhcpOptionCode.TCPKeepaliveInterval: + return new DhcpTCPKeepaliveIntervalOption(random.NextUInt()); + + case DhcpOptionCode.TCPKeepaliveGarbage: + return new DhcpTCPKeepaliveGarbageOption(random.NextBool()); + + #endregion 7. TCP Parameters + + #region 8. Application and Service Parameters + + case DhcpOptionCode.NetworkInformationServiceDomain: + return new DhcpNetworkInformationServiceDomainOption(random.NextCString(1, 254)); + + case DhcpOptionCode.NetworkInformationServers: + return new DhcpNetworkInformationServersOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.NetworkTimeProtocolServers: + return new DhcpNetworkTimeProtocolServersOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.VendorSpecificInformation: + return new DhcpVendorSpecificInformationOption(random.NextDataSegment(random.NextByte(1, 254))); + + case DhcpOptionCode.NetBIOSOverTCPIPNameServer: + return new DhcpNetBIOSOverTCPIPNameServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); ; + + case DhcpOptionCode.NetBIOSOverTCPIPDatagramDistributionServer: + return new DhcpNetBIOSOverTCPIPDatagramDistributionServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.NetBIOSOverTCPIPNodeType: + DhcpNetBIOSOverTCPIPNodeTypeOption.NodeType flag; + do + { + flag = random.NextFlags(); + } while (flag == 0); + return new DhcpNetBIOSOverTCPIPNodeTypeOption(flag); + + case DhcpOptionCode.NetBIOSOverTCPIPScope: + return new DhcpNetBIOSOverTCPIPScopeOption(random.NextDataSegment(random.NextByte(1, 254))); + + case DhcpOptionCode.XWindowSystemFontServer: + return new DhcpXWindowSystemFontServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.XWindowSystemDisplayManager: + return new DhcpXWindowSystemDisplayManagerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.NetworkInformationServicePlusDomain: + return new DhcpNetworkInformationServicePlusDomainOption(random.NextCString(1, 254)); + + case DhcpOptionCode.NetworkInformationServicePlusServers: + return new DhcpNetworkInformationServicePlusServersOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.MobileIPHomeAgent: + return new DhcpMobileIPHomeAgentOption(random.NextIpV4Addresses(random.Next(0, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.SimpleMailTransportProtocolServer: + return new DhcpSimpleMailTransportProtocolServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.PostOfficeProtocolServer: + return new DhcpPostOfficeProtocolServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.NetworkNewsTransportProtocolServer: + return new DhcpNetworkNewsTransportProtocolServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.DefaultWorldWideWebServer: + return new DhcpDefaultWorldWideWebServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.DefaultFingerServer: + return new DhcpDefaultFingerServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.DefaultInternetRelayChatServer: + return new DhcpDefaultInternetRelayChatServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.StreetTalkServer: + return new DhcpStreetTalkServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + case DhcpOptionCode.StreetTalkDirectoryAssistanceServer: + return new DhcpStreetTalkDirectoryAssistanceServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); + + #endregion 8. Application and Service Parameters + + #region 9.DHCP Extensions + + case DhcpOptionCode.RequestedIPAddress: + return new DhcpRequestedIPAddressOption(random.NextIpV4Address()); + + case DhcpOptionCode.IPAddressLeaseTime: + return new DhcpIPAddressLeaseTimeOption(random.NextUInt()); + + case DhcpOptionCode.OptionOverload: + return new DhcpOptionOverloadOption(random.NextEnum()); + + case DhcpOptionCode.TFTPServerName: + return new DhcpTFTPServerNameOption(random.NextCString(1, byte.MaxValue - 1)); + + case DhcpOptionCode.BootfileName: + return new DhcpBootfileNameOption(random.NextCString(1, byte.MaxValue - 1)); + + case DhcpOptionCode.MessageType: + return new DhcpMessageTypeOption(random.NextEnum()); + + case DhcpOptionCode.ServerIdentifier: + return new DhcpServerIdentifierOption(random.NextIpV4Address()); + + case DhcpOptionCode.ParameterRequestList: + return new DhcpParameterRequestListOption(Enumerable.Range(1, random.NextByte(byte.MaxValue - 1)).Select(p => random.NextEnum()).ToList()); + + case DhcpOptionCode.Message: + return new DhcpMessageOption(random.NextCString(1, byte.MaxValue - 1)); + + case DhcpOptionCode.MaximumDhcpMessageSize: + return new DhcpMaximumDhcpMessageSizeOption(random.NextUShort()); + + case DhcpOptionCode.RenewalTimeValue: + return new DhcpRenewalTimeValueOption(random.NextUInt()); + + case DhcpOptionCode.RebindingTimeValue: + return new DhcpRebindingTimeValueOption(random.NextUInt()); + + case DhcpOptionCode.VendorClassidentifier: + return new DhcpVendorClassidentifierOption(random.NextDataSegment(random.NextByte(1, 254))); + + case DhcpOptionCode.ClientIdentifier: + return new DhcpClientIdentifierOption(random.NextByte(), random.NextDataSegment(random.NextByte(1, byte.MaxValue - 1))); + + #endregion 9.DHCP Extensions + + default: + throw new NotSupportedException(); + } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs new file mode 100644 index 00000000..e39c8411 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -0,0 +1,309 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.Arp; +using PcapDotNet.Packets.Dhcp.Options; +using PcapDotNet.Packets.Ethernet; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp +{ + /// + /// RFC 2131. + /// The DHCP message structure is shown below: + ///
+    /// 0                   1                   2                   3
+    /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    /// |     op (1)    |   htype (1)   |   hlen (1)    |   hops (1)    |
+    /// +---------------+---------------+---------------+---------------+
+    /// |                            xid (4)                            |
+    /// +-------------------------------+-------------------------------+
+    /// |           secs (2)            |           flags (2)           |
+    /// +-------------------------------+-------------------------------+
+    /// |                          ciaddr  (4)                          |
+    /// +---------------------------------------------------------------+
+    /// |                          yiaddr  (4)                          |
+    /// +---------------------------------------------------------------+
+    /// |                          siaddr  (4)                          |
+    /// +---------------------------------------------------------------+
+    /// |                          giaddr  (4)                          |
+    /// +---------------------------------------------------------------+
+    /// |                                                               |
+    /// |                          chaddr  (16)                         |
+    /// |                                                               |
+    /// |                                                               |
+    /// +---------------------------------------------------------------+
+    /// |                                                               |
+    /// |                          sname   (64)                         |
+    /// +---------------------------------------------------------------+
+    /// |                                                               |
+    /// |                          file    (128)                        |
+    /// +---------------------------------------------------------------+
+    /// |                                                               |
+    /// |                          options (variable)                   |
+    /// +---------------------------------------------------------------+
+    /// 
+ ///
+ public class DhcpDatagram : Datagram + { + private static class Offset + { + public const int Op = 0; + public const int Htype = 1; + public const int Hlen = 2; + public const int Hops = 3; + public const int Xid = 4; + public const int Secs = 8; + public const int Flags = 10; + public const int CiAddr = 12; + public const int YiAddr = 16; + public const int SiAddr = 20; + public const int GiAddr = 24; + public const int ChAddr = 28; + public const int Sname = 44; + public const int File = 108; + public const int Options = 236; + public const int OptionsWithMagicCookie = 240; + } + + internal const int DHCP_MAGIC_COOKIE = 0x63825363; + + public DhcpMessageType MessageType + { + get { return (DhcpMessageType)this[Offset.Op]; } + } + + public ArpHardwareType HardwareType + { + get { return (ArpHardwareType)this[Offset.Htype]; } + } + + public byte HardwareAddressLength + { + get { return (byte)this[Offset.Hlen]; } + } + + public byte Hops + { + get { return (byte)this[Offset.Hops]; } + } + + public int TransactionId + { + get { return ReadInt(Offset.Xid, Endianity.Big); } + } + + public ushort SecondsElapsed + { + get { return ReadUShort(Offset.Secs, Endianity.Big); } + } + + public DhcpFlags Flags + { + get { return (DhcpFlags)ReadUShort(Offset.Flags, Endianity.Big); } + } + + public IpV4Address ClientIpAddress + { + get { return ReadIpV4Address(Offset.CiAddr, Endianity.Big); } + } + + public IpV4Address YourClientIpAddress + { + get { return ReadIpV4Address(Offset.YiAddr, Endianity.Big); } + } + + public IpV4Address NextServerIpAddress + { + get { return ReadIpV4Address(Offset.SiAddr, Endianity.Big); } + } + + public IpV4Address RelayAgentIpAddress + { + get { return ReadIpV4Address(Offset.GiAddr, Endianity.Big); } + } + + public DataSegment ClientHardwareAddress + { + get { return this.Subsegment(Offset.ChAddr, 16); } + } + + public MacAddress ClientMacAddress + { + get { return new MacAddress(ReadUInt48(Offset.ChAddr, Endianity.Big)); } + } + + public string ServerHostName + { + get + { + ParseServerHostName(); + return _serverHostName; + } + } + + public string BootFileName + { + get + { + ParseBootFileName(); + return _bootFileName; + } + } + + public bool IsDhcp + { + get + { + if (Length >= Offset.Options + 4) + { + return ReadInt(Offset.Options, Endianity.Big) == DHCP_MAGIC_COOKIE; + } + else + { + return false; + } + } + } + + public IReadOnlyCollection Options + { + get + { + ParseOptions(); + return _options; + } + } + + internal DhcpDatagram(byte[] buffer, int offset, int length) : base(buffer, offset, length) + { + } + + private void ParseServerHostName() + { + if (_serverHostName == null) + { + //at the moment we only interpret server host name as sname and ignore options + byte[] byteServerHostName = ReadBytes(Offset.Sname, 64); + _serverHostName = Encoding.ASCII.GetString(byteServerHostName).TrimEnd('\0'); + } + } + + private void ParseBootFileName() + { + if (_bootFileName == null) + { + //at the moment we only interpret server host name as sname and ignore options + byte[] byteBootFileName = ReadBytes(Offset.File, 128); + _bootFileName = Encoding.ASCII.GetString(byteBootFileName).TrimEnd('\0'); + } + } + + private void ParseOptions() + { + if (_options == null) + { + List options = new List(); + int pos = IsDhcp ? Offset.OptionsWithMagicCookie : Offset.Options; + while (pos < Length) + { + options.Add(DhcpOption.CreateInstance(this, ref pos)); + } + this._options = new ReadOnlyCollection(options); + } + } + + /// + /// Creates a Layer that represents the datagram to be used with PacketBuilder. + /// + public override ILayer ExtractLayer() + { + return new DhcpLayer + { + MessageType = MessageType, + HardwareType = HardwareType, + HardwareAddressLength = HardwareAddressLength, + Hops = Hops, + TransactionId = TransactionId, + SecondsElapsed = SecondsElapsed, + Flags = Flags, + ClientIpAddress = ClientIpAddress, + YourClientIpAddress = YourClientIpAddress, + NextServerIpAddress = NextServerIpAddress, + RelayAgentIpAddress = RelayAgentIpAddress, + ClientHardwareAddress = ClientHardwareAddress, + ServerHostName = ServerHostName, + BootFileName = BootFileName, + IsDhcp = IsDhcp, + Options = Options.ToList() + }; + } + + internal static int GetLength(bool isDhcp, IList options) + { + int length = isDhcp ? Offset.OptionsWithMagicCookie : Offset.Options; + + if (options != null) + { + length += options.Sum(p => 1 + (!(p is DhcpPadOption || p is DhcpEndOption) ? 1 : 0) + p.Length); //Type + Len? + Option + } + + return length; + } + + internal static void Write(byte[] buffer, int offset, DhcpMessageType messageType, ArpHardwareType hardwareType, byte hardwareAddressLength, byte hops, int transactionId, ushort secondsElapsed, DhcpFlags flags, IpV4Address clientIpAddress, IpV4Address yourClientIpAddress, IpV4Address nextServerIpAddress, IpV4Address relayAgentIpAddress, DataSegment clientHardwareAddress, string serverHostName, string bootFileName, bool isDhcp, IList options) + { + int startOffset = offset; + buffer.Write(ref offset, (byte)messageType); + buffer.Write(ref offset, (byte)hardwareType); + buffer.Write(ref offset, hardwareAddressLength); + buffer.Write(ref offset, hops); + buffer.Write(ref offset, transactionId, Endianity.Big); + buffer.Write(ref offset, secondsElapsed, Endianity.Big); + buffer.Write(ref offset, (ushort)flags, Endianity.Big); + buffer.Write(ref offset, clientIpAddress, Endianity.Big); + buffer.Write(ref offset, yourClientIpAddress, Endianity.Big); + buffer.Write(ref offset, nextServerIpAddress, Endianity.Big); + buffer.Write(ref offset, relayAgentIpAddress, Endianity.Big); + buffer.Write(offset, clientHardwareAddress); + offset += Offset.Sname - Offset.ChAddr; + if (serverHostName != null) + { + buffer.Write(offset, new DataSegment(Encoding.ASCII.GetBytes(serverHostName))); + } + offset += Offset.File - Offset.Sname; + if (bootFileName != null) + { + buffer.Write(offset, new DataSegment(Encoding.ASCII.GetBytes(bootFileName))); + } + offset += Offset.Options - Offset.File; + if (isDhcp) + { + buffer.Write(ref offset, DHCP_MAGIC_COOKIE, Endianity.Big); + } + if (options != null) + { + foreach (DhcpOption option in options) + { + startOffset = offset; + option.Write(buffer, ref offset); + if (offset != startOffset + option.Length + 2) + { + if (!(option is DhcpPadOption || option is DhcpEndOption)) + { + Console.WriteLine("fail2"); + } + } + } + } + } + + private string _serverHostName; + private string _bootFileName; + private IReadOnlyCollection _options; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs new file mode 100644 index 00000000..7fb3d8ad --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp +{ + /// + /// RFCs 2131. + ///
+    ///                     1 1 1 1 1 1
+    /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    /// |B|             MBZ             |
+    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    ///
+    /// B:  BROADCAST flag
+    /// MBZ:  MUST BE ZERO(reserved for future use)
+    /// 
+ ///
+ [Flags] + public enum DhcpFlags : ushort + { + /// + /// RFCs 2131. + /// Response as Unicast + /// + Unicast = 0 << 15, + + /// + /// RFCs 2131. + /// Response as Broadcast + /// + Broadcast = 1 << 15 + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs new file mode 100644 index 00000000..df98d072 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Base; +using PcapDotNet.Packets.Arp; +using PcapDotNet.Packets.Dhcp.Options; +using PcapDotNet.Packets.Ethernet; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp +{ + /// + /// Represents a DHCP layer. + /// + /// + public sealed class DhcpLayer : SimpleLayer, IEquatable + { + public DhcpMessageType MessageType { get; set; } + + public ArpHardwareType HardwareType { get; set; } + + public byte HardwareAddressLength { get; set; } + + public byte Hops { get; set; } + + public int TransactionId { get; set; } + + public ushort SecondsElapsed { get; set; } + + public DhcpFlags Flags { get; set; } + + public IpV4Address ClientIpAddress { get; set; } + + public IpV4Address YourClientIpAddress { get; set; } + + public IpV4Address NextServerIpAddress { get; set; } + + public IpV4Address RelayAgentIpAddress { get; set; } + + public DataSegment ClientHardwareAddress { get; set; } + + public MacAddress ClientMacAddress + { + get + { + if (ClientHardwareAddress == null) + return MacAddress.Zero; + return new MacAddress(ClientHardwareAddress.ReadUInt48(0, Endianity.Big)); + } + set + { + if (ClientHardwareAddress == null) + ClientHardwareAddress = new DataSegment(new byte[16]); + ClientHardwareAddress.Buffer.Write(0, value, Endianity.Big); + } + } + + public string ServerHostName { get; set; } + + public string BootFileName { get; set; } + + public bool IsDhcp { get; set; } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + public IList Options { get; set; } + + /// + /// The number of bytes this layer will take. + /// + public override int Length + { + get + { + return DhcpDatagram.GetLength(IsDhcp, Options); + } + } + + /// + /// Writes the layer to the buffer. + /// + /// The buffer to write the layer to. + /// The offset in the buffer to start writing the layer at. + protected override void Write(byte[] buffer, int offset) + { + DhcpDatagram.Write(buffer, offset, + MessageType, HardwareType, HardwareAddressLength, Hops, TransactionId, SecondsElapsed, Flags, ClientIpAddress, YourClientIpAddress, + NextServerIpAddress, RelayAgentIpAddress, ClientHardwareAddress, ServerHostName, BootFileName, IsDhcp, Options); + } + + /// + /// Finalizes the layer data in the buffer. + /// Used for fields that must be calculated according to the layer's payload (like checksum). + /// + /// The buffer to finalize the layer in. + /// The offset in the buffer the layer starts. + /// The length of the layer's payload (the number of bytes after the layer in the packet). + /// The layer that comes after this layer. null if this is the last layer. + public override void Finalize(byte[] buffer, int offset, int payloadLength, ILayer nextLayer) + { + } + + /// + /// True if the two objects are equal Layers. + /// + public bool Equals(DhcpLayer other) + { + return other != null && + Equals(MessageType, other.MessageType) && + Equals(HardwareType, other.HardwareType) && + Equals(HardwareAddressLength, other.HardwareAddressLength) && + Equals(Hops, other.Hops) && + Equals(TransactionId, other.TransactionId) && + Equals(SecondsElapsed, other.SecondsElapsed) && + Equals(Flags, other.Flags) && + Equals(ClientIpAddress, other.ClientIpAddress) && + Equals(YourClientIpAddress, other.YourClientIpAddress) && + Equals(NextServerIpAddress, other.NextServerIpAddress) && + Equals(RelayAgentIpAddress, other.RelayAgentIpAddress) && + Equals(ClientHardwareAddress, ClientHardwareAddress) && + Equals(ServerHostName, other.ServerHostName) && + Equals(BootFileName, other.BootFileName) && + Equals(IsDhcp, other.IsDhcp) && + (Options.IsNullOrEmpty() && other.Options.IsNullOrEmpty() || Options.SequenceEqual(other.Options)); + } + + /// + /// True if the two objects are equal Layers. + /// + public override bool Equals(Layer other) + { + return Equals(other as DhcpLayer); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs new file mode 100644 index 00000000..f410f664 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp +{ + /// + /// RFCs 2131. + /// + public enum DhcpMessageType : byte + + { + /// + /// RFC 2131. + /// Indicates a Boot Request + /// + BootRequest = 1, + + /// + /// RFC 2131. + /// Indicates a Boot Reply + /// + BootReply = 2 + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs new file mode 100644 index 00000000..b7f6a2aa --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len           Time
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  35 |  4  |  t1 |  t2 |  t3 |  t4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpARPCacheTimeoutOption : DhcpOption + { + public DhcpARPCacheTimeoutOption() : base(DhcpOptionCode.ARPCacheTimeout) + { + } + + public DhcpARPCacheTimeoutOption(uint timeOffset) : this() + { + TimeOffset = timeOffset; + } + + internal static DhcpARPCacheTimeoutOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + { + throw new ArgumentException("Length of a DHCP ARPCacheTimeout Option has to be 4"); + } + DhcpARPCacheTimeoutOption option = new DhcpARPCacheTimeoutOption(data.ReadUInt(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, TimeOffset, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public uint TimeOffset + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs new file mode 100644 index 00000000..f2146f18 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// Abstract class for all Dhcp-Options with a list of Addresses + /// + public abstract class DhcpAddressListOption : DhcpOption + { + internal const int MAX_ADDRESSES = 255 / IpV4Address.SizeOf; + + internal DhcpAddressListOption(DhcpOptionCode code, IList addresses) : base(code) + { + if (addresses == null) + throw new ArgumentNullException(nameof(addresses)); + if (addresses.Count > MAX_ADDRESSES) + throw new ArgumentOutOfRangeException(nameof(addresses), addresses.Count, $"The maximum items in addresses is {MAX_ADDRESSES}"); + Addresses = new ReadOnlyCollection(addresses); + } + + internal static IList GetAddresses(DataSegment data, byte length, ref int offset) + { + if (length % IpV4Address.SizeOf != 0) + throw new ArgumentOutOfRangeException(nameof(length), length, $"length has to be multiple of {IpV4Address.SizeOf}"); + List addresses = new List(); + for (int i = 0; i < length; i += IpV4Address.SizeOf) + { + addresses.Add(data.ReadIpV4Address(offset + i, Endianity.Big)); + } + offset += length; + return addresses; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + foreach (IpV4Address address in Addresses) + { + buffer.Write(ref offset, address, Endianity.Big); + } + } + + /// + /// RFC 2132. + /// Value of Length-Field + /// + public override byte Length + { + get + { + if (Addresses.Count > MAX_ADDRESSES) + throw new ArgumentOutOfRangeException(nameof(Addresses), Addresses.Count, $"The maximum items in addresses is {MAX_ADDRESSES}"); + + return (byte)(Addresses.Count * IpV4Address.SizeOf); + } + } + + /// + /// collection of all addresses of this option + /// + public IReadOnlyCollection Addresses + { + get; + private set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs new file mode 100644 index 00000000..d35944b9 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  27 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpAllSubnetsAreLocalOption : DhcpOption + { + public DhcpAllSubnetsAreLocalOption(bool enabled) : base(DhcpOptionCode.AllSubnetsAreLocal) + { + } + + internal static DhcpAllSubnetsAreLocalOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP AllSubnetsAreLocal Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP AllSubnetsAreLocal Option has to be 0 or 1"); + DhcpAllSubnetsAreLocalOption option = new DhcpAllSubnetsAreLocalOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs new file mode 100644 index 00000000..b0d32f28 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// DHCP option for undefined options + /// + public class DhcpAnyOption : DhcpOption + { + public DhcpAnyOption(DataSegment data, DhcpOptionCode code) : base(code) + { + Data = data; + } + + public override byte Length + { + get + { + if (Data == null) + { + return 0; + } + return (byte)Data.Length; + } + } + + internal static DhcpAnyOption Read(DataSegment data, ref int offset) + { + DhcpOptionCode code = (DhcpOptionCode)data[offset - 1]; + byte length = data[offset++]; + DhcpAnyOption option = new DhcpAnyOption(data.Subsegment(offset, length), code); + offset += length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + if (Data == null) + throw new ArgumentNullException(nameof(Data)); + if (Data.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(Data), Data.Length, "Data.Length has to be less than 256"); + base.Write(buffer, ref offset); + buffer.Write(ref offset, Data); + } + + public DataSegment Data + { + get { return _data; } + set + { + if (value == null) + throw new ArgumentNullException(nameof(Data)); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(Data), value.Length, "Data.Length has to be less than 256"); + _data = value; + } + } + + private DataSegment _data; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs new file mode 100644 index 00000000..099fe8f4 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len   File Size
+    /// +-----+-----+-----+-----+
+    /// |  13 |  2  |  l1 |  l2 |
+    /// +-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpBootFileSizeOption : DhcpOption + { + public DhcpBootFileSizeOption(ushort fileSize) : base(DhcpOptionCode.BootFileSize) + { + FileSize = fileSize; + } + + internal static DhcpBootFileSizeOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 2) + throw new ArgumentException("Length of a DHCP BootFileSize Option has to be 2"); + DhcpBootFileSizeOption option = new DhcpBootFileSizeOption(data.ReadUShort(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, FileSize, Endianity.Big); + } + + public override byte Length + { + get + { + return 2; + } + } + + public ushort FileSize + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs new file mode 100644 index 00000000..2128451d --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code Len   Bootfile name
+    /// +-----+-----+-----+-----+-----+---
+    /// | 67  |  n  |  c1 |  c2 |  c3 | ...
+    /// +-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpBootfileNameOption : DhcpOption + { + public DhcpBootfileNameOption(string domainName) : base(DhcpOptionCode.BootfileName) + { + BootfileName = domainName; + } + + internal static DhcpBootfileNameOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + DhcpBootfileNameOption option = new DhcpBootfileNameOption(Encoding.ASCII.GetString(data.ReadBytes(offset, len))); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(BootfileName)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(BootfileName); + } + } + + public string BootfileName + { + get { return bootfileName; } + + set + { + if (value == null) + throw new ArgumentNullException(nameof(BootfileName)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(BootfileName), value.Length, "BootfileName has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(BootfileName), value.Length, "BootfileName has to be less than 256 characters long"); + + bootfileName = value; + } + } + + private string bootfileName; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs new file mode 100644 index 00000000..5a063a5f --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len     Broadcast Address
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  28 |  4  |  b1 |  b2 |  b3 |  b4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpBroadcastAddressOption : DhcpOption + { + public DhcpBroadcastAddressOption(IpV4Address broadcastAddress) : base(DhcpOptionCode.BroadcastAddress) + { + BroadcastAddress = broadcastAddress; + } + + internal static DhcpBroadcastAddressOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + throw new ArgumentException("Length of a DHCP SubnetMask Option has to be 4"); + DhcpBroadcastAddressOption option = new DhcpBroadcastAddressOption(data.ReadIpV4Address(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, BroadcastAddress, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public IpV4Address BroadcastAddress + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs new file mode 100644 index 00000000..fce00c70 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len   Type  Client-Identifier
+    /// +-----+-----+-----+-----+-----+---
+    /// |  61 |  n  |  t1 |  i1 |  i2 | ...
+    /// +-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpClientIdentifierOption : DhcpOption + { + public DhcpClientIdentifierOption(byte type, DataSegment clientIdentifier) : base(DhcpOptionCode.ClientIdentifier) + { + Type = type; + ClientIdentifier = clientIdentifier; + } + + internal static DhcpClientIdentifierOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + DhcpClientIdentifierOption option = new DhcpClientIdentifierOption(data[offset], data.Subsegment(offset + 1, length - 1)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Type); + buffer.Write(ref offset, ClientIdentifier); + } + + public override byte Length + { + get + { + return (byte)(sizeof(byte) + ClientIdentifier.Length); + } + } + + public byte Type + { + get; + set; + } + + public DataSegment ClientIdentifier + { + get { return _clientIdentifier; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(ClientIdentifier)); + } + if (value.Length < 1) + { + throw new ArgumentOutOfRangeException(nameof(ClientIdentifier), value.Length, "ClientIdentifier.Length has to be greater than 0"); + } + if (value.Length > byte.MaxValue - 1) + { + throw new ArgumentOutOfRangeException(nameof(ClientIdentifier), value.Length, "ClientIdentifier.Length has to be less than 255"); + } + _clientIdentifier = value; + } + } + + private DataSegment _clientIdentifier; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs new file mode 100644 index 00000000..0afb9c4d --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  8  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpCookieServerOption : DhcpAddressListOption + { + public DhcpCookieServerOption(IList addresses) : base(DhcpOptionCode.CookieServer, addresses) + { + } + + internal static DhcpCookieServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpCookieServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs new file mode 100644 index 00000000..014cda4b --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// | 73  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpDefaultFingerServerOption : DhcpAddressListOption + { + public DhcpDefaultFingerServerOption(IList addresses) : base(DhcpOptionCode.DefaultFingerServer, addresses) + { + } + + internal static DhcpDefaultFingerServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpDefaultFingerServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs new file mode 100644 index 00000000..3fdec04b --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len   TTL
+    /// +-----+-----+-----+
+    /// |  23 |  1  | ttl |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpDefaultIPTimeToLiveOption : DhcpOption + { + public DhcpDefaultIPTimeToLiveOption(byte ttl) : base(DhcpOptionCode.DefaultIPTimeToLive) + { + TTL = ttl; + } + + internal static DhcpDefaultIPTimeToLiveOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 1) + { + throw new ArgumentException("Length of a DHCP DefaultIPTimeToLive Option has to be 1"); + } + DhcpDefaultIPTimeToLiveOption option = new DhcpDefaultIPTimeToLiveOption(data[offset++]); + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, TTL); + } + + public override byte Length + { + get { return 1; } + } + + public byte TTL + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs new file mode 100644 index 00000000..08228f7b --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// | 74  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpDefaultInternetRelayChatServerOption : DhcpAddressListOption + { + public DhcpDefaultInternetRelayChatServerOption(IList addresses) : base(DhcpOptionCode.DefaultInternetRelayChatServer, addresses) + { + } + + internal static DhcpDefaultInternetRelayChatServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpDefaultInternetRelayChatServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs new file mode 100644 index 00000000..35008d04 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// | 72  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpDefaultWorldWideWebServerOption : DhcpAddressListOption + { + public DhcpDefaultWorldWideWebServerOption(IList addresses) : base(DhcpOptionCode.DefaultWorldWideWebServer, addresses) + { + } + + internal static DhcpDefaultWorldWideWebServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpDefaultWorldWideWebServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs new file mode 100644 index 00000000..a6cc9b47 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len        Domain Name
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// |  15 |  n  |  d1 |  d2 |  d3 |  d4 | ...
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpDomainNameOption : DhcpOption + { + public DhcpDomainNameOption(string domainName) : base(DhcpOptionCode.DomainName) + { + DomainName = domainName; + } + + internal static DhcpDomainNameOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); + DhcpDomainNameOption option = new DhcpDomainNameOption(hostName); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(DomainName)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(DomainName); + } + } + + public string DomainName + { + get { return _domainName; } + + set + { + if (value == null) + throw new ArgumentNullException(nameof(DomainName)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(DomainName), value.Length, "DomainName has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(DomainName), value.Length, "DomainName has to be less than 256 characters long"); + + _domainName = value; + } + } + + private string _domainName; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs new file mode 100644 index 00000000..93fc6e7a --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + public class DhcpDomainNameServerOption : DhcpAddressListOption + { + public DhcpDomainNameServerOption(IList addresses) : base(DhcpOptionCode.DomainNameServerServer, addresses) + { + } + + internal static DhcpDomainNameServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpDomainNameServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs new file mode 100644 index 00000000..90148b5f --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code
+    /// +-----+
+    /// | 255 |
+    /// +-----+
+    /// 
+ ///
+ public class DhcpEndOption : DhcpOption + { + public DhcpEndOption() : base(DhcpOptionCode.End) + { + } + + public override byte Length + { + get { return 0; } + } + + internal static DhcpEndOption Read(DataSegment data, ref int offset) + { + return new Options.DhcpEndOption(); + } + + internal override void Write(byte[] buffer, ref int offset) + { + buffer.Write(offset++, (byte)OptionCode); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs new file mode 100644 index 00000000..e85f606f --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  36 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpEthernetEncapsulationOption : DhcpOption + { + public DhcpEthernetEncapsulationOption(bool enabled) : base(DhcpOptionCode.EthernetEncapsulation) + { + } + + internal static DhcpEthernetEncapsulationOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP EthernetEncapsulation Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP EthernetEncapsulation Option has to be 0 or 1"); + DhcpEthernetEncapsulationOption option = new DhcpEthernetEncapsulationOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs new file mode 100644 index 00000000..2fc66241 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len      Dump File Pathname
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// |  18 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpExtensionsPathOption : DhcpOption + { + public DhcpExtensionsPathOption(string extensionsPath) : base(DhcpOptionCode.ExtensionsPath) + { + ExtensionsPath = extensionsPath; + } + + internal static DhcpExtensionsPathOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); + DhcpExtensionsPathOption option = new DhcpExtensionsPathOption(hostName); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(ExtensionsPath)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(ExtensionsPath); + } + } + + public string ExtensionsPath + { + get { return _extensionsPath; } + set + { + if (value == null) + throw new ArgumentNullException(nameof(ExtensionsPath)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(ExtensionsPath), value.Length, "ExtensionsPath has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(ExtensionsPath), value.Length, "ExtensionsPath has to be less than 256 characters long"); + + _extensionsPath = value; + } + } + + private string _extensionsPath; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs new file mode 100644 index 00000000..8eaa21c1 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len                 Host Name
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  12 |  n  |  h1 |  h2 |  h3 |  h4 |  h5 |  h6 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpHostNameOption : DhcpOption + { + public DhcpHostNameOption(string hostName) : base(DhcpOptionCode.HostName) + { + HostName = hostName; + } + + internal static DhcpHostNameOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); + DhcpHostNameOption option = new DhcpHostNameOption(hostName); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(HostName)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(HostName); + } + } + + public string HostName + { + get { return _hostName; } + set + { + if (value == null) + throw new ArgumentNullException(nameof(HostName)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(HostName), value.Length, "HostName has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(HostName), value.Length, "HostName has to be less than 256 characters long"); + + _hostName = value; + } + } + + private string _hostName; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs new file mode 100644 index 00000000..1644469f --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len        Time Offset
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  1  |  4  |  n1 |  n2 |  n3 |  n4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpIPAddressLeaseTimeOption : DhcpOption + { + public DhcpIPAddressLeaseTimeOption(uint leaseTime) : base(DhcpOptionCode.IPAddressLeaseTime) + { + LeaseTime = leaseTime; + } + + internal static DhcpIPAddressLeaseTimeOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + throw new ArgumentException("Length of a DHCP IPAddressLeaseTime Option has to be 4"); + + DhcpIPAddressLeaseTimeOption option = new DhcpIPAddressLeaseTimeOption(data.ReadUInt(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, LeaseTime, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public uint LeaseTime + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs new file mode 100644 index 00000000..4828ae81 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Type
+    /// +-----+-----+-----+
+    /// |  15 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpIPForwardingEnableOption : DhcpOption + { + public DhcpIPForwardingEnableOption(bool value) : base(DhcpOptionCode.IPForwardingEnable) + { + Value = value; + } + + internal static DhcpIPForwardingEnableOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP MessageTypeOption has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP MessageTypeOption has to be 0 or 1"); + DhcpIPForwardingEnableOption option = new DhcpIPForwardingEnableOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs new file mode 100644 index 00000000..3fa6da7a --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + public class DhcpImpressServerOption : DhcpAddressListOption + { + public DhcpImpressServerOption(IList addresses) : base(DhcpOptionCode.ImpressServer, addresses) + { + } + + internal static DhcpImpressServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpImpressServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMTUOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMTUOption.cs new file mode 100644 index 00000000..f52222c4 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMTUOption.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len      MTU
+    /// +-----+-----+-----+-----+
+    /// |  26 |  2  |  m1 |  m2 |
+    /// +-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpInterfaceMTUOption : DhcpOption + { + public DhcpInterfaceMTUOption(ushort mtu) : base(DhcpOptionCode.InterfaceMTU) + { + MTU = mtu; + } + + internal static DhcpInterfaceMTUOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != sizeof(ushort)) + throw new ArgumentException($"Length of a DHCP InterfaceMTU Option has to be {sizeof(ushort)}"); + DhcpInterfaceMTUOption option = new DhcpInterfaceMTUOption(data.ReadUShort(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, MTU, Endianity.Big); + } + + public override byte Length + { + get { return sizeof(ushort); } + } + + public ushort MTU + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLPRServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLPRServerOption.cs new file mode 100644 index 00000000..b960b43c --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLPRServerOption.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + public class DhcpLPRServerOption : DhcpAddressListOption + { + public DhcpLPRServerOption(IList addresses) : base(DhcpOptionCode.LPRServer, addresses) + { + } + + internal static DhcpLPRServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpLPRServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs new file mode 100644 index 00000000..653bac84 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + public class DhcpLogServerOption : DhcpAddressListOption + { + public DhcpLogServerOption(IList addresses) : base(DhcpOptionCode.LogServer, addresses) + { + } + + internal static DhcpLogServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpLogServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs new file mode 100644 index 00000000..b3fb36f9 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  30 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpMaskSupplierOption : DhcpOption + { + public DhcpMaskSupplierOption(bool enabled) : base(DhcpOptionCode.MaskSupplier) + { + } + + internal static DhcpMaskSupplierOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP MaskSupplier Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP MaskSupplier Option has to be 0 or 1"); + DhcpMaskSupplierOption option = new DhcpMaskSupplierOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs new file mode 100644 index 00000000..f3e9faa4 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len      Size
+    /// +-----+-----+-----+-----+
+    /// |  22 |  2  |  s1 |  s2 |
+    /// +-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpMaximumDatagramReassemblySizeOption : DhcpOption + { + public DhcpMaximumDatagramReassemblySizeOption() : base(DhcpOptionCode.MaximumDatagramReassemblySize) + { + } + + public DhcpMaximumDatagramReassemblySizeOption(ushort size) : this() + { + Size = size; + } + + internal static DhcpMaximumDatagramReassemblySizeOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 2) + { + throw new ArgumentException("Length of a DHCP MaximumDatagramReassemblySize Option has to be 2"); + } + DhcpMaximumDatagramReassemblySizeOption option = new DhcpMaximumDatagramReassemblySizeOption(data.ReadUShort(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Size, Endianity.Big); + } + + public override byte Length + { + get { return 2; } + } + + public ushort Size + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs new file mode 100644 index 00000000..fc246fe0 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len     Length
+    /// +-----+-----+-----+-----+
+    /// |  57 |  2  |  l1 |  l2 |
+    /// +-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpMaximumDhcpMessageSizeOption : DhcpOption + { + public DhcpMaximumDhcpMessageSizeOption(ushort maxLength) : base(DhcpOptionCode.MaximumDhcpMessageSize) + { + MaxLength = maxLength; + } + + internal static DhcpMaximumDhcpMessageSizeOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 2) + throw new ArgumentException("Length of a DHCP MaximumDhcpMessageSize Option has to be 2"); + DhcpMaximumDhcpMessageSizeOption option = new DhcpMaximumDhcpMessageSizeOption(data.ReadUShort(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, MaxLength, Endianity.Big); + } + + public override byte Length + { + get + { + return 2; + } + } + + public ushort MaxLength + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs new file mode 100644 index 00000000..d4527eb7 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len      Dump File Pathname
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// |  14 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpMeritDumpFileOption : DhcpOption + { + public DhcpMeritDumpFileOption(string dumpFilePathname) : base(DhcpOptionCode.MeritDumpFile) + { + DumpFilePathname = dumpFilePathname; + } + + internal static DhcpMeritDumpFileOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); + DhcpMeritDumpFileOption option = new DhcpMeritDumpFileOption(hostName); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(DumpFilePathname)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(DumpFilePathname); + } + } + + public string DumpFilePathname + { + get { return _dumpFilePathname; } + set + { + if (value == null) + throw new ArgumentNullException(nameof(DumpFilePathname)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(DumpFilePathname), value.Length, "DumpFilePathname has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(DumpFilePathname), value.Length, "DumpFilePathname has to be less than 256 characters long"); + + _dumpFilePathname = value; + } + } + + private string _dumpFilePathname; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs new file mode 100644 index 00000000..c05b693f --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len     Text
+    /// +-----+-----+-----+-----+---
+    /// |  56 |  n  |  c1 |  c2 | ...
+    /// +-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpMessageOption : DhcpOption + { + public DhcpMessageOption(string text) : base(DhcpOptionCode.Message) + { + Text = text; + } + + internal static DhcpMessageOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + string text = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); + DhcpMessageOption option = new DhcpMessageOption(text); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(Text)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(Text); + } + } + + public string Text + { + get { return _rootPath; } + set + { + if (value == null) + throw new ArgumentNullException(nameof(Text)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(Text), value.Length, "Text has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(Text), value.Length, "Text has to be less than 256 characters long"); + + _rootPath = value; + } + } + + private string _rootPath; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs new file mode 100644 index 00000000..3676ffe9 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Type
+    /// +-----+-----+-----+
+    /// |  53 |  1  | 1-7 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpMessageTypeOption : DhcpOption + { + public DhcpMessageTypeOption(MessageType type) : base(DhcpOptionCode.MessageType) + { + Type = type; + } + + internal static DhcpMessageTypeOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP MessageTypeOption has to be 1"); + DhcpMessageTypeOption option = new DhcpMessageTypeOption((MessageType)data[offset]); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, (byte)Type); + } + + public override byte Length + { + get + { + return 1; + } + } + + public MessageType Type + { + get { return _type; } + set + { + if (!Enum.IsDefined(typeof(MessageType), value)) + throw new ArgumentOutOfRangeException(nameof(Type), value, "Not a valid MessageType"); + _type = value; + } + } + + private MessageType _type; + + public enum MessageType : byte + { + Discover = 1, + Offer = 2, + Request = 3, + Decline = 4, + Ack = 5, + Nak = 6, + Release = 7 + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs new file mode 100644 index 00000000..aeaea243 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code Len    Home Agent Addresses (zero or more)
+    /// +-----+-----+-----+-----+-----+-----+--
+    /// | 68  |  n  | a1  | a2  | a3  | a4  | ...
+    /// +-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpMobileIPHomeAgentOption : DhcpAddressListOption + { + public DhcpMobileIPHomeAgentOption(IList addresses) : base(DhcpOptionCode.MobileIPHomeAgent, addresses) + { + } + + internal static DhcpMobileIPHomeAgentOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpMobileIPHomeAgentOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs new file mode 100644 index 00000000..eae80623 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + public class DhcpNameServerOption : DhcpAddressListOption + { + public DhcpNameServerOption(IList addresses) : base(DhcpOptionCode.NameServer, addresses) + { + } + + internal static DhcpNameServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpNameServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.cs new file mode 100644 index 00000000..59d1de53 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len           Address 1              Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+    /// |  45 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+    /// 
+ ///
+ public class DhcpNetBIOSOverTCPIPDatagramDistributionServerOption : DhcpAddressListOption + { + public DhcpNetBIOSOverTCPIPDatagramDistributionServerOption(IList addresses) : base(DhcpOptionCode.NetBIOSOverTCPIPDatagramDistributionServer, addresses) + { + } + + internal static DhcpNetBIOSOverTCPIPDatagramDistributionServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpNetBIOSOverTCPIPDatagramDistributionServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNameServerOption.cs new file mode 100644 index 00000000..1dc059ab --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNameServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len           Address 1              Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+    /// |  44 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+    /// 
+ ///
+ public class DhcpNetBIOSOverTCPIPNameServerOption : DhcpAddressListOption + { + public DhcpNetBIOSOverTCPIPNameServerOption(IList addresses) : base(DhcpOptionCode.NetBIOSOverTCPIPNameServer, addresses) + { + } + + internal static DhcpNetBIOSOverTCPIPNameServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpNetBIOSOverTCPIPNameServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNodeTypeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNodeTypeOption.cs new file mode 100644 index 00000000..fec4e03e --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNodeTypeOption.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Node Type
+    /// +-----+-----+-----------+
+    /// |  46 |  1  |   flags   |
+    /// +-----+-----+-----------+
+    /// 
+ ///
+ public class DhcpNetBIOSOverTCPIPNodeTypeOption : DhcpOption + { + public DhcpNetBIOSOverTCPIPNodeTypeOption(NodeType type) : base(DhcpOptionCode.NetBIOSOverTCPIPNodeType) + { + Type = type; + } + + internal static DhcpNetBIOSOverTCPIPNodeTypeOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP NetBIOSOverTCPIPNodeType Option has to be 1"); + DhcpNetBIOSOverTCPIPNodeTypeOption option = new DhcpNetBIOSOverTCPIPNodeTypeOption((NodeType)data[offset]); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, (byte)Type); + } + + public override byte Length + { + get + { + return sizeof(NodeType); + } + } + + public NodeType Type + { + get { return _type; } + set + { + bool flagSet = false; + foreach(NodeType type in Enum.GetValues(typeof(NodeType))) + { + if ((value & type) != 0) + { + flagSet = true; + break; + } + } + if (!flagSet) + throw new ArgumentOutOfRangeException(nameof(Type), value, "Not a valid NodeType"); + _type = value; + } + } + + private NodeType _type; + + [Flags] + public enum NodeType : byte + { + BNode = 0x1, + PNode = 0x2, + MNode = 0x4, + HNode = 0x8, + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPScopeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPScopeOption.cs new file mode 100644 index 00000000..c7662a6a --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPScopeOption.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    /// Code   Len       NetBIOS Scope
+    /// +-----+-----+-----+-----+-----+-----+----
+    /// |  47 |  n  |  s1 |  s2 |  s3 |  s4 | ...
+    /// +-----+-----+-----+-----+-----+-----+----
+    /// 
+ ///
+ public class DhcpNetBIOSOverTCPIPScopeOption : DhcpOption + { + public DhcpNetBIOSOverTCPIPScopeOption(DataSegment netBIOSScope) : base(DhcpOptionCode.NetBIOSOverTCPIPScope) + { + NetBIOSScope = netBIOSScope; + } + + internal static DhcpNetBIOSOverTCPIPScopeOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + DhcpNetBIOSOverTCPIPScopeOption option = new DhcpNetBIOSOverTCPIPScopeOption(data.Subsegment(offset, length)); + offset += length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + if (NetBIOSScope == null) + throw new ArgumentNullException(nameof(NetBIOSScope)); + if (NetBIOSScope.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(NetBIOSScope), NetBIOSScope.Length, "NetBIOSScope.Length has to be less than 256"); + base.Write(buffer, ref offset); + buffer.Write(ref offset, NetBIOSScope); + } + + public override byte Length + { + get + { + if (NetBIOSScope == null) + { + return 0; + } + return (byte)NetBIOSScope.Length; + } + } + + public DataSegment NetBIOSScope + { + get { return _netBIOSScope; } + set + { + if (value == null) + throw new ArgumentNullException(nameof(NetBIOSScope)); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(NetBIOSScope), value.Length, "NetBIOSScope.Length has to be less than 256"); + _netBIOSScope = value; + } + } + + private DataSegment _netBIOSScope; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs new file mode 100644 index 00000000..83550dd5 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  41 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpNetworkInformationServersOption : DhcpAddressListOption + { + public DhcpNetworkInformationServersOption(IList addresses) : base(DhcpOptionCode.NetworkInformationServers, addresses) + { + } + + internal static DhcpNetworkInformationServersOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpNetworkInformationServersOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs new file mode 100644 index 00000000..47b7c724 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len      NIS Domain Name
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// |  40 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpNetworkInformationServiceDomainOption : DhcpOption + { + public DhcpNetworkInformationServiceDomainOption(string nisDomainName) : base(DhcpOptionCode.NetworkInformationServiceDomain) + { + NISDomainName = nisDomainName; + } + + internal static DhcpNetworkInformationServiceDomainOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); + DhcpNetworkInformationServiceDomainOption option = new DhcpNetworkInformationServiceDomainOption(hostName); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(NISDomainName)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(NISDomainName); + } + } + + public string NISDomainName + { + get { return _nisDomainName; } + + set + { + if (value == null) + throw new ArgumentNullException(nameof(NISDomainName)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(NISDomainName), value.Length, "NISDomainName has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(NISDomainName), value.Length, "NISDomainName has to be less than 256 characters long"); + + _nisDomainName = value; + } + } + + private string _nisDomainName; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs new file mode 100644 index 00000000..6270902d --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len      NIS Client Domain Name
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// |  64 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpNetworkInformationServicePlusDomainOption : DhcpOption + { + public DhcpNetworkInformationServicePlusDomainOption(string domainName) : base(DhcpOptionCode.NetworkInformationServicePlusDomain) + { + DomainName = domainName; + } + + internal static DhcpNetworkInformationServicePlusDomainOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + DhcpNetworkInformationServicePlusDomainOption option = new DhcpNetworkInformationServicePlusDomainOption(Encoding.ASCII.GetString(data.ReadBytes(offset, len))); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(DomainName)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(DomainName); + } + } + + public string DomainName + { + get { return _domainName; } + + set + { + if (value == null) + throw new ArgumentNullException(nameof(DomainName)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(DomainName), value.Length, "DomainName has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(DomainName), value.Length, "DomainName has to be less than 256 characters long"); + + _domainName = value; + } + } + + private string _domainName; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs new file mode 100644 index 00000000..e2bac760 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  65 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpNetworkInformationServicePlusServersOption : DhcpAddressListOption + { + public DhcpNetworkInformationServicePlusServersOption(IList addresses) : base(DhcpOptionCode.NetworkInformationServicePlusServers, addresses) + { + } + + internal static DhcpNetworkInformationServicePlusServersOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpNetworkInformationServicePlusServersOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs new file mode 100644 index 00000000..9747ff36 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// | 71  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpNetworkNewsTransportProtocolServerOption : DhcpAddressListOption + { + public DhcpNetworkNewsTransportProtocolServerOption(IList addresses) : base(DhcpOptionCode.NetworkNewsTransportProtocolServer, addresses) + { + } + + internal static DhcpNetworkNewsTransportProtocolServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpNetworkNewsTransportProtocolServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs new file mode 100644 index 00000000..e20b6a92 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  42 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpNetworkTimeProtocolServersOption : DhcpAddressListOption + { + public DhcpNetworkTimeProtocolServersOption(IList addresses) : base(DhcpOptionCode.NetworkTimeProtocolServers, addresses) + { + } + + internal static DhcpNetworkTimeProtocolServersOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpNetworkTimeProtocolServersOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs new file mode 100644 index 00000000..c5fc860e --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  20 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpNonLocalSourceRoutingEnableOption : DhcpOption + { + public DhcpNonLocalSourceRoutingEnableOption(bool enabled) : base(DhcpOptionCode.NonLocalSourceRoutingEnable) + { + } + + internal static DhcpNonLocalSourceRoutingEnableOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP NonLocalSourceRoutingEnable Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP NonLocalSourceRoutingEnable Option has to be 0 or 1"); + DhcpNonLocalSourceRoutingEnableOption option = new DhcpNonLocalSourceRoutingEnableOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs new file mode 100644 index 00000000..4316c41f --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs @@ -0,0 +1,359 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// Abstract class for all possible Dhcp-Options + /// + public abstract class DhcpOption : IEquatable + { + /// + /// Option-Code according RFC 2132 + /// + public DhcpOptionCode OptionCode + { + get; + private set; + } + + /// + /// Length of the Dhcp-Option + /// + public abstract byte Length + { + get; + } + + /// + /// create new Option + /// + /// Option-Code + public DhcpOption(DhcpOptionCode code) + { + OptionCode = code; + } + + internal static DhcpOption CreateInstance(DataSegment data, ref int offset) + { + switch ((DhcpOptionCode)data[offset++]) + { + #region 3. RFC 1497 Vendor Extensions + + case DhcpOptionCode.Pad: + return DhcpPadOption.Read(data, ref offset); + + case DhcpOptionCode.End: + return DhcpEndOption.Read(data, ref offset); + + case DhcpOptionCode.SubnetMask: + return DhcpSubnetMaskOption.Read(data, ref offset); + + case DhcpOptionCode.TimeOffset: + return DhcpTimeOffsetOption.Read(data, ref offset); + + case DhcpOptionCode.Router: + return DhcpRouterOption.Read(data, ref offset); + + case DhcpOptionCode.TimeServer: + return DhcpTimeServerOption.Read(data, ref offset); + + case DhcpOptionCode.NameServer: + return DhcpNameServerOption.Read(data, ref offset); + + case DhcpOptionCode.DomainNameServerServer: + return DhcpDomainNameServerOption.Read(data, ref offset); + + case DhcpOptionCode.LogServer: + return DhcpLogServerOption.Read(data, ref offset); + + case DhcpOptionCode.CookieServer: + return DhcpCookieServerOption.Read(data, ref offset); + + case DhcpOptionCode.LPRServer: + return DhcpLPRServerOption.Read(data, ref offset); + + case DhcpOptionCode.ImpressServer: + return DhcpImpressServerOption.Read(data, ref offset); + + case DhcpOptionCode.ResourceLocationServer: + return DhcpResourceLocationServerOption.Read(data, ref offset); + + case DhcpOptionCode.HostName: + return DhcpHostNameOption.Read(data, ref offset); + + case DhcpOptionCode.BootFileSize: + return DhcpBootFileSizeOption.Read(data, ref offset); + + case DhcpOptionCode.MeritDumpFile: + return DhcpMeritDumpFileOption.Read(data, ref offset); + + case DhcpOptionCode.DomainName: + return DhcpDomainNameOption.Read(data, ref offset); + + case DhcpOptionCode.SwapServer: + return DhcpSwapServerOption.Read(data, ref offset); + + case DhcpOptionCode.RootPath: + return DhcpRootPathOption.Read(data, ref offset); + + case DhcpOptionCode.ExtensionsPath: + return DhcpExtensionsPathOption.Read(data, ref offset); + + #endregion 3. RFC 1497 Vendor Extensions + + #region 4. IP Layer Parameters per Host + + case DhcpOptionCode.IPForwardingEnable: + return DhcpIPForwardingEnableOption.Read(data, ref offset); + + case DhcpOptionCode.NonLocalSourceRoutingEnable: + return DhcpNonLocalSourceRoutingEnableOption.Read(data, ref offset); + + case DhcpOptionCode.PolicyFilter: + return DhcpPolicyFilterOption.Read(data, ref offset); + + case DhcpOptionCode.MaximumDatagramReassemblySize: + return DhcpMaximumDatagramReassemblySizeOption.Read(data, ref offset); + + case DhcpOptionCode.DefaultIPTimeToLive: + return DhcpDefaultIPTimeToLiveOption.Read(data, ref offset); + + case DhcpOptionCode.PathMTUAgingTimeout: + return DhcpPathMTUAgingTimeoutOption.Read(data, ref offset); + + case DhcpOptionCode.PathMTUPlateauTable: + return DhcpPathMTUPlateauTableOption.Read(data, ref offset); + + #endregion 4. IP Layer Parameters per Host + + #region 5. IP Layer Parameters per Interface + + case DhcpOptionCode.InterfaceMTU: + return DhcpInterfaceMTUOption.Read(data, ref offset); + + case DhcpOptionCode.AllSubnetsAreLocal: + return DhcpAllSubnetsAreLocalOption.Read(data, ref offset); + + case DhcpOptionCode.BroadcastAddress: + return DhcpBroadcastAddressOption.Read(data, ref offset); + + case DhcpOptionCode.PerformMaskDiscovery: + return DhcpPerformMaskDiscoveryOption.Read(data, ref offset); + + case DhcpOptionCode.MaskSupplier: + return DhcpMaskSupplierOption.Read(data, ref offset); + + case DhcpOptionCode.PerformRouterDiscovery: + return DhcpPerformRouterDiscoveryOption.Read(data, ref offset); + + case DhcpOptionCode.RouterSolicitationAddress: + return DhcpRouterSolicitationAddressOption.Read(data, ref offset); + + case DhcpOptionCode.StaticRoute: + return DhcpStaticRouteOption.Read(data, ref offset); + + #endregion 5. IP Layer Parameters per Interface + + #region 6. Link Layer Parameters per Interface + + case DhcpOptionCode.TrailerEncapsulation: + return DhcpTrailerEncapsulationOption.Read(data, ref offset); + + case DhcpOptionCode.ARPCacheTimeout: + return DhcpARPCacheTimeoutOption.Read(data, ref offset); + + case DhcpOptionCode.EthernetEncapsulation: + return DhcpEthernetEncapsulationOption.Read(data, ref offset); + + #endregion 6. Link Layer Parameters per Interface + + #region 7. TCP Parameters + + case DhcpOptionCode.TCPDefaultTTL: + return DhcpTCPDefaultTTLOption.Read(data, ref offset); + + case DhcpOptionCode.TCPKeepaliveInterval: + return DhcpTCPKeepaliveIntervalOption.Read(data, ref offset); + + case DhcpOptionCode.TCPKeepaliveGarbage: + return DhcpTCPKeepaliveGarbageOption.Read(data, ref offset); + + #endregion 7. TCP Parameters + + #region 8. Application and Service Parameters + + case DhcpOptionCode.NetworkInformationServiceDomain: + return DhcpNetworkInformationServiceDomainOption.Read(data, ref offset); + + case DhcpOptionCode.NetworkInformationServers: + return DhcpNetworkInformationServersOption.Read(data, ref offset); + + case DhcpOptionCode.NetworkTimeProtocolServers: + return DhcpNetworkTimeProtocolServersOption.Read(data, ref offset); + + case DhcpOptionCode.VendorSpecificInformation: + return DhcpVendorSpecificInformationOption.Read(data, ref offset); + + case DhcpOptionCode.NetBIOSOverTCPIPNameServer: + return DhcpNetBIOSOverTCPIPNameServerOption.Read(data, ref offset); + + case DhcpOptionCode.NetBIOSOverTCPIPDatagramDistributionServer: + return DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.Read(data, ref offset); + + case DhcpOptionCode.NetBIOSOverTCPIPNodeType: + return DhcpNetBIOSOverTCPIPNodeTypeOption.Read(data, ref offset); + + case DhcpOptionCode.NetBIOSOverTCPIPScope: + return DhcpNetBIOSOverTCPIPScopeOption.Read(data, ref offset); + + case DhcpOptionCode.XWindowSystemFontServer: + return DhcpXWindowSystemFontServerOption.Read(data, ref offset); + + case DhcpOptionCode.XWindowSystemDisplayManager: + return DhcpXWindowSystemDisplayManagerOption.Read(data, ref offset); + + case DhcpOptionCode.NetworkInformationServicePlusDomain: + return DhcpNetworkInformationServicePlusDomainOption.Read(data, ref offset); + + case DhcpOptionCode.NetworkInformationServicePlusServers: + return DhcpNetworkInformationServicePlusServersOption.Read(data, ref offset); + + case DhcpOptionCode.MobileIPHomeAgent: + return DhcpMobileIPHomeAgentOption.Read(data, ref offset); + + case DhcpOptionCode.SimpleMailTransportProtocolServer: + return DhcpSimpleMailTransportProtocolServerOption.Read(data, ref offset); + + case DhcpOptionCode.PostOfficeProtocolServer: + return DhcpPostOfficeProtocolServerOption.Read(data, ref offset); + + case DhcpOptionCode.NetworkNewsTransportProtocolServer: + return DhcpNetworkNewsTransportProtocolServerOption.Read(data, ref offset); + + case DhcpOptionCode.DefaultWorldWideWebServer: + return DhcpDefaultWorldWideWebServerOption.Read(data, ref offset); + + case DhcpOptionCode.DefaultFingerServer: + return DhcpDefaultFingerServerOption.Read(data, ref offset); + + case DhcpOptionCode.DefaultInternetRelayChatServer: + return DhcpDefaultInternetRelayChatServerOption.Read(data, ref offset); + + case DhcpOptionCode.StreetTalkServer: + return DhcpStreetTalkServerOption.Read(data, ref offset); + + case DhcpOptionCode.StreetTalkDirectoryAssistanceServer: + return DhcpStreetTalkDirectoryAssistanceServerOption.Read(data, ref offset); + + #endregion 8. Application and Service Parameters + + #region 9.DHCP Extensions + + case DhcpOptionCode.RequestedIPAddress: + return DhcpRequestedIPAddressOption.Read(data, ref offset); + + case DhcpOptionCode.IPAddressLeaseTime: + return DhcpIPAddressLeaseTimeOption.Read(data, ref offset); + + case DhcpOptionCode.OptionOverload: + return DhcpOptionOverloadOption.Read(data, ref offset); + + case DhcpOptionCode.TFTPServerName: + return DhcpTFTPServerNameOption.Read(data, ref offset); + + case DhcpOptionCode.BootfileName: + return DhcpBootfileNameOption.Read(data, ref offset); + + case DhcpOptionCode.MessageType: + return DhcpMessageTypeOption.Read(data, ref offset); + + case DhcpOptionCode.ServerIdentifier: + return DhcpServerIdentifierOption.Read(data, ref offset); + + case DhcpOptionCode.ParameterRequestList: + return DhcpParameterRequestListOption.Read(data, ref offset); + + case DhcpOptionCode.Message: + return DhcpMessageOption.Read(data, ref offset); + + case DhcpOptionCode.MaximumDhcpMessageSize: + return DhcpMaximumDhcpMessageSizeOption.Read(data, ref offset); + + case DhcpOptionCode.RenewalTimeValue: + return DhcpRenewalTimeValueOption.Read(data, ref offset); + + case DhcpOptionCode.RebindingTimeValue: + return DhcpRebindingTimeValueOption.Read(data, ref offset); + + case DhcpOptionCode.VendorClassidentifier: + return DhcpVendorClassidentifierOption.Read(data, ref offset); + + case DhcpOptionCode.ClientIdentifier: + return DhcpClientIdentifierOption.Read(data, ref offset); + + #endregion 9.DHCP Extensions + + default: + return DhcpAnyOption.Read(data, ref offset); + } + } + + internal virtual void Write(byte[] buffer, ref int offset) + { + buffer.Write(offset++, (byte)OptionCode); + buffer.Write(offset++, Length); + } + + /// + /// Two options objects are equal if they have the same parameters. + /// + public override bool Equals(object obj) + { + return Equals(obj as DhcpOption); + } + + /// + /// Two options objects are equal if they have the same parameters. + /// + public bool Equals(DhcpOption other) + { + if (other == null) + return false; + + if (OptionCode != other.OptionCode) + return false; + + if (Length != other.Length) + return false; + + //we compare the output of write + + byte[] selfData = new byte[2 + Length]; + byte[] otherData = new byte[2 + other.Length]; + int offset = 0; + Write(selfData, ref offset); + offset = 0; + other.Write(otherData, ref offset); + + return selfData.SequenceEqual(otherData); + } + + /// + /// calucate a hash of the option + /// + /// a hash representing this instance + public override int GetHashCode() + { + byte[] selfData = new byte[2 + Length]; + int offset = 0; + Write(selfData, ref offset); + + return selfData.GetHashCode(); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionCode.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionCode.cs new file mode 100644 index 00000000..93524228 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionCode.cs @@ -0,0 +1,884 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// + public enum DhcpOptionCode : byte + { + #region 3. RFC 1497 Vendor Extensions + + /// + /// RFC 2132. + ///
+        /// +-----+
+        /// |  0  |
+        /// +-----+
+        /// 
+ ///
+ Pad = 0, + + /// + /// RFC 2132. + ///
+        /// +-----+
+        /// | 255 |
+        /// +-----+
+        /// 
+ ///
+ End = 255, + + /// + /// RFC 2132. + ///
+        ///  Code   Len        Subnet Mask
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  1  |  4  |  m1 |  m2 |  m3 |  m4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ SubnetMask = 1, + + /// + /// RFC 2132. + ///
+        ///  Code   Len        Time Offset
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  1  |  4  |  n1 |  n2 |  n3 |  n4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ TimeOffset = 2, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  3  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ Router = 3, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  4  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ TimeServer = 4, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  5  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ NameServer = 5, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  6  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ DomainNameServerServer = 6, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  7  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ LogServer = 7, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  8  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ CookieServer = 8, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  9  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ LPRServer = 9, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  10 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ ImpressServer = 10, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  11 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ ResourceLocationServer = 11, + + /// + /// RFC 2132. + ///
+        ///  Code   Len                 Host Name
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  12 |  n  |  h1 |  h2 |  h3 |  h4 |  h5 |  h6 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ HostName = 12, + + /// + /// RFC 2132. + ///
+        ///  Code   Len   File Size
+        /// +-----+-----+-----+-----+
+        /// |  13 |  2  |  l1 |  l2 |
+        /// +-----+-----+-----+-----+
+        /// 
+ ///
+ BootFileSize = 13, + + /// + /// RFC 2132. + ///
+        ///  Code   Len      Dump File Pathname
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// |  14 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ MeritDumpFile = 14, + + /// + /// RFC 2132. + ///
+        ///  Code   Len        Domain Name
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// |  15 |  n  |  d1 |  d2 |  d3 |  d4 | ...
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ DomainName = 15, + + /// + /// RFC 2132. + ///
+        ///  Code   Len    Swap Server Address
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  16 |  4  |  a1 |  a2 |  a3 |  a4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ SwapServer = 16, + + /// + /// RFC 2132. + ///
+        ///  Code   Len      Root Disk Pathname
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// |  17 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ RootPath = 17, + + /// + /// RFC 2132. + ///
+        ///  Code   Len      Extensions Pathname
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// |  18 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ ExtensionsPath = 18, + + #endregion 3. RFC 1497 Vendor Extensions + + #region 4. IP Layer Parameters per Host + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  19 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ IPForwardingEnable = 19, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  20 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ NonLocalSourceRoutingEnable = 20, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1                  Mask 1
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+        /// |  21 |  n  |  a1 |  a2 |  a3 |  a4 |  m1 |  m2 |  m3 |  m4 |
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+        ///         Address 2                  Mask 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+        /// |  a1 |  a2 |  a3 |  a4 |  m1 |  m2 |  m3 |  m4 | ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ PolicyFilter = 21, + + /// + /// RFC 2132. + ///
+        ///  Code   Len      Size
+        /// +-----+-----+-----+-----+
+        /// |  22 |  2  |  s1 |  s2 |
+        /// +-----+-----+-----+-----+
+        /// 
+ ///
+ MaximumDatagramReassemblySize = 22, + + /// + /// RFC 2132 + ///
+        ///  Code   Len   TTL
+        /// +-----+-----+-----+
+        /// |  23 |  1  | ttl |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ DefaultIPTimeToLive = 23, + + /// + /// RFC 2132 + ///
+        ///  Code   Len           Timeout
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  24 |  4  |  t1 |  t2 |  t3 |  t4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ PathMTUAgingTimeout = 24, + + /// + /// RFC 2132 + ///
+        ///  Code   Len     Size 1      Size 2
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// |  25 |  n  |  s1 |  s2 |  s1 |  s2 | ...
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ PathMTUPlateauTable = 25, + + #endregion 4. IP Layer Parameters per Host + + #region 5. IP Layer Parameters per Interface + + /// + /// RFC 2132 + ///
+        ///  Code   Len      MTU
+        /// +-----+-----+-----+-----+
+        /// |  26 |  2  |  m1 |  m2 |
+        /// +-----+-----+-----+-----+
+        /// 
+ ///
+ InterfaceMTU = 26, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  27 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ AllSubnetsAreLocal = 27, + + /// + /// RFC 2132. + ///
+        ///  Code   Len     Broadcast Address
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  28 |  4  |  b1 |  b2 |  b3 |  b4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ BroadcastAddress = 28, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  29 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ PerformMaskDiscovery = 29, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  30 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ MaskSupplier = 30, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  31 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ PerformRouterDiscovery = 31, + + /// + /// RFC 2132. + ///
+        ///  Code   Len            Address
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  32 |  4  |  a1 |  a2 |  a3 |  a4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ RouterSolicitationAddress = 32, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Destination 1           Router 1
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+        /// |  33 |  n  |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 |  r3 |  r4 |
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+        ///         Destination 2           Router 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+        /// |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 |  r3 |  r4 | ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ StaticRoute = 33, + + #endregion 5. IP Layer Parameters per Interface + + #region 6. Link Layer Parameters per Interface + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  34 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ TrailerEncapsulation = 34, + + /// + /// RFC 2132 + ///
+        ///  Code   Len           Time
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  35 |  4  |  t1 |  t2 |  t3 |  t4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ ARPCacheTimeout = 35, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  36 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ EthernetEncapsulation = 36, + + #endregion 6. Link Layer Parameters per Interface + + #region 7. TCP Parameters + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  37 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ TCPDefaultTTL = 37, + + /// + /// RFC 2132. + ///
+        ///  Code   Len           Time
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  38 |  4  |  t1 |  t2 |  t3 |  t4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ TCPKeepaliveInterval = 38, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  39 |  1  | 0/1 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ TCPKeepaliveGarbage = 39, + + #endregion 7. TCP Parameters + + #region 8. Application and Service Parameters + + /// + /// RFC 2132. + ///
+        ///  Code   Len      NIS Domain Name
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// |  40 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ NetworkInformationServiceDomain = 40, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  41 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ NetworkInformationServers = 41, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  42 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ NetworkTimeProtocolServers = 42, + + /// + /// RFC 2132. + ///
+        /// Code   Len   Vendor-specific information
+        /// +-----+-----+-----+-----+---
+        /// |  43 |  n  |  i1 |  i2 | ...
+        /// +-----+-----+-----+-----+---
+        /// 
+ ///
+ VendorSpecificInformation = 43, + + /// + /// RFC 2132. + ///
+        ///  Code   Len           Address 1              Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+        /// |  44 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+        /// 
+ ///
+ NetBIOSOverTCPIPNameServer = 44, + + /// + /// RFC 2132. + ///
+        ///  Code   Len           Address 1              Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+        /// |  45 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+        /// 
+ ///
+ NetBIOSOverTCPIPDatagramDistributionServer = 45, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Node Type
+        /// +-----+-----+-----------+
+        /// |  46 |  1  |   flags   |
+        /// +-----+-----+-----------+
+        /// 
+ ///
+ NetBIOSOverTCPIPNodeType = 46, + + /// + /// RFC 2132. + ///
+        /// Code   Len       NetBIOS Scope
+        /// +-----+-----+-----+-----+-----+-----+----
+        /// |  47 |  n  |  s1 |  s2 |  s3 |  s4 | ...
+        /// +-----+-----+-----+-----+-----+-----+----
+        /// 
+ ///
+ NetBIOSOverTCPIPScope = 47, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+        /// |  48 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |   ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ XWindowSystemFontServer = 48, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+        /// |  49 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |   ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ XWindowSystemDisplayManager = 49, + + /// + /// RFC 2132. + ///
+        ///  Code   Len      NIS Client Domain Name
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// |  64 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+        /// +-----+-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ NetworkInformationServicePlusDomain = 64, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// |  65 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ NetworkInformationServicePlusServers = 65, + + /// + /// RFC 2132. + ///
+        ///  Code Len    Home Agent Addresses (zero or more)
+        /// +-----+-----+-----+-----+-----+-----+--
+        /// | 68  |  n  | a1  | a2  | a3  | a4  | ...
+        /// +-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ MobileIPHomeAgent = 68, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// | 69  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ SimpleMailTransportProtocolServer = 69, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// | 70  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ PostOfficeProtocolServer = 70, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// | 71  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ NetworkNewsTransportProtocolServer = 71, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// | 72  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ DefaultWorldWideWebServer = 72, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// | 73  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ DefaultFingerServer = 73, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// | 74  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ DefaultInternetRelayChatServer = 74, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// | 75  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ StreetTalkServer = 75, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Address 1               Address 2
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// | 76  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+        /// 
+ ///
+ StreetTalkDirectoryAssistanceServer = 76, + + #endregion 8. Application and Service Parameters + + #region 9. DHCP Extensions + + /// + /// RFC 2132. + ///
+        ///  Code   Len          Address
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  50 |  4  |  a1 |  a2 |  a3 |  a4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ RequestedIPAddress = 50, + + /// + /// RFC 2132. + ///
+        ///  Code   Len         Lease Time
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  51 |  4  |  t1 |  t2 |  t3 |  t4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ IPAddressLeaseTime = 51, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Value
+        /// +-----+-----+-----+
+        /// |  52 |  1  |1/2/3|
+        /// +-----+-----+-----+
+        /// 
+ ///
+ OptionOverload = 52, + + /// + /// RFC 2132. + ///
+        ///  Code Len    TFTP server
+        /// +-----+-----+-----+-----+-----+---
+        /// | 66  |  n  |  c1 |  c2 |  c3 | ...
+        /// +-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ TFTPServerName = 66, + + /// + /// RFC 2132. + ///
+        ///  Code Len    Bootfile name
+        /// +-----+-----+-----+-----+-----+---
+        /// | 67  |  n  |  c1 |  c2 |  c3 | ...
+        /// +-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ BootfileName = 67, + + /// + /// RFC 2132. + ///
+        ///  Code   Len  Type
+        /// +-----+-----+-----+
+        /// |  53 |  1  | 1-7 |
+        /// +-----+-----+-----+
+        /// 
+ ///
+ MessageType = 53, + + /// + /// RFC 2132. + ///
+        ///  Code   Len            Address
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  54 |  4  |  a1 |  a2 |  a3 |  a4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ ServerIdentifier = 54, + + /// + /// RFC 2132. + ///
+        /// Code   Len   Option Codes
+        /// +-----+-----+-----+-----+---
+        /// |  55 |  n  |  c1 |  c2 | ...
+        /// +-----+-----+-----+-----+---
+        /// 
+ ///
+ ParameterRequestList = 55, + + /// + /// RFC 2132. + ///
+        ///  Code   Len     Text
+        /// +-----+-----+-----+-----+---
+        /// |  56 |  n  |  c1 |  c2 | ...
+        /// +-----+-----+-----+-----+---
+        /// 
+ ///
+ Message = 56, + + /// + /// RFC 2132. + ///
+        ///  Code   Len     Length
+        /// +-----+-----+-----+-----+
+        /// |  57 |  2  |  l1 |  l2 |
+        /// +-----+-----+-----+-----+
+        /// 
+ ///
+ MaximumDhcpMessageSize = 57, + + /// + /// RFC 2132 + ///
+        ///  Code   Len         T1 Interval
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  58 |  4  |  t1 |  t2 |  t3 |  t4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ RenewalTimeValue = 58, + + /// + /// RFC 2132 + ///
+        ///  Code   Len         T1 Interval
+        /// +-----+-----+-----+-----+-----+-----+
+        /// |  5859 |  4  |  t1 |  t2 |  t3 |  t4 |
+        /// +-----+-----+-----+-----+-----+-----+
+        /// 
+ ///
+ RebindingTimeValue = 59, + + /// + /// RFC 2132. + ///
+        ///  Code   Len   Vendor class Identifier
+        /// +-----+-----+-----+-----+---
+        /// |  60 |  n  |  i1 |  i2 | ...
+        /// +-----+-----+-----+-----+---
+        /// 
+ ///
+ VendorClassidentifier = 60, + + /// + /// RFC 2132. + ///
+        ///  Code   Len   Type  Client-Identifier
+        /// +-----+-----+-----+-----+-----+---
+        /// |  61 |  n  |  t1 |  i1 |  i2 | ...
+        /// +-----+-----+-----+-----+-----+---
+        /// 
+ ///
+ ClientIdentifier = 61, + + #endregion 9. DHCP Extensions + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs new file mode 100644 index 00000000..9f1d22bd --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  52 |  1  |1/2/3|
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpOptionOverloadOption : DhcpOption + { + public DhcpOptionOverloadOption(OptionOverloadValue value) : base(DhcpOptionCode.OptionOverload) + { + Value = value; + } + + internal static DhcpOptionOverloadOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP OptionOverload Option has to be 1"); + DhcpOptionOverloadOption option = new DhcpOptionOverloadOption((OptionOverloadValue)data[offset]); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, (byte)Value); + } + + public override byte Length + { + get + { + return 1; + } + } + + public OptionOverloadValue Value + { + get { return _value; } + set + { + if (!Enum.IsDefined(typeof(OptionOverloadValue), value)) + throw new ArgumentOutOfRangeException(nameof(Value), value, "Not a valid OptionOverloadValue"); + _value = value; + } + } + + private OptionOverloadValue _value; + + public enum OptionOverloadValue : byte + { + File = 1, + SName = 2, + Both = 3 + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs new file mode 100644 index 00000000..cebc841e --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code
+    /// +-----+
+    /// |  0  |
+    /// +-----+
+    /// 
+ ///
+ public class DhcpPadOption : DhcpOption + { + public DhcpPadOption() : base(DhcpOptionCode.Pad) + { + } + + public override byte Length + { + get { return 0; } + } + + internal static DhcpPadOption Read(DataSegment data, ref int offset) + { + return new Options.DhcpPadOption(); + } + + internal override void Write(byte[] buffer, ref int offset) + { + buffer.Write(offset++, (byte)OptionCode); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs new file mode 100644 index 00000000..ed3146c5 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    /// Code   Len   Option Codes
+    /// +-----+-----+-----+-----+---
+    /// |  55 |  n  |  c1 |  c2 | ...
+    /// +-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpParameterRequestListOption : DhcpOption + { + public DhcpParameterRequestListOption(IList codes) : base(DhcpOptionCode.ParameterRequestList) + { + if (codes == null) + throw new ArgumentNullException(nameof(codes)); + if (codes.Count > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(codes), codes.Count, "The maximum items in codes is 255"); + Codes = new ReadOnlyCollection(codes); + } + + internal static DhcpParameterRequestListOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + List codes = new List(); + for (int i = 0; i < length; i++) + { + codes.Add((DhcpOptionCode)data[offset++]); + } + return new DhcpParameterRequestListOption(codes); + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Codes.Select(p => (byte)p)); + } + + public override byte Length + { + get + { + if (Codes.Count > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(Codes), Codes.Count, "The maximum items in addresses is 255"); + + return (byte)Codes.Count; + } + } + + public IReadOnlyCollection Codes + { + get; + private set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUAgingTimeoutOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUAgingTimeoutOption.cs new file mode 100644 index 00000000..5af8b517 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUAgingTimeoutOption.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len           Timeout
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  24 |  4  |  t1 |  t2 |  t3 |  t4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpPathMTUAgingTimeoutOption : DhcpOption + { + public DhcpPathMTUAgingTimeoutOption() : base(DhcpOptionCode.PathMTUAgingTimeout) + { + } + + public DhcpPathMTUAgingTimeoutOption(uint timeout) : this() + { + Timeout = timeout; + } + + internal static DhcpPathMTUAgingTimeoutOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + { + throw new ArgumentException("Length of a DHCP PathMTUAgingTimeout Option has to be 4"); + } + DhcpPathMTUAgingTimeoutOption option = new DhcpPathMTUAgingTimeoutOption(data.ReadUInt(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Timeout, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public uint Timeout + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUPlateauTableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUPlateauTableOption.cs new file mode 100644 index 00000000..acb5d885 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUPlateauTableOption.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len     Size 1      Size 2
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// |  25 |  n  |  s1 |  s2 |  s1 |  s2 | ...
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpPathMTUPlateauTableOption : DhcpOption + { + internal const int MAX_SIZES = 255 / sizeof(ushort); + + public DhcpPathMTUPlateauTableOption(IList sizes) : base(DhcpOptionCode.PathMTUPlateauTable) + { + if (sizes == null) + throw new ArgumentNullException(nameof(sizes)); + if (sizes.Count > MAX_SIZES) + throw new ArgumentOutOfRangeException(nameof(sizes), sizes.Count, $"The maximum items in addresses is {MAX_SIZES}"); + + Sizes = new ReadOnlyCollection(sizes); + } + + internal static DhcpPathMTUPlateauTableOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len % sizeof(ushort) != 0) + { + throw new ArgumentException("Length of a DHCP PathMTUPlateauTable Option has to be a multiple of 2"); + } + List sizes = new List(); + for (int i = 0; i < len; i += 2) + { + sizes.Add(data.ReadUShort(offset + i, Endianity.Big)); + } + DhcpPathMTUPlateauTableOption option = new DhcpPathMTUPlateauTableOption(sizes); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + foreach (ushort size in Sizes) + { + buffer.Write(ref offset, size, Endianity.Big); + } + } + + public override byte Length + { + get + { + if (Sizes.Count > MAX_SIZES) + throw new ArgumentOutOfRangeException(nameof(Sizes), Sizes.Count, $"The maximum items in addresses is {MAX_SIZES}"); + + return (byte)(Sizes.Count * sizeof(ushort)); + } + } + + public IReadOnlyCollection Sizes + { + get; + private set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs new file mode 100644 index 00000000..5ab0dcc6 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  29 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpPerformMaskDiscoveryOption : DhcpOption + { + public DhcpPerformMaskDiscoveryOption(bool enabled) : base(DhcpOptionCode.PerformMaskDiscovery) + { + } + + internal static DhcpPerformMaskDiscoveryOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP PerformMaskDiscovery Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP PerformMaskDiscovery Option has to be 0 or 1"); + DhcpPerformMaskDiscoveryOption option = new DhcpPerformMaskDiscoveryOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs new file mode 100644 index 00000000..6fb984a7 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  31 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpPerformRouterDiscoveryOption : DhcpOption + { + public DhcpPerformRouterDiscoveryOption(bool enabled) : base(DhcpOptionCode.PerformRouterDiscovery) + { + } + + internal static DhcpPerformRouterDiscoveryOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP PerformRouterDiscovery Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP PerformRouterDiscovery Option has to be 0 or 1"); + DhcpPerformRouterDiscoveryOption option = new DhcpPerformRouterDiscoveryOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs new file mode 100644 index 00000000..da6d3273 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1                  Mask 1
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+    /// |  21 |  n  |  a1 |  a2 |  a3 |  a4 |  m1 |  m2 |  m3 |  m4 |
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+    ///         Address 2                  Mask 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+    /// |  a1 |  a2 |  a3 |  a4 |  m1 |  m2 |  m3 |  m4 | ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpPolicyFilterOption : DhcpOption + { + internal const int MAX_FILTERS = 255 / IpV4AddressWithMask.SizeOf; + + public DhcpPolicyFilterOption(IList filters) : base(DhcpOptionCode.PolicyFilter) + { + if (filters == null) + throw new ArgumentNullException(nameof(filters)); + if (filters.Count > MAX_FILTERS) + throw new ArgumentOutOfRangeException(nameof(filters), filters.Count, $"The maximum items in filters is {MAX_FILTERS}"); + + Filters = new ReadOnlyCollection(filters); + } + + internal static DhcpPolicyFilterOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + if (length % 8 != 0) + throw new ArgumentOutOfRangeException(nameof(length), length, "length has to be a multiple of 8"); + IList addresses = DhcpAddressListOption.GetAddresses(data, length, ref offset); + + List filters = new List(); + for (int i = 0; i < addresses.Count; i += 2) + { + filters.Add(new IpV4AddressWithMask(addresses[i], addresses[i + 1])); + } + return new DhcpPolicyFilterOption(filters); + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + foreach (IpV4AddressWithMask filter in Filters) + { + buffer.Write(ref offset, filter.Address, Endianity.Big); + buffer.Write(ref offset, filter.Mask, Endianity.Big); + } + } + + public override byte Length + { + get + { + if (Filters.Count > MAX_FILTERS) + throw new ArgumentOutOfRangeException(nameof(Filters), Filters.Count, $"The maximum items in Filter is {MAX_FILTERS}"); + + return (byte)(Filters.Count * IpV4AddressWithMask.SizeOf); + } + } + + public IReadOnlyCollection Filters + { + get; + private set; + } + + public struct IpV4AddressWithMask + { + /// + /// The number of bytes the IpV4AddressWithMask take. + /// + public const int SizeOf = IpV4Address.SizeOf + IpV4Address.SizeOf; + + public IpV4Address Address + + { + get; + private set; + } + + public IpV4Address Mask + { + get; + private set; + } + + public IpV4AddressWithMask(IpV4Address address, IpV4Address mask) + { + Address = address; + Mask = mask; + } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs new file mode 100644 index 00000000..e8bcbd21 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// | 70  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpPostOfficeProtocolServerOption : DhcpAddressListOption + { + public DhcpPostOfficeProtocolServerOption(IList addresses) : base(DhcpOptionCode.PostOfficeProtocolServer, addresses) + { + } + + internal static DhcpPostOfficeProtocolServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpPostOfficeProtocolServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs new file mode 100644 index 00000000..0b2ea67f --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len         T1 Interval
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  59 |  4  |  t1 |  t2 |  t3 |  t4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpRebindingTimeValueOption : DhcpOption + { + public DhcpRebindingTimeValueOption(uint interval) : base(DhcpOptionCode.RebindingTimeValue) + { + Interval = interval; + } + + internal static DhcpRebindingTimeValueOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + { + throw new ArgumentException("Length of a DHCP RebindingTimeValue Option has to be 4"); + } + DhcpRebindingTimeValueOption option = new DhcpRebindingTimeValueOption(data.ReadUInt(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Interval, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public uint Interval + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs new file mode 100644 index 00000000..20231190 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len         T1 Interval
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  58 |  4  |  t1 |  t2 |  t3 |  t4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpRenewalTimeValueOption : DhcpOption + { + public DhcpRenewalTimeValueOption(uint interval) : base(DhcpOptionCode.RenewalTimeValue) + { + Interval = interval; + } + + internal static DhcpRenewalTimeValueOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + { + throw new ArgumentException("Length of a DHCP RenewalTimeValue Option has to be 4"); + } + DhcpRenewalTimeValueOption option = new DhcpRenewalTimeValueOption(data.ReadUInt(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Interval, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public uint Interval + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs new file mode 100644 index 00000000..a2032d9d --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len          Address
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  50 |  4  |  a1 |  a2 |  a3 |  a4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpRequestedIPAddressOption : DhcpOption + { + public DhcpRequestedIPAddressOption(IpV4Address address) : base(DhcpOptionCode.RequestedIPAddress) + { + Address = address; + } + + internal static DhcpRequestedIPAddressOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + throw new ArgumentException("Length of a DHCP RequestedIPAddressOption has to be 4"); + DhcpRequestedIPAddressOption option = new DhcpRequestedIPAddressOption(data.ReadIpV4Address(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Address, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public IpV4Address Address + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs new file mode 100644 index 00000000..63e726ea --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + public class DhcpResourceLocationServerOption : DhcpAddressListOption + { + public DhcpResourceLocationServerOption(IList addresses) : base(DhcpOptionCode.ResourceLocationServer, addresses) + { + } + + internal static DhcpResourceLocationServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpResourceLocationServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs new file mode 100644 index 00000000..4f30e271 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len      Root Disk Pathname
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// |  17 |  n  |  n1 |  n2 |  n3 |  n4 | ...
+    /// +-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpRootPathOption : DhcpOption + { + public DhcpRootPathOption(string rootPath) : base(DhcpOptionCode.RootPath) + { + RootPath = rootPath; + } + + internal static DhcpRootPathOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); + DhcpRootPathOption option = new DhcpRootPathOption(hostName); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(RootPath)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(RootPath); + } + } + + public string RootPath + { + get { return _rootPath; } + set + { + if (value == null) + throw new ArgumentNullException(nameof(RootPath)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(RootPath), value.Length, "RootPath has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(RootPath), value.Length, "RootPath has to be less than 256 characters long"); + + _rootPath = value; + } + } + + private string _rootPath; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs new file mode 100644 index 00000000..c8b0b672 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + public class DhcpRouterOption : DhcpAddressListOption + { + public DhcpRouterOption(IList addresses) : base(DhcpOptionCode.Router, addresses) + { + } + + internal static DhcpRouterOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpRouterOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs new file mode 100644 index 00000000..9a74ce39 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len            Address
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  32 |  4  |  a1 |  a2 |  a3 |  a4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpRouterSolicitationAddressOption : DhcpOption + { + public DhcpRouterSolicitationAddressOption(IpV4Address address) : base(DhcpOptionCode.RouterSolicitationAddress) + { + Address = address; + } + + internal static DhcpRouterSolicitationAddressOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + throw new ArgumentException("Length of a DHCP RouterSolicitationAddress Option has to be 4"); + DhcpRouterSolicitationAddressOption option = new DhcpRouterSolicitationAddressOption(data.ReadIpV4Address(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Address, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public IpV4Address Address + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs new file mode 100644 index 00000000..d47ce028 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len             Address
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  54 |  4  |  a1 |  a2 |  a3 |  a4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpServerIdentifierOption : DhcpOption + { + public DhcpServerIdentifierOption(IpV4Address address) : base(DhcpOptionCode.ServerIdentifier) + { + Address = address; + } + + internal static DhcpServerIdentifierOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + throw new ArgumentException("Length of a DHCP ServerIdentifier Option has to be 4"); + DhcpServerIdentifierOption option = new DhcpServerIdentifierOption(data.ReadIpV4Address(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Address, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public IpV4Address Address + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs new file mode 100644 index 00000000..148aad20 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// | 69  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpSimpleMailTransportProtocolServerOption : DhcpAddressListOption + { + public DhcpSimpleMailTransportProtocolServerOption(IList addresses) : base(DhcpOptionCode.SimpleMailTransportProtocolServer, addresses) + { + } + + internal static DhcpSimpleMailTransportProtocolServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpSimpleMailTransportProtocolServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs new file mode 100644 index 00000000..e1a12714 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + public class DhcpStaticRouteOption : DhcpOption + { + internal const int MAX_ROUTES = 255 / 8; + + public DhcpStaticRouteOption(IList routes) : base(DhcpOptionCode.StaticRoute) + { + if (routes == null) + throw new ArgumentNullException(nameof(routes)); + if (routes.Count > MAX_ROUTES) + throw new ArgumentOutOfRangeException(nameof(routes), routes.Count, $"The maximum items in routes is {MAX_ROUTES}"); + + Routes = new ReadOnlyCollection(routes); + } + + internal static DhcpStaticRouteOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + if (length % 8 != 0) + throw new ArgumentOutOfRangeException(nameof(length), length, "length has to be a multiple of 8"); + IList addresses = DhcpAddressListOption.GetAddresses(data, length, ref offset); + + List routes = new List(); + for (int i = 0; i < addresses.Count; i += 2) + { + routes.Add(new IpV4AddressRoute(addresses[i], addresses[i + 1])); + } + return new DhcpStaticRouteOption(routes); + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + foreach (IpV4AddressRoute route in Routes) + { + buffer.Write(ref offset, route.Destination, Endianity.Big); + buffer.Write(ref offset, route.Router, Endianity.Big); + } + } + + public override byte Length + { + get + { + if (Routes.Count > MAX_ROUTES) + throw new ArgumentOutOfRangeException(nameof(Routes), Routes.Count, $"The maximum items in Routes is {MAX_ROUTES}"); + + return (byte)(Routes.Count * 8); + } + } + + public IReadOnlyCollection Routes + { + get; + private set; + } + + public struct IpV4AddressRoute + { + public IpV4Address Destination + + { + get; + private set; + } + + public IpV4Address Router + { + get; + private set; + } + + public IpV4AddressRoute(IpV4Address destination, IpV4Address router) + { + Destination = destination; + Router = router; + } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs new file mode 100644 index 00000000..7afc70c9 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// | 76  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpStreetTalkDirectoryAssistanceServerOption : DhcpAddressListOption + { + public DhcpStreetTalkDirectoryAssistanceServerOption(IList addresses) : base(DhcpOptionCode.StreetTalkDirectoryAssistanceServer, addresses) + { + } + + internal static DhcpStreetTalkDirectoryAssistanceServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpStreetTalkDirectoryAssistanceServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs new file mode 100644 index 00000000..79dec583 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// | 75  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpStreetTalkServerOption : DhcpAddressListOption + { + public DhcpStreetTalkServerOption(IList addresses) : base(DhcpOptionCode.StreetTalkServer, addresses) + { + } + + internal static DhcpStreetTalkServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpStreetTalkServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs new file mode 100644 index 00000000..79fe7c8b --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len        Subnet Mask
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  1  |  4  |  m1 |  m2 |  m3 |  m4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpSubnetMaskOption : DhcpOption + { + public DhcpSubnetMaskOption(IpV4Address subnetMask) : base(DhcpOptionCode.SubnetMask) + { + SubnetMask = subnetMask; + } + + internal static DhcpSubnetMaskOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != IpV4Address.SizeOf) + throw new ArgumentException("Length of a DHCP SubnetMask Option has to be 4"); + DhcpSubnetMaskOption option = new DhcpSubnetMaskOption(data.ReadIpV4Address(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, SubnetMask, Endianity.Big); + } + + public override byte Length + { + get { return IpV4Address.SizeOf; } + } + + public IpV4Address SubnetMask + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs new file mode 100644 index 00000000..162877d8 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len    Swap Server Address
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  16 |  4  |  a1 |  a2 |  a3 |  a4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpSwapServerOption : DhcpOption + { + public DhcpSwapServerOption(IpV4Address swapServer) : base(DhcpOptionCode.SwapServer) + { + SwapServer = swapServer; + } + + internal static DhcpSwapServerOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + throw new ArgumentException("Length of a DHCP SwapServer Option has to be 4"); + DhcpSwapServerOption option = new DhcpSwapServerOption(data.ReadIpV4Address(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, SwapServer, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public IpV4Address SwapServer + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPDefaultTTLOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPDefaultTTLOption.cs new file mode 100644 index 00000000..b723197e --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPDefaultTTLOption.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  37 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpTCPDefaultTTLOption : DhcpOption + { + public DhcpTCPDefaultTTLOption(bool enabled) : base(DhcpOptionCode.TCPDefaultTTL) + { + Value = enabled; + } + + internal static DhcpTCPDefaultTTLOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP TCPDefaultTTL Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP TCPDefaultTTL Option has to be 0 or 1"); + DhcpTCPDefaultTTLOption option = new DhcpTCPDefaultTTLOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveGarbageOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveGarbageOption.cs new file mode 100644 index 00000000..a533252f --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveGarbageOption.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  39 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpTCPKeepaliveGarbageOption : DhcpOption + { + public DhcpTCPKeepaliveGarbageOption(bool enabled) : base(DhcpOptionCode.TCPKeepaliveGarbage) + { + Value = enabled; + } + + internal static DhcpTCPKeepaliveGarbageOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP TCPKeepaliveGarbage Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP TCPKeepaliveGarbage Option has to be 0 or 1"); + DhcpTCPKeepaliveGarbageOption option = new DhcpTCPKeepaliveGarbageOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveIntervalOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveIntervalOption.cs new file mode 100644 index 00000000..c6462af3 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveIntervalOption.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len           Time
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  38 |  4  |  t1 |  t2 |  t3 |  t4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpTCPKeepaliveIntervalOption : DhcpOption + { + public DhcpTCPKeepaliveIntervalOption(uint time) : base(DhcpOptionCode.TCPKeepaliveInterval) + { + Time = time; + } + + internal static DhcpTCPKeepaliveIntervalOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + { + throw new ArgumentException("Length of a DHCP TCPKeepaliveInterval Option has to be 4"); + } + DhcpTCPKeepaliveIntervalOption option = new DhcpTCPKeepaliveIntervalOption(data.ReadUInt(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Time, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public uint Time + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFTPServerNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFTPServerNameOption.cs new file mode 100644 index 00000000..6c48bf09 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFTPServerNameOption.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code Len    TFTP server
+    /// +-----+-----+-----+-----+-----+---
+    /// | 66  |  n  |  c1 |  c2 |  c3 | ...
+    /// +-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpTFTPServerNameOption : DhcpOption + { + public DhcpTFTPServerNameOption(string tfptServer) : base(DhcpOptionCode.TFTPServerName) + { + TFPTServer = tfptServer; + } + + internal static DhcpTFTPServerNameOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + DhcpTFTPServerNameOption option = new DhcpTFTPServerNameOption(Encoding.ASCII.GetString(data.ReadBytes(offset, len))); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(TFPTServer)); + } + + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(TFPTServer); + } + } + + public string TFPTServer + { + get { return bootfileName; } + + set + { + if (value == null) + throw new ArgumentNullException(nameof(TFPTServer)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(TFPTServer), value.Length, "BootfileName has to be at least 1 characters long"); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(TFPTServer), value.Length, "BootfileName has to be less than 256 characters long"); + + bootfileName = value; + } + } + + private string bootfileName; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs new file mode 100644 index 00000000..9f28bcc0 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132 + ///
+    ///  Code   Len        Time Offset
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  1  |  4  |  n1 |  n2 |  n3 |  n4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpTimeOffsetOption : DhcpOption + { + public DhcpTimeOffsetOption(uint timeOffset) : base(DhcpOptionCode.TimeOffset) + { + TimeOffset = timeOffset; + } + + internal static DhcpTimeOffsetOption Read(DataSegment data, ref int offset) + { + if (data[offset++] != 4) + { + throw new ArgumentException("Length of a DHCP TimeOffset Option has to be 4"); + } + DhcpTimeOffsetOption option = new DhcpTimeOffsetOption(data.ReadUInt(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, TimeOffset, Endianity.Big); + } + + public override byte Length + { + get { return 4; } + } + + public uint TimeOffset + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs new file mode 100644 index 00000000..e36efaf9 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + public class DhcpTimeServerOption : DhcpAddressListOption + { + public DhcpTimeServerOption(IList addresses) : base(DhcpOptionCode.TimeServer, addresses) + { + } + + internal static DhcpTimeServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpTimeServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs new file mode 100644 index 00000000..c9e00041 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  34 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpTrailerEncapsulationOption : DhcpOption + { + public DhcpTrailerEncapsulationOption(bool enabled) : base(DhcpOptionCode.TrailerEncapsulation) + { + Value = enabled; + } + + internal static DhcpTrailerEncapsulationOption Read(DataSegment data, ref int offset) + { + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP TrailerEncapsulation Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP TrailerEncapsulation Option has to be 0 or 1"); + DhcpTrailerEncapsulationOption option = new DhcpTrailerEncapsulationOption(data[offset] == 1 ? true : false); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Value ? (byte)1 : (byte)0); + } + + public override byte Length + { + get + { + return 1; + } + } + + public bool Value + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs new file mode 100644 index 00000000..df408d32 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len   Vendor class Identifier
+    /// +-----+-----+-----+-----+---
+    /// |  60 |  n  |  i1 |  i2 | ...
+    /// +-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpVendorClassidentifierOption : DhcpOption + { + public DhcpVendorClassidentifierOption(DataSegment vendorClassIdentifier) : base(DhcpOptionCode.VendorClassidentifier) + { + VendorClassIdentifier = vendorClassIdentifier; + } + + internal static DhcpVendorClassidentifierOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + DhcpVendorClassidentifierOption option = new DhcpVendorClassidentifierOption(data.Subsegment(offset, length)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, VendorClassIdentifier); + } + + public override byte Length + { + get + { + if (VendorClassIdentifier == null) + { + return 0; + } + return (byte)VendorClassIdentifier.Length; + } + } + + public DataSegment VendorClassIdentifier + { + get { return _vendorClassIdentifier; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(VendorClassIdentifier)); + } + if (value.Length < 1) + { + throw new ArgumentOutOfRangeException(nameof(VendorClassIdentifier), value.Length, "VendorClassIdentifier.Length has to be greater than 0"); + } + if (value.Length > byte.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(VendorClassIdentifier), value.Length, "VendorClassIdentifier.Length has to be less than 256"); + } + _vendorClassIdentifier = value; + } + } + + private DataSegment _vendorClassIdentifier; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs new file mode 100644 index 00000000..5600aaf2 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    /// Code   Len   Vendor-specific information
+    /// +-----+-----+-----+-----+---
+    /// |  43 |  n  |  i1 |  i2 | ...
+    /// +-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpVendorSpecificInformationOption : DhcpOption + { + public DhcpVendorSpecificInformationOption(DataSegment vendorSpecificInformation) : base(DhcpOptionCode.VendorSpecificInformation) + { + VendorSpecificInformation = vendorSpecificInformation; + } + + internal static DhcpVendorSpecificInformationOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + DhcpVendorSpecificInformationOption option = new DhcpVendorSpecificInformationOption(data.Subsegment(offset, length)); + offset += length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + if (VendorSpecificInformation == null) + throw new ArgumentNullException(nameof(VendorSpecificInformation)); + if (VendorSpecificInformation.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(VendorSpecificInformation), VendorSpecificInformation.Length, "VendorSpecificInformation.Length has to be less than 256"); + base.Write(buffer, ref offset); + buffer.Write(ref offset, VendorSpecificInformation); + } + + public override byte Length + { + get + { + if (VendorSpecificInformation == null) + { + return 0; + } + return (byte)VendorSpecificInformation.Length; + } + } + + public DataSegment VendorSpecificInformation + { + get { return _vendorSpecificInformation; } + set + { + if (value == null) + throw new ArgumentNullException(nameof(VendorSpecificInformation)); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(VendorSpecificInformation), value.Length, "VendorSpecificInformation.Length has to be less than 256"); + _vendorSpecificInformation = value; + } + } + + private DataSegment _vendorSpecificInformation; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs new file mode 100644 index 00000000..927c8a7e --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+    /// |  49 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |   ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpXWindowSystemDisplayManagerOption : DhcpAddressListOption + { + public DhcpXWindowSystemDisplayManagerOption(IList addresses) : base(DhcpOptionCode.XWindowSystemDisplayManager, addresses) + { + } + + internal static DhcpXWindowSystemDisplayManagerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpXWindowSystemDisplayManagerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs new file mode 100644 index 00000000..bfa41db5 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+    /// |  48 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |   ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpXWindowSystemFontServerOption : DhcpAddressListOption + { + public DhcpXWindowSystemFontServerOption(IList addresses) : base(DhcpOptionCode.XWindowSystemFontServer, addresses) + { + } + + internal static DhcpXWindowSystemFontServerOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return new DhcpXWindowSystemFontServerOption(GetAddresses(data, length, ref offset)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj b/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj index ff5a9534..c5665651 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj +++ b/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj @@ -95,6 +95,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PcapDotNet/src/PcapDotNet.Packets/Transport/UdpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Transport/UdpDatagram.cs index 16490d6a..0b55d652 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Transport/UdpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Transport/UdpDatagram.cs @@ -1,20 +1,21 @@ +using PcapDotNet.Packets.Dhcp; using PcapDotNet.Packets.Dns; namespace PcapDotNet.Packets.Transport { /// /// RFC 768. - /// This User Datagram Protocol (UDP) is defined to make available a datagram mode of packet-switched computer communication - /// in the environment of an interconnected set of computer networks. + /// This User Datagram Protocol (UDP) is defined to make available a datagram mode of packet-switched computer communication + /// in the environment of an interconnected set of computer networks. /// This protocol assumes that the Internet Protocol (IP) is used as the underlying protocol. - /// + /// /// - /// This protocol provides a procedure for application programs to send messages to other programs - /// with a minimum of protocol mechanism. - /// The protocol is transaction oriented, and delivery and duplicate protection are not guaranteed. + /// This protocol provides a procedure for application programs to send messages to other programs + /// with a minimum of protocol mechanism. + /// The protocol is transaction oriented, and delivery and duplicate protection are not guaranteed. /// Applications requiring ordered reliable delivery of streams of data should use the Transmission Control Protocol (TCP). /// - /// + /// /// /// Format ///
@@ -41,14 +42,15 @@ public sealed class UdpDatagram : TransportDatagram
 
         internal static class Offset
         {
-//            public const int SourcePort = 0;
-//            public const int DestinationPort = 2;
+            //            public const int SourcePort = 0;
+            //            public const int DestinationPort = 2;
             public const int TotalLength = 4;
+
             public const int Checksum = 6;
         }
 
         /// 
-        /// The length in octets of this user datagram including this header and the data.   
+        /// The length in octets of this user datagram including this header and the data.
         /// (This  means  the minimum value of the length is eight.)
         /// 
         public ushort TotalLength
@@ -57,7 +59,7 @@ public ushort TotalLength
         }
 
         /// 
-        /// Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header, 
+        /// Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header,
         /// the UDP header, and the data, padded  with zero octets at the end (if  necessary) to  make  a multiple of two octets.
         /// 
         public override ushort Checksum
@@ -79,12 +81,12 @@ public override bool IsChecksumOptional
         public override ILayer ExtractLayer()
         {
             return new UdpLayer
-                       {
-                           Checksum = Checksum,
-                           SourcePort = SourcePort,
-                           DestinationPort = DestinationPort,
-                           CalculateChecksumValue = (Checksum != 0)
-                       };
+            {
+                Checksum = Checksum,
+                SourcePort = SourcePort,
+                DestinationPort = DestinationPort,
+                CalculateChecksumValue = (Checksum != 0)
+            };
         }
 
         /// 
@@ -109,6 +111,20 @@ public DnsDatagram Dns
             }
         }
 
+        /// 
+        /// The payload of the datagram as a DHCP datagram.
+        /// 
+        public DhcpDatagram Dhcp
+        {
+            get
+            {
+                if (_dhcp == null && Length >= HeaderLength)
+                    _dhcp = new DhcpDatagram(Buffer, StartOffset + HeaderLength, Length - HeaderLength);
+
+                return _dhcp;
+            }
+        }
+
         internal override int ChecksumOffset
         {
             get { return Offset.Checksum; }
@@ -134,5 +150,6 @@ protected override bool CalculateIsValid()
         }
 
         private DnsDatagram _dns;
+        private DhcpDatagram _dhcp;
     }
 }
\ No newline at end of file

From 69ea9147688b3f7518549c970b9453ae68f94aba Mon Sep 17 00:00:00 2001
From: vbBerni 
Date: Sat, 17 Dec 2016 13:50:49 +0100
Subject: [PATCH 03/19] finish dhcp-support with documentation and fixes

---
 .../WiresharkCompareTests.cs                  |   71 +-
 .../src/PcapDotNet.Packets.Test/DhcpTests.cs  | 2105 ++++++++++++++++-
 .../RandomDhcpExtensions.cs                   |   71 +-
 .../PcapDotNet.Packets/Dhcp/DhcpDatagram.cs   |   79 +-
 .../src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs  |    2 +-
 .../src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs  |   58 +-
 .../Dhcp/DhcpMessageType.cs                   |    2 +-
 .../Dhcp/Options/DhcpARPCacheTimeoutOption.cs |   48 +-
 .../Dhcp/Options/DhcpAddressListOption.cs     |   34 +-
 .../Options/DhcpAllSubnetsAreLocalOption.cs   |   45 +-
 .../Dhcp/Options/DhcpAnyOption.cs             |   25 +-
 .../Dhcp/Options/DhcpBooleanOption.cs         |   60 +
 .../Dhcp/Options/DhcpBootFileSizeOption.cs    |   39 +-
 .../Dhcp/Options/DhcpBootfileNameOption.cs    |   52 +-
 .../Options/DhcpBroadcastAddressOption.cs     |   37 +-
 .../Dhcp/Options/DhcpByteOption.cs            |   58 +
 .../Options/DhcpClientIdentifierOption.cs     |   35 +-
 .../Dhcp/Options/DhcpCookieServerOption.cs    |   12 +-
 .../Dhcp/Options/DhcpDataSegmentOption.cs     |   74 +
 .../Options/DhcpDefaultFingerServerOption.cs  |   11 +-
 .../Options/DhcpDefaultIPTimeToLiveOption.cs  |   41 +-
 ...hcpDefaultInternetRelayChatServerOption.cs |   11 +-
 .../DhcpDefaultWorldWideWebServerOption.cs    |   11 +-
 .../Dhcp/Options/DhcpDomainNameOption.cs      |   52 +-
 .../Options/DhcpDomainNameServerOption.cs     |   21 +-
 .../Dhcp/Options/DhcpEndOption.cs             |   11 +-
 .../DhcpEthernetEncapsulationOption.cs        |   44 +-
 .../Dhcp/Options/DhcpExtensionsPathOption.cs  |   61 +-
 .../Dhcp/Options/DhcpHostNameOption.cs        |   53 +-
 .../Options/DhcpIPAddressLeaseTimeOption.cs   |   46 +-
 .../Options/DhcpIPForwardingEnableOption.cs   |   46 +-
 .../Dhcp/Options/DhcpImpressServerOption.cs   |   21 +-
 .../Dhcp/Options/DhcpIntOption.cs             |   59 +
 .../Dhcp/Options/DhcpInterfaceMTUOption.cs    |   51 -
 .../Dhcp/Options/DhcpInterfaceMtuOption.cs    |   55 +
 .../Dhcp/Options/DhcpLPRServerOption.cs       |   22 -
 .../Dhcp/Options/DhcpLogServerOption.cs       |   21 +-
 .../Dhcp/Options/DhcpLprServerOption.cs       |   37 +
 .../Dhcp/Options/DhcpMaskSupplierOption.cs    |   43 +-
 ...DhcpMaximumDatagramReassemblySizeOption.cs |   49 +-
 .../DhcpMaximumDhcpMessageSizeOption.cs       |   42 +-
 .../Dhcp/Options/DhcpMeritDumpFileOption.cs   |   53 +-
 .../Dhcp/Options/DhcpMessageOption.cs         |   53 +-
 .../Dhcp/Options/DhcpMessageTypeOption.cs     |   54 +-
 .../Options/DhcpMobileIPHomeAgentOption.cs    |   20 +-
 .../Dhcp/Options/DhcpNameServerOption.cs      |   20 +-
 ...erTCPIPDatagramDistributionServerOption.cs |   31 -
 .../DhcpNetBIOSOverTCPIPNameServerOption.cs   |   31 -
 .../DhcpNetBIOSOverTCPIPScopeOption.cs        |   70 -
 ...erTcpIpDatagramDistributionServerOption.cs |   36 +
 .../DhcpNetBiosOverTcpIpNameServerOption.cs   |   36 +
 ... => DhcpNetBiosOverTcpIpNodeTypeOption.cs} |   49 +-
 .../DhcpNetBiosOverTcpIpScopeOption.cs        |   75 +
 .../DhcpNetworkInformationServersOption.cs    |   12 +-
 ...cpNetworkInformationServiceDomainOption.cs |   53 +-
 ...tworkInformationServicePlusDomainOption.cs |   51 +-
 ...workInformationServicePlusServersOption.cs |   12 +-
 ...etworkNewsTransportProtocolServerOption.cs |   11 +-
 .../DhcpNetworkTimeProtocolServersOption.cs   |   12 +-
 .../DhcpNonLocalSourceRoutingEnableOption.cs  |   43 +-
 .../Dhcp/Options/DhcpOption.cs                |   62 +-
 .../Dhcp/Options/DhcpOptionCode.cs            |  713 ++----
 .../Dhcp/Options/DhcpOptionOverloadOption.cs  |   39 +-
 .../Dhcp/Options/DhcpPadOption.cs             |   12 +-
 .../Options/DhcpParameterRequestListOption.cs |   42 +-
 .../Options/DhcpPathMTUAgingTimeoutOption.cs  |   57 -
 .../Options/DhcpPathMtuAgingTimeoutOption.cs  |   45 +
 ...on.cs => DhcpPathMtuPlateauTableOption.cs} |   31 +-
 .../Options/DhcpPerformMaskDiscoveryOption.cs |   43 +-
 .../DhcpPerformRouterDiscoveryOption.cs       |   43 +-
 .../Dhcp/Options/DhcpPolicyFilterOption.cs    |   96 +-
 .../DhcpPostOfficeProtocolServerOption.cs     |   11 +-
 .../Options/DhcpRebindingTimeValueOption.cs   |   44 +-
 .../Options/DhcpRenewalTimeValueOption.cs     |   42 +-
 .../Options/DhcpRequestedIPAddressOption.cs   |   38 +-
 .../DhcpResourceLocationServerOption.cs       |   21 +-
 .../Dhcp/Options/DhcpRootPathOption.cs        |   55 +-
 .../Dhcp/Options/DhcpRouterOption.cs          |   20 +-
 .../DhcpRouterSolicitationAddressOption.cs    |   36 +-
 .../Options/DhcpServerIdentifierOption.cs     |   45 +-
 ...SimpleMailTransportProtocolServerOption.cs |   11 +-
 .../Dhcp/Options/DhcpSingleAddressOption.cs   |   56 +
 .../Dhcp/Options/DhcpStaticRouteOption.cs     |  113 +-
 ...reetTalkDirectoryAssistanceServerOption.cs |   12 +-
 .../Options/DhcpStreetTalkServerOption.cs     |   12 +-
 .../Dhcp/Options/DhcpStringOption.cs          |   67 +
 .../Dhcp/Options/DhcpSubnetMaskOption.cs      |   40 +-
 .../Dhcp/Options/DhcpSwapServerOption.cs      |   37 +-
 .../Dhcp/Options/DhcpTCPDefaultTTLOption.cs   |   58 -
 .../Options/DhcpTCPKeepaliveGarbageOption.cs  |   58 -
 .../Options/DhcpTCPKeepaliveIntervalOption.cs |   53 -
 .../Dhcp/Options/DhcpTFTPServerNameOption.cs  |   66 -
 .../Dhcp/Options/DhcpTFtpServerNameOption.cs  |   45 +
 .../Dhcp/Options/DhcpTcpDefaultTtlOption.cs   |   46 +
 .../Options/DhcpTcpKeepaliveGarbageOption.cs  |   50 +
 .../Options/DhcpTcpKeepaliveIntervalOption.cs |   48 +
 .../Dhcp/Options/DhcpTimeOffsetOption.cs      |   48 +-
 .../Dhcp/Options/DhcpTimeServerOption.cs      |   21 +-
 .../Options/DhcpTrailerEncapsulationOption.cs |   44 +-
 .../Dhcp/Options/DhcpUIntOption.cs            |   59 +
 .../Dhcp/Options/DhcpUShortOption.cs          |   59 +
 .../DhcpVendorClassidentifierOption.cs        |   67 +-
 .../DhcpVendorSpecificInformationOption.cs    |   63 +-
 .../DhcpXWindowSystemDisplayManagerOption.cs  |   13 +-
 .../DhcpXWindowSystemFontServerOption.cs      |   12 +-
 .../PcapDotNet.Packets.csproj                 |   34 +-
 README.md                                     |    1 +
 107 files changed, 4911 insertions(+), 2214 deletions(-)
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBooleanOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpByteOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDataSegmentOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIntOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMTUOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLPRServerOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNameServerOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPScopeOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs
 rename PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/{DhcpNetBIOSOverTCPIPNodeTypeOption.cs => DhcpNetBiosOverTcpIpNodeTypeOption.cs} (53%)
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUAgingTimeoutOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs
 rename PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/{DhcpPathMTUPlateauTableOption.cs => DhcpPathMtuPlateauTableOption.cs} (63%)
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSingleAddressOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStringOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPDefaultTTLOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveGarbageOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveIntervalOption.cs
 delete mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFTPServerNameOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUIntOption.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUShortOption.cs

diff --git a/PcapDotNet/src/PcapDotNet.Core.Test/WiresharkCompareTests.cs b/PcapDotNet/src/PcapDotNet.Core.Test/WiresharkCompareTests.cs
index 25a23052..a56e3f25 100644
--- a/PcapDotNet/src/PcapDotNet.Core.Test/WiresharkCompareTests.cs
+++ b/PcapDotNet/src/PcapDotNet.Core.Test/WiresharkCompareTests.cs
@@ -9,6 +9,7 @@
 using System.Xml.Linq;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using PcapDotNet.Packets;
+using PcapDotNet.Packets.Dhcp;
 using PcapDotNet.Packets.Dns;
 using PcapDotNet.Packets.Ethernet;
 using PcapDotNet.Packets.Gre;
@@ -390,24 +391,58 @@ private static void CreateRandomIpPayload(Random random, Layer ipLayer, List layers)
-        {
-            if (random.NextBool(20))
-            {
-                // Finish with payload.
-                PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100));
-                layers.Add(payloadLayer);
-                return;
-            }
-
-            DnsLayer dnsLayer = random.NextDnsLayer();
-            layers.Add(dnsLayer);
-
-            ushort specialPort = (ushort)(random.NextBool() ? 53 : 5355);
-            if (dnsLayer.IsQuery)
-                udpLayer.DestinationPort = specialPort;
-            else
-                udpLayer.SourcePort = specialPort;
+        private static void CreateRandomUdpPayload(Random random, UdpLayer udpLayer, List layers)
+        {
+            if (random.NextBool(20))
+            {
+                // Finish with payload.
+                PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100));
+                layers.Add(payloadLayer);
+                return;
+            }
+
+            switch (random.Next(0, 2))
+            {
+                case 0:
+                    {
+                        DnsLayer dnsLayer = random.NextDnsLayer();
+                        layers.Add(dnsLayer);
+
+                        ushort specialPort = (ushort)(random.NextBool() ? 53 : 5355);
+                        if (dnsLayer.IsQuery)
+                            udpLayer.DestinationPort = specialPort;
+                        else
+                            udpLayer.SourcePort = specialPort;
+                        break;
+                    }
+
+                case 1:
+                    {
+                        DhcpLayer dhcpLayer = random.NextDhcpLayer();
+                        layers.Add(dhcpLayer);
+
+                        if (random.NextBool())
+                        {
+                            udpLayer.SourcePort = (ushort)(random.NextBool() ? 67 : 68);
+                        }
+                        else
+                        {
+                            udpLayer.DestinationPort = 5355;
+                        }
+                        if (random.NextBool())
+                        {
+                            udpLayer.SourcePort = (ushort)(random.NextBool() ? 67 : 68);
+                        }
+                        else
+                        {
+                            udpLayer.SourcePort = 5355;
+                        }
+                        break;
+                    }
+
+                default:
+                    throw new InvalidOperationException("Invalid value.");
+            }
         }
 
         private static void CreateRandomTcpPayload(Random random, TcpLayer tcpLayer, List layers)
diff --git a/PcapDotNet/src/PcapDotNet.Packets.Test/DhcpTests.cs b/PcapDotNet/src/PcapDotNet.Packets.Test/DhcpTests.cs
index 81dc57f7..a3bf9f25 100644
--- a/PcapDotNet/src/PcapDotNet.Packets.Test/DhcpTests.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets.Test/DhcpTests.cs
@@ -6,6 +6,7 @@
 using System.Threading.Tasks;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using PcapDotNet.Packets.Dhcp;
+using PcapDotNet.Packets.Dhcp.Options;
 using PcapDotNet.Packets.Ethernet;
 using PcapDotNet.Packets.IpV4;
 using PcapDotNet.Packets.TestUtils;
@@ -73,12 +74,2112 @@ public void RandomDhcpTest()
 
                 Assert.IsTrue(packet.IsValid, "IsValid");
                 DhcpLayer actualLayer = (DhcpLayer)packet.Ethernet.Ip.Udp.Dhcp.ExtractLayer();
-                if (!Object.Equals(dhcpLayer, actualLayer))
+                if (!dhcpLayer.Equals(actualLayer))
                 {
-                    Console.WriteLine(actualLayer);
+                    Console.WriteLine("");
                 }
+
                 Assert.AreEqual(dhcpLayer, actualLayer, "DHCP Layer");
             }
         }
+
+        [TestMethod]
+        public void DhcpDatagramClientMacAddressTest()
+        {
+            Random random = new Random(4711);
+
+            EthernetLayer ethernetLayer = random.NextEthernetLayer(EthernetType.None);
+
+            IpV4Layer ipV4Layer = random.NextIpV4Layer(null);
+            ipV4Layer.HeaderChecksum = null;
+
+            UdpLayer udpLayer = random.NextUdpLayer();
+            udpLayer.Checksum = null;
+
+            DhcpLayer dhcpLayer = new DhcpLayer()
+            {
+                HardwareAddressLength = 6,
+                ClientHardwareAddress = new Packets.DataSegment(new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21 })
+            };
+
+            Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, udpLayer, dhcpLayer);
+
+            Assert.AreEqual(new MacAddress("01:23:45:67:89:AB"), packet.Ethernet.IpV4.Udp.Dhcp.ClientMacAddress);
+
+            Assert.AreEqual(new MacAddress("01:23:45:67:89:AB"), ((DhcpLayer)packet.Ethernet.IpV4.Udp.Dhcp.ExtractLayer()).ClientMacAddress);
+        }
+
+        [TestMethod]
+        public void DhcpLayerClientMacAddressTest()
+        {
+            DhcpLayer dhcpLayer = new DhcpLayer()
+            {
+                HardwareAddressLength = 6,
+                ClientHardwareAddress = new Packets.DataSegment(new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21 })
+            };
+
+            Assert.AreEqual(new MacAddress("01:23:45:67:89:AB"), dhcpLayer.ClientMacAddress);
+
+            dhcpLayer = new DhcpLayer();
+
+            Assert.AreEqual(MacAddress.Zero, dhcpLayer.ClientMacAddress);
+
+            dhcpLayer.ClientMacAddress = new MacAddress("01:23:45:67:89:AB");
+            Assert.AreEqual(new MacAddress("01:23:45:67:89:AB"), dhcpLayer.ClientMacAddress);
+        }
+
+        [TestMethod]
+        public void DhcpOptionEqualsTest()
+        {
+            DhcpBootfileNameOption option = new DhcpBootfileNameOption("file1");
+            Assert.IsFalse(option.Equals(null));
+            Assert.AreNotEqual(option, new DhcpAnyOption(new DataSegment(Encoding.ASCII.GetBytes("file1")), DhcpOptionCode.AllSubnetsAreLocal));
+            Assert.AreNotEqual(option, new DhcpAnyOption(new DataSegment(Encoding.ASCII.GetBytes("filelong")), DhcpOptionCode.BootfileName));
+            Assert.AreNotEqual(option, new DhcpAnyOption(new DataSegment(Encoding.ASCII.GetBytes("file2")), DhcpOptionCode.BootfileName));
+            Assert.AreEqual(option, new DhcpBootfileNameOption("file1"));
+            Assert.AreEqual(option, new DhcpAnyOption(new DataSegment(Encoding.ASCII.GetBytes("file1")), DhcpOptionCode.BootfileName));
+        }
+
+        [TestMethod]
+        public void DhcpAllSubnetsAreLocalOptionTest()
+        {
+            DhcpAllSubnetsAreLocalOption option = new DhcpAllSubnetsAreLocalOption(true);
+            Assert.AreEqual(DhcpOptionCode.AllSubnetsAreLocal, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsTrue(option.Value);
+            option.Value = false;
+            Assert.IsFalse(option.Value);
+
+            option = new DhcpAllSubnetsAreLocalOption(false);
+            Assert.AreEqual(DhcpOptionCode.AllSubnetsAreLocal, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsFalse(option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpAnyOptionTest()
+        {
+            DataSegment data = new DataSegment(new byte[10]);
+            DhcpAnyOption option = new DhcpAnyOption(data, (DhcpOptionCode)240);
+            Assert.AreEqual((DhcpOptionCode)240, option.OptionCode);
+            Assert.AreEqual(10, option.Length);
+            Assert.IsNotNull(option.Data);
+            Assert.AreEqual(data, option.Data);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpAnyOptionCtorNullTest()
+        {
+            new DhcpAnyOption(null, (DhcpOptionCode)240);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpAnyOptionCtorToLargeTest()
+        {
+            new DhcpAnyOption(new DataSegment(new byte[byte.MaxValue + 1]), (DhcpOptionCode)240);
+        }
+
+        [TestMethod]
+        public void DhcpArpCacheTimeoutOptionTest()
+        {
+            DhcpArpCacheTimeoutOption option = new DhcpArpCacheTimeoutOption(4711);
+            Assert.AreEqual(DhcpOptionCode.ArpCacheTimeout, option.OptionCode);
+            Assert.AreEqual(4, option.Length);
+            Assert.AreEqual(4711, option.Time);
+
+            option.Time = 801;
+            Assert.AreEqual(801, option.Time);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpBootfileNameOptionTest()
+        {
+            DhcpBootfileNameOption option = new DhcpBootfileNameOption("bootfile");
+            Assert.AreEqual(DhcpOptionCode.BootfileName, option.OptionCode);
+            Assert.AreEqual("bootfile", option.BootfileName);
+
+            option.BootfileName = "changed";
+            Assert.AreEqual("changed", option.BootfileName);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpBootfileNameOptionCtorNullTest()
+        {
+            new DhcpBootfileNameOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpBootfileNameOptionCtorEmptryTest()
+        {
+            new DhcpBootfileNameOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpBootfileNameOptionCtorToLongTest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpBootfileNameOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpBootFileSizeOptionTest()
+        {
+            DhcpBootFileSizeOption option = new DhcpBootFileSizeOption(4711);
+            Assert.AreEqual(DhcpOptionCode.BootFileSize, option.OptionCode);
+            Assert.AreEqual(4711, option.FileSize);
+
+            option.FileSize = 999;
+            Assert.AreEqual(999, option.FileSize);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpBroadcastAddressOptionTest()
+        {
+            DhcpBroadcastAddressOption option = new DhcpBroadcastAddressOption(new IpV4Address("10.20.30.40"));
+            Assert.AreEqual(DhcpOptionCode.BroadcastAddress, option.OptionCode);
+            Assert.AreEqual(new IpV4Address("10.20.30.40"), option.BroadcastAddress);
+
+            option.BroadcastAddress = new IpV4Address("11.12.13.14");
+            Assert.AreEqual(new IpV4Address("11.12.13.14"), option.BroadcastAddress);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpClientIdentifierOptionTest()
+        {
+            DataSegment testData = new DataSegment(new byte[] { 1, 4, 5, 6, 3, 2 });
+            DhcpClientIdentifierOption option = new DhcpClientIdentifierOption(5, testData);
+            Assert.AreEqual(DhcpOptionCode.ClientIdentifier, option.OptionCode);
+            Assert.AreEqual(5, option.ClientIdentifierType);
+            Assert.AreEqual(testData, option.ClientIdentifier);
+
+            testData = new DataSegment(new byte[] { 3, 2, 4, 52, 2, 3, 4 });
+            option.ClientIdentifierType = 47;
+            option.ClientIdentifier = testData;
+            Assert.AreEqual(47, option.ClientIdentifierType);
+            Assert.AreEqual(testData, option.ClientIdentifier);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpClientIdentifierOptionCtorNullTest()
+        {
+            new DhcpClientIdentifierOption(5, null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpClientIdentifierOptionCtorEmptyTest()
+        {
+            new DhcpClientIdentifierOption(5, new DataSegment(new byte[0]));
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpClientIdentifierOptionCtorToLongest()
+        {
+            new DhcpClientIdentifierOption(5, new DataSegment(new byte[byte.MaxValue - 1]));
+        }
+
+        [TestMethod]
+        public void DhcpCookieServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpCookieServerOption option = new DhcpCookieServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.CookieServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpCookieServerOptionCtorNullTest()
+        {
+            new DhcpCookieServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpCookieServerOptionCtorEmptyTest()
+        {
+            new DhcpCookieServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpCookieServerOptionCtorToLongest()
+        {
+            new DhcpCookieServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpDefaultFingerServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpDefaultFingerServerOption option = new DhcpDefaultFingerServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.DefaultFingerServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpDefaultFingerServerOptionCtorNullTest()
+        {
+            new DhcpCookieServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDefaultFingerServerOptionCtorEmptyTest()
+        {
+            new DhcpCookieServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDefaultFingerServerOptionCtorToLongest()
+        {
+            new DhcpCookieServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpDefaultInternetRelayChatServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpDefaultInternetRelayChatServerOption option = new DhcpDefaultInternetRelayChatServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.DefaultInternetRelayChatServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpDefaultInternetRelayChatServerOptionCtorNullTest()
+        {
+            new DhcpDefaultInternetRelayChatServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDefaultInternetRelayChatServerOptionCtorEmptyTest()
+        {
+            new DhcpDefaultInternetRelayChatServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDefaultInternetRelayChatServerOptionCtorToLongest()
+        {
+            new DhcpDefaultInternetRelayChatServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpDefaultIPTimeToLiveOptionTest()
+        {
+            DhcpDefaultIPTimeToLiveOption option = new DhcpDefaultIPTimeToLiveOption(47);
+            Assert.AreEqual(DhcpOptionCode.DefaultIpTimeToLive, option.OptionCode);
+            Assert.AreEqual(47, option.Ttl);
+
+            option.Ttl = 200;
+            Assert.AreEqual(200, option.Ttl);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpDefaultWorldWideWebServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpDefaultWorldWideWebServerOption option = new DhcpDefaultWorldWideWebServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.DefaultWorldWideWebServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpDefaultWorldWideWebServerOptionCtorNullTest()
+        {
+            new DhcpDefaultWorldWideWebServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDefaultWorldWideWebServerOptionCtorEmptyTest()
+        {
+            new DhcpDefaultWorldWideWebServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDefaultWorldWideWebServerOptionCtorToLongest()
+        {
+            new DhcpDefaultWorldWideWebServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpDomainNameOptionTest()
+        {
+            DhcpDomainNameOption option = new DhcpDomainNameOption("domainName");
+            Assert.AreEqual(DhcpOptionCode.DomainName, option.OptionCode);
+            Assert.AreEqual("domainName", option.DomainName);
+
+            option.DomainName = "changed";
+            Assert.AreEqual("changed", option.DomainName);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpDomainNameOptionCtorNullTest()
+        {
+            new DhcpDomainNameOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDomainNameOptionCtorEmptyTest()
+        {
+            new DhcpDomainNameOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDomainNameOptionCtorToLongest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpDomainNameOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpDomainNameServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpDomainNameServerOption option = new DhcpDomainNameServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.DomainNameServerServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpDomainNameServerOptionCtorNullTest()
+        {
+            new DhcpDomainNameServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDomainNameServerOptionCtorEmptyTest()
+        {
+            new DhcpDomainNameServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpDomainNameServerOptionCtorToLongest()
+        {
+            new DhcpDomainNameServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpEndOptionTest()
+        {
+            DhcpEndOption option = new DhcpEndOption();
+            Assert.AreEqual(DhcpOptionCode.End, option.OptionCode);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpEthernetEncapsulationOptionTest()
+        {
+            DhcpEthernetEncapsulationOption option = new DhcpEthernetEncapsulationOption(true);
+            Assert.AreEqual(DhcpOptionCode.EthernetEncapsulation, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsTrue(option.Value);
+            option.Value = false;
+            Assert.IsFalse(option.Value);
+
+            option = new DhcpEthernetEncapsulationOption(false);
+            Assert.AreEqual(DhcpOptionCode.EthernetEncapsulation, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsFalse(option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpExtensionsPathOptionTest()
+        {
+            DhcpExtensionsPathOption option = new DhcpExtensionsPathOption("extensionPathname");
+            Assert.AreEqual(DhcpOptionCode.ExtensionsPath, option.OptionCode);
+            Assert.AreEqual("extensionPathname", option.ExtensionsPathname);
+
+            option.ExtensionsPathname = "changed";
+            Assert.AreEqual("changed", option.ExtensionsPathname);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpExtensionsPathOptionCtorNullTest()
+        {
+            new DhcpExtensionsPathOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpExtensionsPathOptionCtorEmptyTest()
+        {
+            new DhcpExtensionsPathOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpExtensionsPathOptionCtorToLongest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpExtensionsPathOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpHostNameOptionTest()
+        {
+            DhcpHostNameOption option = new DhcpHostNameOption("hostName");
+            Assert.AreEqual(DhcpOptionCode.HostName, option.OptionCode);
+            Assert.AreEqual("hostName", option.HostName);
+
+            option.HostName = "changed";
+            Assert.AreEqual("changed", option.HostName);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpHostNameOptionCtorNullTest()
+        {
+            new DhcpHostNameOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpHostNameOptionCtorEmptyTest()
+        {
+            new DhcpHostNameOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpHostNameOptionCtorToLongest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpHostNameOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpImpressServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpImpressServerOption option = new DhcpImpressServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.ImpressServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpImpressServerOptionCtorNullTest()
+        {
+            new DhcpImpressServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpImpressServerOptionCtorEmptyTest()
+        {
+            new DhcpImpressServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpImpressServerOptionCtorToLongest()
+        {
+            new DhcpImpressServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpInterfaceMtuOptionTest()
+        {
+            DhcpInterfaceMtuOption option = new DhcpInterfaceMtuOption(100);
+            Assert.AreEqual(DhcpOptionCode.InterfaceMtu, option.OptionCode);
+            Assert.AreEqual(100, option.Mtu);
+
+            option.Mtu = 200;
+            Assert.AreEqual(200, option.Mtu);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpInterfaceMtuOptionCtorMinMTUTest()
+        {
+            new DhcpInterfaceMtuOption(67);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpInterfaceMtuOptionMinMTUTest()
+        {
+            new DhcpInterfaceMtuOption(500).Mtu = 67;
+        }
+
+        [TestMethod]
+        public void DhcpIPAddressLeaseTimeOptionTest()
+        {
+            DhcpIPAddressLeaseTimeOption option = new DhcpIPAddressLeaseTimeOption(100);
+            Assert.AreEqual(DhcpOptionCode.IPAddressLeaseTime, option.OptionCode);
+            Assert.AreEqual(100, option.LeaseTime);
+
+            option.LeaseTime = 200;
+            Assert.AreEqual(200, option.LeaseTime);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpIPForwardingEnableOptionTest()
+        {
+            DhcpIPForwardingEnableOption option = new DhcpIPForwardingEnableOption(true);
+            Assert.AreEqual(DhcpOptionCode.IPForwardingEnable, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsTrue(option.Value);
+            option.Value = false;
+            Assert.IsFalse(option.Value);
+
+            option = new DhcpIPForwardingEnableOption(false);
+            Assert.AreEqual(DhcpOptionCode.IPForwardingEnable, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsFalse(option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpLogServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpLogServerOption option = new DhcpLogServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.LogServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpLogServerOptionCtorNullTest()
+        {
+            new DhcpLogServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpLogServerOptionCtorEmptyTest()
+        {
+            new DhcpLogServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpLogServerOptionCtorToLongest()
+        {
+            new DhcpLogServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpLprServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpLprServerOption option = new DhcpLprServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.LprServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpLprServerOptionCtorNullTest()
+        {
+            new DhcpLprServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpLprServerOptionCtorEmptyTest()
+        {
+            new DhcpLprServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpLprServerOptionCtorToLongest()
+        {
+            new DhcpLprServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpMaskSupplierOptionTest()
+        {
+            DhcpMaskSupplierOption option = new DhcpMaskSupplierOption(true);
+            Assert.AreEqual(DhcpOptionCode.MaskSupplier, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsTrue(option.Value);
+            option.Value = false;
+            Assert.IsFalse(option.Value);
+
+            option = new DhcpMaskSupplierOption(false);
+            Assert.AreEqual(DhcpOptionCode.MaskSupplier, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsFalse(option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpMaximumDatagramReassemblySizeOptionTest()
+        {
+            DhcpMaximumDatagramReassemblySizeOption option = new DhcpMaximumDatagramReassemblySizeOption(600);
+            Assert.AreEqual(DhcpOptionCode.MaximumDatagramReassemblySize, option.OptionCode);
+            Assert.AreEqual(600, option.Size);
+
+            option.Size = 8000;
+            Assert.AreEqual(8000, option.Size);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpMaximumDatagramReassemblySizeOptionCtorMinSizeTest()
+        {
+            new DhcpMaximumDatagramReassemblySizeOption(575);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpMaximumDatagramReassemblySizeOptionMinSizeTest()
+        {
+            new DhcpMaximumDatagramReassemblySizeOption(600).Size = 575;
+        }
+
+        [TestMethod]
+        public void DhcpMaximumDhcpMessageSizeOptionTest()
+        {
+            DhcpMaximumDhcpMessageSizeOption option = new DhcpMaximumDhcpMessageSizeOption(600);
+            Assert.AreEqual(DhcpOptionCode.MaximumDhcpMessageSize, option.OptionCode);
+            Assert.AreEqual(600, option.MaxLength);
+
+            option.MaxLength = 8000;
+            Assert.AreEqual(8000, option.MaxLength);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpMeritDumpFileOptionTest()
+        {
+            DhcpMeritDumpFileOption option = new DhcpMeritDumpFileOption("DumpFilePathname");
+            Assert.AreEqual(DhcpOptionCode.MeritDumpFile, option.OptionCode);
+            Assert.AreEqual("DumpFilePathname", option.DumpFilePathname);
+
+            option.DumpFilePathname = "changed";
+            Assert.AreEqual("changed", option.DumpFilePathname);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpMeritDumpFileOptionCtorNullTest()
+        {
+            new DhcpMeritDumpFileOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpMeritDumpFileOptionCtorEmptryTest()
+        {
+            new DhcpMeritDumpFileOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpMeritDumpFileOptionCtorToLongTest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpMeritDumpFileOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpMessageOptionTest()
+        {
+            DhcpMessageOption option = new DhcpMessageOption("Text");
+            Assert.AreEqual(DhcpOptionCode.Message, option.OptionCode);
+            Assert.AreEqual("Text", option.Text);
+
+            option.Text = "changed";
+            Assert.AreEqual("changed", option.Text);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpMessageOptionCtorNullTest()
+        {
+            new DhcpMessageOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpMessageOptionCtorEmptryTest()
+        {
+            new DhcpMessageOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpMessageOptionCtorToLongTest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpMessageOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpMessageTypeOptionTest()
+        {
+            DhcpMessageTypeOption option = new DhcpMessageTypeOption(DhcpMessageTypeOption.MessageType.Ack);
+            Assert.AreEqual(DhcpOptionCode.MessageType, option.OptionCode);
+            Assert.AreEqual(DhcpMessageTypeOption.MessageType.Ack, option.Type);
+
+            option.Type = DhcpMessageTypeOption.MessageType.Release;
+            Assert.AreEqual(DhcpMessageTypeOption.MessageType.Release, option.Type);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpBootfileNameCtorInvalidTest()
+        {
+            new DhcpMessageTypeOption((DhcpMessageTypeOption.MessageType)77);
+        }
+
+        [TestMethod]
+        public void DhcpMobileIPHomeAgentOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpMobileIPHomeAgentOption option = new DhcpMobileIPHomeAgentOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.MobileIPHomeAgent, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpMobileIPHomeAgentOptionCtorNullTest()
+        {
+            new DhcpMobileIPHomeAgentOption(null);
+        }
+
+        [TestMethod]
+        public void DhcpMobileIPHomeAgentOptionCtorEmptyTest()
+        {
+            new DhcpMobileIPHomeAgentOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpMobileIPHomeAgentOptionCtorToLongest()
+        {
+            new DhcpMobileIPHomeAgentOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpNameServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpNameServerOption option = new DhcpNameServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.NameServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNameServerOptionCtorNullTest()
+        {
+            new DhcpNameServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNameServerOptionCtorEmptyTest()
+        {
+            new DhcpNameServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNameServerOptionCtorToLongest()
+        {
+            new DhcpNameServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpNetBiosOverTcpIpDatagramDistributionServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpNetBiosOverTcpIpDatagramDistributionServerOption option = new DhcpNetBiosOverTcpIpDatagramDistributionServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.NetBiosOverTcpIpDatagramDistributionServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNetBiosOverTcpIpDatagramDistributionServerOptionCtorNullTest()
+        {
+            new DhcpNetBiosOverTcpIpDatagramDistributionServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetBiosOverTcpIpDatagramDistributionServerOptionCtorEmptyTest()
+        {
+            new DhcpNetBiosOverTcpIpDatagramDistributionServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetBiosOverTcpIpDatagramDistributionServerOptionCtorToLongest()
+        {
+            new DhcpNetBiosOverTcpIpDatagramDistributionServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpNetBiosOverTcpIpNameServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpNetBiosOverTcpIpNameServerOption option = new DhcpNetBiosOverTcpIpNameServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.NetBiosOverTcpIpNameServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNetBiosOverTcpIpNameServerOptionCtorNullTest()
+        {
+            new DhcpNetBiosOverTcpIpNameServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetBiosOverTcpIpNameServerOptionCtorEmptyTest()
+        {
+            new DhcpNetBiosOverTcpIpNameServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetBiosOverTcpIpNameServerOptionCtorToLongest()
+        {
+            new DhcpNetBiosOverTcpIpNameServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpNetBiosOverTcpIpNodeTypeOptionTest()
+        {
+            DhcpNetBiosOverTcpIpNodeTypeOption option = new DhcpNetBiosOverTcpIpNodeTypeOption(DhcpNetBiosOverTcpIpNodeTypeOption.NodeType.BNode);
+            Assert.AreEqual(DhcpOptionCode.NetBiosOverTcpIpNodeType, option.OptionCode);
+            Assert.AreEqual(DhcpNetBiosOverTcpIpNodeTypeOption.NodeType.BNode, option.Type);
+
+            option.Type = DhcpNetBiosOverTcpIpNodeTypeOption.NodeType.HNode | DhcpNetBiosOverTcpIpNodeTypeOption.NodeType.PNode;
+            Assert.AreEqual(DhcpNetBiosOverTcpIpNodeTypeOption.NodeType.HNode | DhcpNetBiosOverTcpIpNodeTypeOption.NodeType.PNode, option.Type);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetBiosOverTcpIpNodeTypeOptionCtorInvalidTest()
+        {
+            new DhcpNetBiosOverTcpIpNodeTypeOption(0);
+        }
+
+        [TestMethod]
+        public void DhcpNetBiosOverTcpIpScopeOptionTest()
+        {
+            DataSegment data = new DataSegment(new byte[10]);
+            DhcpNetBiosOverTcpIpScopeOption option = new DhcpNetBiosOverTcpIpScopeOption(data);
+            Assert.IsNotNull(option.NetBiosScope);
+            Assert.AreEqual(data, option.NetBiosScope);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNetBiosOverTcpIpScopeOptionCtorNullTest()
+        {
+            new DhcpNetBiosOverTcpIpScopeOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetBiosOverTcpIpScopeOptionToLargeTest()
+        {
+            new DhcpNetBiosOverTcpIpScopeOption(new DataSegment(new byte[byte.MaxValue + 1]));
+        }
+
+        [TestMethod]
+        public void DhcpNetworkInformationServersOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpNetworkInformationServersOption option = new DhcpNetworkInformationServersOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.NetworkInformationServers, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNetworkInformationServersOptionCtorNullTest()
+        {
+            new DhcpNetworkInformationServersOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkInformationServersOptionCtorEmptyTest()
+        {
+            new DhcpNetworkInformationServersOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkInformationServersOptionCtorToLongest()
+        {
+            new DhcpNetworkInformationServersOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpNetworkInformationServiceDomainOptionTest()
+        {
+            DhcpNetworkInformationServiceDomainOption option = new DhcpNetworkInformationServiceDomainOption("NIS Domain Name");
+            Assert.AreEqual(DhcpOptionCode.NetworkInformationServiceDomain, option.OptionCode);
+            Assert.AreEqual("NIS Domain Name", option.NisDomainName);
+
+            option.NisDomainName = "changed";
+            Assert.AreEqual("changed", option.NisDomainName);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNetworkInformationServiceDomainOptionCtorNullTest()
+        {
+            new DhcpNetworkInformationServiceDomainOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkInformationServiceDomainOptionCtorEmptryTest()
+        {
+            new DhcpNetworkInformationServiceDomainOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkInformationServiceDomainOptionCtorToLongTest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpNetworkInformationServiceDomainOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpNetworkInformationServicePlusDomainOptionOptionTest()
+        {
+            DhcpNetworkInformationServicePlusDomainOption option = new DhcpNetworkInformationServicePlusDomainOption("NIS Client Domain Name");
+            Assert.AreEqual(DhcpOptionCode.NetworkInformationServicePlusDomain, option.OptionCode);
+            Assert.AreEqual("NIS Client Domain Name", option.NisClientDomainName);
+
+            option.NisClientDomainName = "changed";
+            Assert.AreEqual("changed", option.NisClientDomainName);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNetworkInformationServicePlusDomainOptionCtorNullTest()
+        {
+            new DhcpNetworkInformationServicePlusDomainOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkInformationServicePlusDomainOptionCtorEmptryTest()
+        {
+            new DhcpNetworkInformationServicePlusDomainOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkInformationServicePlusDomainOptionCtorToLongTest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpNetworkInformationServicePlusDomainOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpNetworkInformationServicePlusServersOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpNetworkInformationServicePlusServersOption option = new DhcpNetworkInformationServicePlusServersOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.NetworkInformationServicePlusServers, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNetworkInformationServicePlusServersOptionCtorNullTest()
+        {
+            new DhcpNetworkInformationServicePlusServersOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkInformationServicePlusServersOptionCtorEmptyTest()
+        {
+            new DhcpNetworkInformationServicePlusServersOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkInformationServicePlusServersOptionCtorToLongest()
+        {
+            new DhcpNetworkInformationServicePlusServersOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpNetworkNewsTransportProtocolServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpNetworkNewsTransportProtocolServerOption option = new DhcpNetworkNewsTransportProtocolServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.NetworkNewsTransportProtocolServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNetworkNewsTransportProtocolServerOptionCtorNullTest()
+        {
+            new DhcpNetworkNewsTransportProtocolServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkNewsTransportProtocolServerOptionCtorEmptyTest()
+        {
+            new DhcpNetworkNewsTransportProtocolServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkNewsTransportProtocolServerOptionCtorToLongest()
+        {
+            new DhcpNetworkNewsTransportProtocolServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpNetworkTimeProtocolServersOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpNetworkTimeProtocolServersOption option = new DhcpNetworkTimeProtocolServersOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.NetworkTimeProtocolServers, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpNetworkTimeProtocolServersOptionCtorNullTest()
+        {
+            new DhcpNetworkTimeProtocolServersOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkTimeProtocolServersOptionCtorEmptyTest()
+        {
+            new DhcpNetworkTimeProtocolServersOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpNetworkTimeProtocolServersOptionCtorToLongest()
+        {
+            new DhcpNetworkTimeProtocolServersOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpNonLocalSourceRoutingEnableOptionnTest()
+        {
+            DhcpNonLocalSourceRoutingEnableOption option = new DhcpNonLocalSourceRoutingEnableOption(true);
+            Assert.AreEqual(DhcpOptionCode.NonLocalSourceRoutingEnable, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsTrue(option.Value);
+            option.Value = false;
+            Assert.IsFalse(option.Value);
+
+            option = new DhcpNonLocalSourceRoutingEnableOption(false);
+            Assert.AreEqual(DhcpOptionCode.NonLocalSourceRoutingEnable, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsFalse(option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpOptionOverloadOptionTest()
+        {
+            DhcpOptionOverloadOption option = new DhcpOptionOverloadOption(DhcpOptionOverloadOption.OptionOverloadValue.SName);
+            Assert.AreEqual(DhcpOptionCode.OptionOverload, option.OptionCode);
+            Assert.AreEqual(DhcpOptionOverloadOption.OptionOverloadValue.SName, option.Value);
+
+            option.Value = DhcpOptionOverloadOption.OptionOverloadValue.Both;
+            Assert.AreEqual(DhcpOptionOverloadOption.OptionOverloadValue.Both, option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpOptionOverloadOptionCtorInvalidTest()
+        {
+            new DhcpOptionOverloadOption(0);
+        }
+
+        [TestMethod]
+        public void DhcpPadOptionTest()
+        {
+            DhcpPadOption option = new DhcpPadOption();
+            Assert.AreEqual(DhcpOptionCode.Pad, option.OptionCode);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpParameterRequestListOptionTest()
+        {
+            DhcpOptionCode[] options = new DhcpOptionCode[] { DhcpOptionCode.End, DhcpOptionCode.ParameterRequestList };
+            DhcpParameterRequestListOption option = new DhcpParameterRequestListOption(options);
+            Assert.AreEqual(DhcpOptionCode.ParameterRequestList, option.OptionCode);
+            CollectionAssert.AreEqual(options, option.OptionCodes.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpParameterRequestListOptionCtorNullTest()
+        {
+            new DhcpParameterRequestListOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpParameterRequestListOptionCtorEmptyTest()
+        {
+            new DhcpParameterRequestListOption(new DhcpOptionCode[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpParameterRequestListOptionCtorToLongest()
+        {
+            new DhcpParameterRequestListOption(new DhcpOptionCode[255 / sizeof(DhcpOptionCode) + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpPathMtuAgingTimeoutOptionTest()
+        {
+            DhcpPathMtuAgingTimeoutOption option = new DhcpPathMtuAgingTimeoutOption(4711);
+            Assert.AreEqual(DhcpOptionCode.PathMtuAgingTimeout, option.OptionCode);
+            Assert.AreEqual(4711, option.Timeout);
+
+            option.Timeout = 999;
+            Assert.AreEqual(999, option.Timeout);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpPathMtuPlateauTableOptionTest()
+        {
+            ushort[] sizes = new ushort[] { 4711, 666 };
+            DhcpPathMtuPlateauTableOption option = new DhcpPathMtuPlateauTableOption(sizes);
+            Assert.AreEqual(DhcpOptionCode.PathMtuPlateauTable, option.OptionCode);
+            CollectionAssert.AreEqual(sizes, option.Sizes.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpPathMtuPlateauTableOptionCtorNullTest()
+        {
+            new DhcpPathMtuPlateauTableOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpPathMtuPlateauTableOptionCtorEmptyTest()
+        {
+            new DhcpPathMtuPlateauTableOption(new ushort[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpPathMtuPlateauTableOptionCtorToLongest()
+        {
+            new DhcpPathMtuPlateauTableOption(new ushort[255 / sizeof(ushort) + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpPerformMaskDiscoveryOptionTest()
+        {
+            DhcpPerformMaskDiscoveryOption option = new DhcpPerformMaskDiscoveryOption(true);
+            Assert.AreEqual(DhcpOptionCode.PerformMaskDiscovery, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsTrue(option.Value);
+            option.Value = false;
+            Assert.IsFalse(option.Value);
+
+            option = new DhcpPerformMaskDiscoveryOption(false);
+            Assert.AreEqual(DhcpOptionCode.PerformMaskDiscovery, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsFalse(option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpPerformRouterDiscoveryOptionTest()
+        {
+            DhcpPerformRouterDiscoveryOption option = new DhcpPerformRouterDiscoveryOption(true);
+            Assert.AreEqual(DhcpOptionCode.PerformRouterDiscovery, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsTrue(option.Value);
+            option.Value = false;
+            Assert.IsFalse(option.Value);
+
+            option = new DhcpPerformRouterDiscoveryOption(false);
+            Assert.AreEqual(DhcpOptionCode.PerformRouterDiscovery, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsFalse(option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpPolicyFilterOptionTest()
+        {
+            DhcpPolicyFilterOption.IpV4AddressWithMask[] filters = new DhcpPolicyFilterOption.IpV4AddressWithMask[] { new DhcpPolicyFilterOption.IpV4AddressWithMask(new IpV4Address("10.20.30.40"), new IpV4Address("255.255.255.0")), new DhcpPolicyFilterOption.IpV4AddressWithMask(new IpV4Address("1.2.3.4"), new IpV4Address("222.0.0.0")) };
+            DhcpPolicyFilterOption option = new DhcpPolicyFilterOption(filters);
+            Assert.AreEqual(DhcpOptionCode.PolicyFilter, option.OptionCode);
+            CollectionAssert.AreEqual(filters, option.Filters.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpPolicyFilterOptionCtorNullTest()
+        {
+            new DhcpPolicyFilterOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpPolicyFilterOptionCtorEmptyTest()
+        {
+            new DhcpPolicyFilterOption(new DhcpPolicyFilterOption.IpV4AddressWithMask[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpPolicyFilterOptionCtorToLongest()
+        {
+            new DhcpPolicyFilterOption(new DhcpPolicyFilterOption.IpV4AddressWithMask[255 / DhcpPolicyFilterOption.IpV4AddressWithMask.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpPolicyFilterOptionIpV4AddressWithMaskEqualsTest()
+        {
+            DhcpPolicyFilterOption.IpV4AddressWithMask a = new DhcpPolicyFilterOption.IpV4AddressWithMask(new IpV4Address("10.20.30.40"), new IpV4Address("255.255.255.0"));
+            DhcpPolicyFilterOption.IpV4AddressWithMask a2 = new DhcpPolicyFilterOption.IpV4AddressWithMask(new IpV4Address("10.20.30.40"), new IpV4Address("255.255.255.0"));
+            DhcpPolicyFilterOption.IpV4AddressWithMask b = new DhcpPolicyFilterOption.IpV4AddressWithMask(new IpV4Address("1.2.3.4"), new IpV4Address("222.0.0.0"));
+            DhcpPolicyFilterOption.IpV4AddressWithMask b2 = new DhcpPolicyFilterOption.IpV4AddressWithMask(new IpV4Address("10.20.30.40"), new IpV4Address("222.0.0.0"));
+            DhcpPolicyFilterOption.IpV4AddressWithMask b3 = new DhcpPolicyFilterOption.IpV4AddressWithMask(new IpV4Address("1.2.3.4"), new IpV4Address("255.255.255.0"));
+
+            Assert.IsTrue(a.Equals(a2));
+            Assert.IsFalse(a.Equals(null));
+            Assert.IsFalse(a.Equals(new object()));
+            Assert.IsFalse(a.Equals(b));
+            Assert.IsFalse(a.Equals(b2));
+            Assert.IsFalse(a.Equals(b3));
+
+            Assert.IsTrue(a == a2);
+            Assert.IsFalse(a == null);
+            Assert.IsFalse(null == a);
+            Assert.IsFalse(a == b);
+            Assert.IsFalse(a == b2);
+            Assert.IsFalse(a == b3);
+
+            Assert.IsFalse(a != a2);
+            Assert.IsTrue(a != null);
+            Assert.IsTrue(null != a);
+            Assert.IsTrue(a != b);
+            Assert.IsTrue(a != b2);
+            Assert.IsTrue(a != b3);
+        }
+
+        [TestMethod]
+        public void DhcpPostOfficeProtocolServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpPostOfficeProtocolServerOption option = new DhcpPostOfficeProtocolServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.PostOfficeProtocolServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpPostOfficeProtocolServerOptionCtorNullTest()
+        {
+            new DhcpPostOfficeProtocolServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpPostOfficeProtocolServerOptionCtorEmptyTest()
+        {
+            new DhcpPostOfficeProtocolServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpPostOfficeProtocolServerOptionCtorToLongest()
+        {
+            new DhcpPostOfficeProtocolServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpRebindingTimeValueOptionTest()
+        {
+            DhcpRebindingTimeValueOption option = new DhcpRebindingTimeValueOption(4711);
+            Assert.AreEqual(DhcpOptionCode.RebindingTimeValue, option.OptionCode);
+            Assert.AreEqual(4711, option.T2Interval);
+
+            option.T2Interval = 999;
+            Assert.AreEqual(999, option.T2Interval);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpRenewalTimeValueOptionTest()
+        {
+            DhcpRenewalTimeValueOption option = new DhcpRenewalTimeValueOption(4711);
+            Assert.AreEqual(DhcpOptionCode.RenewalTimeValue, option.OptionCode);
+            Assert.AreEqual(4711, option.T1Interval);
+
+            option.T1Interval = 999;
+            Assert.AreEqual(999, option.T1Interval);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpRequestedIPAddressOptionTest()
+        {
+            DhcpRequestedIPAddressOption option = new DhcpRequestedIPAddressOption(new IpV4Address("10.20.30.40"));
+            Assert.AreEqual(DhcpOptionCode.RequestedIPAddress, option.OptionCode);
+            Assert.AreEqual(new IpV4Address("10.20.30.40"), option.Address);
+
+            option.Address = new IpV4Address("1.2.3.4");
+            Assert.AreEqual(new IpV4Address("1.2.3.4"), option.Address);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpResourceLocationServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpResourceLocationServerOption option = new DhcpResourceLocationServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.ResourceLocationServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpResourceLocationServerOptionCtorNullTest()
+        {
+            new DhcpResourceLocationServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpResourceLocationServerOptionCtorEmptyTest()
+        {
+            new DhcpResourceLocationServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpResourceLocationServerOptionCtorToLongest()
+        {
+            new DhcpResourceLocationServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpRootPathOptionTest()
+        {
+            DhcpRootPathOption option = new DhcpRootPathOption("Root Disk Pathname");
+            Assert.AreEqual(DhcpOptionCode.RootPath, option.OptionCode);
+            Assert.AreEqual("Root Disk Pathname", option.RootDiskPathname);
+
+            option.RootDiskPathname = "changed";
+            Assert.AreEqual("changed", option.RootDiskPathname);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpRootPathOptionCtorNullTest()
+        {
+            new DhcpRootPathOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpRootPathOptionCtorEmptryTest()
+        {
+            new DhcpRootPathOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpRootPathOptionCtorToLongTest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpRootPathOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpRouterOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpRouterOption option = new DhcpRouterOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.Router, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpRouterOptionCtorNullTest()
+        {
+            new DhcpRouterOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpRouterOptionCtorEmptyTest()
+        {
+            new DhcpRouterOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpRouterOptionCtorToLongest()
+        {
+            new DhcpRouterOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpRouterSolicitationAddressOptionTest()
+        {
+            DhcpRouterSolicitationAddressOption option = new DhcpRouterSolicitationAddressOption(new IpV4Address("10.20.30.40"));
+            Assert.AreEqual(DhcpOptionCode.RouterSolicitationAddress, option.OptionCode);
+            Assert.AreEqual(new IpV4Address("10.20.30.40"), option.Address);
+
+            option.Address = new IpV4Address("1.2.3.4");
+            Assert.AreEqual(new IpV4Address("1.2.3.4"), option.Address);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpServerIdentifierOptionTest()
+        {
+            DhcpServerIdentifierOption option = new DhcpServerIdentifierOption(new IpV4Address("10.20.30.40"));
+            Assert.AreEqual(DhcpOptionCode.ServerIdentifier, option.OptionCode);
+            Assert.AreEqual(new IpV4Address("10.20.30.40"), option.Address);
+
+            option.Address = new IpV4Address("1.2.3.4");
+            Assert.AreEqual(new IpV4Address("1.2.3.4"), option.Address);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpSimpleMailTransportProtocolServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpSimpleMailTransportProtocolServerOption option = new DhcpSimpleMailTransportProtocolServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.SimpleMailTransportProtocolServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpSimpleMailTransportProtocolServerOptionCtorNullTest()
+        {
+            new DhcpSimpleMailTransportProtocolServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpSimpleMailTransportProtocolServerOptionCtorEmptyTest()
+        {
+            new DhcpSimpleMailTransportProtocolServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpSimpleMailTransportProtocolServerOptionCtorToLongest()
+        {
+            new DhcpSimpleMailTransportProtocolServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpStaticRouteOptionTest()
+        {
+            DhcpStaticRouteOption.IpV4AddressRoute[] filters = new DhcpStaticRouteOption.IpV4AddressRoute[] { new DhcpStaticRouteOption.IpV4AddressRoute(new IpV4Address("10.20.30.40"), new IpV4Address("255.255.255.0")), new DhcpStaticRouteOption.IpV4AddressRoute(new IpV4Address("1.2.3.4"), new IpV4Address("222.0.0.0")) };
+            DhcpStaticRouteOption option = new DhcpStaticRouteOption(filters);
+            Assert.AreEqual(DhcpOptionCode.StaticRoute, option.OptionCode);
+            CollectionAssert.AreEqual(filters, option.Routes.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpStaticRouteOptionCtorNullTest()
+        {
+            new DhcpStaticRouteOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpStaticRouteOptionCtorEmptyTest()
+        {
+            new DhcpStaticRouteOption(new DhcpStaticRouteOption.IpV4AddressRoute[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpStaticRouteOptionCtorToLongest()
+        {
+            new DhcpStaticRouteOption(new DhcpStaticRouteOption.IpV4AddressRoute[255 / DhcpStaticRouteOption.IpV4AddressRoute.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpStaticRouteOptionIpV4AddressRouteEqualsTest()
+        {
+            DhcpStaticRouteOption.IpV4AddressRoute a = new DhcpStaticRouteOption.IpV4AddressRoute(new IpV4Address("10.20.30.40"), new IpV4Address("255.255.255.0"));
+            DhcpStaticRouteOption.IpV4AddressRoute a2 = new DhcpStaticRouteOption.IpV4AddressRoute(new IpV4Address("10.20.30.40"), new IpV4Address("255.255.255.0"));
+            DhcpStaticRouteOption.IpV4AddressRoute b = new DhcpStaticRouteOption.IpV4AddressRoute(new IpV4Address("1.2.3.4"), new IpV4Address("222.0.0.0"));
+            DhcpStaticRouteOption.IpV4AddressRoute b2 = new DhcpStaticRouteOption.IpV4AddressRoute(new IpV4Address("10.20.30.40"), new IpV4Address("222.0.0.0"));
+            DhcpStaticRouteOption.IpV4AddressRoute b3 = new DhcpStaticRouteOption.IpV4AddressRoute(new IpV4Address("1.2.3.4"), new IpV4Address("255.255.255.0"));
+
+            Assert.IsTrue(a.Equals(a2));
+            Assert.IsFalse(a.Equals(null));
+            Assert.IsFalse(a.Equals(new object()));
+            Assert.IsFalse(a.Equals(b));
+            Assert.IsFalse(a.Equals(b2));
+            Assert.IsFalse(a.Equals(b3));
+
+            Assert.IsTrue(a == a2);
+            Assert.IsFalse(a == null);
+            Assert.IsFalse(null == a);
+            Assert.IsFalse(a == b);
+            Assert.IsFalse(a == b2);
+            Assert.IsFalse(a == b3);
+
+            Assert.IsFalse(a != a2);
+            Assert.IsTrue(a != null);
+            Assert.IsTrue(null != a);
+            Assert.IsTrue(a != b);
+            Assert.IsTrue(a != b2);
+            Assert.IsTrue(a != b3);
+        }
+
+        [TestMethod]
+        public void DhcpStreetTalkDirectoryAssistanceServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpStreetTalkDirectoryAssistanceServerOption option = new DhcpStreetTalkDirectoryAssistanceServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.StreetTalkDirectoryAssistanceServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpStreetTalkDirectoryAssistanceServerOptionCtorNullTest()
+        {
+            new DhcpStreetTalkDirectoryAssistanceServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpStreetTalkDirectoryAssistanceServerOptionCtorEmptyTest()
+        {
+            new DhcpStreetTalkDirectoryAssistanceServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpStreetTalkDirectoryAssistanceServerOptionCtorToLongest()
+        {
+            new DhcpStreetTalkDirectoryAssistanceServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpStreetTalkServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpStreetTalkServerOption option = new DhcpStreetTalkServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.StreetTalkServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpStreetTalkServerOptionCtorNullTest()
+        {
+            new DhcpStreetTalkServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpStreetTalkServerOptionCtorEmptyTest()
+        {
+            new DhcpStreetTalkServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpStreetTalkServerOptionCtorToLongest()
+        {
+            new DhcpStreetTalkServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpSubnetMaskOptionTest()
+        {
+            DhcpSubnetMaskOption option = new DhcpSubnetMaskOption(new IpV4Address("10.20.30.40"));
+            Assert.AreEqual(DhcpOptionCode.SubnetMask, option.OptionCode);
+            Assert.AreEqual(new IpV4Address("10.20.30.40"), option.SubnetMask);
+
+            option.SubnetMask = new IpV4Address("255.255.255.255");
+            Assert.AreEqual(new IpV4Address("255.255.255.255"), option.SubnetMask);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpSwapServerOptionTest()
+        {
+            DhcpSwapServerOption option = new DhcpSwapServerOption(new IpV4Address("10.20.30.40"));
+            Assert.AreEqual(DhcpOptionCode.SwapServer, option.OptionCode);
+            Assert.AreEqual(new IpV4Address("10.20.30.40"), option.SwapServerAddress);
+
+            option.SwapServerAddress = new IpV4Address("1.2.3.4");
+            Assert.AreEqual(new IpV4Address("1.2.3.4"), option.SwapServerAddress);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpTcpDefaultTtlOptionTest()
+        {
+            DhcpTcpDefaultTtlOption option = new DhcpTcpDefaultTtlOption(100);
+            Assert.AreEqual(DhcpOptionCode.TcpDefaultTtl, option.OptionCode);
+            Assert.AreEqual(100, option.Ttl);
+
+            option.Ttl = 42;
+            Assert.AreEqual(42, option.Ttl);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpTcpKeepaliveGarbageOptionTest()
+        {
+            DhcpTcpKeepaliveGarbageOption option = new DhcpTcpKeepaliveGarbageOption(true);
+            Assert.AreEqual(DhcpOptionCode.TcpKeepaliveGarbage, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsTrue(option.Value);
+            option.Value = false;
+            Assert.IsFalse(option.Value);
+
+            option = new DhcpTcpKeepaliveGarbageOption(false);
+            Assert.AreEqual(DhcpOptionCode.TcpKeepaliveGarbage, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsFalse(option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpTcpKeepaliveIntervalOptionTest()
+        {
+            DhcpTcpKeepaliveIntervalOption option = new DhcpTcpKeepaliveIntervalOption(4711);
+            Assert.AreEqual(DhcpOptionCode.TcpKeepaliveInterval, option.OptionCode);
+            Assert.AreEqual(4711, option.Time);
+
+            option.Time = 42;
+            Assert.AreEqual(42, option.Time);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpTFtpServerNameOptionTest()
+        {
+            DhcpTFtpServerNameOption option = new DhcpTFtpServerNameOption("TFTP server");
+            Assert.AreEqual(DhcpOptionCode.TfptServerName, option.OptionCode);
+            Assert.AreEqual("TFTP server", option.TFtpServer);
+
+            option.TFtpServer = "changed";
+            Assert.AreEqual("changed", option.TFtpServer);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpTFtpServerNameOptionCtorNullTest()
+        {
+            new DhcpTFtpServerNameOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpTFtpServerNameOptionCtorEmptryTest()
+        {
+            new DhcpTFtpServerNameOption("");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpTFtpServerNameOptionCtorToLongTest()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < byte.MaxValue; i++)
+                sb.Append('a');
+            new DhcpTFtpServerNameOption(sb.ToString());
+        }
+
+        [TestMethod]
+        public void DhcpTimeOffsetOptionTest()
+        {
+            DhcpTimeOffsetOption option = new DhcpTimeOffsetOption(4711);
+            Assert.AreEqual(DhcpOptionCode.TimeOffset, option.OptionCode);
+            Assert.AreEqual(4711, option.TimeOffset);
+
+            option.TimeOffset = -42;
+            Assert.AreEqual(-42, option.TimeOffset);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpTimeServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpTimeServerOption option = new DhcpTimeServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.TimeServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpTimeServerOptionCtorNullTest()
+        {
+            new DhcpTimeServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpTimeServerOptionCtorEmptyTest()
+        {
+            new DhcpTimeServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpTimeServerOptionCtorToLongest()
+        {
+            new DhcpTimeServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpTrailerEncapsulationOptionTest()
+        {
+            DhcpTrailerEncapsulationOption option = new DhcpTrailerEncapsulationOption(true);
+            Assert.AreEqual(DhcpOptionCode.TrailerEncapsulation, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsTrue(option.Value);
+            option.Value = false;
+            Assert.IsFalse(option.Value);
+
+            option = new DhcpTrailerEncapsulationOption(false);
+            Assert.AreEqual(DhcpOptionCode.TrailerEncapsulation, option.OptionCode);
+            Assert.AreEqual(1, option.Length);
+            Assert.IsFalse(option.Value);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        public void DhcpVendorClassidentifierOptionTest()
+        {
+            DataSegment data = new DataSegment(new byte[10]);
+            DhcpVendorClassidentifierOption option = new DhcpVendorClassidentifierOption(data);
+            Assert.AreEqual(DhcpOptionCode.VendorClassidentifier, option.OptionCode);
+            Assert.AreEqual(10, option.Length);
+            Assert.AreEqual(data, option.VendorClassIdentifier);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpVendorClassidentifierOptionCtorNullTest()
+        {
+            new DhcpVendorClassidentifierOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpVendorClassidentifierOptionCtorToLargeTest()
+        {
+            new DhcpVendorClassidentifierOption(new DataSegment(new byte[byte.MaxValue + 1]));
+        }
+
+        [TestMethod]
+        public void DhcpVendorSpecificInformationOptionTest()
+        {
+            DataSegment data = new DataSegment(new byte[10]);
+            DhcpVendorSpecificInformationOption option = new DhcpVendorSpecificInformationOption(data);
+            Assert.AreEqual(DhcpOptionCode.VendorSpecificInformation, option.OptionCode);
+            Assert.AreEqual(10, option.Length);
+            Assert.AreEqual(data, option.VendorSpecificInformation);
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpVendorSpecificInformationOptionCtorNullTest()
+        {
+            new DhcpVendorSpecificInformationOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpVendorSpecificInformationOptionCtorToLargeTest()
+        {
+            new DhcpVendorSpecificInformationOption(new DataSegment(new byte[byte.MaxValue + 1]));
+        }
+
+        [TestMethod]
+        public void DhcpXWindowSystemDisplayManagerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpXWindowSystemDisplayManagerOption option = new DhcpXWindowSystemDisplayManagerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.XWindowSystemDisplayManager, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpXWindowSystemDisplayManagerOptionCtorNullTest()
+        {
+            new DhcpXWindowSystemDisplayManagerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpXWindowSystemDisplayManagerOptionCtorEmptyTest()
+        {
+            new DhcpXWindowSystemDisplayManagerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpXWindowSystemDisplayManagerOptionCtorToLongest()
+        {
+            new DhcpXWindowSystemDisplayManagerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        [TestMethod]
+        public void DhcpXWindowSystemFontServerOptionTest()
+        {
+            IpV4Address[] addresses = new IpV4Address[] { new IpV4Address("10.20.30.40"), new IpV4Address("11.22.33.44") };
+            DhcpXWindowSystemFontServerOption option = new DhcpXWindowSystemFontServerOption(addresses);
+            Assert.AreEqual(DhcpOptionCode.XWindowSystemFontServer, option.OptionCode);
+            CollectionAssert.AreEqual(addresses, option.Addresses.ToArray());
+
+            TestOption(option);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void DhcpXWindowSystemFontServerOptionCtorNullTest()
+        {
+            new DhcpXWindowSystemFontServerOption(null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpXWindowSystemFontServerOptionCtorEmptyTest()
+        {
+            new DhcpXWindowSystemFontServerOption(new IpV4Address[0]);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void DhcpXWindowSystemFontServerOptionCtorToLongest()
+        {
+            new DhcpXWindowSystemFontServerOption(new IpV4Address[255 / IpV4Address.SizeOf + 1]);
+        }
+
+        private void TestOption(DhcpOption option)
+        {
+            int seed = new Random().Next();
+            Console.WriteLine("Seed-TestOption: " + seed);
+            Random random = new Random(seed);
+
+            EthernetLayer ethernetLayer = random.NextEthernetLayer(EthernetType.None);
+
+            IpV4Layer ipV4Layer = random.NextIpV4Layer(null);
+            ipV4Layer.HeaderChecksum = null;
+
+            UdpLayer udpLayer = random.NextUdpLayer();
+            udpLayer.Checksum = null;
+
+            DhcpLayer dhcpLayer = random.NextDhcpLayer();
+            dhcpLayer.Options.Clear();
+            dhcpLayer.Options.Add(option);
+
+            Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, udpLayer, dhcpLayer);
+
+            Assert.AreEqual(option, packet.Ethernet.IpV4.Udp.Dhcp.Options.Single());
+            Assert.AreEqual(option.GetHashCode(), packet.Ethernet.IpV4.Udp.Dhcp.Options.Single().GetHashCode());
+        }
     }
 }
\ No newline at end of file
diff --git a/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs
index f4939c7a..70a63d2b 100644
--- a/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs
@@ -27,12 +27,11 @@ public static DhcpLayer NextDhcpLayer(this Random random)
             dhcpLayer.Hops = random.NextByte();
             dhcpLayer.TransactionId = random.NextInt();
             dhcpLayer.SecondsElapsed = random.NextUShort();
-            dhcpLayer.Flags = random.NextEnum();
+            dhcpLayer.DhcpFlags = random.NextEnum();
             dhcpLayer.ClientIpAddress = random.NextIpV4Address();
             dhcpLayer.YourClientIpAddress = random.NextIpV4Address();
             dhcpLayer.NextServerIpAddress = random.NextIpV4Address();
             dhcpLayer.RelayAgentIpAddress = random.NextIpV4Address();
-            dhcpLayer.RelayAgentIpAddress = random.NextIpV4Address();
             dhcpLayer.ClientHardwareAddress = random.NextDataSegment(16);
             if (random.NextBool())
             {
@@ -76,7 +75,7 @@ public static DhcpOption NextDhcpOption(this Random random)
                     return new DhcpSubnetMaskOption(random.NextIpV4Address());
 
                 case DhcpOptionCode.TimeOffset:
-                    return new DhcpTimeOffsetOption(random.NextUInt());
+                    return new DhcpTimeOffsetOption(random.NextInt());
 
                 case DhcpOptionCode.Router:
                     return new DhcpRouterOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf)));
@@ -96,8 +95,8 @@ public static DhcpOption NextDhcpOption(this Random random)
                 case DhcpOptionCode.CookieServer:
                     return new DhcpCookieServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf)));
 
-                case DhcpOptionCode.LPRServer:
-                    return new DhcpLPRServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf)));
+                case DhcpOptionCode.LprServer:
+                    return new DhcpLprServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf)));
 
                 case DhcpOptionCode.ImpressServer:
                     return new DhcpImpressServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf)));
@@ -137,26 +136,26 @@ public static DhcpOption NextDhcpOption(this Random random)
                     return new DhcpNonLocalSourceRoutingEnableOption(random.NextBool());
 
                 case DhcpOptionCode.PolicyFilter:
-                    return new DhcpPolicyFilterOption(Enumerable.Range(0, random.NextByte() / DhcpPolicyFilterOption.IpV4AddressWithMask.SizeOf).Select(p => new DhcpPolicyFilterOption.IpV4AddressWithMask(random.NextIpV4Address(), random.NextIpV4Address())).ToList());
+                    return new DhcpPolicyFilterOption(Enumerable.Range(0, random.NextByte(DhcpPolicyFilterOption.IpV4AddressWithMask.SizeOf, byte.MaxValue) / DhcpPolicyFilterOption.IpV4AddressWithMask.SizeOf).Select(p => new DhcpPolicyFilterOption.IpV4AddressWithMask(random.NextIpV4Address(), random.NextIpV4Address())).ToList());
 
                 case DhcpOptionCode.MaximumDatagramReassemblySize:
-                    return new DhcpMaximumDatagramReassemblySizeOption(random.NextUShort());
+                    return new DhcpMaximumDatagramReassemblySizeOption(random.NextUShort(576, ushort.MaxValue));
 
-                case DhcpOptionCode.DefaultIPTimeToLive:
+                case DhcpOptionCode.DefaultIpTimeToLive:
                     return new DhcpDefaultIPTimeToLiveOption(random.NextByte());
 
-                case DhcpOptionCode.PathMTUAgingTimeout:
-                    return new DhcpPathMTUAgingTimeoutOption(random.NextUInt());
+                case DhcpOptionCode.PathMtuAgingTimeout:
+                    return new DhcpPathMtuAgingTimeoutOption(random.NextUInt());
 
-                case DhcpOptionCode.PathMTUPlateauTable:
-                    return new DhcpPathMTUPlateauTableOption(Enumerable.Range(0, random.NextByte() / sizeof(ushort)).Select(p => random.NextUShort()).ToList());
+                case DhcpOptionCode.PathMtuPlateauTable:
+                    return new DhcpPathMtuPlateauTableOption(Enumerable.Range(0, random.NextByte(sizeof(ushort), byte.MaxValue) / sizeof(ushort)).Select(p => random.NextUShort()).ToList());
 
                 #endregion 4. IP Layer Parameters per Host
 
                 #region 5. IP Layer Parameters per Interface
 
-                case DhcpOptionCode.InterfaceMTU:
-                    return new DhcpInterfaceMTUOption(random.NextUShort());
+                case DhcpOptionCode.InterfaceMtu:
+                    return new DhcpInterfaceMtuOption(random.NextUShort(68, ushort.MaxValue));
 
                 case DhcpOptionCode.AllSubnetsAreLocal:
                     return new DhcpAllSubnetsAreLocalOption(random.NextBool());
@@ -177,7 +176,7 @@ public static DhcpOption NextDhcpOption(this Random random)
                     return new DhcpRouterSolicitationAddressOption(random.NextIpV4Address());
 
                 case DhcpOptionCode.StaticRoute:
-                    return new DhcpStaticRouteOption(Enumerable.Range(0, random.NextByte() / IpV4Address.SizeOf / 2).Select(p => new DhcpStaticRouteOption.IpV4AddressRoute(random.NextIpV4Address(), random.NextIpV4Address())).ToList());
+                    return new DhcpStaticRouteOption(Enumerable.Range(0, random.NextByte(IpV4Address.SizeOf * 2, byte.MaxValue) / IpV4Address.SizeOf / 2).Select(p => new DhcpStaticRouteOption.IpV4AddressRoute(random.NextIpV4Address(), random.NextIpV4Address())).ToList());
 
                 #endregion 5. IP Layer Parameters per Interface
 
@@ -186,8 +185,8 @@ public static DhcpOption NextDhcpOption(this Random random)
                 case DhcpOptionCode.TrailerEncapsulation:
                     return new DhcpTrailerEncapsulationOption(random.NextBool());
 
-                case DhcpOptionCode.ARPCacheTimeout:
-                    return new DhcpARPCacheTimeoutOption(random.NextUInt());
+                case DhcpOptionCode.ArpCacheTimeout:
+                    return new DhcpArpCacheTimeoutOption(random.NextUInt());
 
                 case DhcpOptionCode.EthernetEncapsulation:
                     return new DhcpEthernetEncapsulationOption(random.NextBool());
@@ -196,14 +195,14 @@ public static DhcpOption NextDhcpOption(this Random random)
 
                 #region 7. TCP Parameters
 
-                case DhcpOptionCode.TCPDefaultTTL:
-                    return new DhcpTCPDefaultTTLOption(random.NextBool());
+                case DhcpOptionCode.TcpDefaultTtl:
+                    return new DhcpTcpDefaultTtlOption(random.NextByte());
 
-                case DhcpOptionCode.TCPKeepaliveInterval:
-                    return new DhcpTCPKeepaliveIntervalOption(random.NextUInt());
+                case DhcpOptionCode.TcpKeepaliveInterval:
+                    return new DhcpTcpKeepaliveIntervalOption(random.NextUInt());
 
-                case DhcpOptionCode.TCPKeepaliveGarbage:
-                    return new DhcpTCPKeepaliveGarbageOption(random.NextBool());
+                case DhcpOptionCode.TcpKeepaliveGarbage:
+                    return new DhcpTcpKeepaliveGarbageOption(random.NextBool());
 
                 #endregion 7. TCP Parameters
 
@@ -221,22 +220,22 @@ public static DhcpOption NextDhcpOption(this Random random)
                 case DhcpOptionCode.VendorSpecificInformation:
                     return new DhcpVendorSpecificInformationOption(random.NextDataSegment(random.NextByte(1, 254)));
 
-                case DhcpOptionCode.NetBIOSOverTCPIPNameServer:
-                    return new DhcpNetBIOSOverTCPIPNameServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); ;
+                case DhcpOptionCode.NetBiosOverTcpIpNameServer:
+                    return new DhcpNetBiosOverTcpIpNameServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf))); ;
 
-                case DhcpOptionCode.NetBIOSOverTCPIPDatagramDistributionServer:
-                    return new DhcpNetBIOSOverTCPIPDatagramDistributionServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf)));
+                case DhcpOptionCode.NetBiosOverTcpIpDatagramDistributionServer:
+                    return new DhcpNetBiosOverTcpIpDatagramDistributionServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf)));
 
-                case DhcpOptionCode.NetBIOSOverTCPIPNodeType:
-                    DhcpNetBIOSOverTCPIPNodeTypeOption.NodeType flag;
+                case DhcpOptionCode.NetBiosOverTcpIpNodeType:
+                    DhcpNetBiosOverTcpIpNodeTypeOption.NodeType flag;
                     do
                     {
-                        flag = random.NextFlags();
+                        flag = random.NextFlags();
                     } while (flag == 0);
-                    return new DhcpNetBIOSOverTCPIPNodeTypeOption(flag);
+                    return new DhcpNetBiosOverTcpIpNodeTypeOption(flag);
 
-                case DhcpOptionCode.NetBIOSOverTCPIPScope:
-                    return new DhcpNetBIOSOverTCPIPScopeOption(random.NextDataSegment(random.NextByte(1, 254)));
+                case DhcpOptionCode.NetBiosOverTcpIpScope:
+                    return new DhcpNetBiosOverTcpIpScopeOption(random.NextDataSegment(random.NextByte(1, 254)));
 
                 case DhcpOptionCode.XWindowSystemFontServer:
                     return new DhcpXWindowSystemFontServerOption(random.NextIpV4Addresses(random.Next(1, byte.MaxValue / IpV4Address.SizeOf)));
@@ -290,8 +289,8 @@ public static DhcpOption NextDhcpOption(this Random random)
                 case DhcpOptionCode.OptionOverload:
                     return new DhcpOptionOverloadOption(random.NextEnum());
 
-                case DhcpOptionCode.TFTPServerName:
-                    return new DhcpTFTPServerNameOption(random.NextCString(1, byte.MaxValue - 1));
+                case DhcpOptionCode.TfptServerName:
+                    return new DhcpTFtpServerNameOption(random.NextCString(1, byte.MaxValue - 1));
 
                 case DhcpOptionCode.BootfileName:
                     return new DhcpBootfileNameOption(random.NextCString(1, byte.MaxValue - 1));
@@ -303,7 +302,7 @@ public static DhcpOption NextDhcpOption(this Random random)
                     return new DhcpServerIdentifierOption(random.NextIpV4Address());
 
                 case DhcpOptionCode.ParameterRequestList:
-                    return new DhcpParameterRequestListOption(Enumerable.Range(1, random.NextByte(byte.MaxValue - 1)).Select(p => random.NextEnum()).ToList());
+                    return new DhcpParameterRequestListOption(Enumerable.Range(0, random.NextByte(sizeof(DhcpOptionCode), byte.MaxValue) / sizeof(DhcpOptionCode)).Select(p => random.NextEnum()).ToList());
 
                 case DhcpOptionCode.Message:
                     return new DhcpMessageOption(random.NextCString(1, byte.MaxValue - 1));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
index e39c8411..56a0519e 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
@@ -72,71 +72,127 @@ private static class Offset
 
         internal const int DHCP_MAGIC_COOKIE = 0x63825363;
 
+        /// 
+        /// RFC 2131.
+        /// Message op code
+        /// 
         public DhcpMessageType MessageType
         {
             get { return (DhcpMessageType)this[Offset.Op]; }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Hardware address type
+        /// 
         public ArpHardwareType HardwareType
         {
             get { return (ArpHardwareType)this[Offset.Htype]; }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Hardware address length
+        /// 
         public byte HardwareAddressLength
         {
             get { return (byte)this[Offset.Hlen]; }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Client sets to zero, optionally used by relay agents when booting via a relay agent.
+        /// 
         public byte Hops
         {
             get { return (byte)this[Offset.Hops]; }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Transaction ID, a random number chosen by the client, used by the client and server to associate messages and responses between a client and a server.
+        /// 
         public int TransactionId
         {
             get { return ReadInt(Offset.Xid, Endianity.Big); }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Filled in by client, seconds elapsed since client began address acquisition or renewal process.
+        /// 
         public ushort SecondsElapsed
         {
             get { return ReadUShort(Offset.Secs, Endianity.Big); }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Flags
+        /// 
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")]
         public DhcpFlags Flags
         {
             get { return (DhcpFlags)ReadUShort(Offset.Flags, Endianity.Big); }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Client IP address; only filled in if client is in BOUND, RENEW or REBINDING state and can respond to ARP requests.
+        /// 
         public IpV4Address ClientIpAddress
         {
             get { return ReadIpV4Address(Offset.CiAddr, Endianity.Big); }
         }
 
+        /// 
+        /// RFC 2131.
+        /// 'your' (client) IP address.
+        /// 
         public IpV4Address YourClientIpAddress
         {
             get { return ReadIpV4Address(Offset.YiAddr, Endianity.Big); }
         }
 
+        /// 
+        /// RFC 2131.
+        /// IP address of next server to use in bootstrap; returned in DHCPOFFER, DHCPACK by server.
+        /// 
         public IpV4Address NextServerIpAddress
         {
             get { return ReadIpV4Address(Offset.SiAddr, Endianity.Big); }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Relay agent IP address, used in booting via a relay agent.
+        /// 
         public IpV4Address RelayAgentIpAddress
         {
             get { return ReadIpV4Address(Offset.GiAddr, Endianity.Big); }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Client hardware address.
+        /// 
         public DataSegment ClientHardwareAddress
         {
             get { return this.Subsegment(Offset.ChAddr, 16); }
         }
 
+        /// 
+        /// Client MAC address
+        /// 
         public MacAddress ClientMacAddress
         {
             get { return new MacAddress(ReadUInt48(Offset.ChAddr, Endianity.Big)); }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Optional server host name
+        /// 
         public string ServerHostName
         {
             get
@@ -146,6 +202,10 @@ public string ServerHostName
             }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Boot file name; "generic" name or null in DHCPDISCOVER, fully qualified directory-path name in DHCPOFFER.
+        /// 
         public string BootFileName
         {
             get
@@ -155,6 +215,10 @@ public string BootFileName
             }
         }
 
+        /// 
+        /// RFC 2131.
+        /// true if the magic dhcp-cookie is set
+        /// 
         public bool IsDhcp
         {
             get
@@ -170,6 +234,10 @@ public bool IsDhcp
             }
         }
 
+        /// 
+        /// RFC 2131.
+        /// Optional parameters field
+        /// 
         public IReadOnlyCollection Options
         {
             get
@@ -230,7 +298,7 @@ public override ILayer ExtractLayer()
                 Hops = Hops,
                 TransactionId = TransactionId,
                 SecondsElapsed = SecondsElapsed,
-                Flags = Flags,
+                DhcpFlags = Flags,
                 ClientIpAddress = ClientIpAddress,
                 YourClientIpAddress = YourClientIpAddress,
                 NextServerIpAddress = NextServerIpAddress,
@@ -257,7 +325,6 @@ internal static int GetLength(bool isDhcp, IList options)
 
         internal static void Write(byte[] buffer, int offset, DhcpMessageType messageType, ArpHardwareType hardwareType, byte hardwareAddressLength, byte hops, int transactionId, ushort secondsElapsed, DhcpFlags flags, IpV4Address clientIpAddress, IpV4Address yourClientIpAddress, IpV4Address nextServerIpAddress, IpV4Address relayAgentIpAddress, DataSegment clientHardwareAddress, string serverHostName, string bootFileName, bool isDhcp, IList options)
         {
-            int startOffset = offset;
             buffer.Write(ref offset, (byte)messageType);
             buffer.Write(ref offset, (byte)hardwareType);
             buffer.Write(ref offset, hardwareAddressLength);
@@ -289,15 +356,7 @@ internal static void Write(byte[] buffer, int offset, DhcpMessageType messageTyp
             {
                 foreach (DhcpOption option in options)
                 {
-                    startOffset = offset;
                     option.Write(buffer, ref offset);
-                    if (offset != startOffset + option.Length + 2)
-                    {
-                        if (!(option is DhcpPadOption || option is DhcpEndOption))
-                        {
-                            Console.WriteLine("fail2");
-                        }
-                    }
                 }
             }
         }
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs
index 7fb3d8ad..56f1a251 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs
@@ -19,7 +19,7 @@ namespace PcapDotNet.Packets.Dhcp
     /// MBZ:  MUST BE ZERO(reserved for future use)
     /// 
///
- [Flags] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] public enum DhcpFlags : ushort { /// diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs index df98d072..8246855f 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs @@ -17,30 +17,70 @@ namespace PcapDotNet.Packets.Dhcp /// public sealed class DhcpLayer : SimpleLayer, IEquatable { + /// + /// Message op code + /// public DhcpMessageType MessageType { get; set; } + /// + /// Hardware address type + /// public ArpHardwareType HardwareType { get; set; } + /// + /// Hardware address length + /// public byte HardwareAddressLength { get; set; } + /// + /// Client sets to zero, optionally used by relay agents when booting via a relay agent. + /// public byte Hops { get; set; } + /// + /// Transaction ID, a random number chosen by the client, used by the client and server to associate messages and responses between a client and a server. + /// public int TransactionId { get; set; } + /// + /// Filled in by client, seconds elapsed since client began address acquisition or renewal process. + /// public ushort SecondsElapsed { get; set; } - public DhcpFlags Flags { get; set; } + /// + /// Flags + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] + public DhcpFlags DhcpFlags { get; set; } + /// + /// Client IP address; only filled in if client is in BOUND, RENEW or REBINDING state and can respond to ARP requests. + /// public IpV4Address ClientIpAddress { get; set; } + /// + /// 'your' (client) IP address. + /// public IpV4Address YourClientIpAddress { get; set; } + /// + /// IP address of next server to use in bootstrap; returned in DHCPOFFER, DHCPACK by server. + /// public IpV4Address NextServerIpAddress { get; set; } + /// + /// Relay agent IP address, used in booting via a relay agent. + /// public IpV4Address RelayAgentIpAddress { get; set; } + /// + /// Client hardware address. + /// public DataSegment ClientHardwareAddress { get; set; } + /// + /// Client MAC address + /// public MacAddress ClientMacAddress { get @@ -57,12 +97,24 @@ public MacAddress ClientMacAddress } } + /// + /// Optional server host name + /// public string ServerHostName { get; set; } + /// + /// Boot file name; "generic" name or null in DHCPDISCOVER, fully qualified directory-path name in DHCPOFFER. + /// public string BootFileName { get; set; } + /// + /// true if the magic dhcp-cookie is set + /// public bool IsDhcp { get; set; } + /// + /// Optional parameters field + /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public IList Options { get; set; } @@ -85,7 +137,7 @@ public override int Length protected override void Write(byte[] buffer, int offset) { DhcpDatagram.Write(buffer, offset, - MessageType, HardwareType, HardwareAddressLength, Hops, TransactionId, SecondsElapsed, Flags, ClientIpAddress, YourClientIpAddress, + MessageType, HardwareType, HardwareAddressLength, Hops, TransactionId, SecondsElapsed, DhcpFlags, ClientIpAddress, YourClientIpAddress, NextServerIpAddress, RelayAgentIpAddress, ClientHardwareAddress, ServerHostName, BootFileName, IsDhcp, Options); } @@ -113,7 +165,7 @@ public bool Equals(DhcpLayer other) Equals(Hops, other.Hops) && Equals(TransactionId, other.TransactionId) && Equals(SecondsElapsed, other.SecondsElapsed) && - Equals(Flags, other.Flags) && + Equals(DhcpFlags, other.DhcpFlags) && Equals(ClientIpAddress, other.ClientIpAddress) && Equals(YourClientIpAddress, other.YourClientIpAddress) && Equals(NextServerIpAddress, other.NextServerIpAddress) && diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs index f410f664..3e70551b 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs @@ -9,8 +9,8 @@ namespace PcapDotNet.Packets.Dhcp /// /// RFCs 2131. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] public enum DhcpMessageType : byte - { /// /// RFC 2131. diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs index b7f6a2aa..e2dcdf7d 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs @@ -7,7 +7,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// This option specifies the timeout in seconds for ARP cache entries. ///
     ///  Code   Len           Time
     /// +-----+-----+-----+-----+-----+-----+
@@ -15,43 +16,30 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpARPCacheTimeoutOption : DhcpOption + public class DhcpArpCacheTimeoutOption : DhcpUIntOption { - public DhcpARPCacheTimeoutOption() : base(DhcpOptionCode.ARPCacheTimeout) + /// + /// create new ArpCacheTimeoutOption + /// + /// Time + public DhcpArpCacheTimeoutOption(uint time) : base(time, DhcpOptionCode.ArpCacheTimeout) { } - public DhcpARPCacheTimeoutOption(uint timeOffset) : this() + internal static DhcpArpCacheTimeoutOption Read(DataSegment data, ref int offset) { - TimeOffset = timeOffset; + return DhcpUIntOption.Read(data, ref offset, p => new DhcpArpCacheTimeoutOption(p)); } - internal static DhcpARPCacheTimeoutOption Read(DataSegment data, ref int offset) + /// + /// RFC 2132. + /// Time + /// timeout in seconds for ARP cache entries + /// + public uint Time { - if (data[offset++] != 4) - { - throw new ArgumentException("Length of a DHCP ARPCacheTimeout Option has to be 4"); - } - DhcpARPCacheTimeoutOption option = new DhcpARPCacheTimeoutOption(data.ReadUInt(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, TimeOffset, Endianity.Big); - } - - public override byte Length - { - get { return 4; } - } - - public uint TimeOffset - { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs index f2146f18..b72ef9b3 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs @@ -13,21 +13,35 @@ namespace PcapDotNet.Packets.Dhcp.Options ///
public abstract class DhcpAddressListOption : DhcpOption { - internal const int MAX_ADDRESSES = 255 / IpV4Address.SizeOf; + internal const int MAX_ADDRESSES = byte.MaxValue / IpV4Address.SizeOf; - internal DhcpAddressListOption(DhcpOptionCode code, IList addresses) : base(code) + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] + internal DhcpAddressListOption(IList addresses, DhcpOptionCode code) : base(code) { if (addresses == null) throw new ArgumentNullException(nameof(addresses)); + if (addresses.Count == 0 && !AllowEmptyAddresses) + throw new ArgumentOutOfRangeException(nameof(addresses), addresses.Count, "The minimum items in addresses is 1"); if (addresses.Count > MAX_ADDRESSES) - throw new ArgumentOutOfRangeException(nameof(addresses), addresses.Count, $"The maximum items in addresses is {MAX_ADDRESSES}"); + throw new ArgumentOutOfRangeException(nameof(addresses), addresses.Count, "The maximum items in addresses is " + MAX_ADDRESSES); Addresses = new ReadOnlyCollection(addresses); } + internal static T Read(DataSegment data, ref int offset, Func, T> ctor) where T : DhcpAddressListOption + { + return ctor(GetAddresses(data, ref offset)); + } + + internal static IList GetAddresses(DataSegment data, ref int offset) + { + byte length = data[offset++]; + return GetAddresses(data, length, ref offset); + } + internal static IList GetAddresses(DataSegment data, byte length, ref int offset) { if (length % IpV4Address.SizeOf != 0) - throw new ArgumentOutOfRangeException(nameof(length), length, $"length has to be multiple of {IpV4Address.SizeOf}"); + throw new ArgumentOutOfRangeException(nameof(length), length, "length has to be multiple of " + IpV4Address.SizeOf); List addresses = new List(); for (int i = 0; i < length; i += IpV4Address.SizeOf) { @@ -46,6 +60,14 @@ internal override void Write(byte[] buffer, ref int offset) } } + /// + /// true if Addresses-List is allowed to be empty (Default false) + /// + protected virtual bool AllowEmptyAddresses + { + get { return false; } + } + /// /// RFC 2132. /// Value of Length-Field @@ -54,14 +76,12 @@ public override byte Length { get { - if (Addresses.Count > MAX_ADDRESSES) - throw new ArgumentOutOfRangeException(nameof(Addresses), Addresses.Count, $"The maximum items in addresses is {MAX_ADDRESSES}"); - return (byte)(Addresses.Count * IpV4Address.SizeOf); } } /// + /// RFC 2132. /// collection of all addresses of this option /// public IReadOnlyCollection Addresses diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs index d35944b9..ee426197 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs @@ -9,6 +9,10 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies whether or not the client may assume that all + /// subnets of the IP network to which the client is connected use the + /// same MTU as the subnet of that network to which the client is + /// directly connected. ///
     ///  Code   Len  Value
     /// +-----+-----+-----+
@@ -16,42 +20,31 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+
     /// 
///
- public class DhcpAllSubnetsAreLocalOption : DhcpOption + public class DhcpAllSubnetsAreLocalOption : DhcpBooleanOption { - public DhcpAllSubnetsAreLocalOption(bool enabled) : base(DhcpOptionCode.AllSubnetsAreLocal) + /// + /// create new AllSubnetsAreLocalOption + /// + /// Value + public DhcpAllSubnetsAreLocalOption(bool value) : base(value, DhcpOptionCode.AllSubnetsAreLocal) { } internal static DhcpAllSubnetsAreLocalOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP AllSubnetsAreLocal Option has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP AllSubnetsAreLocal Option has to be 0 or 1"); - DhcpAllSubnetsAreLocalOption option = new DhcpAllSubnetsAreLocalOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } + return DhcpBooleanOption.Read(data, ref offset, p => new DhcpAllSubnetsAreLocalOption(p)); } + /// + /// RFC 2132. + /// True indicates that all subnets share + /// the same MTU. False means that the client should assume that + /// some subnets of the directly connected network may have smaller MTUs. + /// public bool Value { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs index b0d32f28..5c412820 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs @@ -7,23 +7,27 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// DHCP option for undefined options + /// DHCP option for any options /// public class DhcpAnyOption : DhcpOption { + /// + /// create new Any-Option + /// + /// data represented by the option + /// the OptionCode public DhcpAnyOption(DataSegment data, DhcpOptionCode code) : base(code) { Data = data; } + /// + /// Length of the Dhcp-Option + /// public override byte Length { get { - if (Data == null) - { - return 0; - } return (byte)Data.Length; } } @@ -39,23 +43,24 @@ internal static DhcpAnyOption Read(DataSegment data, ref int offset) internal override void Write(byte[] buffer, ref int offset) { - if (Data == null) - throw new ArgumentNullException(nameof(Data)); if (Data.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Data), Data.Length, "Data.Length has to be less than 256"); + throw new InvalidOperationException("Data.Length has to be less than 256 but is " + Data.Length); base.Write(buffer, ref offset); buffer.Write(ref offset, Data); } + /// + /// Data of the Option + /// public DataSegment Data { get { return _data; } set { if (value == null) - throw new ArgumentNullException(nameof(Data)); + throw new ArgumentNullException(nameof(value)); if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Data), value.Length, "Data.Length has to be less than 256"); + throw new ArgumentOutOfRangeException(nameof(value), value.Length, "Data.Length has to be less than 256"); _data = value; } } diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBooleanOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBooleanOption.cs new file mode 100644 index 00000000..6b02c00b --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBooleanOption.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// Abstract class for all Dhcp-Options with a boolean value + /// + public class DhcpBooleanOption : DhcpOption + { + internal DhcpBooleanOption(bool value, DhcpOptionCode code) : base(code) + { + InternalValue = value; + } + + internal static T Read(DataSegment data, ref int offset, Func ctor) where T : DhcpBooleanOption + { + if (ctor == null) + throw new ArgumentNullException(nameof(ctor)); + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP DhcpBooleanOption Option has to be 1"); + if (data[offset] != 0 && data[offset] != 1) + throw new ArgumentException("Value of a DHCP DhcpBooleanOption Option has to be 0 or 1"); + T option = ctor(data[offset++] == 1 ? true : false); + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, InternalValue ? (byte)1 : (byte)0); + } + + /// + /// RFC 2132. + /// Value of Length-Field + /// + public override byte Length + { + get + { + return sizeof(bool); + } + } + + /// + /// The real value of the BooleanOption + /// + protected bool InternalValue + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs index 099fe8f4..5183cab4 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the length in 512-octet blocks of the default + /// boot image for the client. ///
     ///  Code   Len   File Size
     /// +-----+-----+-----+-----+
@@ -16,41 +18,28 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+
     /// 
///
- public class DhcpBootFileSizeOption : DhcpOption + public class DhcpBootFileSizeOption : DhcpUShortOption { - public DhcpBootFileSizeOption(ushort fileSize) : base(DhcpOptionCode.BootFileSize) + /// + /// create new DhcpBootFileSizeOption + /// + /// File Size + public DhcpBootFileSizeOption(ushort fileSize) : base(fileSize, DhcpOptionCode.BootFileSize) { - FileSize = fileSize; } internal static DhcpBootFileSizeOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 2) - throw new ArgumentException("Length of a DHCP BootFileSize Option has to be 2"); - DhcpBootFileSizeOption option = new DhcpBootFileSizeOption(data.ReadUShort(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, FileSize, Endianity.Big); - } - - public override byte Length - { - get - { - return 2; - } + return DhcpUShortOption.Read(data, ref offset, p => new DhcpBootFileSizeOption(p)); } + /// + /// File Size + /// public ushort FileSize { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs index 2128451d..adb977a0 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs @@ -8,59 +8,37 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option is used to identify a bootfile when the 'file' field in + /// the DHCP header has been used for DHCP options. ///
-    ///  Code Len   Bootfile name
+    ///  Code  Len    Bootfile name
     /// +-----+-----+-----+-----+-----+---
     /// | 67  |  n  |  c1 |  c2 |  c3 | ...
     /// +-----+-----+-----+-----+-----+---
     /// 
///
- public class DhcpBootfileNameOption : DhcpOption + public class DhcpBootfileNameOption : DhcpStringOption { - public DhcpBootfileNameOption(string domainName) : base(DhcpOptionCode.BootfileName) + /// + /// create new DhcpBootfileNameOption + /// + /// Bootfilename + public DhcpBootfileNameOption(string bootfileName) : base(bootfileName, DhcpOptionCode.BootfileName) { - BootfileName = domainName; } internal static DhcpBootfileNameOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - DhcpBootfileNameOption option = new DhcpBootfileNameOption(Encoding.ASCII.GetString(data.ReadBytes(offset, len))); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(BootfileName)); - } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(BootfileName); - } + return DhcpStringOption.Read(data, ref offset, p => new DhcpBootfileNameOption(p)); } + /// + /// Bootfilename + /// public string BootfileName { - get { return bootfileName; } - - set - { - if (value == null) - throw new ArgumentNullException(nameof(BootfileName)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(BootfileName), value.Length, "BootfileName has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(BootfileName), value.Length, "BootfileName has to be less than 256 characters long"); - - bootfileName = value; - } + get { return InternalValue; } + set { InternalValue = value; } } - - private string bootfileName; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs index 5a063a5f..e7846be6 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs @@ -8,7 +8,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// This option specifies the broadcast address in use on the client's + /// subnet. ///
     ///  Code   Len     Broadcast Address
     /// +-----+-----+-----+-----+-----+-----+
@@ -16,37 +18,28 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpBroadcastAddressOption : DhcpOption + public class DhcpBroadcastAddressOption : DhcpSingleAddressOption { - public DhcpBroadcastAddressOption(IpV4Address broadcastAddress) : base(DhcpOptionCode.BroadcastAddress) + /// + /// create new DhcpBroadcastAddressOption + /// + /// Broadcast Address + public DhcpBroadcastAddressOption(IpV4Address broadcastAddress) : base(broadcastAddress, DhcpOptionCode.BroadcastAddress) { - BroadcastAddress = broadcastAddress; } internal static DhcpBroadcastAddressOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 4) - throw new ArgumentException("Length of a DHCP SubnetMask Option has to be 4"); - DhcpBroadcastAddressOption option = new DhcpBroadcastAddressOption(data.ReadIpV4Address(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, BroadcastAddress, Endianity.Big); - } - - public override byte Length - { - get { return 4; } + return DhcpSingleAddressOption.Read(data, ref offset, p => new DhcpBroadcastAddressOption(p)); } + /// + /// Broadcast Address + /// public IpV4Address BroadcastAddress { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpByteOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpByteOption.cs new file mode 100644 index 00000000..1c46d187 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpByteOption.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// Abstract class for all Dhcp-Options with a byte value + /// + public class DhcpByteOption : DhcpOption + { + internal DhcpByteOption(byte value, DhcpOptionCode code) : base(code) + { + InternalValue = value; + } + + internal static T Read(DataSegment data, ref int offset, Func ctor) where T : DhcpByteOption + { + if (ctor == null) + throw new ArgumentNullException(nameof(ctor)); + byte len = data[offset++]; + if (len != 1) + throw new ArgumentException("Length of a DHCP DhcpByteOption Option has to be 1"); + T option = ctor(data[offset++]); + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, InternalValue); + } + + /// + /// RFC 2132. + /// Value of Length-Field + /// + public override byte Length + { + get + { + return sizeof(byte); + } + } + + /// + /// The real value of the ByteOption + /// + protected byte InternalValue + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs index fce00c70..fe2acda3 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs @@ -8,6 +8,10 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option is used by DHCP clients to specify their unique + /// identifier.DHCP servers use this value to index their database of + /// address bindings. This value is expected to be unique for all + /// clients in an administrative domain. ///
     ///  Code   Len   Type  Client-Identifier
     /// +-----+-----+-----+-----+-----+---
@@ -17,9 +21,14 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpClientIdentifierOption : DhcpOption { + /// + /// create new DhcpClientIdentifierOption + /// + /// Type + /// Client-Identifier public DhcpClientIdentifierOption(byte type, DataSegment clientIdentifier) : base(DhcpOptionCode.ClientIdentifier) { - Type = type; + ClientIdentifierType = type; ClientIdentifier = clientIdentifier; } @@ -34,10 +43,14 @@ internal static DhcpClientIdentifierOption Read(DataSegment data, ref int offset internal override void Write(byte[] buffer, ref int offset) { base.Write(buffer, ref offset); - buffer.Write(ref offset, Type); + buffer.Write(ref offset, ClientIdentifierType); buffer.Write(ref offset, ClientIdentifier); } + /// + /// RFC 2132. + /// Value of Length-Field + /// public override byte Length { get @@ -46,12 +59,20 @@ public override byte Length } } - public byte Type + /// + /// RFC 2132. + /// Type + /// + public byte ClientIdentifierType { get; set; } + /// + /// RFC 2132. + /// Client-Identifier + /// public DataSegment ClientIdentifier { get { return _clientIdentifier; } @@ -59,15 +80,15 @@ public DataSegment ClientIdentifier { if (value == null) { - throw new ArgumentNullException(nameof(ClientIdentifier)); + throw new ArgumentNullException(nameof(value)); } if (value.Length < 1) { - throw new ArgumentOutOfRangeException(nameof(ClientIdentifier), value.Length, "ClientIdentifier.Length has to be greater than 0"); + throw new ArgumentOutOfRangeException(nameof(value), value.Length, "ClientIdentifier.Length has to be greater than 0"); } - if (value.Length > byte.MaxValue - 1) + if (value.Length >= byte.MaxValue - 1) { - throw new ArgumentOutOfRangeException(nameof(ClientIdentifier), value.Length, "ClientIdentifier.Length has to be less than 255"); + throw new ArgumentOutOfRangeException(nameof(value), value.Length, "ClientIdentifier.Length has to be less than 254"); } _clientIdentifier = value; } diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs index 0afb9c4d..d1b9ac28 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs @@ -9,6 +9,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// The cookie server option specifies a list of RFC 865 [9] cookie + /// servers available to the client.Servers SHOULD be listed in order + /// of preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +21,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpCookieServerOption : DhcpAddressListOption { - public DhcpCookieServerOption(IList addresses) : base(DhcpOptionCode.CookieServer, addresses) + /// + /// create new DhcpCookieServerOption + /// + /// Addresses + public DhcpCookieServerOption(IList addresses) : base(addresses, DhcpOptionCode.CookieServer) { } internal static DhcpCookieServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpCookieServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, (p) => new DhcpCookieServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDataSegmentOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDataSegmentOption.cs new file mode 100644 index 00000000..d19d78c4 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDataSegmentOption.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// Abstract class for all Dhcp-Options with a DataSegment value + /// + public class DhcpDataSegmentOption : DhcpOption + { + internal DhcpDataSegmentOption(DataSegment value, DhcpOptionCode code) : base(code) + { + InternalValue = value; + } + + internal static T Read(DataSegment data, ref int offset, Func ctor) where T : DhcpDataSegmentOption + { + if (ctor == null) + throw new ArgumentNullException(nameof(ctor)); + byte len = data[offset++]; + T option = ctor(data.Subsegment(offset, len)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, InternalValue); + } + + /// + /// RFC 2132. + /// Value of Length-Field + /// + public override byte Length + { + get + { + return (byte)InternalValue.Length; + } + } + + /// + /// The real value of the UIntOption + /// + protected DataSegment InternalValue + { + get { return _internalValue; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + if (value.Length < 1) + { + throw new ArgumentOutOfRangeException(nameof(value), value.Length, "DataSegment.Length has to be greater than 0"); + } + if (value.Length > byte.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(value), value.Length, "DataSegment.Length has to be less than 256"); + } + _internalValue = value; + } + } + + private DataSegment _internalValue; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs index 014cda4b..5c2a9fbe 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// The Finger server option specifies a list of Finger available to the + /// client.Servers SHOULD be listed in order of preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +20,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpDefaultFingerServerOption : DhcpAddressListOption { - public DhcpDefaultFingerServerOption(IList addresses) : base(DhcpOptionCode.DefaultFingerServer, addresses) + /// + /// create new DhcpDefaultFingerServerOption + /// + /// Addresses + public DhcpDefaultFingerServerOption(IList addresses) : base(addresses, DhcpOptionCode.DefaultFingerServer) { } internal static DhcpDefaultFingerServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpDefaultFingerServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, (p) => new DhcpDefaultFingerServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs index 3fdec04b..eaceb8c4 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs @@ -7,7 +7,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// This option specifies the default time-to-live that the client should + /// use on outgoing datagrams. ///
     ///  Code   Len   TTL
     /// +-----+-----+-----+
@@ -15,38 +17,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+
     /// 
///
- public class DhcpDefaultIPTimeToLiveOption : DhcpOption + public class DhcpDefaultIPTimeToLiveOption : DhcpByteOption { - public DhcpDefaultIPTimeToLiveOption(byte ttl) : base(DhcpOptionCode.DefaultIPTimeToLive) + /// + /// create new DhcpDefaultIPTimeToLiveOption + /// + /// TTL + public DhcpDefaultIPTimeToLiveOption(byte ttl) : base(ttl, DhcpOptionCode.DefaultIpTimeToLive) { - TTL = ttl; } internal static DhcpDefaultIPTimeToLiveOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 1) - { - throw new ArgumentException("Length of a DHCP DefaultIPTimeToLive Option has to be 1"); - } - DhcpDefaultIPTimeToLiveOption option = new DhcpDefaultIPTimeToLiveOption(data[offset++]); - return option; + return Read(data, ref offset, p => new DhcpDefaultIPTimeToLiveOption(p)); } - internal override void Write(byte[] buffer, ref int offset) + /// + /// RFC 2132. + /// TTL + /// + public byte Ttl { - base.Write(buffer, ref offset); - buffer.Write(ref offset, TTL); - } - - public override byte Length - { - get { return 1; } - } - - public byte TTL - { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs index 08228f7b..cf00aa4a 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// The IRC server option specifies a list of IRC available to the + /// client.Servers SHOULD be listed in order of preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +20,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpDefaultInternetRelayChatServerOption : DhcpAddressListOption { - public DhcpDefaultInternetRelayChatServerOption(IList addresses) : base(DhcpOptionCode.DefaultInternetRelayChatServer, addresses) + /// + /// create new DhcpDefaultInternetRelayChatServerOption + /// + /// Addresses + public DhcpDefaultInternetRelayChatServerOption(IList addresses) : base(addresses, DhcpOptionCode.DefaultInternetRelayChatServer) { } internal static DhcpDefaultInternetRelayChatServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpDefaultInternetRelayChatServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, (p) => new DhcpDefaultInternetRelayChatServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs index 35008d04..f7d5e030 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// The WWW server option specifies a list of WWW available to the + /// client.Servers SHOULD be listed in order of preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +20,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpDefaultWorldWideWebServerOption : DhcpAddressListOption { - public DhcpDefaultWorldWideWebServerOption(IList addresses) : base(DhcpOptionCode.DefaultWorldWideWebServer, addresses) + /// + /// create new DhcpDefaultWorldWideWebServerOption + /// + /// Addresses + public DhcpDefaultWorldWideWebServerOption(IList addresses) : base(addresses, DhcpOptionCode.DefaultWorldWideWebServer) { } internal static DhcpDefaultWorldWideWebServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpDefaultWorldWideWebServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpDefaultWorldWideWebServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs index a6cc9b47..d393c410 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs @@ -8,6 +8,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the domain name that client should use when + /// resolving hostnames via the Domain Name System. ///
     ///  Code   Len        Domain Name
     /// +-----+-----+-----+-----+-----+-----+---
@@ -15,53 +17,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+---
     /// 
///
- public class DhcpDomainNameOption : DhcpOption + public class DhcpDomainNameOption : DhcpStringOption { - public DhcpDomainNameOption(string domainName) : base(DhcpOptionCode.DomainName) + /// + /// create new DhcpDomainNameOption + /// + /// Domain Name + public DhcpDomainNameOption(string domainName) : base(domainName, DhcpOptionCode.DomainName) { - DomainName = domainName; } internal static DhcpDomainNameOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); - DhcpDomainNameOption option = new DhcpDomainNameOption(hostName); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(DomainName)); - } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(DomainName); - } + return DhcpStringOption.Read(data, ref offset, p => new DhcpDomainNameOption(p)); } + /// + /// RFC 2132. + /// Domain Name + /// public string DomainName { - get { return _domainName; } - - set - { - if (value == null) - throw new ArgumentNullException(nameof(DomainName)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(DomainName), value.Length, "DomainName has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(DomainName), value.Length, "DomainName has to be less than 256 characters long"); - - _domainName = value; - } + get { return InternalValue; } + set { InternalValue = value; } } - - private string _domainName; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs index 93fc6e7a..78ef0486 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs @@ -7,16 +7,31 @@ namespace PcapDotNet.Packets.Dhcp.Options { + /// + /// RFC 2132. + /// The domain name server option specifies a list of Domain Name System + /// (STD 13, RFC 1035 [8]) name servers available to the client. Servers + /// SHOULD be listed in order of preference. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  6  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
public class DhcpDomainNameServerOption : DhcpAddressListOption { - public DhcpDomainNameServerOption(IList addresses) : base(DhcpOptionCode.DomainNameServerServer, addresses) + /// + /// create new DhcpDomainNameServerOption + /// + /// Addresses + public DhcpDomainNameServerOption(IList addresses) : base(addresses, DhcpOptionCode.DomainNameServerServer) { } internal static DhcpDomainNameServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpDomainNameServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpDomainNameServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs index 90148b5f..39cadf65 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs @@ -7,7 +7,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// The end option marks the end of valid information in the vendor field. ///
     ///  Code
     /// +-----+
@@ -17,15 +18,23 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpEndOption : DhcpOption { + /// + /// create new EndOption + /// public DhcpEndOption() : base(DhcpOptionCode.End) { } + /// + /// Length of the Dhcp-Option + /// public override byte Length { get { return 0; } } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "offset")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "data")] internal static DhcpEndOption Read(DataSegment data, ref int offset) { return new Options.DhcpEndOption(); diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs index e85f606f..c2ecdc7a 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs @@ -9,6 +9,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies whether or not the client should use Ethernet + /// Version 2 (RFC 894 [15]) or IEEE 802.3 (RFC 1042 [16]) encapsulation + /// if the interface is an Ethernet. ///
     ///  Code   Len  Value
     /// +-----+-----+-----+
@@ -16,42 +19,31 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+
     /// 
///
- public class DhcpEthernetEncapsulationOption : DhcpOption + public class DhcpEthernetEncapsulationOption : DhcpBooleanOption { - public DhcpEthernetEncapsulationOption(bool enabled) : base(DhcpOptionCode.EthernetEncapsulation) + /// + /// create new DhcpEthernetEncapsulationOption + /// + /// Value + public DhcpEthernetEncapsulationOption(bool value) : base(value, DhcpOptionCode.EthernetEncapsulation) { } internal static DhcpEthernetEncapsulationOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP EthernetEncapsulation Option has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP EthernetEncapsulation Option has to be 0 or 1"); - DhcpEthernetEncapsulationOption option = new DhcpEthernetEncapsulationOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } + return Read(data, ref offset, p => new DhcpEthernetEncapsulationOption(p)); } + /// + /// RFC 2132. + /// A value of false indicates that the + /// client should use RFC 894 encapsulation. A value of true means that the + /// client should use RFC 1042 encapsulation. + /// public bool Value { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs index 2fc66241..8ab690d9 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs @@ -8,59 +8,44 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// A string to specify a file, retrievable via TFTP, which contains + /// information which can be interpreted in the same way as the 64-octet + /// vendor-extension field within the BOOTP response, with the following + /// exceptions: + /// - the length of the file is unconstrained; + /// - all references to Tag 18 (i.e., instances of the BOOTP Extensions Path field) within the file are ignored. ///
-    ///  Code   Len      Dump File Pathname
+    ///  Code   Len      Extensions Pathname
     /// +-----+-----+-----+-----+-----+-----+---
     /// |  18 |  n  |  n1 |  n2 |  n3 |  n4 | ...
     /// +-----+-----+-----+-----+-----+-----+---
     /// 
///
- public class DhcpExtensionsPathOption : DhcpOption + public class DhcpExtensionsPathOption : DhcpStringOption { - public DhcpExtensionsPathOption(string extensionsPath) : base(DhcpOptionCode.ExtensionsPath) + /// + /// create new DhcpExtensionsPathOption + /// + /// Extensions Pathname + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] + public DhcpExtensionsPathOption(string extensionsPathname) : base(extensionsPathname, DhcpOptionCode.ExtensionsPath) { - ExtensionsPath = extensionsPath; } internal static DhcpExtensionsPathOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); - DhcpExtensionsPathOption option = new DhcpExtensionsPathOption(hostName); - offset += option.Length; - return option; + return Read(data, ref offset, p => new Options.DhcpExtensionsPathOption(p)); } - internal override void Write(byte[] buffer, ref int offset) + /// + /// RFC 2132. + /// Extensions Pathname + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] + public string ExtensionsPathname { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(ExtensionsPath)); + get { return InternalValue; } + set { InternalValue = value; } } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(ExtensionsPath); - } - } - - public string ExtensionsPath - { - get { return _extensionsPath; } - set - { - if (value == null) - throw new ArgumentNullException(nameof(ExtensionsPath)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(ExtensionsPath), value.Length, "ExtensionsPath has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(ExtensionsPath), value.Length, "ExtensionsPath has to be less than 256 characters long"); - - _extensionsPath = value; - } - } - - private string _extensionsPath; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs index 8eaa21c1..23ce75bc 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs @@ -8,6 +8,10 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the name of the client. The name may or may + /// not be qualified with the local domain name(see section 3.17 for the + /// preferred way to retrieve the domain name). See RFC 1035 for + /// character set restrictions. ///
     ///  Code   Len                 Host Name
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -15,52 +19,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
     /// 
///
- public class DhcpHostNameOption : DhcpOption + public class DhcpHostNameOption : DhcpStringOption { - public DhcpHostNameOption(string hostName) : base(DhcpOptionCode.HostName) + /// + /// create new DhcpHostNameOption + /// + /// Host Name + public DhcpHostNameOption(string hostName) : base(hostName, DhcpOptionCode.HostName) { - HostName = hostName; } internal static DhcpHostNameOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); - DhcpHostNameOption option = new DhcpHostNameOption(hostName); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(HostName)); - } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(HostName); - } + return Read(data, ref offset, p => new DhcpHostNameOption(p)); } + /// + /// RFC 2132. + /// Host Name + /// public string HostName { - get { return _hostName; } - set - { - if (value == null) - throw new ArgumentNullException(nameof(HostName)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(HostName), value.Length, "HostName has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(HostName), value.Length, "HostName has to be less than 256 characters long"); - - _hostName = value; - } + get { return InternalValue; } + set { InternalValue = value; } } - - private string _hostName; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs index 1644469f..8d666e13 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs @@ -7,46 +7,42 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// This option is used in a client request (DHCPDISCOVER or DHCPREQUEST) + /// to allow the client to request a lease time for the IP address. In a + /// server reply(DHCPOFFER), a DHCP server uses this option to specify + /// the lease time it is willing to offer. ///
-    ///  Code   Len        Time Offset
+    ///  Code   Len         Lease Time
     /// +-----+-----+-----+-----+-----+-----+
-    /// |  1  |  4  |  n1 |  n2 |  n3 |  n4 |
+    /// |  51 |  4  |  t1 |  t2 |  t3 |  t4 |
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpIPAddressLeaseTimeOption : DhcpOption + public class DhcpIPAddressLeaseTimeOption : DhcpUIntOption { - public DhcpIPAddressLeaseTimeOption(uint leaseTime) : base(DhcpOptionCode.IPAddressLeaseTime) + /// + /// create new DhcpIPAddressLeaseTimeOption + /// + /// Lease Time + public DhcpIPAddressLeaseTimeOption(uint leaseTime) : base(leaseTime, DhcpOptionCode.IPAddressLeaseTime) { - LeaseTime = leaseTime; } internal static DhcpIPAddressLeaseTimeOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 4) - throw new ArgumentException("Length of a DHCP IPAddressLeaseTime Option has to be 4"); - - DhcpIPAddressLeaseTimeOption option = new DhcpIPAddressLeaseTimeOption(data.ReadUInt(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, LeaseTime, Endianity.Big); - } - - public override byte Length - { - get { return 4; } + return Read(data, ref offset, p => new Options.DhcpIPAddressLeaseTimeOption(p)); } + /// + /// RFC 2132. + /// Lease Time + /// The time is in units of seconds + /// public uint LeaseTime { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs index 4828ae81..6288400a 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs @@ -9,50 +9,38 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies whether the client should configure its IP + /// layer for packet forwarding. ///
-    ///  Code   Len  Type
+    ///  Code   Len  Value
     /// +-----+-----+-----+
-    /// |  15 |  1  | 0/1 |
+    /// |  19 |  1  | 0/1 |
     /// +-----+-----+-----+
     /// 
///
- public class DhcpIPForwardingEnableOption : DhcpOption + public class DhcpIPForwardingEnableOption : DhcpBooleanOption { - public DhcpIPForwardingEnableOption(bool value) : base(DhcpOptionCode.IPForwardingEnable) + /// + /// create new DhcpIPForwardingEnableOption + /// + /// Value + public DhcpIPForwardingEnableOption(bool value) : base(value, DhcpOptionCode.IPForwardingEnable) { - Value = value; } internal static DhcpIPForwardingEnableOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP MessageTypeOption has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP MessageTypeOption has to be 0 or 1"); - DhcpIPForwardingEnableOption option = new DhcpIPForwardingEnableOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } + return Read(data, ref offset, p => new DhcpIPForwardingEnableOption(p)); } + /// + /// RFC 2132. + /// A value of false means disable IP forwarding, and a value of true means enable IP forwarding. + /// public bool Value { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs index 3fa6da7a..6a55098c 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs @@ -7,16 +7,31 @@ namespace PcapDotNet.Packets.Dhcp.Options { + /// + /// RFC 2132. + /// The Impress server option specifies a list of Imagen Impress servers + /// available to the client.Servers SHOULD be listed in order of + /// preference. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  10 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
public class DhcpImpressServerOption : DhcpAddressListOption { - public DhcpImpressServerOption(IList addresses) : base(DhcpOptionCode.ImpressServer, addresses) + /// + /// create new DhcpImpressServerOption + /// + /// Addresses + public DhcpImpressServerOption(IList addresses) : base(addresses, DhcpOptionCode.ImpressServer) { } internal static DhcpImpressServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpImpressServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new Options.DhcpImpressServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIntOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIntOption.cs new file mode 100644 index 00000000..95185680 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIntOption.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// Abstract class for all Dhcp-Options with a int value + /// + public class DhcpIntOption : DhcpOption + { + internal DhcpIntOption(int value, DhcpOptionCode code) : base(code) + { + InternalValue = value; + } + + internal static T Read(DataSegment data, ref int offset, Func ctor) where T : DhcpIntOption + { + if (ctor == null) + throw new ArgumentNullException(nameof(ctor)); + byte len = data[offset++]; + if (len != sizeof(int)) + throw new ArgumentException("Length of a DHCP UIntOption Option has to be 4"); + T option = ctor(data.ReadInt(offset, Endianity.Big)); + offset += sizeof(uint); + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, InternalValue, Endianity.Big); + } + + /// + /// RFC 2132. + /// Value of Length-Field + /// + public override byte Length + { + get + { + return sizeof(int); + } + } + + /// + /// The real value of the IntOption + /// + protected int InternalValue + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMTUOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMTUOption.cs deleted file mode 100644 index f52222c4..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMTUOption.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - /// - /// RFC 2132 - ///
-    ///  Code   Len      MTU
-    /// +-----+-----+-----+-----+
-    /// |  26 |  2  |  m1 |  m2 |
-    /// +-----+-----+-----+-----+
-    /// 
- ///
- public class DhcpInterfaceMTUOption : DhcpOption - { - public DhcpInterfaceMTUOption(ushort mtu) : base(DhcpOptionCode.InterfaceMTU) - { - MTU = mtu; - } - - internal static DhcpInterfaceMTUOption Read(DataSegment data, ref int offset) - { - if (data[offset++] != sizeof(ushort)) - throw new ArgumentException($"Length of a DHCP InterfaceMTU Option has to be {sizeof(ushort)}"); - DhcpInterfaceMTUOption option = new DhcpInterfaceMTUOption(data.ReadUShort(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, MTU, Endianity.Big); - } - - public override byte Length - { - get { return sizeof(ushort); } - } - - public ushort MTU - { - get; - set; - } - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs new file mode 100644 index 00000000..198adb74 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// This option specifies the MTU to use on this interface. The MTU is + /// specified as a 16-bit unsigned integer. The minimum legal value for + /// the MTU is 68. + ///
+    ///  Code   Len      MTU
+    /// +-----+-----+-----+-----+
+    /// |  26 |  2  |  m1 |  m2 |
+    /// +-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpInterfaceMtuOption : DhcpUShortOption + { + private const ushort MIN_MTU = 68; + + /// + /// create new DhcpInterfaceMTUOption + /// + /// MTU + public DhcpInterfaceMtuOption(ushort mtu) : base(mtu, DhcpOptionCode.InterfaceMtu) + { + if (mtu < MIN_MTU) + throw new ArgumentOutOfRangeException(nameof(mtu), mtu, "Minimum value of MTU is " + MIN_MTU); + } + + internal static DhcpInterfaceMtuOption Read(DataSegment data, ref int offset) + { + return Read(data, ref offset, p => new DhcpInterfaceMtuOption(p)); + } + + /// + /// RFC 2132. + /// MTU + /// + public ushort Mtu + { + get { return InternalValue; } + set + { + if (value < MIN_MTU) + throw new ArgumentOutOfRangeException(nameof(value), value, "Minimum value of MTU is " + MIN_MTU); + InternalValue = value; + } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLPRServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLPRServerOption.cs deleted file mode 100644 index b960b43c..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLPRServerOption.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using PcapDotNet.Packets.IpV4; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - public class DhcpLPRServerOption : DhcpAddressListOption - { - public DhcpLPRServerOption(IList addresses) : base(DhcpOptionCode.LPRServer, addresses) - { - } - - internal static DhcpLPRServerOption Read(DataSegment data, ref int offset) - { - byte length = data[offset++]; - return new DhcpLPRServerOption(GetAddresses(data, length, ref offset)); - } - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs index 653bac84..8dd932b4 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs @@ -7,16 +7,31 @@ namespace PcapDotNet.Packets.Dhcp.Options { + /// + /// RFC 2132. + /// The log server option specifies a list of MIT-LCS UDP log servers + /// available to the client. Servers SHOULD be listed in order of + /// preference. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  7  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
public class DhcpLogServerOption : DhcpAddressListOption { - public DhcpLogServerOption(IList addresses) : base(DhcpOptionCode.LogServer, addresses) + /// + /// create new DhcpLogServerOption + /// + /// Addresses + public DhcpLogServerOption(IList addresses) : base(addresses, DhcpOptionCode.LogServer) { } internal static DhcpLogServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpLogServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpLogServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs new file mode 100644 index 00000000..fc526212 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// The LPR server option specifies a list of RFC 1179 [10] line printer + /// servers available to the client. Servers SHOULD be listed in order + /// of preference. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  9  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
+ public class DhcpLprServerOption : DhcpAddressListOption + { + /// + /// create new DhcpLprServerOption + /// + /// Addresses + public DhcpLprServerOption(IList addresses) : base(addresses, DhcpOptionCode.LprServer) + { + } + + internal static DhcpLprServerOption Read(DataSegment data, ref int offset) + { + return Read(data, ref offset, p => new DhcpLprServerOption(p)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs index b3fb36f9..a35fe00c 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies whether or not the client should respond to + /// subnet mask requests using ICMP. ///
     ///  Code   Len  Value
     /// +-----+-----+-----+
@@ -16,42 +18,31 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+
     /// 
///
- public class DhcpMaskSupplierOption : DhcpOption + public class DhcpMaskSupplierOption : DhcpBooleanOption { - public DhcpMaskSupplierOption(bool enabled) : base(DhcpOptionCode.MaskSupplier) + /// + /// create new DhcpMaskSupplierOption + /// + /// Value + public DhcpMaskSupplierOption(bool value) : base(value, DhcpOptionCode.MaskSupplier) { } internal static DhcpMaskSupplierOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP MaskSupplier Option has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP MaskSupplier Option has to be 0 or 1"); - DhcpMaskSupplierOption option = new DhcpMaskSupplierOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } + return Read(data, ref offset, p => new Options.DhcpMaskSupplierOption(p)); } + /// + /// RFC 2132. + /// A value of false indicates that the client + /// should not perform mask discovery. A value of true means that the + /// client should perform mask discovery. + /// public bool Value { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs index f3e9faa4..3a2ee643 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs @@ -8,6 +8,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the maximum size datagram that the client + /// should be prepared to reassemble.unsigned integer. ///
     ///  Code   Len      Size
     /// +-----+-----+-----+-----+
@@ -15,43 +17,38 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+
     /// 
///
- public class DhcpMaximumDatagramReassemblySizeOption : DhcpOption + public class DhcpMaximumDatagramReassemblySizeOption : DhcpUShortOption { - public DhcpMaximumDatagramReassemblySizeOption() : base(DhcpOptionCode.MaximumDatagramReassemblySize) - { - } + private const ushort MIN_SIZE = 576; - public DhcpMaximumDatagramReassemblySizeOption(ushort size) : this() + /// + /// create new DhcpMaximumDatagramReassemblySizeOption + /// + /// Size + public DhcpMaximumDatagramReassemblySizeOption(ushort size) : base(size, DhcpOptionCode.MaximumDatagramReassemblySize) { - Size = size; + if (size < MIN_SIZE) + throw new ArgumentOutOfRangeException(nameof(size), size, "Minimum value of Size is " + MIN_SIZE); } internal static DhcpMaximumDatagramReassemblySizeOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 2) - { - throw new ArgumentException("Length of a DHCP MaximumDatagramReassemblySize Option has to be 2"); - } - DhcpMaximumDatagramReassemblySizeOption option = new DhcpMaximumDatagramReassemblySizeOption(data.ReadUShort(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Size, Endianity.Big); - } - - public override byte Length - { - get { return 2; } + return Read(data, ref offset, p => new DhcpMaximumDatagramReassemblySizeOption(p)); } + /// + /// RFC 2132. + /// Size + /// public ushort Size { - get; - set; + get { return InternalValue; } + set + { + if (value < MIN_SIZE) + throw new ArgumentOutOfRangeException(nameof(value), value, "Minimum value of Size is " + MIN_SIZE); + InternalValue = value; + } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs index fc246fe0..387667c5 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs @@ -9,6 +9,10 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the maximum length DHCP message that it is + /// willing to accept. A client may use the maximum DHCP message size option in + /// DHCPDISCOVER or DHCPREQUEST messages, but should not use the option + /// in DHCPDECLINE messages. ///
     ///  Code   Len     Length
     /// +-----+-----+-----+-----+
@@ -16,41 +20,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+
     /// 
///
- public class DhcpMaximumDhcpMessageSizeOption : DhcpOption + public class DhcpMaximumDhcpMessageSizeOption : DhcpUShortOption { - public DhcpMaximumDhcpMessageSizeOption(ushort maxLength) : base(DhcpOptionCode.MaximumDhcpMessageSize) + /// + /// create new DhcpMaximumDhcpMessageSizeOption + /// + /// Length + public DhcpMaximumDhcpMessageSizeOption(ushort length) : base(length, DhcpOptionCode.MaximumDhcpMessageSize) { - MaxLength = maxLength; } internal static DhcpMaximumDhcpMessageSizeOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 2) - throw new ArgumentException("Length of a DHCP MaximumDhcpMessageSize Option has to be 2"); - DhcpMaximumDhcpMessageSizeOption option = new DhcpMaximumDhcpMessageSizeOption(data.ReadUShort(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, MaxLength, Endianity.Big); - } - - public override byte Length - { - get - { - return 2; - } + return Read(data, ref offset, p => new DhcpMaximumDhcpMessageSizeOption(p)); } + /// + /// RFC 2132. + /// Length + /// public ushort MaxLength { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs index d4527eb7..c73ddcab 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs @@ -8,6 +8,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the path-name of a file to which the client's + /// core image should be dumped in the event the client crashes. ///
     ///  Code   Len      Dump File Pathname
     /// +-----+-----+-----+-----+-----+-----+---
@@ -15,52 +17,31 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+---
     /// 
///
- public class DhcpMeritDumpFileOption : DhcpOption + public class DhcpMeritDumpFileOption : DhcpStringOption { - public DhcpMeritDumpFileOption(string dumpFilePathname) : base(DhcpOptionCode.MeritDumpFile) + /// + /// create new DhcpMeritDumpFileOption + /// + /// Dump File Pathname + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] + public DhcpMeritDumpFileOption(string dumpFilePathname) : base(dumpFilePathname, DhcpOptionCode.MeritDumpFile) { - DumpFilePathname = dumpFilePathname; } internal static DhcpMeritDumpFileOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); - DhcpMeritDumpFileOption option = new DhcpMeritDumpFileOption(hostName); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(DumpFilePathname)); - } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(DumpFilePathname); - } + return Read(data, ref offset, p => new DhcpMeritDumpFileOption(p)); } + /// + /// RFC 2132. + /// Dump File Pathname + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] public string DumpFilePathname { - get { return _dumpFilePathname; } - set - { - if (value == null) - throw new ArgumentNullException(nameof(DumpFilePathname)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(DumpFilePathname), value.Length, "DumpFilePathname has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(DumpFilePathname), value.Length, "DumpFilePathname has to be less than 256 characters long"); - - _dumpFilePathname = value; - } + get { return InternalValue; } + set { InternalValue = value; } } - - private string _dumpFilePathname; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs index c05b693f..fde899cb 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs @@ -8,6 +8,10 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option is used by a DHCP server to provide an error message to a + /// DHCP client in a DHCPNAK message in the event of a failure. A client + /// may use this option in a DHCPDECLINE message to indicate the why the + /// client declined the offered parameters. ///
     ///  Code   Len     Text
     /// +-----+-----+-----+-----+---
@@ -15,52 +19,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+---
     /// 
///
- public class DhcpMessageOption : DhcpOption + public class DhcpMessageOption : DhcpStringOption { - public DhcpMessageOption(string text) : base(DhcpOptionCode.Message) + /// + /// create new DhcpMessageOption + /// + /// Text + public DhcpMessageOption(string text) : base(text, DhcpOptionCode.Message) { - Text = text; } internal static DhcpMessageOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - string text = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); - DhcpMessageOption option = new DhcpMessageOption(text); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(Text)); - } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(Text); - } + return Read(data, ref offset, p => new DhcpMessageOption(p)); } + /// + /// RFC 2132. + /// Text + /// public string Text { - get { return _rootPath; } - set - { - if (value == null) - throw new ArgumentNullException(nameof(Text)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(Text), value.Length, "Text has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Text), value.Length, "Text has to be less than 256 characters long"); - - _rootPath = value; - } + get { return InternalValue; } + set { InternalValue = value; } } - - private string _rootPath; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs index 3676ffe9..e7f66699 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs @@ -9,6 +9,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option is used to convey the type of the DHCP message. ///
     ///  Code   Len  Type
     /// +-----+-----+-----+
@@ -18,6 +19,10 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpMessageTypeOption : DhcpOption { + /// + /// create new DhcpMessageTypeOption + /// + /// Type public DhcpMessageTypeOption(MessageType type) : base(DhcpOptionCode.MessageType) { Type = type; @@ -39,6 +44,9 @@ internal override void Write(byte[] buffer, ref int offset) buffer.Write(ref offset, (byte)Type); } + /// + /// Length of the Dhcp-Option + /// public override byte Length { get @@ -47,27 +55,71 @@ public override byte Length } } + /// + /// RFC 2132. + /// Message Type + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")] public MessageType Type { get { return _type; } set { if (!Enum.IsDefined(typeof(MessageType), value)) - throw new ArgumentOutOfRangeException(nameof(Type), value, "Not a valid MessageType"); + throw new ArgumentOutOfRangeException(nameof(value), value, "Not a valid MessageType"); _type = value; } } private MessageType _type; + /// + /// RFC 2132. + /// Supported Message-Types + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] public enum MessageType : byte { + /// + /// RFC 2132. + /// DHCP Discover message + /// Discover = 1, + + /// + /// RFC 2132. + /// DHCP Offer message + /// Offer = 2, + + /// + /// RFC 2132. + /// DHCP Request message + /// Request = 3, + + /// + /// RFC 2132. + /// DHCP Decline message + /// Decline = 4, + + /// + /// RFC 2132. + /// DHCP Acknowledgment message + /// Ack = 5, + + /// + /// RFC 2132. + /// DHCP Negative Acknowledgment message + /// Nak = 6, + + /// + /// RFC 2132. + /// DHCP Release message + /// Release = 7 } } diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs index aeaea243..378136f4 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs @@ -9,6 +9,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies a list of IP addresses indicating mobile IP + /// home agents available to the client. Agents SHOULD be listed in + /// order of preference. ///
     ///  Code Len    Home Agent Addresses (zero or more)
     /// +-----+-----+-----+-----+-----+-----+--
@@ -18,7 +21,11 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpMobileIPHomeAgentOption : DhcpAddressListOption { - public DhcpMobileIPHomeAgentOption(IList addresses) : base(DhcpOptionCode.MobileIPHomeAgent, addresses) + /// + /// create new DhcpMobileIPHomeAgentOption + /// + /// Addresses + public DhcpMobileIPHomeAgentOption(IList addresses) : base(addresses, DhcpOptionCode.MobileIPHomeAgent) { } @@ -27,5 +34,16 @@ internal static DhcpMobileIPHomeAgentOption Read(DataSegment data, ref int offse byte length = data[offset++]; return new DhcpMobileIPHomeAgentOption(GetAddresses(data, length, ref offset)); } + + /// + /// true if Addresses-List is allowed to be empty + /// + protected override bool AllowEmptyAddresses + { + get + { + return true; + } + } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs index eae80623..8a541e5f 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs @@ -7,16 +7,30 @@ namespace PcapDotNet.Packets.Dhcp.Options { + /// + /// RFC 2132. + /// The name server option specifies a list of IEN 116 [7] name servers + /// available to the client.Servers SHOULD be listed in order of preference. + ///
+    ///  Code Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  5  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
public class DhcpNameServerOption : DhcpAddressListOption { - public DhcpNameServerOption(IList addresses) : base(DhcpOptionCode.NameServer, addresses) + /// + /// create new DhcpNameServerOption + /// + /// Addresses + public DhcpNameServerOption(IList addresses) : base(addresses, DhcpOptionCode.NameServer) { } internal static DhcpNameServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpNameServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpNameServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.cs deleted file mode 100644 index 59d1de53..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using PcapDotNet.Packets.IpV4; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - /// - /// RFC 2132. - ///
-    ///  Code   Len           Address 1              Address 2
-    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-    /// |  45 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
-    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-    /// 
- ///
- public class DhcpNetBIOSOverTCPIPDatagramDistributionServerOption : DhcpAddressListOption - { - public DhcpNetBIOSOverTCPIPDatagramDistributionServerOption(IList addresses) : base(DhcpOptionCode.NetBIOSOverTCPIPDatagramDistributionServer, addresses) - { - } - - internal static DhcpNetBIOSOverTCPIPDatagramDistributionServerOption Read(DataSegment data, ref int offset) - { - byte length = data[offset++]; - return new DhcpNetBIOSOverTCPIPDatagramDistributionServerOption(GetAddresses(data, length, ref offset)); - } - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNameServerOption.cs deleted file mode 100644 index 1dc059ab..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNameServerOption.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using PcapDotNet.Packets.IpV4; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - /// - /// RFC 2132. - ///
-    ///  Code   Len           Address 1              Address 2
-    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-    /// |  44 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
-    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-    /// 
- ///
- public class DhcpNetBIOSOverTCPIPNameServerOption : DhcpAddressListOption - { - public DhcpNetBIOSOverTCPIPNameServerOption(IList addresses) : base(DhcpOptionCode.NetBIOSOverTCPIPNameServer, addresses) - { - } - - internal static DhcpNetBIOSOverTCPIPNameServerOption Read(DataSegment data, ref int offset) - { - byte length = data[offset++]; - return new DhcpNetBIOSOverTCPIPNameServerOption(GetAddresses(data, length, ref offset)); - } - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPScopeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPScopeOption.cs deleted file mode 100644 index c7662a6a..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPScopeOption.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - /// - /// RFC 2132. - ///
-    /// Code   Len       NetBIOS Scope
-    /// +-----+-----+-----+-----+-----+-----+----
-    /// |  47 |  n  |  s1 |  s2 |  s3 |  s4 | ...
-    /// +-----+-----+-----+-----+-----+-----+----
-    /// 
- ///
- public class DhcpNetBIOSOverTCPIPScopeOption : DhcpOption - { - public DhcpNetBIOSOverTCPIPScopeOption(DataSegment netBIOSScope) : base(DhcpOptionCode.NetBIOSOverTCPIPScope) - { - NetBIOSScope = netBIOSScope; - } - - internal static DhcpNetBIOSOverTCPIPScopeOption Read(DataSegment data, ref int offset) - { - byte length = data[offset++]; - DhcpNetBIOSOverTCPIPScopeOption option = new DhcpNetBIOSOverTCPIPScopeOption(data.Subsegment(offset, length)); - offset += length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - if (NetBIOSScope == null) - throw new ArgumentNullException(nameof(NetBIOSScope)); - if (NetBIOSScope.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(NetBIOSScope), NetBIOSScope.Length, "NetBIOSScope.Length has to be less than 256"); - base.Write(buffer, ref offset); - buffer.Write(ref offset, NetBIOSScope); - } - - public override byte Length - { - get - { - if (NetBIOSScope == null) - { - return 0; - } - return (byte)NetBIOSScope.Length; - } - } - - public DataSegment NetBIOSScope - { - get { return _netBIOSScope; } - set - { - if (value == null) - throw new ArgumentNullException(nameof(NetBIOSScope)); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(NetBIOSScope), value.Length, "NetBIOSScope.Length has to be less than 256"); - _netBIOSScope = value; - } - } - - private DataSegment _netBIOSScope; - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs new file mode 100644 index 00000000..0376c9b1 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// The NetBIOS datagram distribution server (NBDD) option specifies a + /// list of RFC 1001/1002 NBDD servers listed in order of preference. + ///
+    ///  Code   Len           Address 1              Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+    /// |  45 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+    /// 
+ ///
+ public class DhcpNetBiosOverTcpIpDatagramDistributionServerOption : DhcpAddressListOption + { + /// + /// create new DhcpNetBiosOverTcpIpDatagramDistributionServerOption + /// + /// + public DhcpNetBiosOverTcpIpDatagramDistributionServerOption(IList addresses) : base(addresses, DhcpOptionCode.NetBiosOverTcpIpDatagramDistributionServer) + { + } + + internal static DhcpNetBiosOverTcpIpDatagramDistributionServerOption Read(DataSegment data, ref int offset) + { + return Read(data, ref offset, p => new DhcpNetBiosOverTcpIpDatagramDistributionServerOption(p)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs new file mode 100644 index 00000000..0d9ec62a --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// The NetBIOS name server (NBNS) option specifies a list of RFC 1001/1002 [19] [20] + /// NBNS name servers listed in order of preference. + ///
+    ///  Code   Len           Address 1              Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+    /// |  44 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+    /// 
+ ///
+ public class DhcpNetBiosOverTcpIpNameServerOption : DhcpAddressListOption + { + /// + /// create new DhcpNetBiosOverTcpIpNameServerOption + /// + /// Addresses + public DhcpNetBiosOverTcpIpNameServerOption(IList addresses) : base(addresses, DhcpOptionCode.NetBiosOverTcpIpNameServer) + { + } + + internal static DhcpNetBiosOverTcpIpNameServerOption Read(DataSegment data, ref int offset) + { + return Read(data, ref offset, p => new DhcpNetBiosOverTcpIpNameServerOption(p)); + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNodeTypeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs similarity index 53% rename from PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNodeTypeOption.cs rename to PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs index fec4e03e..65e7a65b 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBIOSOverTCPIPNodeTypeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// The NetBIOS node type option allows NetBIOS over TCP/IP clients which + /// are configurable to be configured as described in RFC 1001/1002. ///
     ///  Code   Len  Node Type
     /// +-----+-----+-----------+
@@ -16,19 +18,23 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----------+
     /// 
///
- public class DhcpNetBIOSOverTCPIPNodeTypeOption : DhcpOption + public class DhcpNetBiosOverTcpIpNodeTypeOption : DhcpOption { - public DhcpNetBIOSOverTCPIPNodeTypeOption(NodeType type) : base(DhcpOptionCode.NetBIOSOverTCPIPNodeType) + /// + /// create new DhcpNetBIOSOverTCPIPNodeTypeOption + /// + /// Type + public DhcpNetBiosOverTcpIpNodeTypeOption(NodeType type) : base(DhcpOptionCode.NetBiosOverTcpIpNodeType) { Type = type; } - internal static DhcpNetBIOSOverTCPIPNodeTypeOption Read(DataSegment data, ref int offset) + internal static DhcpNetBiosOverTcpIpNodeTypeOption Read(DataSegment data, ref int offset) { byte len = data[offset++]; if (len != 1) throw new ArgumentException("Length of a DHCP NetBIOSOverTCPIPNodeType Option has to be 1"); - DhcpNetBIOSOverTCPIPNodeTypeOption option = new DhcpNetBIOSOverTCPIPNodeTypeOption((NodeType)data[offset]); + DhcpNetBiosOverTcpIpNodeTypeOption option = new DhcpNetBiosOverTcpIpNodeTypeOption((NodeType)data[offset]); offset += option.Length; return option; } @@ -39,6 +45,9 @@ internal override void Write(byte[] buffer, ref int offset) buffer.Write(ref offset, (byte)Type); } + /// + /// Length of the Dhcp-Option + /// public override byte Length { get @@ -47,13 +56,18 @@ public override byte Length } } + /// + /// RFC 2132. + /// Node Type + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")] public NodeType Type { get { return _type; } set { bool flagSet = false; - foreach(NodeType type in Enum.GetValues(typeof(NodeType))) + foreach (NodeType type in Enum.GetValues(typeof(NodeType))) { if ((value & type) != 0) { @@ -62,19 +76,42 @@ public NodeType Type } } if (!flagSet) - throw new ArgumentOutOfRangeException(nameof(Type), value, "Not a valid NodeType"); + throw new ArgumentOutOfRangeException(nameof(value), value, "Not a valid NodeType"); _type = value; } } private NodeType _type; + /// + /// RFC 2132. + /// Node Type + /// [Flags] public enum NodeType : byte { + /// + /// RFC 2132. + /// B-node + /// BNode = 0x1, + + /// + /// RFC 2132. + /// P-node + /// PNode = 0x2, + + /// + /// RFC 2132. + /// M-node + /// MNode = 0x4, + + /// + /// RFC 2132. + /// H-node + /// HNode = 0x8, } } diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs new file mode 100644 index 00000000..434459e6 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// The NetBIOS scope option specifies the NetBIOS over TCP/IP scope + /// parameter for the client as specified in RFC 1001/1002. + ///
+    /// Code   Len       NetBIOS Scope
+    /// +-----+-----+-----+-----+-----+-----+----
+    /// |  47 |  n  |  s1 |  s2 |  s3 |  s4 | ...
+    /// +-----+-----+-----+-----+-----+-----+----
+    /// 
+ ///
+ public class DhcpNetBiosOverTcpIpScopeOption : DhcpOption + { + /// + /// create new DhcpNetBiosOverTcpIpScopeOption + /// + /// NetBIOS Scope + public DhcpNetBiosOverTcpIpScopeOption(DataSegment netBiosScope) : base(DhcpOptionCode.NetBiosOverTcpIpScope) + { + NetBiosScope = netBiosScope; + } + + internal static DhcpNetBiosOverTcpIpScopeOption Read(DataSegment data, ref int offset) + { + byte length = data[offset++]; + DhcpNetBiosOverTcpIpScopeOption option = new DhcpNetBiosOverTcpIpScopeOption(data.Subsegment(offset, length)); + offset += length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, NetBiosScope); + } + + /// + /// Length of the Dhcp-Option + /// + public override byte Length + { + get + { + return (byte)NetBiosScope.Length; + } + } + + /// + /// RFC 2132. + /// NetBIOS Scope + /// + public DataSegment NetBiosScope + { + get { return _netBiosScope; } + set + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + if (value.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(value), value.Length, "NetBiosScope.Length has to be less than 256"); + _netBiosScope = value; + } + } + + private DataSegment _netBiosScope; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs index 83550dd5..30679013 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs @@ -9,6 +9,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies a list of IP addresses indicating NIS servers + /// available to the client.Servers SHOULD be listed in order of + /// preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +21,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpNetworkInformationServersOption : DhcpAddressListOption { - public DhcpNetworkInformationServersOption(IList addresses) : base(DhcpOptionCode.NetworkInformationServers, addresses) + /// + /// create new DhcpNetworkInformationServersOption + /// + /// Addresses + public DhcpNetworkInformationServersOption(IList addresses) : base(addresses, DhcpOptionCode.NetworkInformationServers) { } internal static DhcpNetworkInformationServersOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpNetworkInformationServersOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new Options.DhcpNetworkInformationServersOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs index 47b7c724..55bb99b6 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs @@ -8,6 +8,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the name of the client's NIS [17] domain. ///
     ///  Code   Len      NIS Domain Name
     /// +-----+-----+-----+-----+-----+-----+---
@@ -15,53 +16,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+---
     /// 
///
- public class DhcpNetworkInformationServiceDomainOption : DhcpOption + public class DhcpNetworkInformationServiceDomainOption : DhcpStringOption { - public DhcpNetworkInformationServiceDomainOption(string nisDomainName) : base(DhcpOptionCode.NetworkInformationServiceDomain) + /// + /// create new DhcpNetworkInformationServiceDomainOption + /// + /// NIS Domain Name + public DhcpNetworkInformationServiceDomainOption(string nisDomainName) : base(nisDomainName, DhcpOptionCode.NetworkInformationServiceDomain) { - NISDomainName = nisDomainName; } internal static DhcpNetworkInformationServiceDomainOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); - DhcpNetworkInformationServiceDomainOption option = new DhcpNetworkInformationServiceDomainOption(hostName); - offset += option.Length; - return option; + return Read(data, ref offset, p => new DhcpNetworkInformationServiceDomainOption(p)); } - internal override void Write(byte[] buffer, ref int offset) + /// + /// RFC 2132. + /// NIS Domain Name + /// + public string NisDomainName { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(NISDomainName)); + get { return InternalValue; } + set { InternalValue = value; } } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(NISDomainName); - } - } - - public string NISDomainName - { - get { return _nisDomainName; } - - set - { - if (value == null) - throw new ArgumentNullException(nameof(NISDomainName)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(NISDomainName), value.Length, "NISDomainName has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(NISDomainName), value.Length, "NISDomainName has to be less than 256 characters long"); - - _nisDomainName = value; - } - } - - private string _nisDomainName; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs index 6270902d..e3395679 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs @@ -8,6 +8,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the name of the client's NIS+ [17] domain. ///
     ///  Code   Len      NIS Client Domain Name
     /// +-----+-----+-----+-----+-----+-----+---
@@ -15,52 +16,30 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+---
     /// 
///
- public class DhcpNetworkInformationServicePlusDomainOption : DhcpOption + public class DhcpNetworkInformationServicePlusDomainOption : DhcpStringOption { - public DhcpNetworkInformationServicePlusDomainOption(string domainName) : base(DhcpOptionCode.NetworkInformationServicePlusDomain) + /// + /// create new DhcpNetworkInformationServicePlusDomainOption + /// + /// NIS Client Domain Name + public DhcpNetworkInformationServicePlusDomainOption(string nisClientDomainName) : base(nisClientDomainName, DhcpOptionCode.NetworkInformationServicePlusDomain) { - DomainName = domainName; } internal static DhcpNetworkInformationServicePlusDomainOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - DhcpNetworkInformationServicePlusDomainOption option = new DhcpNetworkInformationServicePlusDomainOption(Encoding.ASCII.GetString(data.ReadBytes(offset, len))); - offset += option.Length; - return option; + return Read(data, ref offset, p => new Options.DhcpNetworkInformationServicePlusDomainOption(p)); } - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(DomainName)); - } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(DomainName); - } - } + /// + /// RFC 2132. + /// NIS Client Domain Name + /// + public string NisClientDomainName - public string DomainName { - get { return _domainName; } - - set - { - if (value == null) - throw new ArgumentNullException(nameof(DomainName)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(DomainName), value.Length, "DomainName has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(DomainName), value.Length, "DomainName has to be less than 256 characters long"); - - _domainName = value; - } + get { return InternalValue; } + set { InternalValue = value; } } - - private string _domainName; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs index e2bac760..6825f501 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs @@ -9,6 +9,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies a list of IP addresses indicating NIS+ servers + /// available to the client.Servers SHOULD be listed in order of + /// preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +21,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpNetworkInformationServicePlusServersOption : DhcpAddressListOption { - public DhcpNetworkInformationServicePlusServersOption(IList addresses) : base(DhcpOptionCode.NetworkInformationServicePlusServers, addresses) + /// + /// create new DhcpNetworkInformationServicePlusServersOption + /// + /// Addresses + public DhcpNetworkInformationServicePlusServersOption(IList addresses) : base(addresses, DhcpOptionCode.NetworkInformationServicePlusServers) { } internal static DhcpNetworkInformationServicePlusServersOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpNetworkInformationServicePlusServersOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpNetworkInformationServicePlusServersOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs index 9747ff36..83108127 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// The NNTP server option specifies a list of NNTP available to the + /// client.Servers SHOULD be listed in order of preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +20,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpNetworkNewsTransportProtocolServerOption : DhcpAddressListOption { - public DhcpNetworkNewsTransportProtocolServerOption(IList addresses) : base(DhcpOptionCode.NetworkNewsTransportProtocolServer, addresses) + /// + /// create new DhcpNetworkNewsTransportProtocolServerOption + /// + /// Addresses + public DhcpNetworkNewsTransportProtocolServerOption(IList addresses) : base(addresses, DhcpOptionCode.NetworkNewsTransportProtocolServer) { } internal static DhcpNetworkNewsTransportProtocolServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpNetworkNewsTransportProtocolServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new Options.DhcpNetworkNewsTransportProtocolServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs index e20b6a92..71eebabc 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs @@ -9,6 +9,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies a list of IP addresses indicating NTP [18] + /// servers available to the client.Servers SHOULD be listed in order + /// of preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +21,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpNetworkTimeProtocolServersOption : DhcpAddressListOption { - public DhcpNetworkTimeProtocolServersOption(IList addresses) : base(DhcpOptionCode.NetworkTimeProtocolServers, addresses) + /// + /// create new DhcpNetworkTimeProtocolServersOption + /// + /// Addresses + public DhcpNetworkTimeProtocolServersOption(IList addresses) : base(addresses, DhcpOptionCode.NetworkTimeProtocolServers) { } internal static DhcpNetworkTimeProtocolServersOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpNetworkTimeProtocolServersOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new Options.DhcpNetworkTimeProtocolServersOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs index c5fc860e..813a729a 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies whether the client should configure its IP + /// layer to allow forwarding of datagrams with non-local source routes. ///
     ///  Code   Len  Value
     /// +-----+-----+-----+
@@ -16,42 +18,31 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+
     /// 
///
- public class DhcpNonLocalSourceRoutingEnableOption : DhcpOption + public class DhcpNonLocalSourceRoutingEnableOption : DhcpBooleanOption { - public DhcpNonLocalSourceRoutingEnableOption(bool enabled) : base(DhcpOptionCode.NonLocalSourceRoutingEnable) + /// + /// create new DhcpNonLocalSourceRoutingEnableOption + /// + /// Value + public DhcpNonLocalSourceRoutingEnableOption(bool value) : base(value, DhcpOptionCode.NonLocalSourceRoutingEnable) { } internal static DhcpNonLocalSourceRoutingEnableOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP NonLocalSourceRoutingEnable Option has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP NonLocalSourceRoutingEnable Option has to be 0 or 1"); - DhcpNonLocalSourceRoutingEnableOption option = new DhcpNonLocalSourceRoutingEnableOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } + return Read(data, ref offset, p => new DhcpNonLocalSourceRoutingEnableOption(p)); } + /// + /// RFC 2132. + /// Value + /// A value of false means disallow forwarding of such datagrams, and a value of true + /// means allow forwarding. + /// public bool Value { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs index 4316c41f..4aff8de9 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using PcapDotNet.Base; namespace PcapDotNet.Packets.Dhcp.Options { @@ -10,6 +11,7 @@ namespace PcapDotNet.Packets.Dhcp.Options /// RFC 2132. /// Abstract class for all possible Dhcp-Options ///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] public abstract class DhcpOption : IEquatable { /// @@ -33,11 +35,13 @@ public abstract byte Length /// create new Option /// /// Option-Code - public DhcpOption(DhcpOptionCode code) + protected DhcpOption(DhcpOptionCode code) { OptionCode = code; } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] internal static DhcpOption CreateInstance(DataSegment data, ref int offset) { switch ((DhcpOptionCode)data[offset++]) @@ -74,8 +78,8 @@ internal static DhcpOption CreateInstance(DataSegment data, ref int offset) case DhcpOptionCode.CookieServer: return DhcpCookieServerOption.Read(data, ref offset); - case DhcpOptionCode.LPRServer: - return DhcpLPRServerOption.Read(data, ref offset); + case DhcpOptionCode.LprServer: + return DhcpLprServerOption.Read(data, ref offset); case DhcpOptionCode.ImpressServer: return DhcpImpressServerOption.Read(data, ref offset); @@ -120,21 +124,21 @@ internal static DhcpOption CreateInstance(DataSegment data, ref int offset) case DhcpOptionCode.MaximumDatagramReassemblySize: return DhcpMaximumDatagramReassemblySizeOption.Read(data, ref offset); - case DhcpOptionCode.DefaultIPTimeToLive: + case DhcpOptionCode.DefaultIpTimeToLive: return DhcpDefaultIPTimeToLiveOption.Read(data, ref offset); - case DhcpOptionCode.PathMTUAgingTimeout: - return DhcpPathMTUAgingTimeoutOption.Read(data, ref offset); + case DhcpOptionCode.PathMtuAgingTimeout: + return DhcpPathMtuAgingTimeoutOption.Read(data, ref offset); - case DhcpOptionCode.PathMTUPlateauTable: - return DhcpPathMTUPlateauTableOption.Read(data, ref offset); + case DhcpOptionCode.PathMtuPlateauTable: + return DhcpPathMtuPlateauTableOption.Read(data, ref offset); #endregion 4. IP Layer Parameters per Host #region 5. IP Layer Parameters per Interface - case DhcpOptionCode.InterfaceMTU: - return DhcpInterfaceMTUOption.Read(data, ref offset); + case DhcpOptionCode.InterfaceMtu: + return DhcpInterfaceMtuOption.Read(data, ref offset); case DhcpOptionCode.AllSubnetsAreLocal: return DhcpAllSubnetsAreLocalOption.Read(data, ref offset); @@ -164,8 +168,8 @@ internal static DhcpOption CreateInstance(DataSegment data, ref int offset) case DhcpOptionCode.TrailerEncapsulation: return DhcpTrailerEncapsulationOption.Read(data, ref offset); - case DhcpOptionCode.ARPCacheTimeout: - return DhcpARPCacheTimeoutOption.Read(data, ref offset); + case DhcpOptionCode.ArpCacheTimeout: + return DhcpArpCacheTimeoutOption.Read(data, ref offset); case DhcpOptionCode.EthernetEncapsulation: return DhcpEthernetEncapsulationOption.Read(data, ref offset); @@ -174,14 +178,14 @@ internal static DhcpOption CreateInstance(DataSegment data, ref int offset) #region 7. TCP Parameters - case DhcpOptionCode.TCPDefaultTTL: - return DhcpTCPDefaultTTLOption.Read(data, ref offset); + case DhcpOptionCode.TcpDefaultTtl: + return DhcpTcpDefaultTtlOption.Read(data, ref offset); - case DhcpOptionCode.TCPKeepaliveInterval: - return DhcpTCPKeepaliveIntervalOption.Read(data, ref offset); + case DhcpOptionCode.TcpKeepaliveInterval: + return DhcpTcpKeepaliveIntervalOption.Read(data, ref offset); - case DhcpOptionCode.TCPKeepaliveGarbage: - return DhcpTCPKeepaliveGarbageOption.Read(data, ref offset); + case DhcpOptionCode.TcpKeepaliveGarbage: + return DhcpTcpKeepaliveGarbageOption.Read(data, ref offset); #endregion 7. TCP Parameters @@ -199,17 +203,17 @@ internal static DhcpOption CreateInstance(DataSegment data, ref int offset) case DhcpOptionCode.VendorSpecificInformation: return DhcpVendorSpecificInformationOption.Read(data, ref offset); - case DhcpOptionCode.NetBIOSOverTCPIPNameServer: - return DhcpNetBIOSOverTCPIPNameServerOption.Read(data, ref offset); + case DhcpOptionCode.NetBiosOverTcpIpNameServer: + return DhcpNetBiosOverTcpIpNameServerOption.Read(data, ref offset); - case DhcpOptionCode.NetBIOSOverTCPIPDatagramDistributionServer: - return DhcpNetBIOSOverTCPIPDatagramDistributionServerOption.Read(data, ref offset); + case DhcpOptionCode.NetBiosOverTcpIpDatagramDistributionServer: + return DhcpNetBiosOverTcpIpDatagramDistributionServerOption.Read(data, ref offset); - case DhcpOptionCode.NetBIOSOverTCPIPNodeType: - return DhcpNetBIOSOverTCPIPNodeTypeOption.Read(data, ref offset); + case DhcpOptionCode.NetBiosOverTcpIpNodeType: + return DhcpNetBiosOverTcpIpNodeTypeOption.Read(data, ref offset); - case DhcpOptionCode.NetBIOSOverTCPIPScope: - return DhcpNetBIOSOverTCPIPScopeOption.Read(data, ref offset); + case DhcpOptionCode.NetBiosOverTcpIpScope: + return DhcpNetBiosOverTcpIpScopeOption.Read(data, ref offset); case DhcpOptionCode.XWindowSystemFontServer: return DhcpXWindowSystemFontServerOption.Read(data, ref offset); @@ -263,8 +267,8 @@ internal static DhcpOption CreateInstance(DataSegment data, ref int offset) case DhcpOptionCode.OptionOverload: return DhcpOptionOverloadOption.Read(data, ref offset); - case DhcpOptionCode.TFTPServerName: - return DhcpTFTPServerNameOption.Read(data, ref offset); + case DhcpOptionCode.TfptServerName: + return DhcpTFtpServerNameOption.Read(data, ref offset); case DhcpOptionCode.BootfileName: return DhcpBootfileNameOption.Read(data, ref offset); @@ -353,7 +357,7 @@ public override int GetHashCode() int offset = 0; Write(selfData, ref offset); - return selfData.GetHashCode(); + return Sequence.GetHashCode(selfData.Cast().ToArray()); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionCode.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionCode.cs index 93524228..0dc56b6f 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionCode.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionCode.cs @@ -15,219 +15,153 @@ public enum DhcpOptionCode : byte /// /// RFC 2132. - ///
-        /// +-----+
-        /// |  0  |
-        /// +-----+
-        /// 
+ /// The pad option can be used to cause subsequent fields to align on + /// word boundaries. ///
Pad = 0, /// /// RFC 2132. - ///
-        /// +-----+
-        /// | 255 |
-        /// +-----+
-        /// 
+ /// The end option marks the end of valid information in the vendor field. ///
End = 255, /// /// RFC 2132. - ///
-        ///  Code   Len        Subnet Mask
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  1  |  4  |  m1 |  m2 |  m3 |  m4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// The subnet mask option specifies the client's subnet mask as per RFC + /// 950 [5]. + /// If both the subnet mask and the router option are specified in a DHCP + /// reply, the subnet mask option MUST be first. ///
SubnetMask = 1, /// /// RFC 2132. - ///
-        ///  Code   Len        Time Offset
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  1  |  4  |  n1 |  n2 |  n3 |  n4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// The time offset field specifies the offset of the client's subnet in + /// seconds from Coordinated Universal Time(UTC). ///
TimeOffset = 2, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  3  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The router option specifies a list of IP addresses for routers on the + /// client's subnet. Routers SHOULD be listed in order of preference. ///
Router = 3, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  4  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The time server option specifies a list of RFC 868 [6] time servers + /// available to the client.Servers SHOULD be listed in order of + /// preference. ///
TimeServer = 4, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  5  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The name server option specifies a list of IEN 116 [7] name servers + /// available to the client.Servers SHOULD be listed in order of preference. ///
NameServer = 5, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  6  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The domain name server option specifies a list of Domain Name System + /// (STD 13, RFC 1035 [8]) name servers available to the client. Servers + /// SHOULD be listed in order of preference. ///
DomainNameServerServer = 6, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  7  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The log server option specifies a list of MIT-LCS UDP log servers + /// available to the client ///
LogServer = 7, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  8  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The cookie server option specifies a list of RFC 865 [9] cookie + /// servers available to the client. Servers SHOULD be listed in order + /// of preference. ///
CookieServer = 8, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  9  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The LPR server option specifies a list of RFC 1179 [10] line printer + /// servers available to the client. Servers SHOULD be listed in order + /// of preference. ///
- LPRServer = 9, + LprServer = 9, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  10 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The Impress server option specifies a list of Imagen Impress servers + /// available to the client.Servers SHOULD be listed in order of + /// preference. ///
ImpressServer = 10, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  11 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// This option specifies a list of RFC 887 [11] Resource Location + /// servers available to the client.Servers SHOULD be listed in order + /// of preference. ///
ResourceLocationServer = 11, /// /// RFC 2132. - ///
-        ///  Code   Len                 Host Name
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  12 |  n  |  h1 |  h2 |  h3 |  h4 |  h5 |  h6 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// This option specifies the name of the client. The name may or may + /// not be qualified with the local domain name(see section 3.17 for the + /// preferred way to retrieve the domain name). See RFC 1035 for + /// character set restrictions. ///
HostName = 12, /// /// RFC 2132. - ///
-        ///  Code   Len   File Size
-        /// +-----+-----+-----+-----+
-        /// |  13 |  2  |  l1 |  l2 |
-        /// +-----+-----+-----+-----+
-        /// 
+ /// This option specifies the length in 512-octet blocks of the default + /// boot image for the client. ///
BootFileSize = 13, /// /// RFC 2132. - ///
-        ///  Code   Len      Dump File Pathname
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// |  14 |  n  |  n1 |  n2 |  n3 |  n4 | ...
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// This option specifies the path-name of a file to which the client's + /// core image should be dumped in the event the client crashes. ///
MeritDumpFile = 14, /// /// RFC 2132. - ///
-        ///  Code   Len        Domain Name
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// |  15 |  n  |  d1 |  d2 |  d3 |  d4 | ...
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// This option specifies the domain name that client should use when + /// resolving hostnames via the Domain Name System. ///
DomainName = 15, /// /// RFC 2132. - ///
-        ///  Code   Len    Swap Server Address
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  16 |  4  |  a1 |  a2 |  a3 |  a4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// This specifies the IP address of the client's swap server. ///
SwapServer = 16, /// /// RFC 2132. - ///
-        ///  Code   Len      Root Disk Pathname
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// |  17 |  n  |  n1 |  n2 |  n3 |  n4 | ...
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// This option specifies the path-name that contains the client's root + /// disk. ///
RootPath = 17, /// /// RFC 2132. - ///
-        ///  Code   Len      Extensions Pathname
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// |  18 |  n  |  n1 |  n2 |  n3 |  n4 | ...
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// A string to specify a file, retrievable via TFTP, which contains + /// information which can be interpreted in the same way as the 64-octet + /// vendor-extension field within the BOOTP response, with the following + /// exceptions: + /// - the length of the file is unconstrained; + /// - all references to Tag 18 (i.e., instances of the BOOTP Extensions Path field) within the file are ignored. ///
ExtensionsPath = 18, @@ -237,178 +171,117 @@ public enum DhcpOptionCode : byte /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  19 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies whether the client should configure its IP + /// layer for packet forwarding. ///
IPForwardingEnable = 19, /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  20 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies whether the client should configure its IP + /// layer to allow forwarding of datagrams with non-local source routes. ///
NonLocalSourceRoutingEnable = 20, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1                  Mask 1
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
-        /// |  21 |  n  |  a1 |  a2 |  a3 |  a4 |  m1 |  m2 |  m3 |  m4 |
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
-        ///         Address 2                  Mask 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
-        /// |  a1 |  a2 |  a3 |  a4 |  m1 |  m2 |  m3 |  m4 | ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// This option specifies policy filters for non-local source routing. + /// The filters consist of a list of IP addresses and masks which specify + /// destination/mask pairs with which to filter incoming source routes. + /// Any source routed datagram whose next-hop address does not match one + /// of the filters should be discarded by the client. ///
PolicyFilter = 21, /// /// RFC 2132. - ///
-        ///  Code   Len      Size
-        /// +-----+-----+-----+-----+
-        /// |  22 |  2  |  s1 |  s2 |
-        /// +-----+-----+-----+-----+
-        /// 
+ /// This option specifies the maximum size datagram that the client + /// should be prepared to reassemble.unsigned integer. ///
MaximumDatagramReassemblySize = 22, /// - /// RFC 2132 - ///
-        ///  Code   Len   TTL
-        /// +-----+-----+-----+
-        /// |  23 |  1  | ttl |
-        /// +-----+-----+-----+
-        /// 
+ /// RFC 2132. + /// This option specifies the default time-to-live that the client should + /// use on outgoing datagrams. ///
- DefaultIPTimeToLive = 23, + DefaultIpTimeToLive = 23, /// - /// RFC 2132 - ///
-        ///  Code   Len           Timeout
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  24 |  4  |  t1 |  t2 |  t3 |  t4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// RFC 2132. + /// This option specifies the timeout (in seconds) to use when aging Path + /// MTU values discovered by the mechanism defined in RFC 1191 [12]. ///
- PathMTUAgingTimeout = 24, + PathMtuAgingTimeout = 24, /// - /// RFC 2132 - ///
-        ///  Code   Len     Size 1      Size 2
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// |  25 |  n  |  s1 |  s2 |  s1 |  s2 | ...
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// RFC 2132. + /// This option specifies a table of MTU sizes to use when performing + /// Path MTU Discovery as defined in RFC 1191. The table is formatted as + /// a list of 16-bit unsigned integers, ordered from smallest to largest. ///
- PathMTUPlateauTable = 25, + PathMtuPlateauTable = 25, #endregion 4. IP Layer Parameters per Host #region 5. IP Layer Parameters per Interface /// - /// RFC 2132 - ///
-        ///  Code   Len      MTU
-        /// +-----+-----+-----+-----+
-        /// |  26 |  2  |  m1 |  m2 |
-        /// +-----+-----+-----+-----+
-        /// 
+ /// RFC 2132. + /// This option specifies the MTU to use on this interface. ///
- InterfaceMTU = 26, + InterfaceMtu = 26, /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  27 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies whether or not the client may assume that all + /// subnets of the IP network to which the client is connected use the + /// same MTU as the subnet of that network to which the client is + /// directly connected. ///
AllSubnetsAreLocal = 27, /// /// RFC 2132. - ///
-        ///  Code   Len     Broadcast Address
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  28 |  4  |  b1 |  b2 |  b3 |  b4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// This option specifies the broadcast address in use on the client's + /// subnet. ///
BroadcastAddress = 28, /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  29 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies whether or not the client should perform subnet + /// mask discovery using ICMP. ///
PerformMaskDiscovery = 29, /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  30 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies whether or not the client should respond to + /// subnet mask requests using ICMP. ///
MaskSupplier = 30, /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  31 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies whether or not the client should solicit + /// routers using the Router Discovery mechanism defined in RFC 1256. ///
PerformRouterDiscovery = 31, /// /// RFC 2132. - ///
-        ///  Code   Len            Address
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  32 |  4  |  a1 |  a2 |  a3 |  a4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// This option specifies the address to which the client should transmit + /// router solicitation requests. ///
RouterSolicitationAddress = 32, /// /// RFC 2132. - ///
-        ///  Code   Len         Destination 1           Router 1
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
-        /// |  33 |  n  |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 |  r3 |  r4 |
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
-        ///         Destination 2           Router 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
-        /// |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 |  r3 |  r4 | ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// This option specifies a list of static routes that the client should + /// install in its routing cache.If multiple routes to the same + /// destination are specified, they are listed in descending order of + /// priority. ///
StaticRoute = 33, @@ -418,34 +291,22 @@ public enum DhcpOptionCode : byte /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  34 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies whether or not the client should negotiate the + /// use of trailers(RFC 893 [14]) when using the ARP protocol. ///
TrailerEncapsulation = 34, /// - /// RFC 2132 - ///
-        ///  Code   Len           Time
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  35 |  4  |  t1 |  t2 |  t3 |  t4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// RFC 2132. + /// This option specifies the timeout in seconds for ARP cache entries. ///
- ARPCacheTimeout = 35, + ArpCacheTimeout = 35, /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  36 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies whether or not the client should use Ethernet + /// Version 2 (RFC 894 [15]) or IEEE 802.3 (RFC 1042 [16]) encapsulation + /// if the interface is an Ethernet. ///
EthernetEncapsulation = 36, @@ -455,36 +316,25 @@ public enum DhcpOptionCode : byte /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  37 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies the default TTL that the client should use when + /// sending TCP segments. ///
- TCPDefaultTTL = 37, + TcpDefaultTtl = 37, /// /// RFC 2132. - ///
-        ///  Code   Len           Time
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  38 |  4  |  t1 |  t2 |  t3 |  t4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// This option specifies the interval (in seconds) that the client TCP + /// should wait before sending a keepalive message on a TCP connection. ///
- TCPKeepaliveInterval = 38, + TcpKeepaliveInterval = 38, /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  39 |  1  | 0/1 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option specifies the whether or not the client should send TCP + /// keepalive messages with a octet of garbage for compatibility with + /// older implementations. ///
- TCPKeepaliveGarbage = 39, + TcpKeepaliveGarbage = 39, #endregion 7. TCP Parameters @@ -492,232 +342,161 @@ public enum DhcpOptionCode : byte /// /// RFC 2132. - ///
-        ///  Code   Len      NIS Domain Name
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// |  40 |  n  |  n1 |  n2 |  n3 |  n4 | ...
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// This option specifies the name of the client's NIS [17] domain. ///
NetworkInformationServiceDomain = 40, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  41 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// This option specifies a list of IP addresses indicating NIS servers + /// available to the client.Servers SHOULD be listed in order of ///
NetworkInformationServers = 41, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  42 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// This option specifies a list of IP addresses indicating NTP [18] + /// servers available to the client.Servers SHOULD be listed in order + /// of preference. ///
NetworkTimeProtocolServers = 42, /// /// RFC 2132. - ///
-        /// Code   Len   Vendor-specific information
-        /// +-----+-----+-----+-----+---
-        /// |  43 |  n  |  i1 |  i2 | ...
-        /// +-----+-----+-----+-----+---
-        /// 
+ /// This option is used by clients and servers to exchange vendor- + /// specific information. The information is an opaque object of n + /// octets, presumably interpreted by vendor-specific code on the clients + /// and servers. The definition of this information is vendor specific. + /// The vendor is indicated in the vendor class identifier option. + /// Servers not equipped to interpret the vendor-specific information + /// sent by a client MUST ignore it(although it may be reported). + /// Clients which do not receive desired vendor-specific information + /// SHOULD make an attempt to operate without it, although they may do so + /// (and announce they are doing so) in a degraded mode. ///
VendorSpecificInformation = 43, /// /// RFC 2132. - ///
-        ///  Code   Len           Address 1              Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-        /// |  44 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-        /// 
+ /// The NetBIOS name server (NBNS) option specifies a list of RFC 1001/1002 [19] [20] + /// NBNS name servers listed in order of preference. ///
- NetBIOSOverTCPIPNameServer = 44, + NetBiosOverTcpIpNameServer = 44, /// /// RFC 2132. - ///
-        ///  Code   Len           Address 1              Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-        /// |  45 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-        /// 
+ /// The NetBIOS datagram distribution server (NBDD) option specifies a + /// list of RFC 1001/1002 NBDD servers listed in order of preference. ///
- NetBIOSOverTCPIPDatagramDistributionServer = 45, + NetBiosOverTcpIpDatagramDistributionServer = 45, /// /// RFC 2132. - ///
-        ///  Code   Len  Node Type
-        /// +-----+-----+-----------+
-        /// |  46 |  1  |   flags   |
-        /// +-----+-----+-----------+
-        /// 
+ /// The NetBIOS node type option allows NetBIOS over TCP/IP clients which + /// are configurable to be configured as described in RFC 1001/1002. ///
- NetBIOSOverTCPIPNodeType = 46, + NetBiosOverTcpIpNodeType = 46, /// /// RFC 2132. - ///
-        /// Code   Len       NetBIOS Scope
-        /// +-----+-----+-----+-----+-----+-----+----
-        /// |  47 |  n  |  s1 |  s2 |  s3 |  s4 | ...
-        /// +-----+-----+-----+-----+-----+-----+----
-        /// 
+ /// The NetBIOS scope option specifies the NetBIOS over TCP/IP scope + /// parameter for the client as specified in RFC 1001/1002. ///
- NetBIOSOverTCPIPScope = 47, + NetBiosOverTcpIpScope = 47, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
-        /// |  48 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |   ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// This option specifies a list of X Window System [21] Font servers + /// available to the client. Servers SHOULD be listed in order of + /// preference. ///
XWindowSystemFontServer = 48, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
-        /// |  49 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |   ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// This option specifies a list of IP addresses of systems that are + /// running the X Window System Display Manager and are available to the + /// client. ///
XWindowSystemDisplayManager = 49, /// /// RFC 2132. - ///
-        ///  Code   Len      NIS Client Domain Name
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// |  64 |  n  |  n1 |  n2 |  n3 |  n4 | ...
-        /// +-----+-----+-----+-----+-----+-----+---
-        /// 
+ /// This option specifies the name of the client's NIS+ [17] domain. ///
NetworkInformationServicePlusDomain = 64, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// |  65 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// This option specifies a list of IP addresses indicating NIS+ servers + /// available to the client.Servers SHOULD be listed in order of + /// preference. ///
NetworkInformationServicePlusServers = 65, /// /// RFC 2132. - ///
-        ///  Code Len    Home Agent Addresses (zero or more)
-        /// +-----+-----+-----+-----+-----+-----+--
-        /// | 68  |  n  | a1  | a2  | a3  | a4  | ...
-        /// +-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// This option specifies a list of IP addresses indicating mobile IP + /// home agents available to the client. Agents SHOULD be listed in + /// order of preference. ///
MobileIPHomeAgent = 68, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// | 69  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The SMTP server option specifies a list of SMTP servers available to + /// the client. Servers SHOULD be listed in order of preference. ///
SimpleMailTransportProtocolServer = 69, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// | 70  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The POP3 server option specifies a list of POP3 available to the + /// client.Servers SHOULD be listed in order of preference. ///
PostOfficeProtocolServer = 70, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// | 71  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The NNTP server option specifies a list of NNTP available to the + /// client.Servers SHOULD be listed in order of preference. ///
NetworkNewsTransportProtocolServer = 71, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// | 72  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The WWW server option specifies a list of WWW available to the + /// client.Servers SHOULD be listed in order of preference. ///
DefaultWorldWideWebServer = 72, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// | 73  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The Finger server option specifies a list of Finger available to the + /// client.Servers SHOULD be listed in order of preference. ///
DefaultFingerServer = 73, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// | 74  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The IRC server option specifies a list of IRC available to the + /// client.Servers SHOULD be listed in order of preference. ///
DefaultInternetRelayChatServer = 74, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// | 75  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The StreetTalk server option specifies a list of StreetTalk servers + /// available to the client.Servers SHOULD be listed in order of + /// preference. ///
StreetTalkServer = 75, /// /// RFC 2132. - ///
-        ///  Code   Len         Address 1               Address 2
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// | 76  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
-        /// +-----+-----+-----+-----+-----+-----+-----+-----+--
-        /// 
+ /// The StreetTalk Directory Assistance (STDA) server option specifies a + /// list of STDA servers available to the client.Servers SHOULD be + /// listed in order of preference. ///
StreetTalkDirectoryAssistanceServer = 76, @@ -727,155 +506,123 @@ public enum DhcpOptionCode : byte /// /// RFC 2132. - ///
-        ///  Code   Len          Address
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  50 |  4  |  a1 |  a2 |  a3 |  a4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// This option is used in a client request (DHCPDISCOVER) to allow the + /// client to request that a particular IP address be assigned. ///
RequestedIPAddress = 50, /// /// RFC 2132. - ///
-        ///  Code   Len         Lease Time
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  51 |  4  |  t1 |  t2 |  t3 |  t4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// This option is used in a client request (DHCPDISCOVER or DHCPREQUEST) + /// to allow the client to request a lease time for the IP address. In a + /// server reply(DHCPOFFER), a DHCP server uses this option to specify + /// the lease time it is willing to offer. ///
IPAddressLeaseTime = 51, /// /// RFC 2132. - ///
-        ///  Code   Len  Value
-        /// +-----+-----+-----+
-        /// |  52 |  1  |1/2/3|
-        /// +-----+-----+-----+
-        /// 
+ /// This option is used to indicate that the DHCP 'sname' or 'file' + /// fields are being overloaded by using them to carry DHCP options.A + /// DHCP server inserts this option if the returned parameters will + /// exceed the usual space allotted for options. + /// If this option is present, the client interprets the specified + /// additional fields after it concludes interpretation of the standard + /// option fields. ///
OptionOverload = 52, /// /// RFC 2132. - ///
-        ///  Code Len    TFTP server
-        /// +-----+-----+-----+-----+-----+---
-        /// | 66  |  n  |  c1 |  c2 |  c3 | ...
-        /// +-----+-----+-----+-----+-----+---
-        /// 
+ /// This option is used to identify a TFTP server when the 'sname' field + /// in the DHCP header has been used for DHCP options. ///
- TFTPServerName = 66, + TfptServerName = 66, /// /// RFC 2132. - ///
-        ///  Code Len    Bootfile name
-        /// +-----+-----+-----+-----+-----+---
-        /// | 67  |  n  |  c1 |  c2 |  c3 | ...
-        /// +-----+-----+-----+-----+-----+---
-        /// 
+ /// This option is used to identify a bootfile when the 'file' field in + /// the DHCP header has been used for DHCP options. ///
BootfileName = 67, /// /// RFC 2132. - ///
-        ///  Code   Len  Type
-        /// +-----+-----+-----+
-        /// |  53 |  1  | 1-7 |
-        /// +-----+-----+-----+
-        /// 
+ /// This option is used to convey the type of the DHCP message. ///
MessageType = 53, /// /// RFC 2132. - ///
-        ///  Code   Len            Address
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  54 |  4  |  a1 |  a2 |  a3 |  a4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// This option is used in DHCPOFFER and DHCPREQUEST messages, and may + /// optionally be included in the DHCPACK and DHCPNAK messages.DHCP + /// servers include this option in the DHCPOFFER in order to allow the + /// client to distinguish between lease offers. DHCP clients use the + /// contents of the 'server identifier' field as the destination address + /// for any DHCP messages unicast to the DHCP server. DHCP clients also + /// indicate which of several lease offers is being accepted by including + /// this option in a DHCPREQUEST message. ///
ServerIdentifier = 54, /// /// RFC 2132. - ///
-        /// Code   Len   Option Codes
-        /// +-----+-----+-----+-----+---
-        /// |  55 |  n  |  c1 |  c2 | ...
-        /// +-----+-----+-----+-----+---
-        /// 
+ /// This option is used by a DHCP client to request values for specified + /// configuration parameters.The list of requested parameters is + /// specified as n octets, where each octet is a valid DHCP option code + /// as defined in this document. + /// The client MAY list the options in order of preference.The DHCP + /// server is not required to return the options in the requested order, + /// but MUST try to insert the requested options in the order requested + /// by the client. ///
ParameterRequestList = 55, /// /// RFC 2132. - ///
-        ///  Code   Len     Text
-        /// +-----+-----+-----+-----+---
-        /// |  56 |  n  |  c1 |  c2 | ...
-        /// +-----+-----+-----+-----+---
-        /// 
+ /// This option is used by a DHCP server to provide an error message to a + /// DHCP client in a DHCPNAK message in the event of a failure. A client + /// may use this option in a DHCPDECLINE message to indicate the why the + /// client declined the offered parameters. ///
Message = 56, /// /// RFC 2132. - ///
-        ///  Code   Len     Length
-        /// +-----+-----+-----+-----+
-        /// |  57 |  2  |  l1 |  l2 |
-        /// +-----+-----+-----+-----+
-        /// 
+ /// This option specifies the maximum length DHCP message that it is + /// willing to accept. A client may use the maximum DHCP message size option in + /// DHCPDISCOVER or DHCPREQUEST messages, but should not use the option + /// in DHCPDECLINE messages. ///
MaximumDhcpMessageSize = 57, /// - /// RFC 2132 - ///
-        ///  Code   Len         T1 Interval
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  58 |  4  |  t1 |  t2 |  t3 |  t4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// RFC 2132. + /// This option specifies the time interval from address assignment until + /// the client transitions to the RENEWING state. ///
RenewalTimeValue = 58, /// - /// RFC 2132 - ///
-        ///  Code   Len         T1 Interval
-        /// +-----+-----+-----+-----+-----+-----+
-        /// |  5859 |  4  |  t1 |  t2 |  t3 |  t4 |
-        /// +-----+-----+-----+-----+-----+-----+
-        /// 
+ /// RFC 2132. + /// This option specifies the time interval from address assignment until + /// the client transitions to the REBINDING state. ///
RebindingTimeValue = 59, /// /// RFC 2132. - ///
-        ///  Code   Len   Vendor class Identifier
-        /// +-----+-----+-----+-----+---
-        /// |  60 |  n  |  i1 |  i2 | ...
-        /// +-----+-----+-----+-----+---
-        /// 
+ /// This option is used by DHCP clients to optionally identify the vendor + /// type and configuration of a DHCP client. ///
VendorClassidentifier = 60, /// /// RFC 2132. - ///
-        ///  Code   Len   Type  Client-Identifier
-        /// +-----+-----+-----+-----+-----+---
-        /// |  61 |  n  |  t1 |  i1 |  i2 | ...
-        /// +-----+-----+-----+-----+-----+---
-        /// 
+ /// This option is used by DHCP clients to specify their unique + /// identifier.DHCP servers use this value to index their database of + /// address bindings. This value is expected to be unique for all + /// clients in an administrative domain. ///
ClientIdentifier = 61, diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs index 9f1d22bd..d0169984 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs @@ -9,6 +9,13 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option is used to indicate that the DHCP 'sname' or 'file' + /// fields are being overloaded by using them to carry DHCP options.A + /// DHCP server inserts this option if the returned parameters will + /// exceed the usual space allotted for options. + /// If this option is present, the client interprets the specified + /// additional fields after it concludes interpretation of the standard + /// option fields. ///
     ///  Code   Len  Value
     /// +-----+-----+-----+
@@ -18,6 +25,10 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpOptionOverloadOption : DhcpOption { + /// + /// create new DhcpOptionOverloadOption + /// + /// Value public DhcpOptionOverloadOption(OptionOverloadValue value) : base(DhcpOptionCode.OptionOverload) { Value = value; @@ -39,6 +50,9 @@ internal override void Write(byte[] buffer, ref int offset) buffer.Write(ref offset, (byte)Value); } + /// + /// Length of the Dhcp-Option + /// public override byte Length { get @@ -47,23 +61,46 @@ public override byte Length } } + /// + /// RFC 2132. + /// Value + /// public OptionOverloadValue Value { get { return _value; } set { if (!Enum.IsDefined(typeof(OptionOverloadValue), value)) - throw new ArgumentOutOfRangeException(nameof(Value), value, "Not a valid OptionOverloadValue"); + throw new ArgumentOutOfRangeException(nameof(value), value, "Not a valid OptionOverloadValue"); _value = value; } } private OptionOverloadValue _value; + /// + /// RFC 2132. + /// Option Overload Value + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] public enum OptionOverloadValue : byte { + /// + /// RFC 2132. + /// the 'file' field is used to hold options + /// File = 1, + + /// + /// RFC 2132. + /// the 'sname' field is used to hold options + /// SName = 2, + + /// + /// RFC 2132. + /// both fields are used to hold options + /// Both = 3 } } diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs index cebc841e..3a5e2286 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs @@ -7,7 +7,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// The pad option can be used to cause subsequent fields to align on + /// word boundaries. ///
     ///  Code
     /// +-----+
@@ -17,15 +19,23 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpPadOption : DhcpOption { + /// + /// create new PadOption + /// public DhcpPadOption() : base(DhcpOptionCode.Pad) { } + /// + /// Length of the Dhcp-Option + /// public override byte Length { get { return 0; } } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "data")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "offset")] internal static DhcpPadOption Read(DataSegment data, ref int offset) { return new Options.DhcpPadOption(); diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs index ed3146c5..60db9b5f 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs @@ -10,6 +10,14 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option is used by a DHCP client to request values for specified + /// configuration parameters.The list of requested parameters is + /// specified as n octets, where each octet is a valid DHCP option code + /// as defined in this document. + /// The client MAY list the options in order of preference.The DHCP + /// server is not required to return the options in the requested order, + /// but MUST try to insert the requested options in the order requested + /// by the client. ///
     /// Code   Len   Option Codes
     /// +-----+-----+-----+-----+---
@@ -19,13 +27,19 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpParameterRequestListOption : DhcpOption { - public DhcpParameterRequestListOption(IList codes) : base(DhcpOptionCode.ParameterRequestList) + /// + /// create new DhcpParameterRequestListOption + /// + /// Option Codes + public DhcpParameterRequestListOption(IList optionCodes) : base(DhcpOptionCode.ParameterRequestList) { - if (codes == null) - throw new ArgumentNullException(nameof(codes)); - if (codes.Count > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(codes), codes.Count, "The maximum items in codes is 255"); - Codes = new ReadOnlyCollection(codes); + if (optionCodes == null) + throw new ArgumentNullException(nameof(optionCodes)); + if (optionCodes.Count < 1) + throw new ArgumentOutOfRangeException(nameof(optionCodes), optionCodes.Count, "The minimum items in optionCodes is 1"); + if (optionCodes.Count > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(optionCodes), optionCodes.Count, "The maximum items in optionCodes is 255"); + OptionCodes = new ReadOnlyCollection(optionCodes); } internal static DhcpParameterRequestListOption Read(DataSegment data, ref int offset) @@ -42,21 +56,25 @@ internal static DhcpParameterRequestListOption Read(DataSegment data, ref int of internal override void Write(byte[] buffer, ref int offset) { base.Write(buffer, ref offset); - buffer.Write(ref offset, Codes.Select(p => (byte)p)); + buffer.Write(ref offset, OptionCodes.Select(p => (byte)p)); } + /// + /// Length of the Dhcp-Option + /// public override byte Length { get { - if (Codes.Count > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Codes), Codes.Count, "The maximum items in addresses is 255"); - - return (byte)Codes.Count; + return (byte)OptionCodes.Count; } } - public IReadOnlyCollection Codes + /// + /// RFC 2132. + /// Option Codes + /// + public IReadOnlyCollection OptionCodes { get; private set; diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUAgingTimeoutOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUAgingTimeoutOption.cs deleted file mode 100644 index 5af8b517..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUAgingTimeoutOption.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - /// - /// RFC 2132 - ///
-    ///  Code   Len           Timeout
-    /// +-----+-----+-----+-----+-----+-----+
-    /// |  24 |  4  |  t1 |  t2 |  t3 |  t4 |
-    /// +-----+-----+-----+-----+-----+-----+
-    /// 
- ///
- public class DhcpPathMTUAgingTimeoutOption : DhcpOption - { - public DhcpPathMTUAgingTimeoutOption() : base(DhcpOptionCode.PathMTUAgingTimeout) - { - } - - public DhcpPathMTUAgingTimeoutOption(uint timeout) : this() - { - Timeout = timeout; - } - - internal static DhcpPathMTUAgingTimeoutOption Read(DataSegment data, ref int offset) - { - if (data[offset++] != 4) - { - throw new ArgumentException("Length of a DHCP PathMTUAgingTimeout Option has to be 4"); - } - DhcpPathMTUAgingTimeoutOption option = new DhcpPathMTUAgingTimeoutOption(data.ReadUInt(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Timeout, Endianity.Big); - } - - public override byte Length - { - get { return 4; } - } - - public uint Timeout - { - get; - set; - } - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs new file mode 100644 index 00000000..02fc8914 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// This option specifies the timeout (in seconds) to use when aging Path + /// MTU values discovered by the mechanism defined in RFC 1191 [12]. + ///
+    ///  Code   Len           Timeout
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  24 |  4  |  t1 |  t2 |  t3 |  t4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpPathMtuAgingTimeoutOption : DhcpUIntOption + { + /// + /// create new DhcpPathMtuAgingTimeoutOption + /// + /// Timeout + public DhcpPathMtuAgingTimeoutOption(uint timeout) : base(timeout, DhcpOptionCode.PathMtuAgingTimeout) + { + } + + internal static DhcpPathMtuAgingTimeoutOption Read(DataSegment data, ref int offset) + { + return Read(data, ref offset, p => new DhcpPathMtuAgingTimeoutOption(p)); + } + + /// + /// RFC 2132. + /// Timeout + /// + public uint Timeout + { + get { return InternalValue; } + set { InternalValue = value; } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUPlateauTableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs similarity index 63% rename from PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUPlateauTableOption.cs rename to PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs index acb5d885..404b9e89 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMTUPlateauTableOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs @@ -8,7 +8,10 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// This option specifies a table of MTU sizes to use when performing + /// Path MTU Discovery as defined in RFC 1191. The table is formatted as + /// a list of 16-bit unsigned integers, ordered from smallest to largest. ///
     ///  Code   Len     Size 1      Size 2
     /// +-----+-----+-----+-----+-----+-----+---
@@ -16,21 +19,27 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+---
     /// 
///
- public class DhcpPathMTUPlateauTableOption : DhcpOption + public class DhcpPathMtuPlateauTableOption : DhcpOption { internal const int MAX_SIZES = 255 / sizeof(ushort); - public DhcpPathMTUPlateauTableOption(IList sizes) : base(DhcpOptionCode.PathMTUPlateauTable) + /// + /// create new DhcpPathMtuPlateauTableOption + /// + /// Sizes + public DhcpPathMtuPlateauTableOption(IList sizes) : base(DhcpOptionCode.PathMtuPlateauTable) { if (sizes == null) throw new ArgumentNullException(nameof(sizes)); + if (sizes.Count < 1) + throw new ArgumentOutOfRangeException(nameof(sizes), sizes.Count, "The minimum items in sizes is 1"); if (sizes.Count > MAX_SIZES) - throw new ArgumentOutOfRangeException(nameof(sizes), sizes.Count, $"The maximum items in addresses is {MAX_SIZES}"); + throw new ArgumentOutOfRangeException(nameof(sizes), sizes.Count, "The maximum items in addresses is " + MAX_SIZES); Sizes = new ReadOnlyCollection(sizes); } - internal static DhcpPathMTUPlateauTableOption Read(DataSegment data, ref int offset) + internal static DhcpPathMtuPlateauTableOption Read(DataSegment data, ref int offset) { byte len = data[offset++]; if (len % sizeof(ushort) != 0) @@ -42,7 +51,7 @@ internal static DhcpPathMTUPlateauTableOption Read(DataSegment data, ref int off { sizes.Add(data.ReadUShort(offset + i, Endianity.Big)); } - DhcpPathMTUPlateauTableOption option = new DhcpPathMTUPlateauTableOption(sizes); + DhcpPathMtuPlateauTableOption option = new DhcpPathMtuPlateauTableOption(sizes); offset += option.Length; return option; } @@ -56,17 +65,21 @@ internal override void Write(byte[] buffer, ref int offset) } } + /// + /// Length of the Dhcp-Option + /// public override byte Length { get { - if (Sizes.Count > MAX_SIZES) - throw new ArgumentOutOfRangeException(nameof(Sizes), Sizes.Count, $"The maximum items in addresses is {MAX_SIZES}"); - return (byte)(Sizes.Count * sizeof(ushort)); } } + /// + /// RFC 2132. + /// Sizes + /// public IReadOnlyCollection Sizes { get; diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs index 5ab0dcc6..da06641c 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies whether or not the client should perform subnet + /// mask discovery using ICMP. ///
     ///  Code   Len  Value
     /// +-----+-----+-----+
@@ -16,42 +18,31 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+
     /// 
///
- public class DhcpPerformMaskDiscoveryOption : DhcpOption + public class DhcpPerformMaskDiscoveryOption : DhcpBooleanOption { - public DhcpPerformMaskDiscoveryOption(bool enabled) : base(DhcpOptionCode.PerformMaskDiscovery) + /// + /// create new DhcpPerformMaskDiscoveryOption + /// + /// Value + public DhcpPerformMaskDiscoveryOption(bool value) : base(value, DhcpOptionCode.PerformMaskDiscovery) { } internal static DhcpPerformMaskDiscoveryOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP PerformMaskDiscovery Option has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP PerformMaskDiscovery Option has to be 0 or 1"); - DhcpPerformMaskDiscoveryOption option = new DhcpPerformMaskDiscoveryOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } + return Read(data, ref offset, p => new DhcpPerformMaskDiscoveryOption(p)); } + /// + /// RFC 2132. + /// A value of false indicates that the client + /// should not perform mask discovery. A value of true means that the + /// client should perform mask discovery. + /// public bool Value { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs index 6fb984a7..8efa0c79 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies whether or not the client should solicit + /// routers using the Router Discovery mechanism defined in RFC 1256. ///
     ///  Code   Len  Value
     /// +-----+-----+-----+
@@ -16,42 +18,31 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+
     /// 
///
- public class DhcpPerformRouterDiscoveryOption : DhcpOption + public class DhcpPerformRouterDiscoveryOption : DhcpBooleanOption { - public DhcpPerformRouterDiscoveryOption(bool enabled) : base(DhcpOptionCode.PerformRouterDiscovery) + /// + /// create new DhcpPerformRouterDiscoveryOption + /// + /// Value + public DhcpPerformRouterDiscoveryOption(bool value) : base(value, DhcpOptionCode.PerformRouterDiscovery) { } internal static DhcpPerformRouterDiscoveryOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP PerformRouterDiscovery Option has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP PerformRouterDiscovery Option has to be 0 or 1"); - DhcpPerformRouterDiscoveryOption option = new DhcpPerformRouterDiscoveryOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } + return Read(data, ref offset, p => new DhcpPerformRouterDiscoveryOption(p)); } + /// + /// RFC 2132. + /// A value of false indicates that the client should not perform + /// router discovery. A value of true means that the client should perform + /// router discovery. + /// public bool Value { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs index da6d3273..95b9dac9 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs @@ -10,6 +10,11 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies policy filters for non-local source routing. + /// The filters consist of a list of IP addresses and masks which specify + /// destination/mask pairs with which to filter incoming source routes. + /// Any source routed datagram whose next-hop address does not match one + /// of the filters should be discarded by the client. ///
     ///  Code   Len         Address 1                  Mask 1
     /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -25,12 +30,18 @@ public class DhcpPolicyFilterOption : DhcpOption
     {
         internal const int MAX_FILTERS = 255 / IpV4AddressWithMask.SizeOf;
 
+        /// 
+        /// create new DhcpPolicyFilterOption
+        /// 
+        /// Filters
         public DhcpPolicyFilterOption(IList filters) : base(DhcpOptionCode.PolicyFilter)
         {
             if (filters == null)
                 throw new ArgumentNullException(nameof(filters));
+            if (filters.Count < 1)
+                throw new ArgumentOutOfRangeException(nameof(filters), filters.Count, "The minimum items in filters is 1");
             if (filters.Count > MAX_FILTERS)
-                throw new ArgumentOutOfRangeException(nameof(filters), filters.Count, $"The maximum items in filters is {MAX_FILTERS}");
+                throw new ArgumentOutOfRangeException(nameof(filters), filters.Count, "The maximum items in filters is " + MAX_FILTERS);
 
             Filters = new ReadOnlyCollection(filters);
         }
@@ -39,7 +50,7 @@ internal static DhcpPolicyFilterOption Read(DataSegment data, ref int offset)
         {
             byte length = data[offset++];
             if (length % 8 != 0)
-                throw new ArgumentOutOfRangeException(nameof(length), length, "length has to be a multiple of 8");
+                throw new ArgumentException("length has to be a multiple of 8");
             IList addresses = DhcpAddressListOption.GetAddresses(data, length, ref offset);
 
             List filters = new List();
@@ -60,30 +71,39 @@ internal override void Write(byte[] buffer, ref int offset)
             }
         }
 
+        /// 
+        /// Length of the Dhcp-Option
+        /// 
         public override byte Length
         {
             get
             {
-                if (Filters.Count > MAX_FILTERS)
-                    throw new ArgumentOutOfRangeException(nameof(Filters), Filters.Count, $"The maximum items in Filter is {MAX_FILTERS}");
-
                 return (byte)(Filters.Count * IpV4AddressWithMask.SizeOf);
             }
         }
 
+        /// 
+        /// Filters
+        /// 
         public IReadOnlyCollection Filters
         {
             get;
             private set;
         }
 
-        public struct IpV4AddressWithMask
+        /// 
+        /// Represents and IpV4Address with Mask
+        /// 
+        public struct IpV4AddressWithMask : IEquatable
         {
             /// 
             /// The number of bytes the IpV4AddressWithMask take.
             /// 
             public const int SizeOf = IpV4Address.SizeOf + IpV4Address.SizeOf;
 
+            /// 
+            /// Address
+            /// 
             public IpV4Address Address
 
             {
@@ -91,17 +111,81 @@ public IpV4Address Address
                 private set;
             }
 
+            /// 
+            /// Mask
+            /// 
             public IpV4Address Mask
             {
                 get;
                 private set;
             }
 
+            /// 
+            /// create new IpV4AddressWithMask
+            /// 
+            /// Address
+            /// Mask
             public IpV4AddressWithMask(IpV4Address address, IpV4Address mask)
             {
                 Address = address;
                 Mask = mask;
             }
+
+            /// 
+            /// Determines whether the specified object is equal to the current object.
+            /// 
+            /// The object to compare with the current object.
+            /// true if the specified object is equal to the current object; otherwise, false.
+            public override bool Equals(object obj)
+            {
+                if (obj is IpV4AddressWithMask)
+                {
+                    return Equals((IpV4AddressWithMask)obj);
+                }
+                return false;
+            }
+
+            /// 
+            /// Determines whether the IpV4AddressWithMask is equal to the current IpV4AddressWithMask.
+            /// 
+            /// The object to compare with the current object.
+            /// true if the specified object is equal to the current object; otherwise, false.
+            public bool Equals(IpV4AddressWithMask other)
+            {
+                return object.Equals(Address, other.Address) &&
+                    object.Equals(Mask, other.Mask);
+            }
+
+            /// 
+            /// Returns the hash code for this instance.
+            /// 
+            /// A 32-bit signed integer hash code.
+            public override int GetHashCode()
+            {
+                return Address.GetHashCode() ^ Mask.GetHashCode();
+            }
+
+            /// 
+            /// Determines whether the IpV4AddressWithMask is equal to the current IpV4AddressWithMask.
+            /// 
+            /// left IpV4AddressWithMask
+            /// right IpV4AddressWithMask
+            /// 
+            public static bool operator ==(IpV4AddressWithMask left, IpV4AddressWithMask right)
+            {
+                return Object.Equals(left, right);
+            }
+
+            /// 
+            /// Determines whether the IpV4AddressWithMask is not equal to the current IpV4AddressWithMask.
+            /// 
+            /// left IpV4AddressWithMask
+            /// right IpV4AddressWithMask
+            /// 
+            public static bool operator !=(IpV4AddressWithMask left, IpV4AddressWithMask right)
+            {
+                return !Object.Equals(left, right);
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs
index e8bcbd21..2aaf55ab 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs
@@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options
 {
     /// 
     /// RFC 2132.
+    /// The POP3 server option specifies a list of POP3 available to the
+    /// client.Servers SHOULD be listed in order of preference.
     /// 
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +20,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpPostOfficeProtocolServerOption : DhcpAddressListOption { - public DhcpPostOfficeProtocolServerOption(IList addresses) : base(DhcpOptionCode.PostOfficeProtocolServer, addresses) + /// + /// create new DhcpPostOfficeProtocolServerOption + /// + /// + public DhcpPostOfficeProtocolServerOption(IList addresses) : base(addresses, DhcpOptionCode.PostOfficeProtocolServer) { } internal static DhcpPostOfficeProtocolServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpPostOfficeProtocolServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpPostOfficeProtocolServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs index 0b2ea67f..2c8b3512 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs @@ -7,47 +7,39 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// This option specifies the time interval from address assignment until + /// the client transitions to the REBINDING state. ///
-    ///  Code   Len         T1 Interval
+    ///  Code   Len         T2 Interval
     /// +-----+-----+-----+-----+-----+-----+
     /// |  59 |  4  |  t1 |  t2 |  t3 |  t4 |
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpRebindingTimeValueOption : DhcpOption + public class DhcpRebindingTimeValueOption : DhcpUIntOption { - public DhcpRebindingTimeValueOption(uint interval) : base(DhcpOptionCode.RebindingTimeValue) + /// + /// create new DhcpRebindingTimeValueOption + /// + /// T1 Interval + public DhcpRebindingTimeValueOption(uint t2Interval) : base(t2Interval, DhcpOptionCode.RebindingTimeValue) { - Interval = interval; } internal static DhcpRebindingTimeValueOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 4) - { - throw new ArgumentException("Length of a DHCP RebindingTimeValue Option has to be 4"); - } - DhcpRebindingTimeValueOption option = new DhcpRebindingTimeValueOption(data.ReadUInt(offset, Endianity.Big)); - offset += option.Length; - return option; + return Read(data, ref offset, p => new Options.DhcpRebindingTimeValueOption(p)); } - internal override void Write(byte[] buffer, ref int offset) + /// + /// RFC 2132. + /// T2 Interval + /// + public uint T2Interval { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Interval, Endianity.Big); - } - - public override byte Length - { - get { return 4; } - } - - public uint Interval - { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs index 20231190..86427bc3 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs @@ -7,7 +7,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// This option specifies the time interval from address assignment until + /// the client transitions to the RENEWING state. ///
     ///  Code   Len         T1 Interval
     /// +-----+-----+-----+-----+-----+-----+
@@ -15,39 +17,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpRenewalTimeValueOption : DhcpOption + public class DhcpRenewalTimeValueOption : DhcpUIntOption { - public DhcpRenewalTimeValueOption(uint interval) : base(DhcpOptionCode.RenewalTimeValue) + /// + /// DhcpRenewalTimeValueOption + /// + /// + public DhcpRenewalTimeValueOption(uint t1Interval) : base(t1Interval, DhcpOptionCode.RenewalTimeValue) { - Interval = interval; } internal static DhcpRenewalTimeValueOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 4) - { - throw new ArgumentException("Length of a DHCP RenewalTimeValue Option has to be 4"); - } - DhcpRenewalTimeValueOption option = new DhcpRenewalTimeValueOption(data.ReadUInt(offset, Endianity.Big)); - offset += option.Length; - return option; + return Read(data, ref offset, p => new DhcpRenewalTimeValueOption(p)); } - internal override void Write(byte[] buffer, ref int offset) + /// + /// RFC 2132. + /// T1 Interval + /// + public uint T1Interval { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Interval, Endianity.Big); - } - - public override byte Length - { - get { return 4; } - } - - public uint Interval - { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs index a2032d9d..4d6b0e82 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs @@ -8,7 +8,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// This option is used in a client request (DHCPDISCOVER) to allow the + /// client to request that a particular IP address be assigned. ///
     ///  Code   Len          Address
     /// +-----+-----+-----+-----+-----+-----+
@@ -16,37 +18,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpRequestedIPAddressOption : DhcpOption + public class DhcpRequestedIPAddressOption : DhcpSingleAddressOption { - public DhcpRequestedIPAddressOption(IpV4Address address) : base(DhcpOptionCode.RequestedIPAddress) + /// + /// create new DhcpRequestedIPAddressOption + /// + /// Address + public DhcpRequestedIPAddressOption(IpV4Address address) : base(address, DhcpOptionCode.RequestedIPAddress) { - Address = address; } internal static DhcpRequestedIPAddressOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 4) - throw new ArgumentException("Length of a DHCP RequestedIPAddressOption has to be 4"); - DhcpRequestedIPAddressOption option = new DhcpRequestedIPAddressOption(data.ReadIpV4Address(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Address, Endianity.Big); - } - - public override byte Length - { - get { return 4; } + return Read(data, ref offset, p => new Options.DhcpRequestedIPAddressOption(p)); } + /// + /// RFC 2132. + /// Address + /// public IpV4Address Address { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs index 63e726ea..de319625 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs @@ -7,16 +7,31 @@ namespace PcapDotNet.Packets.Dhcp.Options { + /// + /// RFC 2132. + /// This option specifies a list of RFC 887 [11] Resource Location + /// servers available to the client.Servers SHOULD be listed in order + /// of preference. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  11 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
public class DhcpResourceLocationServerOption : DhcpAddressListOption { - public DhcpResourceLocationServerOption(IList addresses) : base(DhcpOptionCode.ResourceLocationServer, addresses) + /// + /// create new DhcpResourceLocationServerOption + /// + /// Addresses + public DhcpResourceLocationServerOption(IList addresses) : base(addresses, DhcpOptionCode.ResourceLocationServer) { } internal static DhcpResourceLocationServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpResourceLocationServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new Options.DhcpResourceLocationServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs index 4f30e271..9a4e8b91 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs @@ -8,6 +8,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the path-name that contains the client's root + /// disk. ///
     ///  Code   Len      Root Disk Pathname
     /// +-----+-----+-----+-----+-----+-----+---
@@ -15,52 +17,31 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+---
     /// 
///
- public class DhcpRootPathOption : DhcpOption + public class DhcpRootPathOption : DhcpStringOption { - public DhcpRootPathOption(string rootPath) : base(DhcpOptionCode.RootPath) + /// + /// create new DhcpRootPathOption + /// + /// Root Disk Pathname + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] + public DhcpRootPathOption(string rootDiskPathname) : base(rootDiskPathname, DhcpOptionCode.RootPath) { - RootPath = rootPath; } internal static DhcpRootPathOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - string hostName = Encoding.ASCII.GetString(data.ReadBytes(offset, len)); - DhcpRootPathOption option = new DhcpRootPathOption(hostName); - offset += option.Length; - return option; + return Read(data, ref offset, p => new DhcpRootPathOption(p)); } - internal override void Write(byte[] buffer, ref int offset) + /// + /// RFC 2132. + /// Root Disk Pathname + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] + public string RootDiskPathname { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(RootPath)); + get { return InternalValue; } + set { InternalValue = value; } } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(RootPath); - } - } - - public string RootPath - { - get { return _rootPath; } - set - { - if (value == null) - throw new ArgumentNullException(nameof(RootPath)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(RootPath), value.Length, "RootPath has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(RootPath), value.Length, "RootPath has to be less than 256 characters long"); - - _rootPath = value; - } - } - - private string _rootPath; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs index c8b0b672..8bd42926 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs @@ -7,16 +7,30 @@ namespace PcapDotNet.Packets.Dhcp.Options { + /// + /// RFC 2132. + /// The router option specifies a list of IP addresses for routers on the + /// client's subnet. Routers SHOULD be listed in order of preference. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  3  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
public class DhcpRouterOption : DhcpAddressListOption { - public DhcpRouterOption(IList addresses) : base(DhcpOptionCode.Router, addresses) + /// + /// create new DhcpRouterOption + /// + /// Addresses + public DhcpRouterOption(IList addresses) : base(addresses, DhcpOptionCode.Router) { } internal static DhcpRouterOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpRouterOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpRouterOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs index 9a74ce39..845c11cb 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies the address to which the client should transmit + /// router solicitation requests. ///
     ///  Code   Len            Address
     /// +-----+-----+-----+-----+-----+-----+
@@ -16,37 +18,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpRouterSolicitationAddressOption : DhcpOption + public class DhcpRouterSolicitationAddressOption : DhcpSingleAddressOption { - public DhcpRouterSolicitationAddressOption(IpV4Address address) : base(DhcpOptionCode.RouterSolicitationAddress) + /// + /// create new DhcpRouterSolicitationAddressOption + /// + /// Address + public DhcpRouterSolicitationAddressOption(IpV4Address address) : base(address, DhcpOptionCode.RouterSolicitationAddress) { - Address = address; } internal static DhcpRouterSolicitationAddressOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 4) - throw new ArgumentException("Length of a DHCP RouterSolicitationAddress Option has to be 4"); - DhcpRouterSolicitationAddressOption option = new DhcpRouterSolicitationAddressOption(data.ReadIpV4Address(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Address, Endianity.Big); - } - - public override byte Length - { - get { return 4; } + return Read(data, ref offset, p => new DhcpRouterSolicitationAddressOption(p)); } + /// + /// RFC 2132. + /// Address + /// public IpV4Address Address { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs index d47ce028..9bb04727 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs @@ -8,7 +8,16 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// This option is used in DHCPOFFER and DHCPREQUEST messages, and may + /// optionally be included in the DHCPACK and DHCPNAK messages.DHCP + /// servers include this option in the DHCPOFFER in order to allow the + /// client to distinguish between lease offers. DHCP clients use the + /// contents of the 'server identifier' field as the destination address + /// for any DHCP messages unicast to the DHCP server. DHCP clients also + /// indicate which of several lease offers is being accepted by including + /// this option in a DHCPREQUEST message. + /// The identifier is the IP address of the selected server. ///
     ///  Code   Len             Address
     /// +-----+-----+-----+-----+-----+-----+
@@ -16,37 +25,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpServerIdentifierOption : DhcpOption + public class DhcpServerIdentifierOption : DhcpSingleAddressOption { - public DhcpServerIdentifierOption(IpV4Address address) : base(DhcpOptionCode.ServerIdentifier) + /// + /// create new DhcpServerIdentifierOption + /// + /// Address + public DhcpServerIdentifierOption(IpV4Address address) : base(address, DhcpOptionCode.ServerIdentifier) { - Address = address; } internal static DhcpServerIdentifierOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 4) - throw new ArgumentException("Length of a DHCP ServerIdentifier Option has to be 4"); - DhcpServerIdentifierOption option = new DhcpServerIdentifierOption(data.ReadIpV4Address(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Address, Endianity.Big); - } - - public override byte Length - { - get { return 4; } + return Read(data, ref offset, p => new DhcpServerIdentifierOption(p)); } + /// + /// RFC 2132 + /// Address + /// public IpV4Address Address { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs index 148aad20..5093fc53 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// The SMTP server option specifies a list of SMTP servers available to + /// the client. Servers SHOULD be listed in order of preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +20,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpSimpleMailTransportProtocolServerOption : DhcpAddressListOption { - public DhcpSimpleMailTransportProtocolServerOption(IList addresses) : base(DhcpOptionCode.SimpleMailTransportProtocolServer, addresses) + /// + /// create new DhcpSimpleMailTransportProtocolServerOption + /// + /// Addresses + public DhcpSimpleMailTransportProtocolServerOption(IList addresses) : base(addresses, DhcpOptionCode.SimpleMailTransportProtocolServer) { } internal static DhcpSimpleMailTransportProtocolServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpSimpleMailTransportProtocolServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpSimpleMailTransportProtocolServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSingleAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSingleAddressOption.cs new file mode 100644 index 00000000..d631fce2 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSingleAddressOption.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// Abstract class for all Dhcp-Options with a single Addresses + /// + public abstract class DhcpSingleAddressOption : DhcpOption + { + internal DhcpSingleAddressOption(IpV4Address address, DhcpOptionCode code) : base(code) + { + InternalValue = address; + } + + internal static T Read(DataSegment data, ref int offset, Func ctor) where T : DhcpSingleAddressOption + { + if (ctor == null) + throw new ArgumentNullException(nameof(ctor)); + byte len = data[offset++]; + if (len != IpV4Address.SizeOf) + throw new ArgumentException("Length of a DHCP SingleAddress Option has to be 4"); + T option = ctor(data.ReadIpV4Address(offset, Endianity.Big)); + offset += IpV4Address.SizeOf; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, InternalValue, Endianity.Big); + } + + /// + /// RFC 2132. + /// Value of Length-Field + /// + public override byte Length + { + get { return IpV4Address.SizeOf; } + } + + /// + /// The real value of the SingleAddressOption + /// + protected IpV4Address InternalValue + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs index e1a12714..1c1c37c1 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs @@ -8,16 +8,39 @@ namespace PcapDotNet.Packets.Dhcp.Options { + /// + /// RFC 2132. + /// This option specifies a list of static routes that the client should + /// install in its routing cache.If multiple routes to the same + /// destination are specified, they are listed in descending order of + /// priority. + ///
+    ///  Code   Len         Destination 1           Router 1
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+    /// |  33 |  n  |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 |  r3 |  r4 |
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+    ///         Destination 2           Router 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+    /// |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 |  r3 |  r4 | ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+---
+    /// 
+ ///
public class DhcpStaticRouteOption : DhcpOption { internal const int MAX_ROUTES = 255 / 8; + /// + /// create new DhcpStaticRouteOption + /// + /// Routes public DhcpStaticRouteOption(IList routes) : base(DhcpOptionCode.StaticRoute) { if (routes == null) throw new ArgumentNullException(nameof(routes)); + if (routes.Count < 1) + throw new ArgumentOutOfRangeException(nameof(routes), routes.Count, "The minimum items in routes is 1"); if (routes.Count > MAX_ROUTES) - throw new ArgumentOutOfRangeException(nameof(routes), routes.Count, $"The maximum items in routes is {MAX_ROUTES}"); + throw new ArgumentOutOfRangeException(nameof(routes), routes.Count, "The maximum items in routes is " + MAX_ROUTES); Routes = new ReadOnlyCollection(routes); } @@ -26,7 +49,7 @@ internal static DhcpStaticRouteOption Read(DataSegment data, ref int offset) { byte length = data[offset++]; if (length % 8 != 0) - throw new ArgumentOutOfRangeException(nameof(length), length, "length has to be a multiple of 8"); + throw new ArgumentException("length has to be a multiple of 8"); IList addresses = DhcpAddressListOption.GetAddresses(data, length, ref offset); List routes = new List(); @@ -47,25 +70,39 @@ internal override void Write(byte[] buffer, ref int offset) } } + /// + /// Length of the Dhcp-Option + /// public override byte Length { get { - if (Routes.Count > MAX_ROUTES) - throw new ArgumentOutOfRangeException(nameof(Routes), Routes.Count, $"The maximum items in Routes is {MAX_ROUTES}"); - return (byte)(Routes.Count * 8); } } + /// + /// Routes + /// public IReadOnlyCollection Routes { get; private set; } - public struct IpV4AddressRoute + /// + /// Mapping between Ipv$Address and Route Address + /// + public struct IpV4AddressRoute : IEquatable { + /// + /// The number of bytes the IpV4AddressRoute take. + /// + public const int SizeOf = IpV4Address.SizeOf + IpV4Address.SizeOf; + + /// + /// Destination Address + /// public IpV4Address Destination { @@ -73,17 +110,81 @@ public IpV4Address Destination private set; } + /// + /// Router-IP + /// public IpV4Address Router { get; private set; } + /// + /// create new IpV4AddressRoute + /// + /// Destination IP + /// Router IP public IpV4AddressRoute(IpV4Address destination, IpV4Address router) { Destination = destination; Router = router; } + + /// + /// Determines whether the specified object is equal to the current object. + /// + /// The object to compare with the current object. + /// true if the specified object is equal to the current object; otherwise, false. + public override bool Equals(object obj) + { + if (obj is IpV4AddressRoute) + { + return Equals((IpV4AddressRoute)obj); + } + return false; + } + + /// + /// Determines whether the IpV4AddressWithMask is equal to the current IpV4AddressWithMask. + /// + /// The object to compare with the current object. + /// true if the specified object is equal to the current object; otherwise, false. + public bool Equals(IpV4AddressRoute other) + { + return object.Equals(Destination, other.Destination) && + object.Equals(Router, other.Router); + } + + /// + /// Returns the hash code for this instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return Destination.GetHashCode() ^ Router.GetHashCode(); + } + + /// + /// Determines whether the IpV4AddressWithMask is equal to the current IpV4AddressWithMask. + /// + /// left IpV4AddressWithMask + /// right IpV4AddressWithMask + /// + public static bool operator ==(IpV4AddressRoute left, IpV4AddressRoute right) + { + return Object.Equals(left, right); + } + + /// + /// Determines whether the IpV4AddressWithMask is not equal to the current IpV4AddressWithMask. + /// + /// left IpV4AddressWithMask + /// right IpV4AddressWithMask + /// + public static bool operator !=(IpV4AddressRoute left, IpV4AddressRoute right) + { + return !Object.Equals(left, right); + } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs index 7afc70c9..b0d54f67 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs @@ -9,6 +9,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// The StreetTalk Directory Assistance (STDA) server option specifies a + /// list of STDA servers available to the client.Servers SHOULD be + /// listed in order of preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +21,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpStreetTalkDirectoryAssistanceServerOption : DhcpAddressListOption { - public DhcpStreetTalkDirectoryAssistanceServerOption(IList addresses) : base(DhcpOptionCode.StreetTalkDirectoryAssistanceServer, addresses) + /// + /// create new DhcpStreetTalkDirectoryAssistanceServerOption + /// + /// Addresses + public DhcpStreetTalkDirectoryAssistanceServerOption(IList addresses) : base(addresses, DhcpOptionCode.StreetTalkDirectoryAssistanceServer) { } internal static DhcpStreetTalkDirectoryAssistanceServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpStreetTalkDirectoryAssistanceServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new Options.DhcpStreetTalkDirectoryAssistanceServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs index 79dec583..27e8877b 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs @@ -9,6 +9,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// The StreetTalk server option specifies a list of StreetTalk servers + /// available to the client.Servers SHOULD be listed in order of + /// preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+--
@@ -18,14 +21,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpStreetTalkServerOption : DhcpAddressListOption { - public DhcpStreetTalkServerOption(IList addresses) : base(DhcpOptionCode.StreetTalkServer, addresses) + /// + /// create new DhcpStreetTalkServerOption + /// + /// Addresses + public DhcpStreetTalkServerOption(IList addresses) : base(addresses, DhcpOptionCode.StreetTalkServer) { } internal static DhcpStreetTalkServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpStreetTalkServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpStreetTalkServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStringOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStringOption.cs new file mode 100644 index 00000000..efd498be --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStringOption.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// + /// + public abstract class DhcpStringOption : DhcpOption + { + internal DhcpStringOption(string value, DhcpOptionCode code) : base(code) + { + InternalValue = value; + } + + internal static T Read(DataSegment data, ref int offset, Func ctor) where T : DhcpStringOption + { + byte len = data[offset++]; + T option = ctor(Encoding.ASCII.GetString(data.ReadBytes(offset, len))); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, Encoding.ASCII.GetBytes(InternalValue)); + } + + /// + /// RFC 2132. + /// Value of Length-Field + /// + public override byte Length + { + get + { + return (byte)Encoding.ASCII.GetByteCount(InternalValue); + } + } + + /// + /// The real value of the StringOption + /// + protected string InternalValue + { + get { return _value; } + + set + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + if (value.Length < 1) + throw new ArgumentOutOfRangeException(nameof(value), value.Length, "Value has to be at least 1 characters long"); + if (value.Length >= byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(value), value.Length, "Value has to be less than 255 characters long"); + + _value = value; + } + } + + private string _value; + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs index 79fe7c8b..8558231e 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs @@ -8,7 +8,11 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// The subnet mask option specifies the client's subnet mask as per RFC + /// 950 [5]. + /// If both the subnet mask and the router option are specified in a DHCP + /// reply, the subnet mask option MUST be first. ///
     ///  Code   Len        Subnet Mask
     /// +-----+-----+-----+-----+-----+-----+
@@ -16,37 +20,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpSubnetMaskOption : DhcpOption + public class DhcpSubnetMaskOption : DhcpSingleAddressOption { - public DhcpSubnetMaskOption(IpV4Address subnetMask) : base(DhcpOptionCode.SubnetMask) + /// + /// create new DhcpSubnetMaskOption + /// + /// Subnet Mask> + public DhcpSubnetMaskOption(IpV4Address subnetMask) : base(subnetMask, DhcpOptionCode.SubnetMask) { - SubnetMask = subnetMask; } internal static DhcpSubnetMaskOption Read(DataSegment data, ref int offset) { - if (data[offset++] != IpV4Address.SizeOf) - throw new ArgumentException("Length of a DHCP SubnetMask Option has to be 4"); - DhcpSubnetMaskOption option = new DhcpSubnetMaskOption(data.ReadIpV4Address(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, SubnetMask, Endianity.Big); - } - - public override byte Length - { - get { return IpV4Address.SizeOf; } + return Read(data, ref offset, p => new Options.DhcpSubnetMaskOption(p)); } + /// + /// RFC 2132. + /// Subnet Mask + /// public IpV4Address SubnetMask { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs index 162877d8..1484af00 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs @@ -9,6 +9,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This specifies the IP address of the client's swap server. ///
     ///  Code   Len    Swap Server Address
     /// +-----+-----+-----+-----+-----+-----+
@@ -16,37 +17,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpSwapServerOption : DhcpOption + public class DhcpSwapServerOption : DhcpSingleAddressOption { - public DhcpSwapServerOption(IpV4Address swapServer) : base(DhcpOptionCode.SwapServer) + /// + /// create new DhcpSwapServerOption + /// + /// Swap Server Address + public DhcpSwapServerOption(IpV4Address swapServerAddress) : base(swapServerAddress, DhcpOptionCode.SwapServer) { - SwapServer = swapServer; } internal static DhcpSwapServerOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 4) - throw new ArgumentException("Length of a DHCP SwapServer Option has to be 4"); - DhcpSwapServerOption option = new DhcpSwapServerOption(data.ReadIpV4Address(offset, Endianity.Big)); - offset += option.Length; - return option; + return Read(data, ref offset, p => new DhcpSwapServerOption(p)); } - internal override void Write(byte[] buffer, ref int offset) + /// + /// RFC 2132. + /// Swap Server Address + /// + public IpV4Address SwapServerAddress { - base.Write(buffer, ref offset); - buffer.Write(ref offset, SwapServer, Endianity.Big); - } - - public override byte Length - { - get { return 4; } - } - - public IpV4Address SwapServer - { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPDefaultTTLOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPDefaultTTLOption.cs deleted file mode 100644 index b723197e..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPDefaultTTLOption.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using PcapDotNet.Packets.IpV4; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - /// - /// RFC 2132. - ///
-    ///  Code   Len  Value
-    /// +-----+-----+-----+
-    /// |  37 |  1  | 0/1 |
-    /// +-----+-----+-----+
-    /// 
- ///
- public class DhcpTCPDefaultTTLOption : DhcpOption - { - public DhcpTCPDefaultTTLOption(bool enabled) : base(DhcpOptionCode.TCPDefaultTTL) - { - Value = enabled; - } - - internal static DhcpTCPDefaultTTLOption Read(DataSegment data, ref int offset) - { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP TCPDefaultTTL Option has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP TCPDefaultTTL Option has to be 0 or 1"); - DhcpTCPDefaultTTLOption option = new DhcpTCPDefaultTTLOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } - } - - public bool Value - { - get; - set; - } - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveGarbageOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveGarbageOption.cs deleted file mode 100644 index a533252f..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveGarbageOption.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using PcapDotNet.Packets.IpV4; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - /// - /// RFC 2132. - ///
-    ///  Code   Len  Value
-    /// +-----+-----+-----+
-    /// |  39 |  1  | 0/1 |
-    /// +-----+-----+-----+
-    /// 
- ///
- public class DhcpTCPKeepaliveGarbageOption : DhcpOption - { - public DhcpTCPKeepaliveGarbageOption(bool enabled) : base(DhcpOptionCode.TCPKeepaliveGarbage) - { - Value = enabled; - } - - internal static DhcpTCPKeepaliveGarbageOption Read(DataSegment data, ref int offset) - { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP TCPKeepaliveGarbage Option has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP TCPKeepaliveGarbage Option has to be 0 or 1"); - DhcpTCPKeepaliveGarbageOption option = new DhcpTCPKeepaliveGarbageOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } - } - - public bool Value - { - get; - set; - } - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveIntervalOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveIntervalOption.cs deleted file mode 100644 index c6462af3..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTCPKeepaliveIntervalOption.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - /// - /// RFC 2132. - ///
-    ///  Code   Len           Time
-    /// +-----+-----+-----+-----+-----+-----+
-    /// |  38 |  4  |  t1 |  t2 |  t3 |  t4 |
-    /// +-----+-----+-----+-----+-----+-----+
-    /// 
- ///
- public class DhcpTCPKeepaliveIntervalOption : DhcpOption - { - public DhcpTCPKeepaliveIntervalOption(uint time) : base(DhcpOptionCode.TCPKeepaliveInterval) - { - Time = time; - } - - internal static DhcpTCPKeepaliveIntervalOption Read(DataSegment data, ref int offset) - { - if (data[offset++] != 4) - { - throw new ArgumentException("Length of a DHCP TCPKeepaliveInterval Option has to be 4"); - } - DhcpTCPKeepaliveIntervalOption option = new DhcpTCPKeepaliveIntervalOption(data.ReadUInt(offset, Endianity.Big)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Time, Endianity.Big); - } - - public override byte Length - { - get { return 4; } - } - - public uint Time - { - get; - set; - } - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFTPServerNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFTPServerNameOption.cs deleted file mode 100644 index 6c48bf09..00000000 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFTPServerNameOption.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace PcapDotNet.Packets.Dhcp.Options -{ - /// - /// RFC 2132. - ///
-    ///  Code Len    TFTP server
-    /// +-----+-----+-----+-----+-----+---
-    /// | 66  |  n  |  c1 |  c2 |  c3 | ...
-    /// +-----+-----+-----+-----+-----+---
-    /// 
- ///
- public class DhcpTFTPServerNameOption : DhcpOption - { - public DhcpTFTPServerNameOption(string tfptServer) : base(DhcpOptionCode.TFTPServerName) - { - TFPTServer = tfptServer; - } - - internal static DhcpTFTPServerNameOption Read(DataSegment data, ref int offset) - { - byte len = data[offset++]; - DhcpTFTPServerNameOption option = new DhcpTFTPServerNameOption(Encoding.ASCII.GetString(data.ReadBytes(offset, len))); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Encoding.ASCII.GetBytes(TFPTServer)); - } - - public override byte Length - { - get - { - return (byte)Encoding.ASCII.GetByteCount(TFPTServer); - } - } - - public string TFPTServer - { - get { return bootfileName; } - - set - { - if (value == null) - throw new ArgumentNullException(nameof(TFPTServer)); - if (value.Length < 1) - throw new ArgumentOutOfRangeException(nameof(TFPTServer), value.Length, "BootfileName has to be at least 1 characters long"); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(TFPTServer), value.Length, "BootfileName has to be less than 256 characters long"); - - bootfileName = value; - } - } - - private string bootfileName; - } -} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs new file mode 100644 index 00000000..a23572a8 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// This option is used to identify a TFTP server when the 'sname' field + /// in the DHCP header has been used for DHCP options. + ///
+    ///  Code Len    TFTP server
+    /// +-----+-----+-----+-----+-----+---
+    /// | 66  |  n  |  c1 |  c2 |  c3 | ...
+    /// +-----+-----+-----+-----+-----+---
+    /// 
+ ///
+ public class DhcpTFtpServerNameOption : DhcpStringOption + { + /// + /// create new DhcpTFtpServerNameOption + /// + /// TFTP server + public DhcpTFtpServerNameOption(string tfptServer) : base(tfptServer, DhcpOptionCode.TfptServerName) + { + } + + internal static DhcpTFtpServerNameOption Read(DataSegment data, ref int offset) + { + return Read(data, ref offset, p => new DhcpTFtpServerNameOption(p)); + } + + /// + /// RFC 2132. + /// TFTP server + /// + public string TFtpServer + { + get { return InternalValue; } + set { InternalValue = value; } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs new file mode 100644 index 00000000..4cb984b9 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// This option specifies the default TTL that the client should use when + /// sending TCP segments. + ///
+    ///  Code   Len   TTL
+    /// +-----+-----+-----+
+    /// |  37 |  1  |  n  |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpTcpDefaultTtlOption : DhcpByteOption + { + /// + /// create new DhcpTcpDefaultTtlOption + /// + /// TTL + public DhcpTcpDefaultTtlOption(byte ttl) : base(ttl, DhcpOptionCode.TcpDefaultTtl) + { + } + + internal static DhcpTcpDefaultTtlOption Read(DataSegment data, ref int offset) + { + return Read(data, ref offset, p => new DhcpTcpDefaultTtlOption(p)); + } + + /// + /// RFC 2132. + /// TTL + /// + public byte Ttl + { + get { return InternalValue; } + set { InternalValue = value; } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs new file mode 100644 index 00000000..02f727e8 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// This option specifies the whether or not the client should send TCP + /// keepalive messages with a octet of garbage for compatibility with + /// older implementations. + ///
+    ///  Code   Len  Value
+    /// +-----+-----+-----+
+    /// |  39 |  1  | 0/1 |
+    /// +-----+-----+-----+
+    /// 
+ ///
+ public class DhcpTcpKeepaliveGarbageOption : DhcpBooleanOption + { + /// + /// create new DhcpTcpKeepaliveGarbageOption + /// + /// Value + public DhcpTcpKeepaliveGarbageOption(bool value) : base(value, DhcpOptionCode.TcpKeepaliveGarbage) + { + } + + internal static DhcpTcpKeepaliveGarbageOption Read(DataSegment data, ref int offset) + { + return Read(data, ref offset, p => new DhcpTcpKeepaliveGarbageOption(p)); + } + + /// + /// RFC 2132. + /// Value + /// A value of false indicates that a garbage octet + /// should not be sent. A value of true indicates that a garbage octet + /// should be sent. + /// + public bool Value + { + get { return InternalValue; } + set { InternalValue = value; } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs new file mode 100644 index 00000000..13e6bdf2 --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// RFC 2132. + /// This option specifies the interval (in seconds) that the client TCP + /// should wait before sending a keepalive message on a TCP connection. + ///
+    ///  Code   Len           Time
+    /// +-----+-----+-----+-----+-----+-----+
+    /// |  38 |  4  |  t1 |  t2 |  t3 |  t4 |
+    /// +-----+-----+-----+-----+-----+-----+
+    /// 
+ ///
+ public class DhcpTcpKeepaliveIntervalOption : DhcpUIntOption + { + /// + /// create new DhcpTcpKeepaliveIntervalOption + /// + /// Time + public DhcpTcpKeepaliveIntervalOption(uint time) : base(time, DhcpOptionCode.TcpKeepaliveInterval) + { + } + + internal static DhcpTcpKeepaliveIntervalOption Read(DataSegment data, ref int offset) + { + return Read(data, ref offset, p => new DhcpTcpKeepaliveIntervalOption(p)); + } + + /// + /// RFC 2132. + /// Time + /// A value of zero + /// indicates that the client should not generate keepalive messages on + /// connections unless specifically requested by an application. + /// + public uint Time + { + get { return InternalValue; } + set { InternalValue = value; } + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs index 9f28bcc0..381fd4c7 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs @@ -7,47 +7,43 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// RFC 2132 + /// RFC 2132. + /// The time offset field specifies the offset of the client's subnet in + /// seconds from Coordinated Universal Time(UTC). ///
     ///  Code   Len        Time Offset
     /// +-----+-----+-----+-----+-----+-----+
-    /// |  1  |  4  |  n1 |  n2 |  n3 |  n4 |
+    /// |  2  |  4  |  n1 |  n2 |  n3 |  n4 |
     /// +-----+-----+-----+-----+-----+-----+
     /// 
///
- public class DhcpTimeOffsetOption : DhcpOption + public class DhcpTimeOffsetOption : DhcpIntOption { - public DhcpTimeOffsetOption(uint timeOffset) : base(DhcpOptionCode.TimeOffset) + /// + /// create new DhcpTimeOffsetOption + /// + /// Time Offset + public DhcpTimeOffsetOption(int timeOffset) : base(timeOffset, DhcpOptionCode.TimeOffset) { - TimeOffset = timeOffset; } internal static DhcpTimeOffsetOption Read(DataSegment data, ref int offset) { - if (data[offset++] != 4) - { - throw new ArgumentException("Length of a DHCP TimeOffset Option has to be 4"); - } - DhcpTimeOffsetOption option = new DhcpTimeOffsetOption(data.ReadUInt(offset, Endianity.Big)); - offset += option.Length; - return option; + return Read(data, ref offset, p => new DhcpTimeOffsetOption(p)); } - internal override void Write(byte[] buffer, ref int offset) + /// + /// RFC 2132. + /// Time Offset + /// The offset is + /// expressed as a two's complement 32-bit integer. A positive offset + /// indicates a location east of the zero meridian and a negative offset + /// indicates a location west of the zero meridian. + /// + public int TimeOffset { - base.Write(buffer, ref offset); - buffer.Write(ref offset, TimeOffset, Endianity.Big); - } - - public override byte Length - { - get { return 4; } - } - - public uint TimeOffset - { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs index e36efaf9..8ffb567c 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs @@ -7,16 +7,31 @@ namespace PcapDotNet.Packets.Dhcp.Options { + /// + /// RFC 2132. + /// The time server option specifies a list of RFC 868 [6] time servers + /// available to the client.Servers SHOULD be listed in order of + /// preference. + ///
+    ///  Code   Len         Address 1               Address 2
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// |  4  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
+    /// +-----+-----+-----+-----+-----+-----+-----+-----+--
+    /// 
+ ///
public class DhcpTimeServerOption : DhcpAddressListOption { - public DhcpTimeServerOption(IList addresses) : base(DhcpOptionCode.TimeServer, addresses) + /// + /// create new DhcpTimeServerOption + /// + /// Addresses + public DhcpTimeServerOption(IList addresses) : base(addresses, DhcpOptionCode.TimeServer) { } internal static DhcpTimeServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpTimeServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new Options.DhcpTimeServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs index c9e00041..c6c52c1e 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs @@ -9,6 +9,8 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies whether or not the client should negotiate the + /// use of trailers (RFC 893 [14]) when using the ARP protocol. ///
     ///  Code   Len  Value
     /// +-----+-----+-----+
@@ -16,43 +18,31 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+
     /// 
///
- public class DhcpTrailerEncapsulationOption : DhcpOption + public class DhcpTrailerEncapsulationOption : DhcpBooleanOption { - public DhcpTrailerEncapsulationOption(bool enabled) : base(DhcpOptionCode.TrailerEncapsulation) + /// + /// create new DhcpTrailerEncapsulationOption + /// + /// Value + public DhcpTrailerEncapsulationOption(bool value) : base(value, DhcpOptionCode.TrailerEncapsulation) { - Value = enabled; } internal static DhcpTrailerEncapsulationOption Read(DataSegment data, ref int offset) { - byte len = data[offset++]; - if (len != 1) - throw new ArgumentException("Length of a DHCP TrailerEncapsulation Option has to be 1"); - if (data[offset] != 0 && data[offset] != 1) - throw new ArgumentException("Value of a DHCP TrailerEncapsulation Option has to be 0 or 1"); - DhcpTrailerEncapsulationOption option = new DhcpTrailerEncapsulationOption(data[offset] == 1 ? true : false); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, Value ? (byte)1 : (byte)0); - } - - public override byte Length - { - get - { - return 1; - } + return Read(data, ref offset, p => new DhcpTrailerEncapsulationOption(p)); } + /// + /// RFC 2132. + /// Value. + /// A value of false indicates that the client should not attempt to use trailers. A + /// value of true means that the client should attempt to use trailers. + /// public bool Value { - get; - set; + get { return InternalValue; } + set { InternalValue = value; } } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUIntOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUIntOption.cs new file mode 100644 index 00000000..1756ef4e --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUIntOption.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// Abstract class for all Dhcp-Options with a uint value + /// + public class DhcpUIntOption : DhcpOption + { + internal DhcpUIntOption(uint value, DhcpOptionCode code) : base(code) + { + InternalValue = value; + } + + internal static T Read(DataSegment data, ref int offset, Func ctor) where T : DhcpUIntOption + { + if (ctor == null) + throw new ArgumentNullException(nameof(ctor)); + byte len = data[offset++]; + if (len != sizeof(uint)) + throw new ArgumentException("Length of a DHCP UIntOption Option has to be 4"); + T option = ctor(data.ReadUInt(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, InternalValue, Endianity.Big); + } + + /// + /// RFC 2132. + /// Value of Length-Field + /// + public override byte Length + { + get + { + return sizeof(uint); + } + } + + /// + /// The real value of the UIntOption + /// + protected uint InternalValue + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUShortOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUShortOption.cs new file mode 100644 index 00000000..016d083f --- /dev/null +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUShortOption.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PcapDotNet.Packets.IpV4; + +namespace PcapDotNet.Packets.Dhcp.Options +{ + /// + /// Abstract class for all Dhcp-Options with a ushort value + /// + public class DhcpUShortOption : DhcpOption + { + internal DhcpUShortOption(ushort value, DhcpOptionCode code) : base(code) + { + InternalValue = value; + } + + internal static T Read(DataSegment data, ref int offset, Func ctor) where T : DhcpUShortOption + { + if (ctor == null) + throw new ArgumentNullException(nameof(ctor)); + byte len = data[offset++]; + if (len != sizeof(ushort)) + throw new ArgumentException("Length of a DHCP UShortOption Option has to be 2"); + T option = ctor(data.ReadUShort(offset, Endianity.Big)); + offset += option.Length; + return option; + } + + internal override void Write(byte[] buffer, ref int offset) + { + base.Write(buffer, ref offset); + buffer.Write(ref offset, InternalValue, Endianity.Big); + } + + /// + /// RFC 2132. + /// Value of Length-Field + /// + public override byte Length + { + get + { + return sizeof(ushort); + } + } + + /// + /// The real value of the UIntOption + /// + protected ushort InternalValue + { + get; + set; + } + } +} \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs index df408d32..9515aa69 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs @@ -8,6 +8,16 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option is used by DHCP clients to optionally identify the vendor + /// type and configuration of a DHCP client. The information is a string + /// of n octets, interpreted by servers. Vendors may choose to define + /// specific vendor class identifiers to convey particular configuration + /// or other identification information about a client. For example, the + /// identifier may encode the client's hardware configuration. Servers + /// not equipped to interpret the class-specific information sent by a + /// client MUST ignore it(although it may be reported). Servers that + /// respond SHOULD only use option 43 to return the vendor-specific + /// information to the client. ///
     ///  Code   Len   Vendor class Identifier
     /// +-----+-----+-----+-----+---
@@ -15,60 +25,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+---
     /// 
///
- public class DhcpVendorClassidentifierOption : DhcpOption + public class DhcpVendorClassidentifierOption : DhcpDataSegmentOption { - public DhcpVendorClassidentifierOption(DataSegment vendorClassIdentifier) : base(DhcpOptionCode.VendorClassidentifier) + /// + /// create new DhcpVendorClassidentifierOption + /// + /// Vendor class Identifier + public DhcpVendorClassidentifierOption(DataSegment vendorClassIdentifier) : base(vendorClassIdentifier, DhcpOptionCode.VendorClassidentifier) { - VendorClassIdentifier = vendorClassIdentifier; } internal static DhcpVendorClassidentifierOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - DhcpVendorClassidentifierOption option = new DhcpVendorClassidentifierOption(data.Subsegment(offset, length)); - offset += option.Length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - base.Write(buffer, ref offset); - buffer.Write(ref offset, VendorClassIdentifier); - } - - public override byte Length - { - get - { - if (VendorClassIdentifier == null) - { - return 0; - } - return (byte)VendorClassIdentifier.Length; - } + return Read(data, ref offset, p => new DhcpVendorClassidentifierOption(p)); } + /// + /// RFC 2132. + /// Vendor class Identifier + /// public DataSegment VendorClassIdentifier { - get { return _vendorClassIdentifier; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(VendorClassIdentifier)); - } - if (value.Length < 1) - { - throw new ArgumentOutOfRangeException(nameof(VendorClassIdentifier), value.Length, "VendorClassIdentifier.Length has to be greater than 0"); - } - if (value.Length > byte.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(VendorClassIdentifier), value.Length, "VendorClassIdentifier.Length has to be less than 256"); - } - _vendorClassIdentifier = value; - } + get { return InternalValue; } + set { InternalValue = value; } } - - private DataSegment _vendorClassIdentifier; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs index 5600aaf2..ff5e9876 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs @@ -8,6 +8,16 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option is used by clients and servers to exchange vendor- + /// specific information. The information is an opaque object of n + /// octets, presumably interpreted by vendor-specific code on the clients + /// and servers. The definition of this information is vendor specific. + /// The vendor is indicated in the vendor class identifier option. + /// Servers not equipped to interpret the vendor-specific information + /// sent by a client MUST ignore it(although it may be reported). + /// Clients which do not receive desired vendor-specific information + /// SHOULD make an attempt to operate without it, although they may do so + /// (and announce they are doing so) in a degraded mode. ///
     /// Code   Len   Vendor-specific information
     /// +-----+-----+-----+-----+---
@@ -15,56 +25,29 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// +-----+-----+-----+-----+---
     /// 
///
- public class DhcpVendorSpecificInformationOption : DhcpOption + public class DhcpVendorSpecificInformationOption : DhcpDataSegmentOption { - public DhcpVendorSpecificInformationOption(DataSegment vendorSpecificInformation) : base(DhcpOptionCode.VendorSpecificInformation) + /// + /// create new DhcpVendorSpecificInformationOption + /// + /// Vendor-specific information + public DhcpVendorSpecificInformationOption(DataSegment vendorSpecificInformation) : base(vendorSpecificInformation, DhcpOptionCode.VendorSpecificInformation) { - VendorSpecificInformation = vendorSpecificInformation; } internal static DhcpVendorSpecificInformationOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - DhcpVendorSpecificInformationOption option = new DhcpVendorSpecificInformationOption(data.Subsegment(offset, length)); - offset += length; - return option; - } - - internal override void Write(byte[] buffer, ref int offset) - { - if (VendorSpecificInformation == null) - throw new ArgumentNullException(nameof(VendorSpecificInformation)); - if (VendorSpecificInformation.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(VendorSpecificInformation), VendorSpecificInformation.Length, "VendorSpecificInformation.Length has to be less than 256"); - base.Write(buffer, ref offset); - buffer.Write(ref offset, VendorSpecificInformation); - } - - public override byte Length - { - get - { - if (VendorSpecificInformation == null) - { - return 0; - } - return (byte)VendorSpecificInformation.Length; - } + return Read(data, ref offset, p => new DhcpVendorSpecificInformationOption(p)); } + /// + /// RFC 2132 + /// Vendor-specific information + /// public DataSegment VendorSpecificInformation { - get { return _vendorSpecificInformation; } - set - { - if (value == null) - throw new ArgumentNullException(nameof(VendorSpecificInformation)); - if (value.Length > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(VendorSpecificInformation), value.Length, "VendorSpecificInformation.Length has to be less than 256"); - _vendorSpecificInformation = value; - } + get { return InternalValue; } + set { InternalValue = value; } } - - private DataSegment _vendorSpecificInformation; } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs index 927c8a7e..e04210e5 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs @@ -9,6 +9,10 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies a list of IP addresses of systems that are + /// running the X Window System Display Manager and are available to the + /// client. + /// Addresses SHOULD be listed in order of preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+---
@@ -18,14 +22,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpXWindowSystemDisplayManagerOption : DhcpAddressListOption { - public DhcpXWindowSystemDisplayManagerOption(IList addresses) : base(DhcpOptionCode.XWindowSystemDisplayManager, addresses) + /// + /// create new DhcpXWindowSystemDisplayManagerOption + /// + /// Addresses + public DhcpXWindowSystemDisplayManagerOption(IList addresses) : base(addresses, DhcpOptionCode.XWindowSystemDisplayManager) { } internal static DhcpXWindowSystemDisplayManagerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpXWindowSystemDisplayManagerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new Options.DhcpXWindowSystemDisplayManagerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs index bfa41db5..0fc9f64d 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs @@ -9,6 +9,9 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. + /// This option specifies a list of X Window System [21] Font servers + /// available to the client. Servers SHOULD be listed in order of + /// preference. ///
     ///  Code   Len         Address 1               Address 2
     /// +-----+-----+-----+-----+-----+-----+-----+-----+---
@@ -18,14 +21,17 @@ namespace PcapDotNet.Packets.Dhcp.Options
     /// 
public class DhcpXWindowSystemFontServerOption : DhcpAddressListOption { - public DhcpXWindowSystemFontServerOption(IList addresses) : base(DhcpOptionCode.XWindowSystemFontServer, addresses) + /// + /// create new DhcpXWindowSystemFontServerOption + /// + /// Addresses + public DhcpXWindowSystemFontServerOption(IList addresses) : base(addresses, DhcpOptionCode.XWindowSystemFontServer) { } internal static DhcpXWindowSystemFontServerOption Read(DataSegment data, ref int offset) { - byte length = data[offset++]; - return new DhcpXWindowSystemFontServerOption(GetAddresses(data, length, ref offset)); + return Read(data, ref offset, p => new DhcpXWindowSystemFontServerOption(p)); } } } \ No newline at end of file diff --git a/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj b/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj index c5665651..4f8575f6 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj +++ b/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj @@ -99,6 +99,14 @@ + + + + + + + + @@ -112,21 +120,21 @@ - - - - + + + + - - + + - + - - + + @@ -135,13 +143,13 @@ - + - + @@ -160,7 +168,7 @@ - + @@ -178,7 +186,7 @@ - + diff --git a/README.md b/README.md index 3e47ea61..f7f5c227 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Not including: * UDP * TCP * DNS +* DHCP * HTTP [![Follow Pcap.Net on Google+](https://ssl.gstatic.com/images/icons/gplus-32.png)](https://plus.google.com/111766834267147414574) [Follow Pcap.Net on Google+](https://plus.google.com/111766834267147414574) From 0e40921dd71690a5eb807045b14d320d7383d76f Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sat, 14 Jan 2017 21:43:52 +0100 Subject: [PATCH 04/19] don't use a random invalid port --- .../WiresharkCompareTests.cs | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Core.Test/WiresharkCompareTests.cs b/PcapDotNet/src/PcapDotNet.Core.Test/WiresharkCompareTests.cs index a56e3f25..b9d7c9aa 100644 --- a/PcapDotNet/src/PcapDotNet.Core.Test/WiresharkCompareTests.cs +++ b/PcapDotNet/src/PcapDotNet.Core.Test/WiresharkCompareTests.cs @@ -419,24 +419,19 @@ private static void CreateRandomUdpPayload(Random random, UdpLayer udpLayer, Lis case 1: { DhcpLayer dhcpLayer = random.NextDhcpLayer(); - layers.Add(dhcpLayer); - - if (random.NextBool()) - { - udpLayer.SourcePort = (ushort)(random.NextBool() ? 67 : 68); - } - else - { - udpLayer.DestinationPort = 5355; - } - if (random.NextBool()) - { - udpLayer.SourcePort = (ushort)(random.NextBool() ? 67 : 68); + layers.Add(dhcpLayer); + + if (random.NextBool()) + { + udpLayer.SourcePort = 67 ; + udpLayer.DestinationPort = 68; } - else - { - udpLayer.SourcePort = 5355; + else + { + udpLayer.SourcePort = 68; + udpLayer.DestinationPort = 67; } + break; } From 7971a205908814c5b8abe8461037bdfcac64b43e Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sat, 14 Jan 2017 21:49:59 +0100 Subject: [PATCH 05/19] TransactionId type int --> uint --- .../PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs | 2 +- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 6 +++--- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs index 70a63d2b..80777e99 100644 --- a/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs +++ b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs @@ -25,7 +25,7 @@ public static DhcpLayer NextDhcpLayer(this Random random) dhcpLayer.HardwareType = random.NextEnum(Enum.GetValues(typeof(ArpHardwareType)).Cast().Where(p => ((short)p) > byte.MaxValue)); dhcpLayer.HardwareAddressLength = random.NextByte(16); dhcpLayer.Hops = random.NextByte(); - dhcpLayer.TransactionId = random.NextInt(); + dhcpLayer.TransactionId = random.NextUInt(); dhcpLayer.SecondsElapsed = random.NextUShort(); dhcpLayer.DhcpFlags = random.NextEnum(); dhcpLayer.ClientIpAddress = random.NextIpV4Address(); diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index 56a0519e..cb519e6a 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -112,9 +112,9 @@ public byte Hops /// RFC 2131. /// Transaction ID, a random number chosen by the client, used by the client and server to associate messages and responses between a client and a server. ///
- public int TransactionId + public uint TransactionId { - get { return ReadInt(Offset.Xid, Endianity.Big); } + get { return ReadUInt(Offset.Xid, Endianity.Big); } } /// @@ -323,7 +323,7 @@ internal static int GetLength(bool isDhcp, IList options) return length; } - internal static void Write(byte[] buffer, int offset, DhcpMessageType messageType, ArpHardwareType hardwareType, byte hardwareAddressLength, byte hops, int transactionId, ushort secondsElapsed, DhcpFlags flags, IpV4Address clientIpAddress, IpV4Address yourClientIpAddress, IpV4Address nextServerIpAddress, IpV4Address relayAgentIpAddress, DataSegment clientHardwareAddress, string serverHostName, string bootFileName, bool isDhcp, IList options) + internal static void Write(byte[] buffer, int offset, DhcpMessageType messageType, ArpHardwareType hardwareType, byte hardwareAddressLength, byte hops, uint transactionId, ushort secondsElapsed, DhcpFlags flags, IpV4Address clientIpAddress, IpV4Address yourClientIpAddress, IpV4Address nextServerIpAddress, IpV4Address relayAgentIpAddress, DataSegment clientHardwareAddress, string serverHostName, string bootFileName, bool isDhcp, IList options) { buffer.Write(ref offset, (byte)messageType); buffer.Write(ref offset, (byte)hardwareType); diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs index 8246855f..d00de070 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs @@ -40,7 +40,7 @@ public sealed class DhcpLayer : SimpleLayer, IEquatable /// /// Transaction ID, a random number chosen by the client, used by the client and server to associate messages and responses between a client and a server. /// - public int TransactionId { get; set; } + public uint TransactionId { get; set; } /// /// Filled in by client, seconds elapsed since client began address acquisition or renewal process. From df7dcd24f131db714708462e79041c3d3d880549 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sat, 14 Jan 2017 22:08:09 +0100 Subject: [PATCH 06/19] rename pos --> offset --- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index cb519e6a..6c0b4f62 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -276,10 +276,10 @@ private void ParseOptions() if (_options == null) { List options = new List(); - int pos = IsDhcp ? Offset.OptionsWithMagicCookie : Offset.Options; - while (pos < Length) + int offset = IsDhcp ? Offset.OptionsWithMagicCookie : Offset.Options; + while (offset < Length) { - options.Add(DhcpOption.CreateInstance(this, ref pos)); + options.Add(DhcpOption.CreateInstance(this, ref offset)); } this._options = new ReadOnlyCollection(options); } From 2912854429b7bcba1af480da46326326a41d2aed Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sat, 14 Jan 2017 22:09:52 +0100 Subject: [PATCH 07/19] Avoid using "this." explicitly. --- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index 6c0b4f62..30d56214 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -178,7 +178,7 @@ public IpV4Address RelayAgentIpAddress /// public DataSegment ClientHardwareAddress { - get { return this.Subsegment(Offset.ChAddr, 16); } + get { return Subsegment(Offset.ChAddr, 16); } } /// @@ -281,7 +281,7 @@ private void ParseOptions() { options.Add(DhcpOption.CreateInstance(this, ref offset)); } - this._options = new ReadOnlyCollection(options); + _options = new ReadOnlyCollection(options); } } From 5170fe1cf8996def5de004433e6f7f2cc405bd6a Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sat, 14 Jan 2017 22:14:40 +0100 Subject: [PATCH 08/19] change method order public, internal, private --- .../PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index 30d56214..bcf7e7d5 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -247,44 +247,6 @@ public IReadOnlyCollection Options } } - internal DhcpDatagram(byte[] buffer, int offset, int length) : base(buffer, offset, length) - { - } - - private void ParseServerHostName() - { - if (_serverHostName == null) - { - //at the moment we only interpret server host name as sname and ignore options - byte[] byteServerHostName = ReadBytes(Offset.Sname, 64); - _serverHostName = Encoding.ASCII.GetString(byteServerHostName).TrimEnd('\0'); - } - } - - private void ParseBootFileName() - { - if (_bootFileName == null) - { - //at the moment we only interpret server host name as sname and ignore options - byte[] byteBootFileName = ReadBytes(Offset.File, 128); - _bootFileName = Encoding.ASCII.GetString(byteBootFileName).TrimEnd('\0'); - } - } - - private void ParseOptions() - { - if (_options == null) - { - List options = new List(); - int offset = IsDhcp ? Offset.OptionsWithMagicCookie : Offset.Options; - while (offset < Length) - { - options.Add(DhcpOption.CreateInstance(this, ref offset)); - } - _options = new ReadOnlyCollection(options); - } - } - /// /// Creates a Layer that represents the datagram to be used with PacketBuilder. /// @@ -311,6 +273,11 @@ public override ILayer ExtractLayer() }; } + + internal DhcpDatagram(byte[] buffer, int offset, int length) : base(buffer, offset, length) + { + } + internal static int GetLength(bool isDhcp, IList options) { int length = isDhcp ? Offset.OptionsWithMagicCookie : Offset.Options; @@ -361,6 +328,40 @@ internal static void Write(byte[] buffer, int offset, DhcpMessageType messageTyp } } + private void ParseServerHostName() + { + if (_serverHostName == null) + { + //at the moment we only interpret server host name as sname and ignore options + byte[] byteServerHostName = ReadBytes(Offset.Sname, 64); + _serverHostName = Encoding.ASCII.GetString(byteServerHostName).TrimEnd('\0'); + } + } + + private void ParseBootFileName() + { + if (_bootFileName == null) + { + //at the moment we only interpret server host name as sname and ignore options + byte[] byteBootFileName = ReadBytes(Offset.File, 128); + _bootFileName = Encoding.ASCII.GetString(byteBootFileName).TrimEnd('\0'); + } + } + + private void ParseOptions() + { + if (_options == null) + { + List options = new List(); + int offset = IsDhcp ? Offset.OptionsWithMagicCookie : Offset.Options; + while (offset < Length) + { + options.Add(DhcpOption.CreateInstance(this, ref offset)); + } + _options = new ReadOnlyCollection(options); + } + } + private string _serverHostName; private string _bootFileName; private IReadOnlyCollection _options; From 3ccd7fc15806228c7dd1a37ce26120251250f420 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sat, 14 Jan 2017 22:15:00 +0100 Subject: [PATCH 09/19] remove useless overwrite --- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs index d00de070..66c5c2db 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs @@ -141,18 +141,6 @@ protected override void Write(byte[] buffer, int offset) NextServerIpAddress, RelayAgentIpAddress, ClientHardwareAddress, ServerHostName, BootFileName, IsDhcp, Options); } - /// - /// Finalizes the layer data in the buffer. - /// Used for fields that must be calculated according to the layer's payload (like checksum). - /// - /// The buffer to finalize the layer in. - /// The offset in the buffer the layer starts. - /// The length of the layer's payload (the number of bytes after the layer in the packet). - /// The layer that comes after this layer. null if this is the last layer. - public override void Finalize(byte[] buffer, int offset, int payloadLength, ILayer nextLayer) - { - } - /// /// True if the two objects are equal Layers. /// From 7e1df4138436b969e4003136b1ac9ae4cc621180 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sun, 15 Jan 2017 22:35:59 +0100 Subject: [PATCH 10/19] End comments with periods. Hopefully I didn't miss any. --- .../src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 16 ++++++++-------- .../src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs | 16 ++++++++-------- .../Dhcp/Options/DhcpARPCacheTimeoutOption.cs | 4 ++-- .../Dhcp/Options/DhcpAddressListOption.cs | 8 ++++---- .../Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs | 2 +- .../Dhcp/Options/DhcpAnyOption.cs | 8 ++++---- .../Dhcp/Options/DhcpBooleanOption.cs | 6 +++--- .../Dhcp/Options/DhcpBootFileSizeOption.cs | 4 ++-- .../Dhcp/Options/DhcpBootfileNameOption.cs | 4 ++-- .../Dhcp/Options/DhcpBroadcastAddressOption.cs | 2 +- .../Dhcp/Options/DhcpByteOption.cs | 6 +++--- .../Dhcp/Options/DhcpClientIdentifierOption.cs | 6 +++--- .../Dhcp/Options/DhcpCookieServerOption.cs | 2 +- .../Dhcp/Options/DhcpDataSegmentOption.cs | 6 +++--- .../Options/DhcpDefaultFingerServerOption.cs | 2 +- .../Options/DhcpDefaultIPTimeToLiveOption.cs | 4 ++-- .../DhcpDefaultInternetRelayChatServerOption.cs | 2 +- .../DhcpDefaultWorldWideWebServerOption.cs | 2 +- .../Dhcp/Options/DhcpDomainNameOption.cs | 4 ++-- .../Dhcp/Options/DhcpDomainNameServerOption.cs | 2 +- .../Dhcp/Options/DhcpEndOption.cs | 2 +- .../Options/DhcpEthernetEncapsulationOption.cs | 2 +- .../Dhcp/Options/DhcpExtensionsPathOption.cs | 4 ++-- .../Dhcp/Options/DhcpHostNameOption.cs | 4 ++-- .../Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs | 6 +++--- .../Dhcp/Options/DhcpIPForwardingEnableOption.cs | 2 +- .../Dhcp/Options/DhcpImpressServerOption.cs | 2 +- .../Dhcp/Options/DhcpIntOption.cs | 6 +++--- .../Dhcp/Options/DhcpInterfaceMtuOption.cs | 4 ++-- .../Dhcp/Options/DhcpLogServerOption.cs | 2 +- .../Dhcp/Options/DhcpLprServerOption.cs | 2 +- .../Dhcp/Options/DhcpMaskSupplierOption.cs | 2 +- .../DhcpMaximumDatagramReassemblySizeOption.cs | 4 ++-- .../Options/DhcpMaximumDhcpMessageSizeOption.cs | 4 ++-- .../Dhcp/Options/DhcpMeritDumpFileOption.cs | 4 ++-- .../Dhcp/Options/DhcpMessageOption.cs | 4 ++-- .../Dhcp/Options/DhcpMessageTypeOption.cs | 8 ++++---- .../Dhcp/Options/DhcpMobileIPHomeAgentOption.cs | 4 ++-- .../Dhcp/Options/DhcpNameServerOption.cs | 2 +- ...sOverTcpIpDatagramDistributionServerOption.cs | 2 +- .../DhcpNetBiosOverTcpIpNameServerOption.cs | 2 +- .../DhcpNetBiosOverTcpIpNodeTypeOption.cs | 4 ++-- .../Options/DhcpNetBiosOverTcpIpScopeOption.cs | 6 +++--- .../DhcpNetworkInformationServersOption.cs | 2 +- .../DhcpNetworkInformationServiceDomainOption.cs | 4 ++-- ...pNetworkInformationServicePlusDomainOption.cs | 4 ++-- ...NetworkInformationServicePlusServersOption.cs | 2 +- ...cpNetworkNewsTransportProtocolServerOption.cs | 2 +- .../DhcpNetworkTimeProtocolServersOption.cs | 2 +- .../DhcpNonLocalSourceRoutingEnableOption.cs | 2 +- .../Dhcp/Options/DhcpOption.cs | 10 +++++----- .../Dhcp/Options/DhcpOptionOverloadOption.cs | 8 ++++---- .../Dhcp/Options/DhcpPadOption.cs | 4 ++-- .../Options/DhcpParameterRequestListOption.cs | 6 +++--- .../Options/DhcpPathMtuAgingTimeoutOption.cs | 4 ++-- .../Options/DhcpPathMtuPlateauTableOption.cs | 6 +++--- .../Options/DhcpPerformMaskDiscoveryOption.cs | 2 +- .../Options/DhcpPerformRouterDiscoveryOption.cs | 2 +- .../Dhcp/Options/DhcpPolicyFilterOption.cs | 10 +++++----- .../DhcpPostOfficeProtocolServerOption.cs | 2 +- .../Dhcp/Options/DhcpRebindingTimeValueOption.cs | 4 ++-- .../Dhcp/Options/DhcpRenewalTimeValueOption.cs | 4 ++-- .../Dhcp/Options/DhcpRequestedIPAddressOption.cs | 4 ++-- .../Options/DhcpResourceLocationServerOption.cs | 2 +- .../Dhcp/Options/DhcpRootPathOption.cs | 4 ++-- .../Dhcp/Options/DhcpRouterOption.cs | 2 +- .../DhcpRouterSolicitationAddressOption.cs | 4 ++-- .../Dhcp/Options/DhcpServerIdentifierOption.cs | 6 +++--- ...hcpSimpleMailTransportProtocolServerOption.cs | 2 +- .../Dhcp/Options/DhcpSingleAddressOption.cs | 6 +++--- .../Dhcp/Options/DhcpStaticRouteOption.cs | 14 +++++++------- ...pStreetTalkDirectoryAssistanceServerOption.cs | 2 +- .../Dhcp/Options/DhcpStreetTalkServerOption.cs | 2 +- .../Dhcp/Options/DhcpStringOption.cs | 6 +++--- .../Dhcp/Options/DhcpSubnetMaskOption.cs | 4 ++-- .../Dhcp/Options/DhcpSwapServerOption.cs | 4 ++-- .../Dhcp/Options/DhcpTFtpServerNameOption.cs | 4 ++-- .../Dhcp/Options/DhcpTcpDefaultTtlOption.cs | 4 ++-- .../Options/DhcpTcpKeepaliveGarbageOption.cs | 2 +- .../Options/DhcpTcpKeepaliveIntervalOption.cs | 4 ++-- .../Dhcp/Options/DhcpTimeOffsetOption.cs | 4 ++-- .../Dhcp/Options/DhcpTimeServerOption.cs | 2 +- .../Options/DhcpTrailerEncapsulationOption.cs | 2 +- .../Dhcp/Options/DhcpUIntOption.cs | 6 +++--- .../Dhcp/Options/DhcpUShortOption.cs | 6 +++--- .../Options/DhcpVendorClassidentifierOption.cs | 4 ++-- .../DhcpVendorSpecificInformationOption.cs | 4 ++-- .../DhcpXWindowSystemDisplayManagerOption.cs | 2 +- .../Options/DhcpXWindowSystemFontServerOption.cs | 2 +- 89 files changed, 188 insertions(+), 188 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index bcf7e7d5..a58d6dd6 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -74,7 +74,7 @@ private static class Offset /// /// RFC 2131. - /// Message op code + /// Message op code. /// public DhcpMessageType MessageType { @@ -83,7 +83,7 @@ public DhcpMessageType MessageType /// /// RFC 2131. - /// Hardware address type + /// Hardware address type. /// public ArpHardwareType HardwareType { @@ -92,7 +92,7 @@ public ArpHardwareType HardwareType /// /// RFC 2131. - /// Hardware address length + /// Hardware address length. /// public byte HardwareAddressLength { @@ -128,7 +128,7 @@ public ushort SecondsElapsed /// /// RFC 2131. - /// Flags + /// Flags. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] public DhcpFlags Flags @@ -182,7 +182,7 @@ public DataSegment ClientHardwareAddress } /// - /// Client MAC address + /// Client MAC address. /// public MacAddress ClientMacAddress { @@ -191,7 +191,7 @@ public MacAddress ClientMacAddress /// /// RFC 2131. - /// Optional server host name + /// Optional server host name. /// public string ServerHostName { @@ -217,7 +217,7 @@ public string BootFileName /// /// RFC 2131. - /// true if the magic dhcp-cookie is set + /// true if the magic dhcp-cookie is set. If set this datagram is a dhcp-datagram. Otherwise it's a bootp-datagram. /// public bool IsDhcp { @@ -236,7 +236,7 @@ public bool IsDhcp /// /// RFC 2131. - /// Optional parameters field + /// Optional parameters field. /// public IReadOnlyCollection Options { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs index 66c5c2db..ee14e574 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs @@ -18,17 +18,17 @@ namespace PcapDotNet.Packets.Dhcp public sealed class DhcpLayer : SimpleLayer, IEquatable { /// - /// Message op code + /// Message op code. /// public DhcpMessageType MessageType { get; set; } /// - /// Hardware address type + /// Hardware address type. /// public ArpHardwareType HardwareType { get; set; } /// - /// Hardware address length + /// Hardware address length. /// public byte HardwareAddressLength { get; set; } @@ -48,7 +48,7 @@ public sealed class DhcpLayer : SimpleLayer, IEquatable public ushort SecondsElapsed { get; set; } /// - /// Flags + /// Flags. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] public DhcpFlags DhcpFlags { get; set; } @@ -79,7 +79,7 @@ public sealed class DhcpLayer : SimpleLayer, IEquatable public DataSegment ClientHardwareAddress { get; set; } /// - /// Client MAC address + /// Client MAC address. /// public MacAddress ClientMacAddress { @@ -98,7 +98,7 @@ public MacAddress ClientMacAddress } /// - /// Optional server host name + /// Optional server host name. /// public string ServerHostName { get; set; } @@ -108,12 +108,12 @@ public MacAddress ClientMacAddress public string BootFileName { get; set; } /// - /// true if the magic dhcp-cookie is set + /// true if the magic dhcp-cookie is set. If set this datagram is a dhcp-datagram. Otherwise it's a bootp-datagram. /// public bool IsDhcp { get; set; } /// - /// Optional parameters field + /// Optional parameters field. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public IList Options { get; set; } diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs index e2dcdf7d..90c44ce1 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs @@ -19,7 +19,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpArpCacheTimeoutOption : DhcpUIntOption { /// - /// create new ArpCacheTimeoutOption + /// create new ArpCacheTimeoutOption. /// /// Time public DhcpArpCacheTimeoutOption(uint time) : base(time, DhcpOptionCode.ArpCacheTimeout) @@ -34,7 +34,7 @@ internal static DhcpArpCacheTimeoutOption Read(DataSegment data, ref int offset) /// /// RFC 2132. /// Time - /// timeout in seconds for ARP cache entries + /// timeout in seconds for ARP cache entries. /// public uint Time { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs index b72ef9b3..3c82097b 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAddressListOption.cs @@ -9,7 +9,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// Abstract class for all Dhcp-Options with a list of Addresses + /// Abstract class for all Dhcp-Options with a list of Addresses. /// public abstract class DhcpAddressListOption : DhcpOption { @@ -61,7 +61,7 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// true if Addresses-List is allowed to be empty (Default false) + /// true if Addresses-List is allowed to be empty (Default false). /// protected virtual bool AllowEmptyAddresses { @@ -70,7 +70,7 @@ protected virtual bool AllowEmptyAddresses /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -82,7 +82,7 @@ public override byte Length /// /// RFC 2132. - /// collection of all addresses of this option + /// collection of all addresses of this option. /// public IReadOnlyCollection Addresses { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs index ee426197..6ddc6887 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs @@ -23,7 +23,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpAllSubnetsAreLocalOption : DhcpBooleanOption { /// - /// create new AllSubnetsAreLocalOption + /// create new AllSubnetsAreLocalOption. /// /// Value public DhcpAllSubnetsAreLocalOption(bool value) : base(value, DhcpOptionCode.AllSubnetsAreLocal) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs index 5c412820..ad581cac 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAnyOption.cs @@ -7,12 +7,12 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// DHCP option for any options + /// DHCP option for any options. /// public class DhcpAnyOption : DhcpOption { /// - /// create new Any-Option + /// create new Any-Option. /// /// data represented by the option /// the OptionCode @@ -22,7 +22,7 @@ public DhcpAnyOption(DataSegment data, DhcpOptionCode code) : base(code) } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { @@ -50,7 +50,7 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// Data of the Option + /// Data of the Option. /// public DataSegment Data { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBooleanOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBooleanOption.cs index 6b02c00b..d083e9d9 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBooleanOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBooleanOption.cs @@ -8,7 +8,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// Abstract class for all Dhcp-Options with a boolean value + /// Abstract class for all Dhcp-Options with a boolean value. /// public class DhcpBooleanOption : DhcpOption { @@ -38,7 +38,7 @@ internal override void Write(byte[] buffer, ref int offset) /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -49,7 +49,7 @@ public override byte Length } /// - /// The real value of the BooleanOption + /// The real value of the BooleanOption. /// protected bool InternalValue { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs index 5183cab4..7922c8af 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpBootFileSizeOption : DhcpUShortOption { /// - /// create new DhcpBootFileSizeOption + /// create new DhcpBootFileSizeOption. /// /// File Size public DhcpBootFileSizeOption(ushort fileSize) : base(fileSize, DhcpOptionCode.BootFileSize) @@ -34,7 +34,7 @@ internal static DhcpBootFileSizeOption Read(DataSegment data, ref int offset) } /// - /// File Size + /// File Size. /// public ushort FileSize { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs index adb977a0..3414a649 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpBootfileNameOption : DhcpStringOption { /// - /// create new DhcpBootfileNameOption + /// create new DhcpBootfileNameOption. /// /// Bootfilename public DhcpBootfileNameOption(string bootfileName) : base(bootfileName, DhcpOptionCode.BootfileName) @@ -33,7 +33,7 @@ internal static DhcpBootfileNameOption Read(DataSegment data, ref int offset) } /// - /// Bootfilename + /// Bootfilename. /// public string BootfileName { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs index e7846be6..02dad5ff 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpBroadcastAddressOption : DhcpSingleAddressOption { /// - /// create new DhcpBroadcastAddressOption + /// create new DhcpBroadcastAddressOption. /// /// Broadcast Address public DhcpBroadcastAddressOption(IpV4Address broadcastAddress) : base(broadcastAddress, DhcpOptionCode.BroadcastAddress) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpByteOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpByteOption.cs index 1c46d187..7a8b07e1 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpByteOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpByteOption.cs @@ -8,7 +8,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// Abstract class for all Dhcp-Options with a byte value + /// Abstract class for all Dhcp-Options with a byte value. /// public class DhcpByteOption : DhcpOption { @@ -36,7 +36,7 @@ internal override void Write(byte[] buffer, ref int offset) /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -47,7 +47,7 @@ public override byte Length } /// - /// The real value of the ByteOption + /// The real value of the ByteOption. /// protected byte InternalValue { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs index fe2acda3..5df4324f 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpClientIdentifierOption : DhcpOption { /// - /// create new DhcpClientIdentifierOption + /// create new DhcpClientIdentifierOption. /// /// Type /// Client-Identifier @@ -49,7 +49,7 @@ internal override void Write(byte[] buffer, ref int offset) /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -71,7 +71,7 @@ public byte ClientIdentifierType /// /// RFC 2132. - /// Client-Identifier + /// Client-Identifier. /// public DataSegment ClientIdentifier { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs index d1b9ac28..1695ecd3 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpCookieServerOption : DhcpAddressListOption { /// - /// create new DhcpCookieServerOption + /// create new DhcpCookieServerOption. /// /// Addresses public DhcpCookieServerOption(IList addresses) : base(addresses, DhcpOptionCode.CookieServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDataSegmentOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDataSegmentOption.cs index d19d78c4..7078c41b 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDataSegmentOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDataSegmentOption.cs @@ -8,7 +8,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// Abstract class for all Dhcp-Options with a DataSegment value + /// Abstract class for all Dhcp-Options with a DataSegment value. /// public class DhcpDataSegmentOption : DhcpOption { @@ -35,7 +35,7 @@ internal override void Write(byte[] buffer, ref int offset) /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -46,7 +46,7 @@ public override byte Length } /// - /// The real value of the UIntOption + /// The real value of the UIntOption. /// protected DataSegment InternalValue { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs index 5c2a9fbe..758e7961 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpDefaultFingerServerOption : DhcpAddressListOption { /// - /// create new DhcpDefaultFingerServerOption + /// create new DhcpDefaultFingerServerOption. /// /// Addresses public DhcpDefaultFingerServerOption(IList addresses) : base(addresses, DhcpOptionCode.DefaultFingerServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs index eaceb8c4..989a328b 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpDefaultIPTimeToLiveOption : DhcpByteOption { /// - /// create new DhcpDefaultIPTimeToLiveOption + /// create new DhcpDefaultIPTimeToLiveOption. /// /// TTL public DhcpDefaultIPTimeToLiveOption(byte ttl) : base(ttl, DhcpOptionCode.DefaultIpTimeToLive) @@ -34,7 +34,7 @@ internal static DhcpDefaultIPTimeToLiveOption Read(DataSegment data, ref int off /// /// RFC 2132. - /// TTL + /// TTL. /// public byte Ttl { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs index cf00aa4a..b848c7d6 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpDefaultInternetRelayChatServerOption : DhcpAddressListOption { /// - /// create new DhcpDefaultInternetRelayChatServerOption + /// create new DhcpDefaultInternetRelayChatServerOption. /// /// Addresses public DhcpDefaultInternetRelayChatServerOption(IList addresses) : base(addresses, DhcpOptionCode.DefaultInternetRelayChatServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs index f7d5e030..a9d8e0d5 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpDefaultWorldWideWebServerOption : DhcpAddressListOption { /// - /// create new DhcpDefaultWorldWideWebServerOption + /// create new DhcpDefaultWorldWideWebServerOption. /// /// Addresses public DhcpDefaultWorldWideWebServerOption(IList addresses) : base(addresses, DhcpOptionCode.DefaultWorldWideWebServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs index d393c410..7dcc6e27 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpDomainNameOption : DhcpStringOption { /// - /// create new DhcpDomainNameOption + /// create new DhcpDomainNameOption. /// /// Domain Name public DhcpDomainNameOption(string domainName) : base(domainName, DhcpOptionCode.DomainName) @@ -34,7 +34,7 @@ internal static DhcpDomainNameOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// Domain Name + /// Domain Name. /// public string DomainName { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs index 78ef0486..c3d4bb06 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpDomainNameServerOption : DhcpAddressListOption { /// - /// create new DhcpDomainNameServerOption + /// create new DhcpDomainNameServerOption. /// /// Addresses public DhcpDomainNameServerOption(IList addresses) : base(addresses, DhcpOptionCode.DomainNameServerServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs index 39cadf65..cba51838 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs @@ -19,7 +19,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpEndOption : DhcpOption { /// - /// create new EndOption + /// create new EndOption. /// public DhcpEndOption() : base(DhcpOptionCode.End) { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs index c2ecdc7a..e64d11f3 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpEthernetEncapsulationOption : DhcpBooleanOption { /// - /// create new DhcpEthernetEncapsulationOption + /// create new DhcpEthernetEncapsulationOption. /// /// Value public DhcpEthernetEncapsulationOption(bool value) : base(value, DhcpOptionCode.EthernetEncapsulation) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs index 8ab690d9..ad8f8543 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs @@ -24,7 +24,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpExtensionsPathOption : DhcpStringOption { /// - /// create new DhcpExtensionsPathOption + /// create new DhcpExtensionsPathOption. /// /// Extensions Pathname [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] @@ -39,7 +39,7 @@ internal static DhcpExtensionsPathOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// Extensions Pathname + /// Extensions Pathname. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] public string ExtensionsPathname diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs index 23ce75bc..0817330d 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpHostNameOption : DhcpStringOption { /// - /// create new DhcpHostNameOption + /// create new DhcpHostNameOption. /// /// Host Name public DhcpHostNameOption(string hostName) : base(hostName, DhcpOptionCode.HostName) @@ -36,7 +36,7 @@ internal static DhcpHostNameOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// Host Name + /// Host Name. /// public string HostName { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs index 8d666e13..be717efb 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpIPAddressLeaseTimeOption : DhcpUIntOption { /// - /// create new DhcpIPAddressLeaseTimeOption + /// create new DhcpIPAddressLeaseTimeOption. /// /// Lease Time public DhcpIPAddressLeaseTimeOption(uint leaseTime) : base(leaseTime, DhcpOptionCode.IPAddressLeaseTime) @@ -36,8 +36,8 @@ internal static DhcpIPAddressLeaseTimeOption Read(DataSegment data, ref int offs /// /// RFC 2132. - /// Lease Time - /// The time is in units of seconds + /// Lease Time. + /// The time is in units of seconds. /// public uint LeaseTime { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs index 6288400a..c9233d55 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpIPForwardingEnableOption : DhcpBooleanOption { /// - /// create new DhcpIPForwardingEnableOption + /// create new DhcpIPForwardingEnableOption. /// /// Value public DhcpIPForwardingEnableOption(bool value) : base(value, DhcpOptionCode.IPForwardingEnable) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs index 6a55098c..4e02f0ea 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpImpressServerOption : DhcpAddressListOption { /// - /// create new DhcpImpressServerOption + /// create new DhcpImpressServerOption. /// /// Addresses public DhcpImpressServerOption(IList addresses) : base(addresses, DhcpOptionCode.ImpressServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIntOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIntOption.cs index 95185680..95876ee6 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIntOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIntOption.cs @@ -8,7 +8,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// Abstract class for all Dhcp-Options with a int value + /// Abstract class for all Dhcp-Options with a int value. /// public class DhcpIntOption : DhcpOption { @@ -37,7 +37,7 @@ internal override void Write(byte[] buffer, ref int offset) /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -48,7 +48,7 @@ public override byte Length } /// - /// The real value of the IntOption + /// The real value of the IntOption. /// protected int InternalValue { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs index 198adb74..57e9f57c 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs @@ -23,7 +23,7 @@ public class DhcpInterfaceMtuOption : DhcpUShortOption private const ushort MIN_MTU = 68; /// - /// create new DhcpInterfaceMTUOption + /// create new DhcpInterfaceMTUOption. /// /// MTU public DhcpInterfaceMtuOption(ushort mtu) : base(mtu, DhcpOptionCode.InterfaceMtu) @@ -39,7 +39,7 @@ internal static DhcpInterfaceMtuOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// MTU + /// MTU. /// public ushort Mtu { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs index 8dd932b4..624de0d1 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpLogServerOption : DhcpAddressListOption { /// - /// create new DhcpLogServerOption + /// create new DhcpLogServerOption. /// /// Addresses public DhcpLogServerOption(IList addresses) : base(addresses, DhcpOptionCode.LogServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs index fc526212..4ed7c3c4 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpLprServerOption : DhcpAddressListOption { /// - /// create new DhcpLprServerOption + /// create new DhcpLprServerOption. /// /// Addresses public DhcpLprServerOption(IList addresses) : base(addresses, DhcpOptionCode.LprServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs index a35fe00c..9a0d3b3d 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpMaskSupplierOption : DhcpBooleanOption { /// - /// create new DhcpMaskSupplierOption + /// create new DhcpMaskSupplierOption. /// /// Value public DhcpMaskSupplierOption(bool value) : base(value, DhcpOptionCode.MaskSupplier) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs index 3a2ee643..42e32f91 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs @@ -22,7 +22,7 @@ public class DhcpMaximumDatagramReassemblySizeOption : DhcpUShortOption private const ushort MIN_SIZE = 576; /// - /// create new DhcpMaximumDatagramReassemblySizeOption + /// create new DhcpMaximumDatagramReassemblySizeOption. /// /// Size public DhcpMaximumDatagramReassemblySizeOption(ushort size) : base(size, DhcpOptionCode.MaximumDatagramReassemblySize) @@ -38,7 +38,7 @@ internal static DhcpMaximumDatagramReassemblySizeOption Read(DataSegment data, r /// /// RFC 2132. - /// Size + /// Size. /// public ushort Size { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs index 387667c5..d9c86b21 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs @@ -23,7 +23,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpMaximumDhcpMessageSizeOption : DhcpUShortOption { /// - /// create new DhcpMaximumDhcpMessageSizeOption + /// create new DhcpMaximumDhcpMessageSizeOption. /// /// Length public DhcpMaximumDhcpMessageSizeOption(ushort length) : base(length, DhcpOptionCode.MaximumDhcpMessageSize) @@ -37,7 +37,7 @@ internal static DhcpMaximumDhcpMessageSizeOption Read(DataSegment data, ref int /// /// RFC 2132. - /// Length + /// Length. /// public ushort MaxLength { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs index c73ddcab..ac374f35 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpMeritDumpFileOption : DhcpStringOption { /// - /// create new DhcpMeritDumpFileOption + /// create new DhcpMeritDumpFileOption. /// /// Dump File Pathname [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] @@ -35,7 +35,7 @@ internal static DhcpMeritDumpFileOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// Dump File Pathname + /// Dump File Pathname. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] public string DumpFilePathname diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs index fde899cb..f8cd38c6 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpMessageOption : DhcpStringOption { /// - /// create new DhcpMessageOption + /// create new DhcpMessageOption. /// /// Text public DhcpMessageOption(string text) : base(text, DhcpOptionCode.Message) @@ -36,7 +36,7 @@ internal static DhcpMessageOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// Text + /// Text. /// public string Text { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs index e7f66699..70c92d62 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpMessageTypeOption : DhcpOption { /// - /// create new DhcpMessageTypeOption + /// create new DhcpMessageTypeOption. /// /// Type public DhcpMessageTypeOption(MessageType type) : base(DhcpOptionCode.MessageType) @@ -45,13 +45,13 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { get { - return 1; + return sizeof(MessageType); } } @@ -75,7 +75,7 @@ public MessageType Type /// /// RFC 2132. - /// Supported Message-Types + /// Supported Message-Types. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] public enum MessageType : byte diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs index 378136f4..9ad84eed 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpMobileIPHomeAgentOption : DhcpAddressListOption { /// - /// create new DhcpMobileIPHomeAgentOption + /// create new DhcpMobileIPHomeAgentOption. /// /// Addresses public DhcpMobileIPHomeAgentOption(IList addresses) : base(addresses, DhcpOptionCode.MobileIPHomeAgent) @@ -36,7 +36,7 @@ internal static DhcpMobileIPHomeAgentOption Read(DataSegment data, ref int offse } /// - /// true if Addresses-List is allowed to be empty + /// true if Addresses-List is allowed to be empty. /// protected override bool AllowEmptyAddresses { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs index 8a541e5f..9dd729fd 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNameServerOption : DhcpAddressListOption { /// - /// create new DhcpNameServerOption + /// create new DhcpNameServerOption. /// /// Addresses public DhcpNameServerOption(IList addresses) : base(addresses, DhcpOptionCode.NameServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs index 0376c9b1..02f17afa 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetBiosOverTcpIpDatagramDistributionServerOption : DhcpAddressListOption { /// - /// create new DhcpNetBiosOverTcpIpDatagramDistributionServerOption + /// create new DhcpNetBiosOverTcpIpDatagramDistributionServerOption. /// /// public DhcpNetBiosOverTcpIpDatagramDistributionServerOption(IList addresses) : base(addresses, DhcpOptionCode.NetBiosOverTcpIpDatagramDistributionServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs index 0d9ec62a..71231f61 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetBiosOverTcpIpNameServerOption : DhcpAddressListOption { /// - /// create new DhcpNetBiosOverTcpIpNameServerOption + /// create new DhcpNetBiosOverTcpIpNameServerOption. /// /// Addresses public DhcpNetBiosOverTcpIpNameServerOption(IList addresses) : base(addresses, DhcpOptionCode.NetBiosOverTcpIpNameServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs index 65e7a65b..4b0a4862 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetBiosOverTcpIpNodeTypeOption : DhcpOption { /// - /// create new DhcpNetBIOSOverTCPIPNodeTypeOption + /// create new DhcpNetBIOSOverTCPIPNodeTypeOption. /// /// Type public DhcpNetBiosOverTcpIpNodeTypeOption(NodeType type) : base(DhcpOptionCode.NetBiosOverTcpIpNodeType) @@ -46,7 +46,7 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs index 434459e6..0d7724c5 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetBiosOverTcpIpScopeOption : DhcpOption { /// - /// create new DhcpNetBiosOverTcpIpScopeOption + /// create new DhcpNetBiosOverTcpIpScopeOption. /// /// NetBIOS Scope public DhcpNetBiosOverTcpIpScopeOption(DataSegment netBiosScope) : base(DhcpOptionCode.NetBiosOverTcpIpScope) @@ -43,7 +43,7 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { @@ -55,7 +55,7 @@ public override byte Length /// /// RFC 2132. - /// NetBIOS Scope + /// NetBIOS Scope. /// public DataSegment NetBiosScope { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs index 30679013..29dd348b 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetworkInformationServersOption : DhcpAddressListOption { /// - /// create new DhcpNetworkInformationServersOption + /// create new DhcpNetworkInformationServersOption. /// /// Addresses public DhcpNetworkInformationServersOption(IList addresses) : base(addresses, DhcpOptionCode.NetworkInformationServers) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs index 55bb99b6..5d445636 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs @@ -19,7 +19,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetworkInformationServiceDomainOption : DhcpStringOption { /// - /// create new DhcpNetworkInformationServiceDomainOption + /// create new DhcpNetworkInformationServiceDomainOption. /// /// NIS Domain Name public DhcpNetworkInformationServiceDomainOption(string nisDomainName) : base(nisDomainName, DhcpOptionCode.NetworkInformationServiceDomain) @@ -33,7 +33,7 @@ internal static DhcpNetworkInformationServiceDomainOption Read(DataSegment data, /// /// RFC 2132. - /// NIS Domain Name + /// NIS Domain Name. /// public string NisDomainName { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs index e3395679..0ad51c2f 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs @@ -19,7 +19,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetworkInformationServicePlusDomainOption : DhcpStringOption { /// - /// create new DhcpNetworkInformationServicePlusDomainOption + /// create new DhcpNetworkInformationServicePlusDomainOption. /// /// NIS Client Domain Name public DhcpNetworkInformationServicePlusDomainOption(string nisClientDomainName) : base(nisClientDomainName, DhcpOptionCode.NetworkInformationServicePlusDomain) @@ -33,7 +33,7 @@ internal static DhcpNetworkInformationServicePlusDomainOption Read(DataSegment d /// /// RFC 2132. - /// NIS Client Domain Name + /// NIS Client Domain Name. /// public string NisClientDomainName diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs index 6825f501..265dbe55 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetworkInformationServicePlusServersOption : DhcpAddressListOption { /// - /// create new DhcpNetworkInformationServicePlusServersOption + /// create new DhcpNetworkInformationServicePlusServersOption. /// /// Addresses public DhcpNetworkInformationServicePlusServersOption(IList addresses) : base(addresses, DhcpOptionCode.NetworkInformationServicePlusServers) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs index 83108127..a3df0002 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetworkNewsTransportProtocolServerOption : DhcpAddressListOption { /// - /// create new DhcpNetworkNewsTransportProtocolServerOption + /// create new DhcpNetworkNewsTransportProtocolServerOption. /// /// Addresses public DhcpNetworkNewsTransportProtocolServerOption(IList addresses) : base(addresses, DhcpOptionCode.NetworkNewsTransportProtocolServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs index 71eebabc..ae6193ae 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNetworkTimeProtocolServersOption : DhcpAddressListOption { /// - /// create new DhcpNetworkTimeProtocolServersOption + /// create new DhcpNetworkTimeProtocolServersOption. /// /// Addresses public DhcpNetworkTimeProtocolServersOption(IList addresses) : base(addresses, DhcpOptionCode.NetworkTimeProtocolServers) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs index 813a729a..5a56a535 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpNonLocalSourceRoutingEnableOption : DhcpBooleanOption { /// - /// create new DhcpNonLocalSourceRoutingEnableOption + /// create new DhcpNonLocalSourceRoutingEnableOption. /// /// Value public DhcpNonLocalSourceRoutingEnableOption(bool value) : base(value, DhcpOptionCode.NonLocalSourceRoutingEnable) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs index 4aff8de9..5238ff07 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs @@ -9,13 +9,13 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// /// RFC 2132. - /// Abstract class for all possible Dhcp-Options + /// Abstract class for all possible Dhcp-Options. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] public abstract class DhcpOption : IEquatable { /// - /// Option-Code according RFC 2132 + /// Option-Code according RFC 2132. /// public DhcpOptionCode OptionCode { @@ -24,7 +24,7 @@ public DhcpOptionCode OptionCode } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public abstract byte Length { @@ -32,7 +32,7 @@ public abstract byte Length } /// - /// create new Option + /// create new Option. /// /// Option-Code protected DhcpOption(DhcpOptionCode code) @@ -348,7 +348,7 @@ public bool Equals(DhcpOption other) } /// - /// calucate a hash of the option + /// calculate a hash of the option. /// /// a hash representing this instance public override int GetHashCode() diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs index d0169984..8f0a2a54 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs @@ -26,7 +26,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpOptionOverloadOption : DhcpOption { /// - /// create new DhcpOptionOverloadOption + /// create new DhcpOptionOverloadOption. /// /// Value public DhcpOptionOverloadOption(OptionOverloadValue value) : base(DhcpOptionCode.OptionOverload) @@ -51,19 +51,19 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { get { - return 1; + return sizeof(OptionOverloadValue); } } /// /// RFC 2132. - /// Value + /// Value. /// public OptionOverloadValue Value { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs index 3a5e2286..b810c4da 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs @@ -20,14 +20,14 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpPadOption : DhcpOption { /// - /// create new PadOption + /// create new PadOption. /// public DhcpPadOption() : base(DhcpOptionCode.Pad) { } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs index 60db9b5f..3b9c392a 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs @@ -28,7 +28,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpParameterRequestListOption : DhcpOption { /// - /// create new DhcpParameterRequestListOption + /// create new DhcpParameterRequestListOption. /// /// Option Codes public DhcpParameterRequestListOption(IList optionCodes) : base(DhcpOptionCode.ParameterRequestList) @@ -60,13 +60,13 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { get { - return (byte)OptionCodes.Count; + return (byte)(OptionCodes.Count * sizeof(DhcpOptionCode)); } } diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs index 02fc8914..7aabf9ba 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpPathMtuAgingTimeoutOption : DhcpUIntOption { /// - /// create new DhcpPathMtuAgingTimeoutOption + /// create new DhcpPathMtuAgingTimeoutOption. /// /// Timeout public DhcpPathMtuAgingTimeoutOption(uint timeout) : base(timeout, DhcpOptionCode.PathMtuAgingTimeout) @@ -34,7 +34,7 @@ internal static DhcpPathMtuAgingTimeoutOption Read(DataSegment data, ref int off /// /// RFC 2132. - /// Timeout + /// Timeout. /// public uint Timeout { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs index 404b9e89..7ccb4240 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs @@ -24,7 +24,7 @@ public class DhcpPathMtuPlateauTableOption : DhcpOption internal const int MAX_SIZES = 255 / sizeof(ushort); /// - /// create new DhcpPathMtuPlateauTableOption + /// create new DhcpPathMtuPlateauTableOption. /// /// Sizes public DhcpPathMtuPlateauTableOption(IList sizes) : base(DhcpOptionCode.PathMtuPlateauTable) @@ -66,7 +66,7 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { @@ -78,7 +78,7 @@ public override byte Length /// /// RFC 2132. - /// Sizes + /// Sizes. /// public IReadOnlyCollection Sizes { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs index da06641c..83cbdc78 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpPerformMaskDiscoveryOption : DhcpBooleanOption { /// - /// create new DhcpPerformMaskDiscoveryOption + /// create new DhcpPerformMaskDiscoveryOption. /// /// Value public DhcpPerformMaskDiscoveryOption(bool value) : base(value, DhcpOptionCode.PerformMaskDiscovery) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs index 8efa0c79..7829b732 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpPerformRouterDiscoveryOption : DhcpBooleanOption { /// - /// create new DhcpPerformRouterDiscoveryOption + /// create new DhcpPerformRouterDiscoveryOption. /// /// Value public DhcpPerformRouterDiscoveryOption(bool value) : base(value, DhcpOptionCode.PerformRouterDiscovery) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs index 95b9dac9..da3b8712 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs @@ -31,7 +31,7 @@ public class DhcpPolicyFilterOption : DhcpOption internal const int MAX_FILTERS = 255 / IpV4AddressWithMask.SizeOf; /// - /// create new DhcpPolicyFilterOption + /// create new DhcpPolicyFilterOption. /// /// Filters public DhcpPolicyFilterOption(IList filters) : base(DhcpOptionCode.PolicyFilter) @@ -72,7 +72,7 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { @@ -83,7 +83,7 @@ public override byte Length } /// - /// Filters + /// Filters. /// public IReadOnlyCollection Filters { @@ -92,7 +92,7 @@ public IReadOnlyCollection Filters } /// - /// Represents and IpV4Address with Mask + /// Represents and IpV4Address with Mask. /// public struct IpV4AddressWithMask : IEquatable { @@ -121,7 +121,7 @@ public IpV4Address Mask } /// - /// create new IpV4AddressWithMask + /// create new IpV4AddressWithMask. /// /// Address /// Mask diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs index 2aaf55ab..88633db5 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpPostOfficeProtocolServerOption : DhcpAddressListOption { /// - /// create new DhcpPostOfficeProtocolServerOption + /// create new DhcpPostOfficeProtocolServerOption. /// /// public DhcpPostOfficeProtocolServerOption(IList addresses) : base(addresses, DhcpOptionCode.PostOfficeProtocolServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs index 2c8b3512..26292c44 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpRebindingTimeValueOption : DhcpUIntOption { /// - /// create new DhcpRebindingTimeValueOption + /// create new DhcpRebindingTimeValueOption. /// /// T1 Interval public DhcpRebindingTimeValueOption(uint t2Interval) : base(t2Interval, DhcpOptionCode.RebindingTimeValue) @@ -34,7 +34,7 @@ internal static DhcpRebindingTimeValueOption Read(DataSegment data, ref int offs /// /// RFC 2132. - /// T2 Interval + /// T2 Interval. /// public uint T2Interval { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs index 86427bc3..2ca77c3e 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpRenewalTimeValueOption : DhcpUIntOption { /// - /// DhcpRenewalTimeValueOption + /// DhcpRenewalTimeValueOption. /// /// public DhcpRenewalTimeValueOption(uint t1Interval) : base(t1Interval, DhcpOptionCode.RenewalTimeValue) @@ -34,7 +34,7 @@ internal static DhcpRenewalTimeValueOption Read(DataSegment data, ref int offset /// /// RFC 2132. - /// T1 Interval + /// T1 Interval. /// public uint T1Interval { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs index 4d6b0e82..71676662 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpRequestedIPAddressOption : DhcpSingleAddressOption { /// - /// create new DhcpRequestedIPAddressOption + /// create new DhcpRequestedIPAddressOption. /// /// Address public DhcpRequestedIPAddressOption(IpV4Address address) : base(address, DhcpOptionCode.RequestedIPAddress) @@ -35,7 +35,7 @@ internal static DhcpRequestedIPAddressOption Read(DataSegment data, ref int offs /// /// RFC 2132. - /// Address + /// Address. /// public IpV4Address Address { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs index de319625..552b93a1 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpResourceLocationServerOption : DhcpAddressListOption { /// - /// create new DhcpResourceLocationServerOption + /// create new DhcpResourceLocationServerOption. /// /// Addresses public DhcpResourceLocationServerOption(IList addresses) : base(addresses, DhcpOptionCode.ResourceLocationServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs index 9a4e8b91..4198feff 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpRootPathOption : DhcpStringOption { /// - /// create new DhcpRootPathOption + /// create new DhcpRootPathOption. /// /// Root Disk Pathname [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] @@ -35,7 +35,7 @@ internal static DhcpRootPathOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// Root Disk Pathname + /// Root Disk Pathname. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Pathname")] public string RootDiskPathname diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs index 8bd42926..b7f1489c 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpRouterOption : DhcpAddressListOption { /// - /// create new DhcpRouterOption + /// create new DhcpRouterOption. /// /// Addresses public DhcpRouterOption(IList addresses) : base(addresses, DhcpOptionCode.Router) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs index 845c11cb..e19bdfa9 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpRouterSolicitationAddressOption : DhcpSingleAddressOption { /// - /// create new DhcpRouterSolicitationAddressOption + /// create new DhcpRouterSolicitationAddressOption. /// /// Address public DhcpRouterSolicitationAddressOption(IpV4Address address) : base(address, DhcpOptionCode.RouterSolicitationAddress) @@ -35,7 +35,7 @@ internal static DhcpRouterSolicitationAddressOption Read(DataSegment data, ref i /// /// RFC 2132. - /// Address + /// Address. /// public IpV4Address Address { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs index 9bb04727..3633b66d 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs @@ -28,7 +28,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpServerIdentifierOption : DhcpSingleAddressOption { /// - /// create new DhcpServerIdentifierOption + /// create new DhcpServerIdentifierOption. /// /// Address public DhcpServerIdentifierOption(IpV4Address address) : base(address, DhcpOptionCode.ServerIdentifier) @@ -41,8 +41,8 @@ internal static DhcpServerIdentifierOption Read(DataSegment data, ref int offset } /// - /// RFC 2132 - /// Address + /// RFC 2132. + /// Address. /// public IpV4Address Address { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs index 5093fc53..b3e45b93 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpSimpleMailTransportProtocolServerOption : DhcpAddressListOption { /// - /// create new DhcpSimpleMailTransportProtocolServerOption + /// create new DhcpSimpleMailTransportProtocolServerOption. /// /// Addresses public DhcpSimpleMailTransportProtocolServerOption(IList addresses) : base(addresses, DhcpOptionCode.SimpleMailTransportProtocolServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSingleAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSingleAddressOption.cs index d631fce2..82308b1c 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSingleAddressOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSingleAddressOption.cs @@ -8,7 +8,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// Abstract class for all Dhcp-Options with a single Addresses + /// Abstract class for all Dhcp-Options with a single Addresses. /// public abstract class DhcpSingleAddressOption : DhcpOption { @@ -37,7 +37,7 @@ internal override void Write(byte[] buffer, ref int offset) /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -45,7 +45,7 @@ public override byte Length } /// - /// The real value of the SingleAddressOption + /// The real value of the SingleAddressOption. /// protected IpV4Address InternalValue { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs index 1c1c37c1..04b5bf12 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs @@ -30,7 +30,7 @@ public class DhcpStaticRouteOption : DhcpOption internal const int MAX_ROUTES = 255 / 8; /// - /// create new DhcpStaticRouteOption + /// create new DhcpStaticRouteOption. /// /// Routes public DhcpStaticRouteOption(IList routes) : base(DhcpOptionCode.StaticRoute) @@ -71,7 +71,7 @@ internal override void Write(byte[] buffer, ref int offset) } /// - /// Length of the Dhcp-Option + /// Length of the Dhcp-Option. /// public override byte Length { @@ -82,7 +82,7 @@ public override byte Length } /// - /// Routes + /// Routes. /// public IReadOnlyCollection Routes { @@ -91,7 +91,7 @@ public IReadOnlyCollection Routes } /// - /// Mapping between Ipv$Address and Route Address + /// Mapping between Ipv$Address and Route Address. /// public struct IpV4AddressRoute : IEquatable { @@ -101,7 +101,7 @@ public struct IpV4AddressRoute : IEquatable public const int SizeOf = IpV4Address.SizeOf + IpV4Address.SizeOf; /// - /// Destination Address + /// Destination Address. /// public IpV4Address Destination @@ -111,7 +111,7 @@ public IpV4Address Destination } /// - /// Router-IP + /// Router-IP. /// public IpV4Address Router { @@ -120,7 +120,7 @@ public IpV4Address Router } /// - /// create new IpV4AddressRoute + /// create new IpV4AddressRoute. /// /// Destination IP /// Router IP diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs index b0d54f67..4561182d 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpStreetTalkDirectoryAssistanceServerOption : DhcpAddressListOption { /// - /// create new DhcpStreetTalkDirectoryAssistanceServerOption + /// create new DhcpStreetTalkDirectoryAssistanceServerOption. /// /// Addresses public DhcpStreetTalkDirectoryAssistanceServerOption(IList addresses) : base(addresses, DhcpOptionCode.StreetTalkDirectoryAssistanceServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs index 27e8877b..55abda4e 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpStreetTalkServerOption : DhcpAddressListOption { /// - /// create new DhcpStreetTalkServerOption + /// create new DhcpStreetTalkServerOption. /// /// Addresses public DhcpStreetTalkServerOption(IList addresses) : base(addresses, DhcpOptionCode.StreetTalkServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStringOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStringOption.cs index efd498be..25909a0e 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStringOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStringOption.cs @@ -7,7 +7,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// + /// Abstract class for all Dhcp-Options with a string property /// public abstract class DhcpStringOption : DhcpOption { @@ -32,7 +32,7 @@ internal override void Write(byte[] buffer, ref int offset) /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -43,7 +43,7 @@ public override byte Length } /// - /// The real value of the StringOption + /// The real value of the StringOption. /// protected string InternalValue { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs index 8558231e..b4019966 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs @@ -23,7 +23,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpSubnetMaskOption : DhcpSingleAddressOption { /// - /// create new DhcpSubnetMaskOption + /// create new DhcpSubnetMaskOption. /// /// Subnet Mask> public DhcpSubnetMaskOption(IpV4Address subnetMask) : base(subnetMask, DhcpOptionCode.SubnetMask) @@ -37,7 +37,7 @@ internal static DhcpSubnetMaskOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// Subnet Mask + /// Subnet Mask. /// public IpV4Address SubnetMask { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs index 1484af00..4917d676 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpSwapServerOption : DhcpSingleAddressOption { /// - /// create new DhcpSwapServerOption + /// create new DhcpSwapServerOption. /// /// Swap Server Address public DhcpSwapServerOption(IpV4Address swapServerAddress) : base(swapServerAddress, DhcpOptionCode.SwapServer) @@ -34,7 +34,7 @@ internal static DhcpSwapServerOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// Swap Server Address + /// Swap Server Address. /// public IpV4Address SwapServerAddress { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs index a23572a8..dd42f6be 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpTFtpServerNameOption : DhcpStringOption { /// - /// create new DhcpTFtpServerNameOption + /// create new DhcpTFtpServerNameOption. /// /// TFTP server public DhcpTFtpServerNameOption(string tfptServer) : base(tfptServer, DhcpOptionCode.TfptServerName) @@ -34,7 +34,7 @@ internal static DhcpTFtpServerNameOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// TFTP server + /// TFTP server. /// public string TFtpServer { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs index 4cb984b9..794f1977 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpTcpDefaultTtlOption : DhcpByteOption { /// - /// create new DhcpTcpDefaultTtlOption + /// create new DhcpTcpDefaultTtlOption. /// /// TTL public DhcpTcpDefaultTtlOption(byte ttl) : base(ttl, DhcpOptionCode.TcpDefaultTtl) @@ -35,7 +35,7 @@ internal static DhcpTcpDefaultTtlOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// TTL + /// TTL. /// public byte Ttl { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs index 02f727e8..f918e3f7 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpTcpKeepaliveGarbageOption : DhcpBooleanOption { /// - /// create new DhcpTcpKeepaliveGarbageOption + /// create new DhcpTcpKeepaliveGarbageOption. /// /// Value public DhcpTcpKeepaliveGarbageOption(bool value) : base(value, DhcpOptionCode.TcpKeepaliveGarbage) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs index 13e6bdf2..5af34ea8 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpTcpKeepaliveIntervalOption : DhcpUIntOption { /// - /// create new DhcpTcpKeepaliveIntervalOption + /// create new DhcpTcpKeepaliveIntervalOption. /// /// Time public DhcpTcpKeepaliveIntervalOption(uint time) : base(time, DhcpOptionCode.TcpKeepaliveInterval) @@ -34,7 +34,7 @@ internal static DhcpTcpKeepaliveIntervalOption Read(DataSegment data, ref int of /// /// RFC 2132. - /// Time + /// Time. /// A value of zero /// indicates that the client should not generate keepalive messages on /// connections unless specifically requested by an application. diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs index 381fd4c7..c3dec98a 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs @@ -20,7 +20,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpTimeOffsetOption : DhcpIntOption { /// - /// create new DhcpTimeOffsetOption + /// create new DhcpTimeOffsetOption. /// /// Time Offset public DhcpTimeOffsetOption(int timeOffset) : base(timeOffset, DhcpOptionCode.TimeOffset) @@ -34,7 +34,7 @@ internal static DhcpTimeOffsetOption Read(DataSegment data, ref int offset) /// /// RFC 2132. - /// Time Offset + /// Time Offset. /// The offset is /// expressed as a two's complement 32-bit integer. A positive offset /// indicates a location east of the zero meridian and a negative offset diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs index 8ffb567c..9cb915d9 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpTimeServerOption : DhcpAddressListOption { /// - /// create new DhcpTimeServerOption + /// create new DhcpTimeServerOption. /// /// Addresses public DhcpTimeServerOption(IList addresses) : base(addresses, DhcpOptionCode.TimeServer) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs index c6c52c1e..dcd9b980 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs @@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpTrailerEncapsulationOption : DhcpBooleanOption { /// - /// create new DhcpTrailerEncapsulationOption + /// create new DhcpTrailerEncapsulationOption. /// /// Value public DhcpTrailerEncapsulationOption(bool value) : base(value, DhcpOptionCode.TrailerEncapsulation) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUIntOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUIntOption.cs index 1756ef4e..16ff324b 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUIntOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUIntOption.cs @@ -8,7 +8,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// Abstract class for all Dhcp-Options with a uint value + /// Abstract class for all Dhcp-Options with a uint value. /// public class DhcpUIntOption : DhcpOption { @@ -37,7 +37,7 @@ internal override void Write(byte[] buffer, ref int offset) /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -48,7 +48,7 @@ public override byte Length } /// - /// The real value of the UIntOption + /// The real value of the UIntOption. /// protected uint InternalValue { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUShortOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUShortOption.cs index 016d083f..3dad87e5 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUShortOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpUShortOption.cs @@ -8,7 +8,7 @@ namespace PcapDotNet.Packets.Dhcp.Options { /// - /// Abstract class for all Dhcp-Options with a ushort value + /// Abstract class for all Dhcp-Options with a ushort value. /// public class DhcpUShortOption : DhcpOption { @@ -37,7 +37,7 @@ internal override void Write(byte[] buffer, ref int offset) /// /// RFC 2132. - /// Value of Length-Field + /// Value of Length-Field. /// public override byte Length { @@ -48,7 +48,7 @@ public override byte Length } /// - /// The real value of the UIntOption + /// The real value of the UIntOption. /// protected ushort InternalValue { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs index 9515aa69..153875ef 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs @@ -28,7 +28,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpVendorClassidentifierOption : DhcpDataSegmentOption { /// - /// create new DhcpVendorClassidentifierOption + /// create new DhcpVendorClassidentifierOption. /// /// Vendor class Identifier public DhcpVendorClassidentifierOption(DataSegment vendorClassIdentifier) : base(vendorClassIdentifier, DhcpOptionCode.VendorClassidentifier) @@ -42,7 +42,7 @@ internal static DhcpVendorClassidentifierOption Read(DataSegment data, ref int o /// /// RFC 2132. - /// Vendor class Identifier + /// Vendor class Identifier. /// public DataSegment VendorClassIdentifier { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs index ff5e9876..cd3b87b7 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs @@ -28,7 +28,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpVendorSpecificInformationOption : DhcpDataSegmentOption { /// - /// create new DhcpVendorSpecificInformationOption + /// create new DhcpVendorSpecificInformationOption. /// /// Vendor-specific information public DhcpVendorSpecificInformationOption(DataSegment vendorSpecificInformation) : base(vendorSpecificInformation, DhcpOptionCode.VendorSpecificInformation) @@ -42,7 +42,7 @@ internal static DhcpVendorSpecificInformationOption Read(DataSegment data, ref i /// /// RFC 2132 - /// Vendor-specific information + /// Vendor-specific information. /// public DataSegment VendorSpecificInformation { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs index e04210e5..4f603905 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs @@ -23,7 +23,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpXWindowSystemDisplayManagerOption : DhcpAddressListOption { /// - /// create new DhcpXWindowSystemDisplayManagerOption + /// create new DhcpXWindowSystemDisplayManagerOption. /// /// Addresses public DhcpXWindowSystemDisplayManagerOption(IList addresses) : base(addresses, DhcpOptionCode.XWindowSystemDisplayManager) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs index 0fc9f64d..69053b10 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs @@ -22,7 +22,7 @@ namespace PcapDotNet.Packets.Dhcp.Options public class DhcpXWindowSystemFontServerOption : DhcpAddressListOption { /// - /// create new DhcpXWindowSystemFontServerOption + /// create new DhcpXWindowSystemFontServerOption. /// /// Addresses public DhcpXWindowSystemFontServerOption(IList addresses) : base(addresses, DhcpOptionCode.XWindowSystemFontServer) From ae3f79ca9fde076efc6b57cf13e938e938e6f763 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sun, 15 Jan 2017 22:38:50 +0100 Subject: [PATCH 11/19] Replace "true if" with "Whether" --- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 2 +- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index a58d6dd6..5fc26b61 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -217,7 +217,7 @@ public string BootFileName /// /// RFC 2131. - /// true if the magic dhcp-cookie is set. If set this datagram is a dhcp-datagram. Otherwise it's a bootp-datagram. + /// Whether the magic dhcp-cookie is set. If set this datagram is a dhcp-datagram. Otherwise it's a bootp-datagram. /// public bool IsDhcp { diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs index ee14e574..b6866bc5 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs @@ -108,7 +108,7 @@ public MacAddress ClientMacAddress public string BootFileName { get; set; } /// - /// true if the magic dhcp-cookie is set. If set this datagram is a dhcp-datagram. Otherwise it's a bootp-datagram. + /// Whether the magic dhcp-cookie is set. If set this datagram is a dhcp-datagram. Otherwise it's a bootp-datagram. /// public bool IsDhcp { get; set; } From c1550dd0a580d7ed6bbef94ff513d1b9f1cba744 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sun, 15 Jan 2017 22:45:28 +0100 Subject: [PATCH 12/19] DHCP_MAGIC_COOKIE int --> uint sizeof instead of constant value --- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index 5fc26b61..9eef1be0 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -70,7 +70,7 @@ private static class Offset public const int OptionsWithMagicCookie = 240; } - internal const int DHCP_MAGIC_COOKIE = 0x63825363; + internal const uint DHCP_MAGIC_COOKIE = 0x63825363; /// /// RFC 2131. @@ -223,9 +223,9 @@ public bool IsDhcp { get { - if (Length >= Offset.Options + 4) + if (Length >= Offset.Options + sizeof(uint)) { - return ReadInt(Offset.Options, Endianity.Big) == DHCP_MAGIC_COOKIE; + return ReadUInt(Offset.Options, Endianity.Big) == DHCP_MAGIC_COOKIE; } else { @@ -284,7 +284,7 @@ internal static int GetLength(bool isDhcp, IList options) if (options != null) { - length += options.Sum(p => 1 + (!(p is DhcpPadOption || p is DhcpEndOption) ? 1 : 0) + p.Length); //Type + Len? + Option + length += options.Sum(option => sizeof(byte) + (!(option.OptionCode == DhcpOptionCode.Pad || option.OptionCode == DhcpOptionCode.End) ? sizeof(byte) : 0) + option.Length); // Type + Len? + Option } return length; From 41bc4921c7af22a0334de755dfb153dcbcc7e45d Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sun, 15 Jan 2017 22:55:33 +0100 Subject: [PATCH 13/19] Be consistent with the name - either "op" or "messageType". (also some changes for "End comments with periods.") --- .../RandomDhcpExtensions.cs | 2 +- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 10 +++++----- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs | 4 ++-- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs | 6 +++--- .../src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs index 80777e99..bcbe3960 100644 --- a/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs +++ b/PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDhcpExtensions.cs @@ -21,7 +21,7 @@ public static DhcpLayer NextDhcpLayer(this Random random) const int MaxOptions = 10; DhcpLayer dhcpLayer = new DhcpLayer(); - dhcpLayer.MessageType = random.NextEnum(); + dhcpLayer.MessageOPCode = random.NextEnum(); dhcpLayer.HardwareType = random.NextEnum(Enum.GetValues(typeof(ArpHardwareType)).Cast().Where(p => ((short)p) > byte.MaxValue)); dhcpLayer.HardwareAddressLength = random.NextByte(16); dhcpLayer.Hops = random.NextByte(); diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index 9eef1be0..b2affc61 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -76,9 +76,9 @@ private static class Offset /// RFC 2131. /// Message op code. /// - public DhcpMessageType MessageType + public DhcpMessageOPCode MessageOPCode { - get { return (DhcpMessageType)this[Offset.Op]; } + get { return (DhcpMessageOPCode)this[Offset.Op]; } } /// @@ -254,7 +254,7 @@ public override ILayer ExtractLayer() { return new DhcpLayer { - MessageType = MessageType, + MessageOPCode = MessageOPCode, HardwareType = HardwareType, HardwareAddressLength = HardwareAddressLength, Hops = Hops, @@ -290,9 +290,9 @@ internal static int GetLength(bool isDhcp, IList options) return length; } - internal static void Write(byte[] buffer, int offset, DhcpMessageType messageType, ArpHardwareType hardwareType, byte hardwareAddressLength, byte hops, uint transactionId, ushort secondsElapsed, DhcpFlags flags, IpV4Address clientIpAddress, IpV4Address yourClientIpAddress, IpV4Address nextServerIpAddress, IpV4Address relayAgentIpAddress, DataSegment clientHardwareAddress, string serverHostName, string bootFileName, bool isDhcp, IList options) + internal static void Write(byte[] buffer, int offset, DhcpMessageOPCode messageOPCode, ArpHardwareType hardwareType, byte hardwareAddressLength, byte hops, uint transactionId, ushort secondsElapsed, DhcpFlags flags, IpV4Address clientIpAddress, IpV4Address yourClientIpAddress, IpV4Address nextServerIpAddress, IpV4Address relayAgentIpAddress, DataSegment clientHardwareAddress, string serverHostName, string bootFileName, bool isDhcp, IList options) { - buffer.Write(ref offset, (byte)messageType); + buffer.Write(ref offset, (byte)messageOPCode); buffer.Write(ref offset, (byte)hardwareType); buffer.Write(ref offset, hardwareAddressLength); buffer.Write(ref offset, hops); diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs index 56f1a251..4ac398d8 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs @@ -24,13 +24,13 @@ public enum DhcpFlags : ushort { /// /// RFCs 2131. - /// Response as Unicast + /// Response as Unicast. /// Unicast = 0 << 15, /// /// RFCs 2131. - /// Response as Broadcast + /// Response as Broadcast. /// Broadcast = 1 << 15 } diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs index b6866bc5..05590f1d 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs @@ -20,7 +20,7 @@ public sealed class DhcpLayer : SimpleLayer, IEquatable /// /// Message op code. /// - public DhcpMessageType MessageType { get; set; } + public DhcpMessageOPCode MessageOPCode { get; set; } /// /// Hardware address type. @@ -137,7 +137,7 @@ public override int Length protected override void Write(byte[] buffer, int offset) { DhcpDatagram.Write(buffer, offset, - MessageType, HardwareType, HardwareAddressLength, Hops, TransactionId, SecondsElapsed, DhcpFlags, ClientIpAddress, YourClientIpAddress, + MessageOPCode, HardwareType, HardwareAddressLength, Hops, TransactionId, SecondsElapsed, DhcpFlags, ClientIpAddress, YourClientIpAddress, NextServerIpAddress, RelayAgentIpAddress, ClientHardwareAddress, ServerHostName, BootFileName, IsDhcp, Options); } @@ -147,7 +147,7 @@ protected override void Write(byte[] buffer, int offset) public bool Equals(DhcpLayer other) { return other != null && - Equals(MessageType, other.MessageType) && + Equals(MessageOPCode, other.MessageOPCode) && Equals(HardwareType, other.HardwareType) && Equals(HardwareAddressLength, other.HardwareAddressLength) && Equals(Hops, other.Hops) && diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs index 3e70551b..b70af703 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs @@ -10,17 +10,17 @@ namespace PcapDotNet.Packets.Dhcp /// RFCs 2131. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] - public enum DhcpMessageType : byte + public enum DhcpMessageOPCode : byte { /// /// RFC 2131. - /// Indicates a Boot Request + /// Indicates a Boot Request. /// BootRequest = 1, /// /// RFC 2131. - /// Indicates a Boot Reply + /// Indicates a Boot Reply. /// BootReply = 2 } From a0d8c6de2568a6e6e7b661f73d52a700f5f245a8 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sun, 15 Jan 2017 23:04:01 +0100 Subject: [PATCH 14/19] fix compilation --- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index b2affc61..0ea10684 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -290,9 +290,9 @@ internal static int GetLength(bool isDhcp, IList options) return length; } - internal static void Write(byte[] buffer, int offset, DhcpMessageOPCode messageOPCode, ArpHardwareType hardwareType, byte hardwareAddressLength, byte hops, uint transactionId, ushort secondsElapsed, DhcpFlags flags, IpV4Address clientIpAddress, IpV4Address yourClientIpAddress, IpV4Address nextServerIpAddress, IpV4Address relayAgentIpAddress, DataSegment clientHardwareAddress, string serverHostName, string bootFileName, bool isDhcp, IList options) + internal static void Write(byte[] buffer, int offset, DhcpMessageOPCode messageType, ArpHardwareType hardwareType, byte hardwareAddressLength, byte hops, uint transactionId, ushort secondsElapsed, DhcpFlags flags, IpV4Address clientIpAddress, IpV4Address yourClientIpAddress, IpV4Address nextServerIpAddress, IpV4Address relayAgentIpAddress, DataSegment clientHardwareAddress, string serverHostName, string bootFileName, bool isDhcp, IList options) { - buffer.Write(ref offset, (byte)messageOPCode); + buffer.Write(ref offset, (byte)messageType); buffer.Write(ref offset, (byte)hardwareType); buffer.Write(ref offset, hardwareAddressLength); buffer.Write(ref offset, hops); From 8b2f118d80a689e198cbe78d49805139628f45b2 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sun, 15 Jan 2017 23:38:48 +0100 Subject: [PATCH 15/19] Consider also writing the null termination. Consider relying on the defined offsets instead of using ref. --- .../PcapDotNet.Packets/Dhcp/DhcpDatagram.cs | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs index 0ea10684..a1429391 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs @@ -292,33 +292,40 @@ internal static int GetLength(bool isDhcp, IList options) internal static void Write(byte[] buffer, int offset, DhcpMessageOPCode messageType, ArpHardwareType hardwareType, byte hardwareAddressLength, byte hops, uint transactionId, ushort secondsElapsed, DhcpFlags flags, IpV4Address clientIpAddress, IpV4Address yourClientIpAddress, IpV4Address nextServerIpAddress, IpV4Address relayAgentIpAddress, DataSegment clientHardwareAddress, string serverHostName, string bootFileName, bool isDhcp, IList options) { - buffer.Write(ref offset, (byte)messageType); - buffer.Write(ref offset, (byte)hardwareType); - buffer.Write(ref offset, hardwareAddressLength); - buffer.Write(ref offset, hops); - buffer.Write(ref offset, transactionId, Endianity.Big); - buffer.Write(ref offset, secondsElapsed, Endianity.Big); - buffer.Write(ref offset, (ushort)flags, Endianity.Big); - buffer.Write(ref offset, clientIpAddress, Endianity.Big); - buffer.Write(ref offset, yourClientIpAddress, Endianity.Big); - buffer.Write(ref offset, nextServerIpAddress, Endianity.Big); - buffer.Write(ref offset, relayAgentIpAddress, Endianity.Big); - buffer.Write(offset, clientHardwareAddress); - offset += Offset.Sname - Offset.ChAddr; + buffer.Write(offset + Offset.Op, (byte)messageType); + buffer.Write(offset + Offset.Htype, (byte)hardwareType); + buffer.Write(offset + Offset.Hlen, hardwareAddressLength); + buffer.Write(offset + Offset.Hops, hops); + buffer.Write(offset + Offset.Xid, transactionId, Endianity.Big); + buffer.Write(offset + Offset.Secs, secondsElapsed, Endianity.Big); + buffer.Write(offset + Offset.Flags, (ushort)flags, Endianity.Big); + buffer.Write(offset + Offset.CiAddr, clientIpAddress, Endianity.Big); + buffer.Write(offset + Offset.YiAddr, yourClientIpAddress, Endianity.Big); + buffer.Write(offset + Offset.SiAddr, nextServerIpAddress, Endianity.Big); + buffer.Write(offset + Offset.GiAddr, relayAgentIpAddress, Endianity.Big); + buffer.Write(offset + Offset.ChAddr, clientHardwareAddress); + + buffer.Write(offset + Offset.Sname, new DataSegment(new byte[Offset.File - Offset.Sname])); // ensure 0 if (serverHostName != null) { - buffer.Write(offset, new DataSegment(Encoding.ASCII.GetBytes(serverHostName))); + buffer.Write(offset + Offset.Sname, new DataSegment(Encoding.ASCII.GetBytes(serverHostName))); } - offset += Offset.File - Offset.Sname; + buffer.Write(offset + Offset.File, new DataSegment(new byte[Offset.Options - Offset.File])); // ensure 0 if (bootFileName != null) { - buffer.Write(offset, new DataSegment(Encoding.ASCII.GetBytes(bootFileName))); + buffer.Write(offset + Offset.File, new DataSegment(Encoding.ASCII.GetBytes(bootFileName))); } - offset += Offset.Options - Offset.File; + if (isDhcp) { - buffer.Write(ref offset, DHCP_MAGIC_COOKIE, Endianity.Big); + buffer.Write(offset + Offset.Options, DHCP_MAGIC_COOKIE, Endianity.Big); + offset += Offset.OptionsWithMagicCookie; } + else + { + offset += Offset.Options; + } + if (options != null) { foreach (DhcpOption option in options) From f10975fb8f4cd33b68f50b052725ce7dc5dc8a51 Mon Sep 17 00:00:00 2001 From: vbBerni Date: Sun, 15 Jan 2017 23:45:05 +0100 Subject: [PATCH 16/19] Replace "RFCs" with "RFC". --- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs | 6 +++--- PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs index 4ac398d8..f08f48ae 100644 --- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs +++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpFlags.cs @@ -7,7 +7,7 @@ namespace PcapDotNet.Packets.Dhcp { /// - /// RFCs 2131. + /// RFC 2131. ///
     ///                     1 1 1 1 1 1
     /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
@@ -23,13 +23,13 @@ namespace PcapDotNet.Packets.Dhcp
     public enum DhcpFlags : ushort
     {
         /// 
-        /// RFCs 2131.
+        /// RFC 2131.
         /// Response as Unicast.
         /// 
         Unicast = 0 << 15,
 
         /// 
-        /// RFCs 2131.
+        /// RFC 2131.
         /// Response as Broadcast.
         /// 
         Broadcast = 1 << 15
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs
index b70af703..6ca39216 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpMessageType.cs
@@ -7,7 +7,7 @@
 namespace PcapDotNet.Packets.Dhcp
 {
     /// 
-    /// RFCs 2131.
+    /// RFC 2131.
     /// 
     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")]
     public enum DhcpMessageOPCode : byte

From 8a31f3311936ea200db29812dc288afda411d9b8 Mon Sep 17 00:00:00 2001
From: vbBerni 
Date: Sun, 15 Jan 2017 23:55:15 +0100
Subject: [PATCH 17/19] Instead of having a field for "flags", split it to the
 different flags (RFC 2131 only has Broadcast).

---
 .../PcapDotNet.Packets/Dhcp/DhcpDatagram.cs   |  8 +++++++
 .../src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs  | 22 +++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
index a1429391..c440adc1 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
@@ -136,6 +136,14 @@ public DhcpFlags Flags
             get { return (DhcpFlags)ReadUShort(Offset.Flags, Endianity.Big); }
         }
 
+        /// 
+        /// Whether the broadcast-flag is set.
+        /// 
+        public bool Broadcast
+        {
+            get { return Flags.HasFlag(DhcpFlags.Broadcast); }
+        }
+
         /// 
         /// RFC 2131.
         /// Client IP address; only filled in if client is in BOUND, RENEW or REBINDING state and can respond to ARP requests.
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs
index 05590f1d..57dd7a22 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs
@@ -53,6 +53,28 @@ public sealed class DhcpLayer : SimpleLayer, IEquatable
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")]
         public DhcpFlags DhcpFlags { get; set; }
 
+        /// 
+        /// Whether the broadcast-flag is set.
+        /// 
+        public bool Broadcast
+        {
+            get
+            {
+                return DhcpFlags.HasFlag(DhcpFlags.Broadcast);
+            }
+            set
+            {
+                if (value)
+                {
+                    DhcpFlags |= DhcpFlags.Broadcast;
+                }
+                else
+                {
+                    DhcpFlags &= ~DhcpFlags.Broadcast;
+                }
+            }
+        }
+
         /// 
         /// Client IP address; only filled in if client is in BOUND, RENEW or REBINDING state and can respond to ARP requests.
         /// 

From 6d0b4dd1161440d4cecd5d785a4eab75ec9e36a1 Mon Sep 17 00:00:00 2001
From: vbBerni 
Date: Wed, 18 Jan 2017 13:05:48 +0100
Subject: [PATCH 18/19] using registration mechanism for the options

---
 .../PcapDotNet.Packets/Dhcp/DhcpDatagram.cs   |   2 +-
 .../Dhcp/DhcpOptionFactory.cs                 |  58 ++++
 .../DhcpOptionReadRegistrationAttribute.cs    |  20 ++
 .../Dhcp/Options/DhcpARPCacheTimeoutOption.cs |   1 +
 .../Options/DhcpAllSubnetsAreLocalOption.cs   |   1 +
 .../Dhcp/Options/DhcpBootFileSizeOption.cs    |   1 +
 .../Dhcp/Options/DhcpBootfileNameOption.cs    |   1 +
 .../Options/DhcpBroadcastAddressOption.cs     |   1 +
 .../Options/DhcpClientIdentifierOption.cs     |   1 +
 .../Dhcp/Options/DhcpCookieServerOption.cs    |   1 +
 .../Options/DhcpDefaultFingerServerOption.cs  |   1 +
 .../Options/DhcpDefaultIPTimeToLiveOption.cs  |   1 +
 ...hcpDefaultInternetRelayChatServerOption.cs |   1 +
 .../DhcpDefaultWorldWideWebServerOption.cs    |   1 +
 .../Dhcp/Options/DhcpDomainNameOption.cs      |   1 +
 .../Options/DhcpDomainNameServerOption.cs     |   1 +
 .../Dhcp/Options/DhcpEndOption.cs             |   1 +
 .../DhcpEthernetEncapsulationOption.cs        |   1 +
 .../Dhcp/Options/DhcpExtensionsPathOption.cs  |   1 +
 .../Dhcp/Options/DhcpHostNameOption.cs        |   1 +
 .../Options/DhcpIPAddressLeaseTimeOption.cs   |   1 +
 .../Options/DhcpIPForwardingEnableOption.cs   |   1 +
 .../Dhcp/Options/DhcpImpressServerOption.cs   |   1 +
 .../Dhcp/Options/DhcpInterfaceMtuOption.cs    |   1 +
 .../Dhcp/Options/DhcpLogServerOption.cs       |   1 +
 .../Dhcp/Options/DhcpLprServerOption.cs       |   1 +
 .../Dhcp/Options/DhcpMaskSupplierOption.cs    |   1 +
 ...DhcpMaximumDatagramReassemblySizeOption.cs |   1 +
 .../DhcpMaximumDhcpMessageSizeOption.cs       |   1 +
 .../Dhcp/Options/DhcpMeritDumpFileOption.cs   |   1 +
 .../Dhcp/Options/DhcpMessageOption.cs         |   1 +
 .../Dhcp/Options/DhcpMessageTypeOption.cs     |   1 +
 .../Options/DhcpMobileIPHomeAgentOption.cs    |   1 +
 .../Dhcp/Options/DhcpNameServerOption.cs      |   1 +
 ...erTcpIpDatagramDistributionServerOption.cs |   2 +
 .../DhcpNetBiosOverTcpIpNameServerOption.cs   |   2 +
 .../DhcpNetBiosOverTcpIpNodeTypeOption.cs     |   1 +
 .../DhcpNetBiosOverTcpIpScopeOption.cs        |   1 +
 .../DhcpNetworkInformationServersOption.cs    |   1 +
 ...cpNetworkInformationServiceDomainOption.cs |   1 +
 ...tworkInformationServicePlusDomainOption.cs |   1 +
 ...workInformationServicePlusServersOption.cs |   1 +
 ...etworkNewsTransportProtocolServerOption.cs |   1 +
 .../DhcpNetworkTimeProtocolServersOption.cs   |   1 +
 .../DhcpNonLocalSourceRoutingEnableOption.cs  |   1 +
 .../Dhcp/Options/DhcpOption.cs                | 269 +-----------------
 .../Dhcp/Options/DhcpOptionOverloadOption.cs  |   1 +
 .../Dhcp/Options/DhcpPadOption.cs             |   1 +
 .../Options/DhcpParameterRequestListOption.cs |   1 +
 .../Options/DhcpPathMtuAgingTimeoutOption.cs  |   1 +
 .../Options/DhcpPathMtuPlateauTableOption.cs  |   1 +
 .../Options/DhcpPerformMaskDiscoveryOption.cs |   1 +
 .../DhcpPerformRouterDiscoveryOption.cs       |   1 +
 .../Dhcp/Options/DhcpPolicyFilterOption.cs    |   1 +
 .../DhcpPostOfficeProtocolServerOption.cs     |   1 +
 .../Options/DhcpRebindingTimeValueOption.cs   |   1 +
 .../Options/DhcpRenewalTimeValueOption.cs     |   1 +
 .../Options/DhcpRequestedIPAddressOption.cs   |   1 +
 .../DhcpResourceLocationServerOption.cs       |   1 +
 .../Dhcp/Options/DhcpRootPathOption.cs        |   1 +
 .../Dhcp/Options/DhcpRouterOption.cs          |   1 +
 .../DhcpRouterSolicitationAddressOption.cs    |   1 +
 .../Options/DhcpServerIdentifierOption.cs     |   3 +-
 ...SimpleMailTransportProtocolServerOption.cs |   1 +
 .../Dhcp/Options/DhcpStaticRouteOption.cs     |   1 +
 ...reetTalkDirectoryAssistanceServerOption.cs |   1 +
 .../Options/DhcpStreetTalkServerOption.cs     |   1 +
 .../Dhcp/Options/DhcpSubnetMaskOption.cs      |   1 +
 .../Dhcp/Options/DhcpSwapServerOption.cs      |   1 +
 .../Dhcp/Options/DhcpTFtpServerNameOption.cs  |   1 +
 .../Dhcp/Options/DhcpTcpDefaultTtlOption.cs   |   1 +
 .../Options/DhcpTcpKeepaliveGarbageOption.cs  |   1 +
 .../Options/DhcpTcpKeepaliveIntervalOption.cs |   1 +
 .../Dhcp/Options/DhcpTimeOffsetOption.cs      |   1 +
 .../Dhcp/Options/DhcpTimeServerOption.cs      |   1 +
 .../Options/DhcpTrailerEncapsulationOption.cs |   1 +
 .../DhcpVendorClassidentifierOption.cs        |   1 +
 .../DhcpVendorSpecificInformationOption.cs    |   1 +
 .../DhcpXWindowSystemDisplayManagerOption.cs  |   1 +
 .../DhcpXWindowSystemFontServerOption.cs      |   1 +
 .../PcapDotNet.Packets.csproj                 |   2 +
 81 files changed, 161 insertions(+), 270 deletions(-)
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpOptionFactory.cs
 create mode 100644 PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpOptionReadRegistrationAttribute.cs

diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
index c440adc1..92df8a48 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
@@ -371,7 +371,7 @@ private void ParseOptions()
                 int offset = IsDhcp ? Offset.OptionsWithMagicCookie : Offset.Options;
                 while (offset < Length)
                 {
-                    options.Add(DhcpOption.CreateInstance(this, ref offset));
+                    options.Add(DhcpOptionFactory.CreateInstance(this, ref offset));
                 }
                 _options = new ReadOnlyCollection(options);
             }
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpOptionFactory.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpOptionFactory.cs
new file mode 100644
index 00000000..8ea067e3
--- /dev/null
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpOptionFactory.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using PcapDotNet.Packets.Dhcp.Options;
+
+namespace PcapDotNet.Packets.Dhcp
+{
+    internal static class DhcpOptionFactory
+    {
+        internal static DhcpOption CreateInstance(DataSegment data, ref int offset)
+        {
+            DhcpOptionCode optionCode = (DhcpOptionCode)data[offset++];
+
+            MethodInfo readMethod;
+            if (_optionReaders.TryGetValue(optionCode, out readMethod))
+            {
+                object[] args = new object[] { data, offset };
+                DhcpOption option = (DhcpOption)readMethod.Invoke(null, args);
+                offset = (int)args[1];
+                return option;
+            }
+            else
+            {
+                return DhcpAnyOption.Read(data, ref offset);
+            }
+        }
+
+        private static Dictionary InitializeComplexOptions()
+        {
+            Dictionary optionReaders = new Dictionary();
+            foreach (MethodInfo readMethod in Assembly.GetExecutingAssembly().GetTypes().
+                Where(type=> typeof(DhcpOption).IsAssignableFrom(type))
+                .SelectMany(type => type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)))
+            {
+                DhcpOptionReadRegistrationAttribute readRegistrationAttribute = readMethod.GetCustomAttribute(false);
+                if (readRegistrationAttribute == null)
+                    continue;
+
+                if (typeof(DataSegment).IsAssignableFrom(readMethod.GetParameters()[0].ParameterType) &&
+                    readMethod.GetParameters()[1].ParameterType == typeof(int).MakeByRefType() &&
+                    typeof(DhcpOption).IsAssignableFrom(readMethod.ReturnType))
+                {
+                    optionReaders.Add(readRegistrationAttribute.OptionCode, readMethod);
+                }
+                else
+                {
+                    throw new NotSupportedException("Method " + readMethod + " has a DhcpOptionReadRegistrationAttribute but has no valid signature");
+                }
+            }
+            return optionReaders;
+        }
+        
+        private static readonly Dictionary _optionReaders = InitializeComplexOptions();
+    }
+}
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpOptionReadRegistrationAttribute.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpOptionReadRegistrationAttribute.cs
new file mode 100644
index 00000000..d0abfeae
--- /dev/null
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpOptionReadRegistrationAttribute.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using PcapDotNet.Packets.Dhcp.Options;
+
+namespace PcapDotNet.Packets.Dhcp
+{
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
+    internal sealed class DhcpOptionReadRegistrationAttribute : Attribute
+    {
+        public DhcpOptionReadRegistrationAttribute(DhcpOptionCode optionCode)
+        {
+            OptionCode = optionCode;
+        }
+
+        public DhcpOptionCode OptionCode { get; private set; }
+    }
+}
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs
index 90c44ce1..b38cf5d2 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpARPCacheTimeoutOption.cs
@@ -26,6 +26,7 @@ public DhcpArpCacheTimeoutOption(uint time) : base(time, DhcpOptionCode.ArpCache
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.ArpCacheTimeout)]
         internal static DhcpArpCacheTimeoutOption Read(DataSegment data, ref int offset)
         {
             return DhcpUIntOption.Read(data, ref offset, p => new DhcpArpCacheTimeoutOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs
index 6ddc6887..996a569c 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpAllSubnetsAreLocalOption.cs
@@ -30,6 +30,7 @@ public DhcpAllSubnetsAreLocalOption(bool value) : base(value, DhcpOptionCode.All
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.AllSubnetsAreLocal)]
         internal static DhcpAllSubnetsAreLocalOption Read(DataSegment data, ref int offset)
         {
             return DhcpBooleanOption.Read(data, ref offset, p => new DhcpAllSubnetsAreLocalOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs
index 7922c8af..16c37450 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootFileSizeOption.cs
@@ -28,6 +28,7 @@ public DhcpBootFileSizeOption(ushort fileSize) : base(fileSize, DhcpOptionCode.B
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.BootFileSize)]
         internal static DhcpBootFileSizeOption Read(DataSegment data, ref int offset)
         {
             return DhcpUShortOption.Read(data, ref offset, p => new DhcpBootFileSizeOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs
index 3414a649..dcbdd87d 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBootfileNameOption.cs
@@ -27,6 +27,7 @@ public DhcpBootfileNameOption(string bootfileName) : base(bootfileName, DhcpOpti
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.BootfileName)]
         internal static DhcpBootfileNameOption Read(DataSegment data, ref int offset)
         {
             return DhcpStringOption.Read(data, ref offset, p => new DhcpBootfileNameOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs
index 02dad5ff..5056fbc3 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpBroadcastAddressOption.cs
@@ -28,6 +28,7 @@ public DhcpBroadcastAddressOption(IpV4Address broadcastAddress) : base(broadcast
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.BroadcastAddress)]
         internal static DhcpBroadcastAddressOption Read(DataSegment data, ref int offset)
         {
             return DhcpSingleAddressOption.Read(data, ref offset, p => new DhcpBroadcastAddressOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs
index 5df4324f..c480ef23 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpClientIdentifierOption.cs
@@ -32,6 +32,7 @@ public DhcpClientIdentifierOption(byte type, DataSegment clientIdentifier) : bas
             ClientIdentifier = clientIdentifier;
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.ClientIdentifier)]
         internal static DhcpClientIdentifierOption Read(DataSegment data, ref int offset)
         {
             byte length = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs
index 1695ecd3..451e2aec 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpCookieServerOption.cs
@@ -29,6 +29,7 @@ public DhcpCookieServerOption(IList addresses) : base(addresses, Dh
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.CookieServer)]
         internal static DhcpCookieServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, (p) => new DhcpCookieServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs
index 758e7961..e9d5d3fe 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultFingerServerOption.cs
@@ -28,6 +28,7 @@ public DhcpDefaultFingerServerOption(IList addresses) : base(addres
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.DefaultFingerServer)]
         internal static DhcpDefaultFingerServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, (p) => new DhcpDefaultFingerServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs
index 989a328b..5b5f1735 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultIPTimeToLiveOption.cs
@@ -27,6 +27,7 @@ public DhcpDefaultIPTimeToLiveOption(byte ttl) : base(ttl, DhcpOptionCode.Defaul
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.DefaultIpTimeToLive)]
         internal static DhcpDefaultIPTimeToLiveOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpDefaultIPTimeToLiveOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs
index b848c7d6..16831bf4 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultInternetRelayChatServerOption.cs
@@ -28,6 +28,7 @@ public DhcpDefaultInternetRelayChatServerOption(IList addresses) :
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.DefaultInternetRelayChatServer)]
         internal static DhcpDefaultInternetRelayChatServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, (p) => new DhcpDefaultInternetRelayChatServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs
index a9d8e0d5..ee563aee 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDefaultWorldWideWebServerOption.cs
@@ -28,6 +28,7 @@ public DhcpDefaultWorldWideWebServerOption(IList addresses) : base(
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.DefaultWorldWideWebServer)]
         internal static DhcpDefaultWorldWideWebServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpDefaultWorldWideWebServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs
index 7dcc6e27..a40b2142 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameOption.cs
@@ -27,6 +27,7 @@ public DhcpDomainNameOption(string domainName) : base(domainName, DhcpOptionCode
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.DomainName)]
         internal static DhcpDomainNameOption Read(DataSegment data, ref int offset)
         {
             return DhcpStringOption.Read(data, ref offset, p => new DhcpDomainNameOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs
index c3d4bb06..9d81d9b0 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpDomainNameServerOption.cs
@@ -29,6 +29,7 @@ public DhcpDomainNameServerOption(IList addresses) : base(addresses
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.DomainNameServerServer)]
         internal static DhcpDomainNameServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpDomainNameServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs
index cba51838..e84d408a 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEndOption.cs
@@ -33,6 +33,7 @@ public override byte Length
             get { return 0; }
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.End)]
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "offset")]
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "data")]
         internal static DhcpEndOption Read(DataSegment data, ref int offset)
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs
index e64d11f3..fc84bcfd 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpEthernetEncapsulationOption.cs
@@ -29,6 +29,7 @@ public DhcpEthernetEncapsulationOption(bool value) : base(value, DhcpOptionCode.
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.EthernetEncapsulation)]
         internal static DhcpEthernetEncapsulationOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpEthernetEncapsulationOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs
index ad8f8543..cd41f3af 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpExtensionsPathOption.cs
@@ -32,6 +32,7 @@ public DhcpExtensionsPathOption(string extensionsPathname) : base(extensionsPath
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.ExtensionsPath)]
         internal static DhcpExtensionsPathOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpExtensionsPathOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs
index 0817330d..42baf093 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpHostNameOption.cs
@@ -29,6 +29,7 @@ public DhcpHostNameOption(string hostName) : base(hostName, DhcpOptionCode.HostN
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.HostName)]
         internal static DhcpHostNameOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpHostNameOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs
index be717efb..f3f5330f 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPAddressLeaseTimeOption.cs
@@ -29,6 +29,7 @@ public DhcpIPAddressLeaseTimeOption(uint leaseTime) : base(leaseTime, DhcpOption
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.IPAddressLeaseTime)]
         internal static DhcpIPAddressLeaseTimeOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpIPAddressLeaseTimeOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs
index c9233d55..116d40f9 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpIPForwardingEnableOption.cs
@@ -28,6 +28,7 @@ public DhcpIPForwardingEnableOption(bool value) : base(value, DhcpOptionCode.IPF
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.IPForwardingEnable)]
         internal static DhcpIPForwardingEnableOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpIPForwardingEnableOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs
index 4e02f0ea..71b7aaa3 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpImpressServerOption.cs
@@ -29,6 +29,7 @@ public DhcpImpressServerOption(IList addresses) : base(addresses, D
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.ImpressServer)]
         internal static DhcpImpressServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpImpressServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs
index 57e9f57c..a709d6e9 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpInterfaceMtuOption.cs
@@ -32,6 +32,7 @@ public DhcpInterfaceMtuOption(ushort mtu) : base(mtu, DhcpOptionCode.InterfaceMt
                 throw new ArgumentOutOfRangeException(nameof(mtu), mtu, "Minimum value of MTU is " + MIN_MTU);
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.InterfaceMtu)]
         internal static DhcpInterfaceMtuOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpInterfaceMtuOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs
index 624de0d1..0393c3d9 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLogServerOption.cs
@@ -29,6 +29,7 @@ public DhcpLogServerOption(IList addresses) : base(addresses, DhcpO
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.LogServer)]
         internal static DhcpLogServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpLogServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs
index 4ed7c3c4..73cd11e4 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpLprServerOption.cs
@@ -29,6 +29,7 @@ public DhcpLprServerOption(IList addresses) : base(addresses, DhcpO
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.LprServer)]
         internal static DhcpLprServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpLprServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs
index 9a0d3b3d..8be8ba82 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaskSupplierOption.cs
@@ -28,6 +28,7 @@ public DhcpMaskSupplierOption(bool value) : base(value, DhcpOptionCode.MaskSuppl
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.MaskSupplier)]
         internal static DhcpMaskSupplierOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpMaskSupplierOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs
index 42e32f91..7e3d10ee 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDatagramReassemblySizeOption.cs
@@ -31,6 +31,7 @@ public DhcpMaximumDatagramReassemblySizeOption(ushort size) : base(size, DhcpOpt
                 throw new ArgumentOutOfRangeException(nameof(size), size, "Minimum value of Size is " + MIN_SIZE);
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.MaximumDatagramReassemblySize)]
         internal static DhcpMaximumDatagramReassemblySizeOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpMaximumDatagramReassemblySizeOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs
index d9c86b21..d592e060 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMaximumDhcpMessageSizeOption.cs
@@ -30,6 +30,7 @@ public DhcpMaximumDhcpMessageSizeOption(ushort length) : base(length, DhcpOption
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.MaximumDhcpMessageSize)]
         internal static DhcpMaximumDhcpMessageSizeOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpMaximumDhcpMessageSizeOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs
index ac374f35..3e0e90d6 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMeritDumpFileOption.cs
@@ -28,6 +28,7 @@ public DhcpMeritDumpFileOption(string dumpFilePathname) : base(dumpFilePathname,
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.MeritDumpFile)]
         internal static DhcpMeritDumpFileOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpMeritDumpFileOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs
index f8cd38c6..b2010917 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageOption.cs
@@ -29,6 +29,7 @@ public DhcpMessageOption(string text) : base(text, DhcpOptionCode.Message)
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.Message)]
         internal static DhcpMessageOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpMessageOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs
index 70c92d62..26dd9f4d 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMessageTypeOption.cs
@@ -28,6 +28,7 @@ public DhcpMessageTypeOption(MessageType type) : base(DhcpOptionCode.MessageType
             Type = type;
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.MessageType)]
         internal static DhcpMessageTypeOption Read(DataSegment data, ref int offset)
         {
             byte len = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs
index 9ad84eed..2b1051f2 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpMobileIPHomeAgentOption.cs
@@ -29,6 +29,7 @@ public DhcpMobileIPHomeAgentOption(IList addresses) : base(addresse
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.MobileIPHomeAgent)]
         internal static DhcpMobileIPHomeAgentOption Read(DataSegment data, ref int offset)
         {
             byte length = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs
index 9dd729fd..96d15ccd 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNameServerOption.cs
@@ -28,6 +28,7 @@ public DhcpNameServerOption(IList addresses) : base(addresses, Dhcp
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NameServer)]
         internal static DhcpNameServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpNameServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs
index 02f17afa..273a619b 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpDatagramDistributionServerOption.cs
@@ -28,6 +28,8 @@ public DhcpNetBiosOverTcpIpDatagramDistributionServerOption(IList a
         {
         }
 
+
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetBiosOverTcpIpDatagramDistributionServer)]
         internal static DhcpNetBiosOverTcpIpDatagramDistributionServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpNetBiosOverTcpIpDatagramDistributionServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs
index 71231f61..288920d3 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNameServerOption.cs
@@ -28,6 +28,8 @@ public DhcpNetBiosOverTcpIpNameServerOption(IList addresses) : base
         {
         }
 
+
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetBiosOverTcpIpNameServer)]
         internal static DhcpNetBiosOverTcpIpNameServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpNetBiosOverTcpIpNameServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs
index 4b0a4862..298ca560 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpNodeTypeOption.cs
@@ -29,6 +29,7 @@ public DhcpNetBiosOverTcpIpNodeTypeOption(NodeType type) : base(DhcpOptionCode.N
             Type = type;
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetBiosOverTcpIpNodeType)]
         internal static DhcpNetBiosOverTcpIpNodeTypeOption Read(DataSegment data, ref int offset)
         {
             byte len = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs
index 0d7724c5..0ecb7b7e 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetBiosOverTcpIpScopeOption.cs
@@ -28,6 +28,7 @@ public DhcpNetBiosOverTcpIpScopeOption(DataSegment netBiosScope) : base(DhcpOpti
             NetBiosScope = netBiosScope;
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetBiosOverTcpIpScope)]
         internal static DhcpNetBiosOverTcpIpScopeOption Read(DataSegment data, ref int offset)
         {
             byte length = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs
index 29dd348b..e60f9595 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServersOption.cs
@@ -29,6 +29,7 @@ public DhcpNetworkInformationServersOption(IList addresses) : base(
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetworkInformationServers)]
         internal static DhcpNetworkInformationServersOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpNetworkInformationServersOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs
index 5d445636..a073e8e9 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServiceDomainOption.cs
@@ -26,6 +26,7 @@ public DhcpNetworkInformationServiceDomainOption(string nisDomainName) : base(ni
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetworkInformationServiceDomain)]
         internal static DhcpNetworkInformationServiceDomainOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpNetworkInformationServiceDomainOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs
index 0ad51c2f..34408046 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusDomainOption.cs
@@ -26,6 +26,7 @@ public DhcpNetworkInformationServicePlusDomainOption(string nisClientDomainName)
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetworkInformationServicePlusDomain)]
         internal static DhcpNetworkInformationServicePlusDomainOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpNetworkInformationServicePlusDomainOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs
index 265dbe55..26736f51 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkInformationServicePlusServersOption.cs
@@ -29,6 +29,7 @@ public DhcpNetworkInformationServicePlusServersOption(IList address
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetworkInformationServicePlusServers)]
         internal static DhcpNetworkInformationServicePlusServersOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpNetworkInformationServicePlusServersOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs
index a3df0002..e08d7042 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkNewsTransportProtocolServerOption.cs
@@ -28,6 +28,7 @@ public DhcpNetworkNewsTransportProtocolServerOption(IList addresses
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetworkNewsTransportProtocolServer)]
         internal static DhcpNetworkNewsTransportProtocolServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpNetworkNewsTransportProtocolServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs
index ae6193ae..97c1ff1a 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNetworkTimeProtocolServersOption.cs
@@ -29,6 +29,7 @@ public DhcpNetworkTimeProtocolServersOption(IList addresses) : base
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NetworkTimeProtocolServers)]
         internal static DhcpNetworkTimeProtocolServersOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpNetworkTimeProtocolServersOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs
index 5a56a535..f3adc8d8 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpNonLocalSourceRoutingEnableOption.cs
@@ -28,6 +28,7 @@ public DhcpNonLocalSourceRoutingEnableOption(bool value) : base(value, DhcpOptio
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.NonLocalSourceRoutingEnable)]
         internal static DhcpNonLocalSourceRoutingEnableOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpNonLocalSourceRoutingEnableOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs
index 5238ff07..c76aca0d 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOption.cs
@@ -39,274 +39,7 @@ protected DhcpOption(DhcpOptionCode code)
         {
             OptionCode = code;
         }
-
-        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
-        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")]
-        internal static DhcpOption CreateInstance(DataSegment data, ref int offset)
-        {
-            switch ((DhcpOptionCode)data[offset++])
-            {
-                #region 3. RFC 1497 Vendor Extensions
-
-                case DhcpOptionCode.Pad:
-                    return DhcpPadOption.Read(data, ref offset);
-
-                case DhcpOptionCode.End:
-                    return DhcpEndOption.Read(data, ref offset);
-
-                case DhcpOptionCode.SubnetMask:
-                    return DhcpSubnetMaskOption.Read(data, ref offset);
-
-                case DhcpOptionCode.TimeOffset:
-                    return DhcpTimeOffsetOption.Read(data, ref offset);
-
-                case DhcpOptionCode.Router:
-                    return DhcpRouterOption.Read(data, ref offset);
-
-                case DhcpOptionCode.TimeServer:
-                    return DhcpTimeServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NameServer:
-                    return DhcpNameServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.DomainNameServerServer:
-                    return DhcpDomainNameServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.LogServer:
-                    return DhcpLogServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.CookieServer:
-                    return DhcpCookieServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.LprServer:
-                    return DhcpLprServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.ImpressServer:
-                    return DhcpImpressServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.ResourceLocationServer:
-                    return DhcpResourceLocationServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.HostName:
-                    return DhcpHostNameOption.Read(data, ref offset);
-
-                case DhcpOptionCode.BootFileSize:
-                    return DhcpBootFileSizeOption.Read(data, ref offset);
-
-                case DhcpOptionCode.MeritDumpFile:
-                    return DhcpMeritDumpFileOption.Read(data, ref offset);
-
-                case DhcpOptionCode.DomainName:
-                    return DhcpDomainNameOption.Read(data, ref offset);
-
-                case DhcpOptionCode.SwapServer:
-                    return DhcpSwapServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.RootPath:
-                    return DhcpRootPathOption.Read(data, ref offset);
-
-                case DhcpOptionCode.ExtensionsPath:
-                    return DhcpExtensionsPathOption.Read(data, ref offset);
-
-                #endregion 3. RFC 1497 Vendor Extensions
-
-                #region 4. IP Layer Parameters per Host
-
-                case DhcpOptionCode.IPForwardingEnable:
-                    return DhcpIPForwardingEnableOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NonLocalSourceRoutingEnable:
-                    return DhcpNonLocalSourceRoutingEnableOption.Read(data, ref offset);
-
-                case DhcpOptionCode.PolicyFilter:
-                    return DhcpPolicyFilterOption.Read(data, ref offset);
-
-                case DhcpOptionCode.MaximumDatagramReassemblySize:
-                    return DhcpMaximumDatagramReassemblySizeOption.Read(data, ref offset);
-
-                case DhcpOptionCode.DefaultIpTimeToLive:
-                    return DhcpDefaultIPTimeToLiveOption.Read(data, ref offset);
-
-                case DhcpOptionCode.PathMtuAgingTimeout:
-                    return DhcpPathMtuAgingTimeoutOption.Read(data, ref offset);
-
-                case DhcpOptionCode.PathMtuPlateauTable:
-                    return DhcpPathMtuPlateauTableOption.Read(data, ref offset);
-
-                #endregion 4. IP Layer Parameters per Host
-
-                #region 5. IP Layer Parameters per Interface
-
-                case DhcpOptionCode.InterfaceMtu:
-                    return DhcpInterfaceMtuOption.Read(data, ref offset);
-
-                case DhcpOptionCode.AllSubnetsAreLocal:
-                    return DhcpAllSubnetsAreLocalOption.Read(data, ref offset);
-
-                case DhcpOptionCode.BroadcastAddress:
-                    return DhcpBroadcastAddressOption.Read(data, ref offset);
-
-                case DhcpOptionCode.PerformMaskDiscovery:
-                    return DhcpPerformMaskDiscoveryOption.Read(data, ref offset);
-
-                case DhcpOptionCode.MaskSupplier:
-                    return DhcpMaskSupplierOption.Read(data, ref offset);
-
-                case DhcpOptionCode.PerformRouterDiscovery:
-                    return DhcpPerformRouterDiscoveryOption.Read(data, ref offset);
-
-                case DhcpOptionCode.RouterSolicitationAddress:
-                    return DhcpRouterSolicitationAddressOption.Read(data, ref offset);
-
-                case DhcpOptionCode.StaticRoute:
-                    return DhcpStaticRouteOption.Read(data, ref offset);
-
-                #endregion 5. IP Layer Parameters per Interface
-
-                #region 6. Link Layer Parameters per Interface
-
-                case DhcpOptionCode.TrailerEncapsulation:
-                    return DhcpTrailerEncapsulationOption.Read(data, ref offset);
-
-                case DhcpOptionCode.ArpCacheTimeout:
-                    return DhcpArpCacheTimeoutOption.Read(data, ref offset);
-
-                case DhcpOptionCode.EthernetEncapsulation:
-                    return DhcpEthernetEncapsulationOption.Read(data, ref offset);
-
-                #endregion 6. Link Layer Parameters per Interface
-
-                #region 7. TCP Parameters
-
-                case DhcpOptionCode.TcpDefaultTtl:
-                    return DhcpTcpDefaultTtlOption.Read(data, ref offset);
-
-                case DhcpOptionCode.TcpKeepaliveInterval:
-                    return DhcpTcpKeepaliveIntervalOption.Read(data, ref offset);
-
-                case DhcpOptionCode.TcpKeepaliveGarbage:
-                    return DhcpTcpKeepaliveGarbageOption.Read(data, ref offset);
-
-                #endregion 7. TCP Parameters
-
-                #region 8. Application and Service Parameters
-
-                case DhcpOptionCode.NetworkInformationServiceDomain:
-                    return DhcpNetworkInformationServiceDomainOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NetworkInformationServers:
-                    return DhcpNetworkInformationServersOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NetworkTimeProtocolServers:
-                    return DhcpNetworkTimeProtocolServersOption.Read(data, ref offset);
-
-                case DhcpOptionCode.VendorSpecificInformation:
-                    return DhcpVendorSpecificInformationOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NetBiosOverTcpIpNameServer:
-                    return DhcpNetBiosOverTcpIpNameServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NetBiosOverTcpIpDatagramDistributionServer:
-                    return DhcpNetBiosOverTcpIpDatagramDistributionServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NetBiosOverTcpIpNodeType:
-                    return DhcpNetBiosOverTcpIpNodeTypeOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NetBiosOverTcpIpScope:
-                    return DhcpNetBiosOverTcpIpScopeOption.Read(data, ref offset);
-
-                case DhcpOptionCode.XWindowSystemFontServer:
-                    return DhcpXWindowSystemFontServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.XWindowSystemDisplayManager:
-                    return DhcpXWindowSystemDisplayManagerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NetworkInformationServicePlusDomain:
-                    return DhcpNetworkInformationServicePlusDomainOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NetworkInformationServicePlusServers:
-                    return DhcpNetworkInformationServicePlusServersOption.Read(data, ref offset);
-
-                case DhcpOptionCode.MobileIPHomeAgent:
-                    return DhcpMobileIPHomeAgentOption.Read(data, ref offset);
-
-                case DhcpOptionCode.SimpleMailTransportProtocolServer:
-                    return DhcpSimpleMailTransportProtocolServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.PostOfficeProtocolServer:
-                    return DhcpPostOfficeProtocolServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.NetworkNewsTransportProtocolServer:
-                    return DhcpNetworkNewsTransportProtocolServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.DefaultWorldWideWebServer:
-                    return DhcpDefaultWorldWideWebServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.DefaultFingerServer:
-                    return DhcpDefaultFingerServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.DefaultInternetRelayChatServer:
-                    return DhcpDefaultInternetRelayChatServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.StreetTalkServer:
-                    return DhcpStreetTalkServerOption.Read(data, ref offset);
-
-                case DhcpOptionCode.StreetTalkDirectoryAssistanceServer:
-                    return DhcpStreetTalkDirectoryAssistanceServerOption.Read(data, ref offset);
-
-                #endregion 8. Application and Service Parameters
-
-                #region 9.DHCP Extensions
-
-                case DhcpOptionCode.RequestedIPAddress:
-                    return DhcpRequestedIPAddressOption.Read(data, ref offset);
-
-                case DhcpOptionCode.IPAddressLeaseTime:
-                    return DhcpIPAddressLeaseTimeOption.Read(data, ref offset);
-
-                case DhcpOptionCode.OptionOverload:
-                    return DhcpOptionOverloadOption.Read(data, ref offset);
-
-                case DhcpOptionCode.TfptServerName:
-                    return DhcpTFtpServerNameOption.Read(data, ref offset);
-
-                case DhcpOptionCode.BootfileName:
-                    return DhcpBootfileNameOption.Read(data, ref offset);
-
-                case DhcpOptionCode.MessageType:
-                    return DhcpMessageTypeOption.Read(data, ref offset);
-
-                case DhcpOptionCode.ServerIdentifier:
-                    return DhcpServerIdentifierOption.Read(data, ref offset);
-
-                case DhcpOptionCode.ParameterRequestList:
-                    return DhcpParameterRequestListOption.Read(data, ref offset);
-
-                case DhcpOptionCode.Message:
-                    return DhcpMessageOption.Read(data, ref offset);
-
-                case DhcpOptionCode.MaximumDhcpMessageSize:
-                    return DhcpMaximumDhcpMessageSizeOption.Read(data, ref offset);
-
-                case DhcpOptionCode.RenewalTimeValue:
-                    return DhcpRenewalTimeValueOption.Read(data, ref offset);
-
-                case DhcpOptionCode.RebindingTimeValue:
-                    return DhcpRebindingTimeValueOption.Read(data, ref offset);
-
-                case DhcpOptionCode.VendorClassidentifier:
-                    return DhcpVendorClassidentifierOption.Read(data, ref offset);
-
-                case DhcpOptionCode.ClientIdentifier:
-                    return DhcpClientIdentifierOption.Read(data, ref offset);
-
-                #endregion 9.DHCP Extensions
-
-                default:
-                    return DhcpAnyOption.Read(data, ref offset);
-            }
-        }
-
+        
         internal virtual void Write(byte[] buffer, ref int offset)
         {
             buffer.Write(offset++, (byte)OptionCode);
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs
index 8f0a2a54..57431850 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpOptionOverloadOption.cs
@@ -34,6 +34,7 @@ public DhcpOptionOverloadOption(OptionOverloadValue value) : base(DhcpOptionCode
             Value = value;
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.OptionOverload)]
         internal static DhcpOptionOverloadOption Read(DataSegment data, ref int offset)
         {
             byte len = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs
index b810c4da..b4ad3444 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPadOption.cs
@@ -34,6 +34,7 @@ public override byte Length
             get { return 0; }
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.Pad)]
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "data")]
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "offset")]
         internal static DhcpPadOption Read(DataSegment data, ref int offset)
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs
index 3b9c392a..3acf9f69 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpParameterRequestListOption.cs
@@ -42,6 +42,7 @@ public DhcpParameterRequestListOption(IList optionCodes) : base(
             OptionCodes = new ReadOnlyCollection(optionCodes);
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.ParameterRequestList)]
         internal static DhcpParameterRequestListOption Read(DataSegment data, ref int offset)
         {
             byte length = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs
index 7aabf9ba..adfb35b3 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuAgingTimeoutOption.cs
@@ -27,6 +27,7 @@ public DhcpPathMtuAgingTimeoutOption(uint timeout) : base(timeout, DhcpOptionCod
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.PathMtuAgingTimeout)]
         internal static DhcpPathMtuAgingTimeoutOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpPathMtuAgingTimeoutOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs
index 7ccb4240..13bb38b4 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPathMtuPlateauTableOption.cs
@@ -39,6 +39,7 @@ public DhcpPathMtuPlateauTableOption(IList sizes) : base(DhcpOptionCode.
             Sizes = new ReadOnlyCollection(sizes);
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.PathMtuPlateauTable)]
         internal static DhcpPathMtuPlateauTableOption Read(DataSegment data, ref int offset)
         {
             byte len = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs
index 83cbdc78..383c7d5e 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformMaskDiscoveryOption.cs
@@ -28,6 +28,7 @@ public DhcpPerformMaskDiscoveryOption(bool value) : base(value, DhcpOptionCode.P
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.PerformMaskDiscovery)]
         internal static DhcpPerformMaskDiscoveryOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpPerformMaskDiscoveryOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs
index 7829b732..8966df25 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPerformRouterDiscoveryOption.cs
@@ -28,6 +28,7 @@ public DhcpPerformRouterDiscoveryOption(bool value) : base(value, DhcpOptionCode
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.PerformRouterDiscovery)]
         internal static DhcpPerformRouterDiscoveryOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpPerformRouterDiscoveryOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs
index da3b8712..6d63d857 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPolicyFilterOption.cs
@@ -46,6 +46,7 @@ public DhcpPolicyFilterOption(IList filters) : base(DhcpOpt
             Filters = new ReadOnlyCollection(filters);
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.PolicyFilter)]
         internal static DhcpPolicyFilterOption Read(DataSegment data, ref int offset)
         {
             byte length = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs
index 88633db5..9e6b6e12 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpPostOfficeProtocolServerOption.cs
@@ -28,6 +28,7 @@ public DhcpPostOfficeProtocolServerOption(IList addresses) : base(a
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.PostOfficeProtocolServer)]
         internal static DhcpPostOfficeProtocolServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpPostOfficeProtocolServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs
index 26292c44..80fe39b9 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRebindingTimeValueOption.cs
@@ -27,6 +27,7 @@ public DhcpRebindingTimeValueOption(uint t2Interval) : base(t2Interval, DhcpOpti
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.RebindingTimeValue)]
         internal static DhcpRebindingTimeValueOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpRebindingTimeValueOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs
index 2ca77c3e..6cae7abe 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRenewalTimeValueOption.cs
@@ -27,6 +27,7 @@ public DhcpRenewalTimeValueOption(uint t1Interval) : base(t1Interval, DhcpOption
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.RenewalTimeValue)]
         internal static DhcpRenewalTimeValueOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpRenewalTimeValueOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs
index 71676662..a200b6be 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRequestedIPAddressOption.cs
@@ -28,6 +28,7 @@ public DhcpRequestedIPAddressOption(IpV4Address address) : base(address, DhcpOpt
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.RequestedIPAddress)]
         internal static DhcpRequestedIPAddressOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpRequestedIPAddressOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs
index 552b93a1..6fddea15 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpResourceLocationServerOption.cs
@@ -29,6 +29,7 @@ public DhcpResourceLocationServerOption(IList addresses) : base(add
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.ResourceLocationServer)]
         internal static DhcpResourceLocationServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpResourceLocationServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs
index 4198feff..0323a3fa 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRootPathOption.cs
@@ -28,6 +28,7 @@ public DhcpRootPathOption(string rootDiskPathname) : base(rootDiskPathname, Dhcp
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.RootPath)]
         internal static DhcpRootPathOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpRootPathOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs
index b7f1489c..b2939760 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterOption.cs
@@ -28,6 +28,7 @@ public DhcpRouterOption(IList addresses) : base(addresses, DhcpOpti
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.Router)]
         internal static DhcpRouterOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpRouterOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs
index e19bdfa9..6f3c9775 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpRouterSolicitationAddressOption.cs
@@ -28,6 +28,7 @@ public DhcpRouterSolicitationAddressOption(IpV4Address address) : base(address,
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.RouterSolicitationAddress)]
         internal static DhcpRouterSolicitationAddressOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpRouterSolicitationAddressOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs
index 3633b66d..2bdb16b2 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpServerIdentifierOption.cs
@@ -34,7 +34,8 @@ public class DhcpServerIdentifierOption : DhcpSingleAddressOption
         public DhcpServerIdentifierOption(IpV4Address address) : base(address, DhcpOptionCode.ServerIdentifier)
         {
         }
-
+        
+        [DhcpOptionReadRegistration(DhcpOptionCode.ServerIdentifier)]
         internal static DhcpServerIdentifierOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpServerIdentifierOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs
index b3e45b93..c4045c4e 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSimpleMailTransportProtocolServerOption.cs
@@ -28,6 +28,7 @@ public DhcpSimpleMailTransportProtocolServerOption(IList addresses)
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.SimpleMailTransportProtocolServer)]
         internal static DhcpSimpleMailTransportProtocolServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpSimpleMailTransportProtocolServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs
index 04b5bf12..d7706691 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStaticRouteOption.cs
@@ -45,6 +45,7 @@ public DhcpStaticRouteOption(IList routes) : base(DhcpOptionCo
             Routes = new ReadOnlyCollection(routes);
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.StaticRoute)]
         internal static DhcpStaticRouteOption Read(DataSegment data, ref int offset)
         {
             byte length = data[offset++];
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs
index 4561182d..7a0238ed 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkDirectoryAssistanceServerOption.cs
@@ -29,6 +29,7 @@ public DhcpStreetTalkDirectoryAssistanceServerOption(IList addresse
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.StreetTalkDirectoryAssistanceServer)]
         internal static DhcpStreetTalkDirectoryAssistanceServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpStreetTalkDirectoryAssistanceServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs
index 55abda4e..4c1e73cf 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpStreetTalkServerOption.cs
@@ -29,6 +29,7 @@ public DhcpStreetTalkServerOption(IList addresses) : base(addresses
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.StreetTalkServer)]
         internal static DhcpStreetTalkServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpStreetTalkServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs
index b4019966..09e117c8 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSubnetMaskOption.cs
@@ -30,6 +30,7 @@ public DhcpSubnetMaskOption(IpV4Address subnetMask) : base(subnetMask, DhcpOptio
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.SubnetMask)]
         internal static DhcpSubnetMaskOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpSubnetMaskOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs
index 4917d676..275723c7 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpSwapServerOption.cs
@@ -27,6 +27,7 @@ public DhcpSwapServerOption(IpV4Address swapServerAddress) : base(swapServerAddr
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.SwapServer)]
         internal static DhcpSwapServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpSwapServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs
index dd42f6be..3c05920e 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTFtpServerNameOption.cs
@@ -27,6 +27,7 @@ public DhcpTFtpServerNameOption(string tfptServer) : base(tfptServer, DhcpOption
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.TfptServerName)]
         internal static DhcpTFtpServerNameOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpTFtpServerNameOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs
index 794f1977..1d1f301f 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpDefaultTtlOption.cs
@@ -28,6 +28,7 @@ public DhcpTcpDefaultTtlOption(byte ttl) : base(ttl, DhcpOptionCode.TcpDefaultTt
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.TcpDefaultTtl)]
         internal static DhcpTcpDefaultTtlOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpTcpDefaultTtlOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs
index f918e3f7..7778282e 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveGarbageOption.cs
@@ -29,6 +29,7 @@ public DhcpTcpKeepaliveGarbageOption(bool value) : base(value, DhcpOptionCode.Tc
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.TcpKeepaliveGarbage)]
         internal static DhcpTcpKeepaliveGarbageOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpTcpKeepaliveGarbageOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs
index 5af34ea8..bb5a8c30 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTcpKeepaliveIntervalOption.cs
@@ -27,6 +27,7 @@ public DhcpTcpKeepaliveIntervalOption(uint time) : base(time, DhcpOptionCode.Tcp
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.TcpKeepaliveInterval)]
         internal static DhcpTcpKeepaliveIntervalOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpTcpKeepaliveIntervalOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs
index c3dec98a..6f098bab 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeOffsetOption.cs
@@ -27,6 +27,7 @@ public DhcpTimeOffsetOption(int timeOffset) : base(timeOffset, DhcpOptionCode.Ti
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.TimeOffset)]
         internal static DhcpTimeOffsetOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpTimeOffsetOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs
index 9cb915d9..7ff087c7 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTimeServerOption.cs
@@ -29,6 +29,7 @@ public DhcpTimeServerOption(IList addresses) : base(addresses, Dhcp
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.TimeServer)]
         internal static DhcpTimeServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpTimeServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs
index dcd9b980..15391a11 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpTrailerEncapsulationOption.cs
@@ -28,6 +28,7 @@ public DhcpTrailerEncapsulationOption(bool value) : base(value, DhcpOptionCode.T
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.TrailerEncapsulation)]
         internal static DhcpTrailerEncapsulationOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpTrailerEncapsulationOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs
index 153875ef..d6974729 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorClassidentifierOption.cs
@@ -35,6 +35,7 @@ public DhcpVendorClassidentifierOption(DataSegment vendorClassIdentifier) : base
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.VendorClassidentifier)]
         internal static DhcpVendorClassidentifierOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpVendorClassidentifierOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs
index cd3b87b7..ad4e28ac 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpVendorSpecificInformationOption.cs
@@ -35,6 +35,7 @@ public DhcpVendorSpecificInformationOption(DataSegment vendorSpecificInformation
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.VendorSpecificInformation)]
         internal static DhcpVendorSpecificInformationOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpVendorSpecificInformationOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs
index 4f603905..aed63282 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemDisplayManagerOption.cs
@@ -30,6 +30,7 @@ public DhcpXWindowSystemDisplayManagerOption(IList addresses) : bas
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.XWindowSystemDisplayManager)]
         internal static DhcpXWindowSystemDisplayManagerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new Options.DhcpXWindowSystemDisplayManagerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs
index 69053b10..47b35309 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/Options/DhcpXWindowSystemFontServerOption.cs
@@ -29,6 +29,7 @@ public DhcpXWindowSystemFontServerOption(IList addresses) : base(ad
         {
         }
 
+        [DhcpOptionReadRegistration(DhcpOptionCode.XWindowSystemFontServer)]
         internal static DhcpXWindowSystemFontServerOption Read(DataSegment data, ref int offset)
         {
             return Read(data, ref offset, p => new DhcpXWindowSystemFontServerOption(p));
diff --git a/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj b/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj
index 4f8575f6..e1e7f938 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj
+++ b/PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj
@@ -99,6 +99,8 @@
     
     
     
+    
+    
     
     
     

From cda72733b9530cfda98294dc4cfeaf3337362f65 Mon Sep 17 00:00:00 2001
From: vbBerni 
Date: Sat, 21 Jan 2017 12:50:27 +0100
Subject: [PATCH 19/19] set HardwareAddressLength when setting setting
 ClientMacAddress

---
 .../src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs  | 20 ++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs
index 57dd7a22..8dedfd0a 100644
--- a/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs
+++ b/PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpLayer.cs
@@ -30,7 +30,17 @@ public sealed class DhcpLayer : SimpleLayer, IEquatable
         /// 
         /// Hardware address length.
         /// 
-        public byte HardwareAddressLength { get; set; }
+        public byte HardwareAddressLength
+        {
+            get
+            {
+                return _hardwareAddressLength.GetValueOrDefault();
+            }
+            set
+            {
+                _hardwareAddressLength = value;
+            }
+        }
 
         /// 
         /// Client sets to zero, optionally used by relay agents when booting via a relay agent.
@@ -102,6 +112,7 @@ public bool Broadcast
 
         /// 
         /// Client MAC address.
+        /// When setting this property and the HardwareAddressLength has not been set, the HardwareAddressLength will be automatically set according MacAddress.SizeOf (6).
         /// 
         public MacAddress ClientMacAddress
         {
@@ -116,6 +127,11 @@ public MacAddress ClientMacAddress
                 if (ClientHardwareAddress == null)
                     ClientHardwareAddress = new DataSegment(new byte[16]);
                 ClientHardwareAddress.Buffer.Write(0, value, Endianity.Big);
+
+                if (!_hardwareAddressLength.HasValue)
+                {
+                    HardwareAddressLength = MacAddress.SizeOf;
+                }
             }
         }
 
@@ -194,5 +210,7 @@ public override bool Equals(Layer other)
         {
             return Equals(other as DhcpLayer);
         }
+
+        private byte? _hardwareAddressLength;
     }
 }
\ No newline at end of file