Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpDatagram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpOption>(options);
}
Expand Down
58 changes: 58 additions & 0 deletions PcapDotNet/src/PcapDotNet.Packets/Dhcp/DhcpOptionFactory.cs
Original file line number Diff line number Diff line change
@@ -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<DhcpOptionCode, MethodInfo> InitializeComplexOptions()
{
Dictionary<DhcpOptionCode, MethodInfo> optionReaders = new Dictionary<DhcpOptionCode, MethodInfo>();
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<DhcpOptionReadRegistrationAttribute>(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<DhcpOptionCode, MethodInfo> _optionReaders = InitializeComplexOptions();
}
}
Original file line number Diff line number Diff line change
@@ -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; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public DhcpArpCacheTimeoutOption(uint time) : base(time, DhcpOptionCode.ArpCache
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.ArpCacheTimeout)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to have this attribute on the classes instead of the creation method?
As long as you don't have two creation methods for the same class, I think putting this on the class is easier to maintain.

internal static DhcpArpCacheTimeoutOption Read(DataSegment data, ref int offset)
{
return DhcpUIntOption.Read(data, ref offset, p => new DhcpArpCacheTimeoutOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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++];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public DhcpCookieServerOption(IList<IpV4Address> addresses) : base(addresses, Dh
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.CookieServer)]
internal static DhcpCookieServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpCookieServerOption>(data, ref offset, (p) => new DhcpCookieServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public DhcpDefaultFingerServerOption(IList<IpV4Address> addresses) : base(addres
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.DefaultFingerServer)]
internal static DhcpDefaultFingerServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpDefaultFingerServerOption>(data, ref offset, (p) => new DhcpDefaultFingerServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpDefaultIPTimeToLiveOption>(data, ref offset, p => new DhcpDefaultIPTimeToLiveOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public DhcpDefaultInternetRelayChatServerOption(IList<IpV4Address> addresses) :
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.DefaultInternetRelayChatServer)]
internal static DhcpDefaultInternetRelayChatServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpDefaultInternetRelayChatServerOption>(data, ref offset, (p) => new DhcpDefaultInternetRelayChatServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public DhcpDefaultWorldWideWebServerOption(IList<IpV4Address> addresses) : base(
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.DefaultWorldWideWebServer)]
internal static DhcpDefaultWorldWideWebServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpDefaultWorldWideWebServerOption>(data, ref offset, p => new DhcpDefaultWorldWideWebServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public DhcpDomainNameServerOption(IList<IpV4Address> addresses) : base(addresses
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.DomainNameServerServer)]
internal static DhcpDomainNameServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpDomainNameServerOption>(data, ref offset, p => new DhcpDomainNameServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpEthernetEncapsulationOption>(data, ref offset, p => new DhcpEthernetEncapsulationOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public DhcpExtensionsPathOption(string extensionsPathname) : base(extensionsPath
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.ExtensionsPath)]
internal static DhcpExtensionsPathOption Read(DataSegment data, ref int offset)
{
return Read<DhcpExtensionsPathOption>(data, ref offset, p => new Options.DhcpExtensionsPathOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpHostNameOption>(data, ref offset, p => new DhcpHostNameOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpIPAddressLeaseTimeOption>(data, ref offset, p => new Options.DhcpIPAddressLeaseTimeOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpIPForwardingEnableOption>(data, ref offset, p => new DhcpIPForwardingEnableOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public DhcpImpressServerOption(IList<IpV4Address> addresses) : base(addresses, D
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.ImpressServer)]
internal static DhcpImpressServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpImpressServerOption>(data, ref offset, p => new Options.DhcpImpressServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpInterfaceMtuOption>(data, ref offset, p => new DhcpInterfaceMtuOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public DhcpLogServerOption(IList<IpV4Address> addresses) : base(addresses, DhcpO
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.LogServer)]
internal static DhcpLogServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpLogServerOption>(data, ref offset, p => new DhcpLogServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public DhcpLprServerOption(IList<IpV4Address> addresses) : base(addresses, DhcpO
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.LprServer)]
internal static DhcpLprServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpLprServerOption>(data, ref offset, p => new DhcpLprServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpMaskSupplierOption>(data, ref offset, p => new Options.DhcpMaskSupplierOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpMaximumDatagramReassemblySizeOption>(data, ref offset, p => new DhcpMaximumDatagramReassemblySizeOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpMaximumDhcpMessageSizeOption>(data, ref offset, p => new DhcpMaximumDhcpMessageSizeOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public DhcpMeritDumpFileOption(string dumpFilePathname) : base(dumpFilePathname,
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.MeritDumpFile)]
internal static DhcpMeritDumpFileOption Read(DataSegment data, ref int offset)
{
return Read<DhcpMeritDumpFileOption>(data, ref offset, p => new DhcpMeritDumpFileOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DhcpMessageOption>(data, ref offset, p => new DhcpMessageOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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++];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public DhcpMobileIPHomeAgentOption(IList<IpV4Address> addresses) : base(addresse
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.MobileIPHomeAgent)]
internal static DhcpMobileIPHomeAgentOption Read(DataSegment data, ref int offset)
{
byte length = data[offset++];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public DhcpNameServerOption(IList<IpV4Address> addresses) : base(addresses, Dhcp
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.NameServer)]
internal static DhcpNameServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpNameServerOption>(data, ref offset, p => new DhcpNameServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public DhcpNetBiosOverTcpIpDatagramDistributionServerOption(IList<IpV4Address> a
{
}


[DhcpOptionReadRegistration(DhcpOptionCode.NetBiosOverTcpIpDatagramDistributionServer)]
internal static DhcpNetBiosOverTcpIpDatagramDistributionServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpNetBiosOverTcpIpDatagramDistributionServerOption>(data, ref offset, p => new DhcpNetBiosOverTcpIpDatagramDistributionServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public DhcpNetBiosOverTcpIpNameServerOption(IList<IpV4Address> addresses) : base
{
}


[DhcpOptionReadRegistration(DhcpOptionCode.NetBiosOverTcpIpNameServer)]
internal static DhcpNetBiosOverTcpIpNameServerOption Read(DataSegment data, ref int offset)
{
return Read<DhcpNetBiosOverTcpIpNameServerOption>(data, ref offset, p => new DhcpNetBiosOverTcpIpNameServerOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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++];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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++];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public DhcpNetworkInformationServersOption(IList<IpV4Address> addresses) : base(
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.NetworkInformationServers)]
internal static DhcpNetworkInformationServersOption Read(DataSegment data, ref int offset)
{
return Read<DhcpNetworkInformationServersOption>(data, ref offset, p => new Options.DhcpNetworkInformationServersOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public DhcpNetworkInformationServiceDomainOption(string nisDomainName) : base(ni
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.NetworkInformationServiceDomain)]
internal static DhcpNetworkInformationServiceDomainOption Read(DataSegment data, ref int offset)
{
return Read<DhcpNetworkInformationServiceDomainOption>(data, ref offset, p => new DhcpNetworkInformationServiceDomainOption(p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public DhcpNetworkInformationServicePlusDomainOption(string nisClientDomainName)
{
}

[DhcpOptionReadRegistration(DhcpOptionCode.NetworkInformationServicePlusDomain)]
internal static DhcpNetworkInformationServicePlusDomainOption Read(DataSegment data, ref int offset)
{
return Read<DhcpNetworkInformationServicePlusDomainOption>(data, ref offset, p => new Options.DhcpNetworkInformationServicePlusDomainOption(p));
Expand Down
Loading