mirror of
https://github.com/fergalmoran/DnsServer.git
synced 2026-02-24 00:37:08 +00:00
dhcp: implemented dhcp message parsing changes. implemented all required options with parsing tests. implemented option fragmentation parsing using option overload.
This commit is contained in:
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
Technitium DNS Server
|
||||
Copyright (C) 2019 Shreyas Zare (shreyas@technitium.com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
{
|
||||
class ClientIdentifierOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly byte _type;
|
||||
readonly byte[] _identifier;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public ClientIdentifierOption(Stream s)
|
||||
: base(DhcpOptionCode.ClientIdentifier)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len < 2)
|
||||
throw new InvalidDataException();
|
||||
|
||||
int type = s.ReadByte();
|
||||
if (type < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
_type = (byte)type;
|
||||
_identifier = s.ReadBytes(len - 1);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_identifier.Length + 1));
|
||||
s.WriteByte(_type);
|
||||
s.Write(_identifier);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region properties
|
||||
|
||||
public byte Type
|
||||
{ get { return _type; } }
|
||||
|
||||
public byte[] Identifier
|
||||
{ get { return _identifier; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using DnsServerCore.Dhcp.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -39,6 +40,7 @@ namespace DnsServerCore.Dhcp
|
||||
|
||||
enum DhcpMessageFlags : ushort
|
||||
{
|
||||
None = 0,
|
||||
Broadcast = 0x8000
|
||||
}
|
||||
|
||||
@@ -46,16 +48,16 @@ namespace DnsServerCore.Dhcp
|
||||
{
|
||||
#region variables
|
||||
|
||||
const uint MAGIC_COOKIE = 0x63825363;
|
||||
const uint MAGIC_COOKIE = 0x63538263; //in reverse format
|
||||
|
||||
readonly DhcpMessageOpCode _op;
|
||||
readonly DhcpMessageHardwareAddressType _htype;
|
||||
readonly byte _hlen;
|
||||
readonly byte _hops;
|
||||
|
||||
readonly uint _xid;
|
||||
readonly byte[] _xid;
|
||||
|
||||
readonly ushort _secs;
|
||||
readonly byte[] _secs;
|
||||
readonly DhcpMessageFlags _flags;
|
||||
|
||||
readonly IPAddress _ciaddr;
|
||||
@@ -67,13 +69,26 @@ namespace DnsServerCore.Dhcp
|
||||
readonly byte[] _sname;
|
||||
readonly byte[] _file;
|
||||
|
||||
readonly List<DhcpOption> _options;
|
||||
readonly IReadOnlyCollection<DhcpOption> _options;
|
||||
|
||||
readonly byte[] _clientHardwareAddress;
|
||||
|
||||
OptionOverloadOption _optionOverload;
|
||||
|
||||
DhcpMessageTypeOption _dhcpMessageType;
|
||||
ClientIdentifierOption _clientIdentifier;
|
||||
HostNameOption _hostName;
|
||||
ClientFullyQualifiedDomainNameOption _clientFullyQualifiedDomainName;
|
||||
ParameterRequestListOption _parameterRequestList;
|
||||
MaximumDhcpMessageSizeOption _maximumDhcpMessageSize;
|
||||
ServerIdentifierOption _serverIdentifier;
|
||||
RequestedIpAddressOption _requestedIpAddress;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public DhcpMessage(DhcpMessageOpCode op, uint xid, ushort secs, DhcpMessageFlags flags, IPAddress ciaddr, IPAddress yiaddr, IPAddress siaddr, IPAddress giaddr, byte[] chaddr, List<DhcpOption> options)
|
||||
public DhcpMessage(DhcpMessageOpCode op, byte[] xid, byte[] secs, DhcpMessageFlags flags, IPAddress ciaddr, IPAddress yiaddr, IPAddress siaddr, IPAddress giaddr, byte[] clientHardwareAddress, IReadOnlyCollection<DhcpOption> options)
|
||||
{
|
||||
if (ciaddr.AddressFamily != AddressFamily.InterNetwork)
|
||||
throw new ArgumentException("Address family not supported.", "ciaddr");
|
||||
@@ -87,22 +102,14 @@ namespace DnsServerCore.Dhcp
|
||||
if (giaddr.AddressFamily != AddressFamily.InterNetwork)
|
||||
throw new ArgumentException("Address family not supported.", "giaddr");
|
||||
|
||||
if (chaddr == null)
|
||||
{
|
||||
chaddr = new byte[16];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chaddr.Length > 16)
|
||||
throw new ArgumentException("Value cannot be greater that 16 bytes.", "chaddr");
|
||||
if ((clientHardwareAddress != null) && (clientHardwareAddress.Length != 6))
|
||||
throw new ArgumentException("Value must be 6 bytes long for a valid Ethernet hardware address.", "chaddr");
|
||||
|
||||
if (chaddr.Length < 16)
|
||||
{
|
||||
byte[] newchaddr = new byte[16];
|
||||
Buffer.BlockCopy(chaddr, 0, newchaddr, 0, chaddr.Length);
|
||||
chaddr = newchaddr;
|
||||
}
|
||||
}
|
||||
if (xid.Length != 4)
|
||||
throw new ArgumentException("Transaction ID must be 4 bytes.", "xid");
|
||||
|
||||
if (secs.Length != 2)
|
||||
throw new ArgumentException("Seconds elapsed must be 2 bytes.", "secs");
|
||||
|
||||
_op = op;
|
||||
_htype = DhcpMessageHardwareAddressType.Ethernet;
|
||||
@@ -119,13 +126,20 @@ namespace DnsServerCore.Dhcp
|
||||
_siaddr = siaddr;
|
||||
_giaddr = giaddr;
|
||||
|
||||
_chaddr = chaddr;
|
||||
_clientHardwareAddress = clientHardwareAddress;
|
||||
_chaddr = new byte[16];
|
||||
Buffer.BlockCopy(_clientHardwareAddress, 0, _chaddr, 0, 6);
|
||||
|
||||
_sname = new byte[64];
|
||||
_file = new byte[128];
|
||||
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public DhcpMessage(DhcpMessage request, IPAddress yiaddr, IPAddress siaddr, IReadOnlyCollection<DhcpOption> options)
|
||||
: this(DhcpMessageOpCode.BootReply, request.TransactionId, request.SecondsElapsed, request.Flags, request.ClientIpAddress, yiaddr, siaddr, request.RelayAgentIpAddress, request.ClientHardwareAddress, options)
|
||||
{ }
|
||||
|
||||
public DhcpMessage(Stream s)
|
||||
{
|
||||
byte[] buffer = new byte[4];
|
||||
@@ -136,12 +150,13 @@ namespace DnsServerCore.Dhcp
|
||||
_hlen = buffer[2];
|
||||
_hops = buffer[3];
|
||||
|
||||
s.ReadBytes(buffer, 0, 4);
|
||||
_xid = BitConverter.ToUInt32(buffer, 0);
|
||||
_xid = s.ReadBytes(4);
|
||||
|
||||
s.ReadBytes(buffer, 0, 4);
|
||||
_secs = BitConverter.ToUInt16(buffer, 0);
|
||||
_flags = (DhcpMessageFlags)BitConverter.ToUInt16(buffer, 2);
|
||||
_secs = new byte[2];
|
||||
Buffer.BlockCopy(buffer, 0, _secs, 0, 2);
|
||||
Array.Reverse(buffer);
|
||||
_flags = (DhcpMessageFlags)BitConverter.ToUInt16(buffer, 0);
|
||||
|
||||
s.ReadBytes(buffer, 0, 4);
|
||||
_ciaddr = new IPAddress(buffer);
|
||||
@@ -156,25 +171,125 @@ namespace DnsServerCore.Dhcp
|
||||
_giaddr = new IPAddress(buffer);
|
||||
|
||||
_chaddr = s.ReadBytes(16);
|
||||
_clientHardwareAddress = new byte[_hlen];
|
||||
Buffer.BlockCopy(_chaddr, 0, _clientHardwareAddress, 0, _hlen);
|
||||
|
||||
_sname = s.ReadBytes(64);
|
||||
_file = s.ReadBytes(128);
|
||||
|
||||
//read options
|
||||
_options = new List<DhcpOption>();
|
||||
List<DhcpOption> options = new List<DhcpOption>();
|
||||
_options = options;
|
||||
|
||||
s.ReadBytes(buffer, 0, 4);
|
||||
Array.Reverse(buffer);
|
||||
uint magicCookie = BitConverter.ToUInt32(buffer, 0);
|
||||
|
||||
if (magicCookie == MAGIC_COOKIE)
|
||||
{
|
||||
while (true)
|
||||
ParseOptions(s, options);
|
||||
|
||||
if (_optionOverload != null)
|
||||
{
|
||||
DhcpOption option = DhcpOption.Parse(s);
|
||||
if (option.Code == DhcpOptionCode.End)
|
||||
if (_optionOverload.Value.HasFlag(OptionOverloadValue.FileFieldUsed))
|
||||
{
|
||||
using (MemoryStream mS = new MemoryStream(_file))
|
||||
{
|
||||
ParseOptions(mS, options);
|
||||
}
|
||||
}
|
||||
|
||||
if (_optionOverload.Value.HasFlag(OptionOverloadValue.SnameFieldUsed))
|
||||
{
|
||||
using (MemoryStream mS = new MemoryStream(_sname))
|
||||
{
|
||||
ParseOptions(mS, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//parse all option values
|
||||
foreach (DhcpOption option in options)
|
||||
option.ParseOptionValue();
|
||||
}
|
||||
|
||||
if (_clientIdentifier == null)
|
||||
_clientIdentifier = new ClientIdentifierOption((byte)_htype, _clientHardwareAddress);
|
||||
|
||||
if (_maximumDhcpMessageSize != null)
|
||||
_maximumDhcpMessageSize = new MaximumDhcpMessageSizeOption(576);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private
|
||||
|
||||
private void ParseOptions(Stream s, List<DhcpOption> options)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
DhcpOption option = DhcpOption.Parse(s);
|
||||
if (option.Code == DhcpOptionCode.End)
|
||||
break;
|
||||
|
||||
if (option.Code == DhcpOptionCode.Pad)
|
||||
continue;
|
||||
|
||||
bool optionExists = false;
|
||||
|
||||
foreach (DhcpOption existingOption in options)
|
||||
{
|
||||
if (existingOption.Code == option.Code)
|
||||
{
|
||||
//option already exists so append current option value into existing option
|
||||
existingOption.AppendOptionValue(option);
|
||||
optionExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optionExists)
|
||||
continue;
|
||||
|
||||
//add option to list
|
||||
options.Add(option);
|
||||
|
||||
switch (option.Code)
|
||||
{
|
||||
case DhcpOptionCode.DhcpMessageType:
|
||||
_dhcpMessageType = option as DhcpMessageTypeOption;
|
||||
break;
|
||||
|
||||
_options.Add(option);
|
||||
case DhcpOptionCode.ClientIdentifier:
|
||||
_clientIdentifier = option as ClientIdentifierOption;
|
||||
break;
|
||||
|
||||
case DhcpOptionCode.HostName:
|
||||
_hostName = option as HostNameOption;
|
||||
break;
|
||||
|
||||
case DhcpOptionCode.ClientFullyQualifiedDomainName:
|
||||
_clientFullyQualifiedDomainName = option as ClientFullyQualifiedDomainNameOption;
|
||||
break;
|
||||
|
||||
case DhcpOptionCode.ParameterRequestList:
|
||||
_parameterRequestList = option as ParameterRequestListOption;
|
||||
break;
|
||||
|
||||
case DhcpOptionCode.MaximumDhcpMessageSize:
|
||||
_maximumDhcpMessageSize = option as MaximumDhcpMessageSizeOption;
|
||||
break;
|
||||
|
||||
case DhcpOptionCode.ServerIdentifier:
|
||||
_serverIdentifier = option as ServerIdentifierOption;
|
||||
break;
|
||||
|
||||
case DhcpOptionCode.RequestedIpAddress:
|
||||
_requestedIpAddress = option as RequestedIpAddressOption;
|
||||
break;
|
||||
|
||||
case DhcpOptionCode.OptionOverload:
|
||||
_optionOverload = option as OptionOverloadOption;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,10 +305,12 @@ namespace DnsServerCore.Dhcp
|
||||
s.WriteByte(_hlen);
|
||||
s.WriteByte(_hops);
|
||||
|
||||
s.Write(BitConverter.GetBytes(_xid));
|
||||
s.Write(_xid);
|
||||
|
||||
s.Write(BitConverter.GetBytes(_secs));
|
||||
s.Write(BitConverter.GetBytes((ushort)_flags));
|
||||
s.Write(_secs);
|
||||
byte[] buffer = BitConverter.GetBytes((ushort)_flags);
|
||||
Array.Reverse(buffer);
|
||||
s.Write(buffer);
|
||||
|
||||
s.Write(_ciaddr.GetAddressBytes());
|
||||
s.Write(_yiaddr.GetAddressBytes());
|
||||
@@ -227,10 +344,10 @@ namespace DnsServerCore.Dhcp
|
||||
public byte Hops
|
||||
{ get { return _hops; } }
|
||||
|
||||
public uint TransactionId
|
||||
public byte[] TransactionId
|
||||
{ get { return _xid; } }
|
||||
|
||||
public ushort SecondsElapsed
|
||||
public byte[] SecondsElapsed
|
||||
{ get { return _secs; } }
|
||||
|
||||
public DhcpMessageFlags Flags
|
||||
@@ -249,7 +366,7 @@ namespace DnsServerCore.Dhcp
|
||||
{ get { return _giaddr; } }
|
||||
|
||||
public byte[] ClientHardwareAddress
|
||||
{ get { return _chaddr; } }
|
||||
{ get { return _clientHardwareAddress; } }
|
||||
|
||||
public byte[] ServerHostName
|
||||
{ get { return _sname; } }
|
||||
@@ -257,9 +374,33 @@ namespace DnsServerCore.Dhcp
|
||||
public byte[] BootFileName
|
||||
{ get { return _file; } }
|
||||
|
||||
public IReadOnlyList<DhcpOption> Options
|
||||
public IReadOnlyCollection<DhcpOption> Options
|
||||
{ get { return _options; } }
|
||||
|
||||
public DhcpMessageTypeOption DhcpMessageType
|
||||
{ get { return _dhcpMessageType; } }
|
||||
|
||||
public ClientIdentifierOption ClientIdentifier
|
||||
{ get { return _clientIdentifier; } }
|
||||
|
||||
public HostNameOption HostName
|
||||
{ get { return _hostName; } }
|
||||
|
||||
public ClientFullyQualifiedDomainNameOption ClientFullyQualifiedDomainName
|
||||
{ get { return _clientFullyQualifiedDomainName; } }
|
||||
|
||||
public ParameterRequestListOption ParameterRequestList
|
||||
{ get { return _parameterRequestList; } }
|
||||
|
||||
public MaximumDhcpMessageSizeOption MaximumDhcpMessageSize
|
||||
{ get { return _maximumDhcpMessageSize; } }
|
||||
|
||||
public ServerIdentifierOption ServerIdentifier
|
||||
{ get { return _serverIdentifier; } }
|
||||
|
||||
public RequestedIpAddressOption RequestedIpAddress
|
||||
{ get { return _requestedIpAddress; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using DnsServerCore.Dhcp.Options;
|
||||
using System;
|
||||
using System.IO;
|
||||
using TechnitiumLibrary.IO;
|
||||
@@ -100,6 +101,8 @@ namespace DnsServerCore.Dhcp
|
||||
DefaultIrc = 74,
|
||||
StreetTalkServer = 75,
|
||||
StreetTalkDirectoryAssistance = 76,
|
||||
ClientFullyQualifiedDomainName = 81,
|
||||
ClasslessStaticRoute = 121,
|
||||
End = 255
|
||||
}
|
||||
|
||||
@@ -108,21 +111,26 @@ namespace DnsServerCore.Dhcp
|
||||
#region variables
|
||||
|
||||
readonly DhcpOptionCode _code;
|
||||
readonly byte[] _value;
|
||||
byte[] _value;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
protected DhcpOption(DhcpOptionCode type)
|
||||
protected DhcpOption(DhcpOptionCode code, Stream s)
|
||||
{
|
||||
_code = type;
|
||||
_code = code;
|
||||
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
_value = s.ReadBytes(len);
|
||||
}
|
||||
|
||||
private DhcpOption(DhcpOptionCode type, byte[] value)
|
||||
protected DhcpOption(DhcpOptionCode code)
|
||||
{
|
||||
_code = type;
|
||||
_value = value;
|
||||
_code = code;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -162,9 +170,6 @@ namespace DnsServerCore.Dhcp
|
||||
case DhcpOptionCode.BroadcastAddress:
|
||||
return new BroadcastAddressOption(s);
|
||||
|
||||
case DhcpOptionCode.StaticRoute:
|
||||
return new StaticRouteOption(s);
|
||||
|
||||
case DhcpOptionCode.NetBiosOverTcpIpNameServer:
|
||||
return new NetBiosNameServerOption(s);
|
||||
|
||||
@@ -201,17 +206,44 @@ namespace DnsServerCore.Dhcp
|
||||
case DhcpOptionCode.ClientIdentifier:
|
||||
return new ClientIdentifierOption(s);
|
||||
|
||||
case DhcpOptionCode.ClientFullyQualifiedDomainName:
|
||||
return new ClientFullyQualifiedDomainNameOption(s);
|
||||
|
||||
case DhcpOptionCode.ClasslessStaticRoute:
|
||||
return new ClasslessStaticRouteOption(s);
|
||||
|
||||
case DhcpOptionCode.Pad:
|
||||
case DhcpOptionCode.End:
|
||||
return new DhcpOption(optionCode, null);
|
||||
return new DhcpOption(optionCode);
|
||||
|
||||
default:
|
||||
//unknown option
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
return new DhcpOption(optionCode, s);
|
||||
}
|
||||
}
|
||||
|
||||
return new DhcpOption(optionCode, s.ReadBytes(len));
|
||||
#endregion
|
||||
|
||||
#region internal
|
||||
|
||||
internal void AppendOptionValue(DhcpOption option)
|
||||
{
|
||||
byte[] value = new byte[_value.Length + option._value.Length];
|
||||
|
||||
Buffer.BlockCopy(_value, 0, value, 0, _value.Length);
|
||||
Buffer.BlockCopy(option._value, 0, value, _value.Length, option._value.Length);
|
||||
|
||||
_value = value;
|
||||
}
|
||||
|
||||
internal void ParseOptionValue()
|
||||
{
|
||||
if (_value != null)
|
||||
{
|
||||
using (MemoryStream mS = new MemoryStream(_value))
|
||||
{
|
||||
ParseOptionValue(mS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,12 +251,14 @@ namespace DnsServerCore.Dhcp
|
||||
|
||||
#region protected
|
||||
|
||||
protected virtual void WriteOptionTo(Stream s)
|
||||
protected virtual void ParseOptionValue(Stream s)
|
||||
{ }
|
||||
|
||||
protected virtual void WriteOptionValue(Stream s)
|
||||
{
|
||||
if (_value == null)
|
||||
throw new NotImplementedException();
|
||||
|
||||
s.WriteByte(Convert.ToByte(_value.Length));
|
||||
s.Write(_value);
|
||||
}
|
||||
|
||||
@@ -234,16 +268,37 @@ namespace DnsServerCore.Dhcp
|
||||
|
||||
public void WriteTo(Stream s)
|
||||
{
|
||||
s.WriteByte((byte)_code);
|
||||
|
||||
switch (_code)
|
||||
{
|
||||
case DhcpOptionCode.Pad:
|
||||
case DhcpOptionCode.End:
|
||||
s.WriteByte((byte)_code);
|
||||
break;
|
||||
|
||||
default:
|
||||
WriteOptionTo(s);
|
||||
using (MemoryStream mS = new MemoryStream())
|
||||
{
|
||||
WriteOptionValue(mS);
|
||||
|
||||
int len = 255;
|
||||
int valueLen = Convert.ToInt32(mS.Position);
|
||||
mS.Position = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if (valueLen < len)
|
||||
len = valueLen;
|
||||
|
||||
//write option
|
||||
s.WriteByte((byte)_code); //code
|
||||
s.WriteByte((byte)len); //len
|
||||
mS.CopyTo(s, len, len); //value
|
||||
|
||||
valueLen -= len;
|
||||
}
|
||||
while (valueLen > 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,38 +21,43 @@ using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class BroadcastAddressOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly IPAddress _broadcastAddress;
|
||||
IPAddress _broadcastAddress;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public BroadcastAddressOption(Stream s)
|
||||
public BroadcastAddressOption(IPAddress broadcastAddress)
|
||||
: base(DhcpOptionCode.BroadcastAddress)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_broadcastAddress = new IPAddress(s.ReadBytes(4));
|
||||
_broadcastAddress = broadcastAddress;
|
||||
}
|
||||
|
||||
public BroadcastAddressOption(Stream s)
|
||||
: base(DhcpOptionCode.BroadcastAddress, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_broadcastAddress = new IPAddress(s.ReadBytes(4));
|
||||
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(4);
|
||||
s.Write(_broadcastAddress.GetAddressBytes());
|
||||
}
|
||||
|
||||
153
DnsServerCore/Dhcp/Options/ClasslessStaticRouteOption.cs
Normal file
153
DnsServerCore/Dhcp/Options/ClasslessStaticRouteOption.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
Technitium DNS Server
|
||||
Copyright (C) 2019 Shreyas Zare (shreyas@technitium.com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class ClasslessStaticRouteOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
ICollection<Route> _routes;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public ClasslessStaticRouteOption(ICollection<Route> routes)
|
||||
: base(DhcpOptionCode.ClasslessStaticRoute)
|
||||
{
|
||||
_routes = routes;
|
||||
}
|
||||
|
||||
public ClasslessStaticRouteOption(Stream s)
|
||||
: base(DhcpOptionCode.ClasslessStaticRoute, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length < 5)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_routes = new List<Route>();
|
||||
|
||||
while (s.Position < s.Length)
|
||||
{
|
||||
_routes.Add(new Route(s));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
foreach (Route route in _routes)
|
||||
route.WriteTo(s);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region properties
|
||||
|
||||
public ICollection<Route> Routes
|
||||
{ get { return _routes; } }
|
||||
|
||||
#endregion
|
||||
|
||||
public class Route
|
||||
{
|
||||
#region private
|
||||
|
||||
readonly IPAddress _destination;
|
||||
readonly IPAddress _subnetMask;
|
||||
readonly IPAddress _router;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public Route(IPAddress destination, IPAddress subnetMask, IPAddress router)
|
||||
{
|
||||
_destination = destination;
|
||||
_subnetMask = subnetMask;
|
||||
_router = router;
|
||||
}
|
||||
|
||||
public Route(Stream s)
|
||||
{
|
||||
int subnetMaskWidth = s.ReadByte();
|
||||
if (subnetMaskWidth < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
_destination = new IPAddress(s.ReadBytes(Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(subnetMaskWidth) / 8))));
|
||||
|
||||
byte[] subnetMaskBuffer = BitConverter.GetBytes(0xFFFFFFFFu << (32 - subnetMaskWidth));
|
||||
Array.Reverse(subnetMaskBuffer);
|
||||
_subnetMask = new IPAddress(subnetMaskBuffer);
|
||||
|
||||
_router = new IPAddress(s.ReadBytes(4));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public
|
||||
|
||||
public void WriteTo(Stream s)
|
||||
{
|
||||
byte[] subnetMaskBuffer = _subnetMask.GetAddressBytes();
|
||||
Array.Reverse(subnetMaskBuffer);
|
||||
uint subnetMaskNumber = BitConverter.ToUInt32(subnetMaskBuffer, 0);
|
||||
|
||||
byte subnetMaskWidth = 0;
|
||||
|
||||
while (subnetMaskNumber > 0u)
|
||||
{
|
||||
subnetMaskNumber <<= 1;
|
||||
subnetMaskWidth++;
|
||||
}
|
||||
|
||||
s.WriteByte(subnetMaskWidth);
|
||||
s.Write(_destination.GetAddressBytes(), 0, Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(subnetMaskWidth) / 8)));
|
||||
s.Write(_router.GetAddressBytes());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region properties
|
||||
|
||||
public IPAddress Destination
|
||||
{ get { return _destination; } }
|
||||
|
||||
public IPAddress SubnetMask
|
||||
{ get { return _subnetMask; } }
|
||||
|
||||
public IPAddress Router
|
||||
{ get { return _router; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Technitium DNS Server
|
||||
Copyright (C) 2019 Shreyas Zare (shreyas@technitium.com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using TechnitiumLibrary.IO;
|
||||
using TechnitiumLibrary.Net.Dns;
|
||||
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
enum ClientFullyQualifiedDomainNameFlags : byte
|
||||
{
|
||||
None = 0,
|
||||
ShouldUpdateDns = 1,
|
||||
OverrideByServer = 2,
|
||||
EncodeUsingCanonicalWireFormat = 4,
|
||||
NoDnsUpdate = 8,
|
||||
}
|
||||
|
||||
class ClientFullyQualifiedDomainNameOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
ClientFullyQualifiedDomainNameFlags _flags;
|
||||
byte _rcode1;
|
||||
byte _rcode2;
|
||||
string _domainName;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public ClientFullyQualifiedDomainNameOption(ClientFullyQualifiedDomainNameFlags flags, byte rcode1, byte rcode2, string domainName)
|
||||
: base(DhcpOptionCode.ClientFullyQualifiedDomainName)
|
||||
{
|
||||
_flags = flags;
|
||||
_rcode1 = rcode1;
|
||||
_rcode2 = rcode2;
|
||||
_domainName = domainName;
|
||||
}
|
||||
|
||||
public ClientFullyQualifiedDomainNameOption(Stream s)
|
||||
: base(DhcpOptionCode.ClientFullyQualifiedDomainName, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length < 3)
|
||||
throw new InvalidDataException();
|
||||
|
||||
int flags = s.ReadByte();
|
||||
if (flags < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
_flags = (ClientFullyQualifiedDomainNameFlags)flags;
|
||||
|
||||
int rcode;
|
||||
|
||||
rcode = s.ReadByte();
|
||||
if (rcode < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
_rcode1 = (byte)rcode;
|
||||
|
||||
rcode = s.ReadByte();
|
||||
if (rcode < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
_rcode2 = (byte)rcode;
|
||||
|
||||
if (_flags.HasFlag(ClientFullyQualifiedDomainNameFlags.EncodeUsingCanonicalWireFormat))
|
||||
_domainName = DnsDatagram.DeserializeDomainName(s);
|
||||
else
|
||||
_domainName = Encoding.ASCII.GetString(s.ReadBytes((int)s.Length - 3));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte((byte)_flags);
|
||||
s.WriteByte(_rcode1);
|
||||
s.WriteByte(_rcode2);
|
||||
|
||||
if (_flags.HasFlag(ClientFullyQualifiedDomainNameFlags.EncodeUsingCanonicalWireFormat))
|
||||
DnsDatagram.SerializeDomainName(_domainName, s);
|
||||
else
|
||||
s.Write(Encoding.ASCII.GetBytes(_domainName));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region properties
|
||||
|
||||
public ClientFullyQualifiedDomainNameFlags Flags
|
||||
{ get { return _flags; } }
|
||||
|
||||
public byte RCODE1
|
||||
{ get { return _rcode1; } }
|
||||
|
||||
public byte RCODE2
|
||||
{ get { return _rcode2; } }
|
||||
|
||||
public string DomainName
|
||||
{ get { return _domainName; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
126
DnsServerCore/Dhcp/Options/ClientIdentifierOption.cs
Normal file
126
DnsServerCore/Dhcp/Options/ClientIdentifierOption.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
Technitium DNS Server
|
||||
Copyright (C) 2019 Shreyas Zare (shreyas@technitium.com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class ClientIdentifierOption : DhcpOption, IEquatable<ClientIdentifierOption>
|
||||
{
|
||||
#region variables
|
||||
|
||||
byte _type;
|
||||
byte[] _identifier;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public ClientIdentifierOption(byte type, byte[] identifier)
|
||||
: base(DhcpOptionCode.ClientIdentifier)
|
||||
{
|
||||
_type = type;
|
||||
_identifier = identifier;
|
||||
}
|
||||
|
||||
public ClientIdentifierOption(Stream s)
|
||||
: base(DhcpOptionCode.ClientIdentifier, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length < 2)
|
||||
throw new InvalidDataException();
|
||||
|
||||
int type = s.ReadByte();
|
||||
if (type < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
_type = (byte)type;
|
||||
_identifier = s.ReadBytes((int)s.Length - 1);
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(_type);
|
||||
s.Write(_identifier);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null)
|
||||
return false;
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
return true;
|
||||
|
||||
return Equals(obj as ClientIdentifierOption);
|
||||
}
|
||||
|
||||
public bool Equals(ClientIdentifierOption other)
|
||||
{
|
||||
if (other is null)
|
||||
return false;
|
||||
|
||||
if (this._type != other._type)
|
||||
return false;
|
||||
|
||||
if (this._identifier.Length != other._identifier.Length)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < this._identifier.Length; i++)
|
||||
{
|
||||
if (this._identifier[i] != other._identifier[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = 937899003;
|
||||
hashCode = hashCode * -1521134295 + _type.GetHashCode();
|
||||
hashCode = hashCode * -1521134295 + BitConverter.ToInt32(_identifier, 0);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region properties
|
||||
|
||||
public byte Type
|
||||
{ get { return _type; } }
|
||||
|
||||
public byte[] Identifier
|
||||
{ get { return _identifier; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
enum DhcpMessageType : byte
|
||||
{
|
||||
Unknown = 0,
|
||||
Discover = 1,
|
||||
Offer = 2,
|
||||
Request = 3,
|
||||
@@ -37,45 +38,58 @@ namespace DnsServerCore.Dhcp
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly DhcpMessageType _messageType;
|
||||
DhcpMessageType _type;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public DhcpMessageTypeOption(Stream s)
|
||||
public DhcpMessageTypeOption(DhcpMessageType type)
|
||||
: base(DhcpOptionCode.DhcpMessageType)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
_type = type;
|
||||
}
|
||||
|
||||
if (len != 1)
|
||||
public DhcpMessageTypeOption(Stream s)
|
||||
: base(DhcpOptionCode.DhcpMessageType, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length != 1)
|
||||
throw new InvalidDataException();
|
||||
|
||||
int type = s.ReadByte();
|
||||
if (type < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
_messageType = (DhcpMessageType)type;
|
||||
_type = (DhcpMessageType)type;
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte((byte)_type);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
#region string
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
public override string ToString()
|
||||
{
|
||||
s.WriteByte(1);
|
||||
s.WriteByte((byte)_messageType);
|
||||
return _type.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region properties
|
||||
|
||||
public DhcpMessageType MessageType
|
||||
{ get { return _messageType; } }
|
||||
public DhcpMessageType Type
|
||||
{ get { return _type; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -17,43 +17,46 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class DomainNameOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly string _domainName;
|
||||
string _domainName;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public DomainNameOption(Stream s)
|
||||
public DomainNameOption(string domainName)
|
||||
: base(DhcpOptionCode.DomainName)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len < 1)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_domainName = Encoding.ASCII.GetString(s.ReadBytes(len));
|
||||
_domainName = domainName;
|
||||
}
|
||||
|
||||
public DomainNameOption(Stream s)
|
||||
: base(DhcpOptionCode.DomainName, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length < 1)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_domainName = Encoding.ASCII.GetString(s.ReadBytes((int)s.Length));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_domainName.Length));
|
||||
s.Write(Encoding.ASCII.GetBytes(_domainName));
|
||||
}
|
||||
|
||||
@@ -17,47 +17,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class DomainNameServerOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly IPAddress[] _addresses;
|
||||
IPAddress[] _addresses;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public DomainNameServerOption(Stream s)
|
||||
public DomainNameServerOption(IPAddress[] addresses)
|
||||
: base(DhcpOptionCode.DomainNameServer)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if ((len % 4 != 0) || (len < 4))
|
||||
throw new InvalidDataException();
|
||||
|
||||
_addresses = new IPAddress[len / 4];
|
||||
|
||||
for (int i = 0; i < _addresses.Length; i++)
|
||||
_addresses[i] = new IPAddress(s.ReadBytes(4));
|
||||
_addresses = addresses;
|
||||
}
|
||||
|
||||
public DomainNameServerOption(Stream s)
|
||||
: base(DhcpOptionCode.DomainNameServer, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_addresses.Length * 4));
|
||||
if ((s.Length % 4 != 0) || (s.Length < 4))
|
||||
throw new InvalidDataException();
|
||||
|
||||
_addresses = new IPAddress[s.Length / 4];
|
||||
|
||||
for (int i = 0; i < _addresses.Length; i++)
|
||||
_addresses[i] = new IPAddress(s.ReadBytes(4));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
foreach (IPAddress address in _addresses)
|
||||
s.Write(address.GetAddressBytes());
|
||||
}
|
||||
@@ -17,43 +17,46 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class HostNameOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly string _hostName;
|
||||
string _hostName;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public HostNameOption(Stream s)
|
||||
public HostNameOption(string hostName)
|
||||
: base(DhcpOptionCode.HostName)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len < 1)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_hostName = Encoding.ASCII.GetString(s.ReadBytes(len));
|
||||
_hostName = hostName;
|
||||
}
|
||||
|
||||
public HostNameOption(Stream s)
|
||||
: base(DhcpOptionCode.HostName, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length < 1)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_hostName = Encoding.ASCII.GetString(s.ReadBytes((int)s.Length));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_hostName.Length));
|
||||
s.Write(Encoding.ASCII.GetBytes(_hostName));
|
||||
}
|
||||
|
||||
@@ -21,39 +21,47 @@ using System;
|
||||
using System.IO;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class IpAddressLeaseTimeOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly uint _leaseTime;
|
||||
uint _leaseTime;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public IpAddressLeaseTimeOption(Stream s)
|
||||
public IpAddressLeaseTimeOption(uint leaseTime)
|
||||
: base(DhcpOptionCode.IpAddressLeaseTime)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_leaseTime = BitConverter.ToUInt32(s.ReadBytes(4), 0);
|
||||
_leaseTime = leaseTime;
|
||||
}
|
||||
|
||||
public IpAddressLeaseTimeOption(Stream s)
|
||||
: base(DhcpOptionCode.IpAddressLeaseTime, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(4);
|
||||
s.Write(BitConverter.GetBytes(_leaseTime));
|
||||
if (s.Length != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
byte[] buffer = s.ReadBytes(4);
|
||||
Array.Reverse(buffer);
|
||||
_leaseTime = BitConverter.ToUInt32(buffer, 0);
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
byte[] buffer = BitConverter.GetBytes(_leaseTime);
|
||||
Array.Reverse(buffer);
|
||||
s.Write(buffer);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -21,39 +21,53 @@ using System;
|
||||
using System.IO;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class MaximumDhcpMessageSizeOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly ushort _length;
|
||||
ushort _length;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public MaximumDhcpMessageSizeOption(Stream s)
|
||||
public MaximumDhcpMessageSizeOption(ushort length)
|
||||
: base(DhcpOptionCode.MaximumDhcpMessageSize)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
if (length < 576)
|
||||
throw new ArgumentOutOfRangeException("length", "Length must be 576 bytes or more.");
|
||||
|
||||
if (len != 2)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_length = BitConverter.ToUInt16(s.ReadBytes(2), 0);
|
||||
_length = length;
|
||||
}
|
||||
|
||||
public MaximumDhcpMessageSizeOption(Stream s)
|
||||
: base(DhcpOptionCode.MaximumDhcpMessageSize, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(2);
|
||||
s.Write(BitConverter.GetBytes(_length));
|
||||
if (s.Length != 2)
|
||||
throw new InvalidDataException();
|
||||
|
||||
byte[] buffer = s.ReadBytes(2);
|
||||
Array.Reverse(buffer);
|
||||
_length = BitConverter.ToUInt16(buffer, 0);
|
||||
|
||||
if (_length < 576)
|
||||
_length = 576;
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
byte[] buffer = BitConverter.GetBytes(_length);
|
||||
Array.Reverse(buffer);
|
||||
s.Write(buffer);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -17,43 +17,51 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class MessageOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly string _text;
|
||||
string _text;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public MessageOption(Stream s)
|
||||
public MessageOption(string text)
|
||||
: base(DhcpOptionCode.Message)
|
||||
{
|
||||
_text = text;
|
||||
}
|
||||
|
||||
public MessageOption(Stream s)
|
||||
: base(DhcpOptionCode.Message, s)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len < 1)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_text = Encoding.ASCII.GetString(s.ReadBytes(len));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length < 1)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_text = Encoding.ASCII.GetString(s.ReadBytes((int)s.Length));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_text.Length));
|
||||
s.Write(Encoding.ASCII.GetBytes(_text));
|
||||
}
|
||||
|
||||
@@ -17,47 +17,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class NetBiosNameServerOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly IPAddress[] _addresses;
|
||||
IPAddress[] _addresses;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public NetBiosNameServerOption(Stream s)
|
||||
public NetBiosNameServerOption(IPAddress[] addresses)
|
||||
: base(DhcpOptionCode.NetBiosOverTcpIpNameServer)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if ((len % 4 != 0) || (len < 4))
|
||||
throw new InvalidDataException();
|
||||
|
||||
_addresses = new IPAddress[len / 4];
|
||||
|
||||
for (int i = 0; i < _addresses.Length; i++)
|
||||
_addresses[i] = new IPAddress(s.ReadBytes(4));
|
||||
_addresses = addresses;
|
||||
}
|
||||
|
||||
public NetBiosNameServerOption(Stream s)
|
||||
: base(DhcpOptionCode.NetBiosOverTcpIpNameServer, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_addresses.Length * 4));
|
||||
if ((s.Length % 4 != 0) || (s.Length < 4))
|
||||
throw new InvalidDataException();
|
||||
|
||||
_addresses = new IPAddress[s.Length / 4];
|
||||
|
||||
for (int i = 0; i < _addresses.Length; i++)
|
||||
_addresses[i] = new IPAddress(s.ReadBytes(4));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
foreach (IPAddress address in _addresses)
|
||||
s.Write(address.GetAddressBytes());
|
||||
}
|
||||
@@ -17,47 +17,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class NetworkTimeProtocolServersOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly IPAddress[] _addresses;
|
||||
IPAddress[] _addresses;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public NetworkTimeProtocolServersOption(Stream s)
|
||||
public NetworkTimeProtocolServersOption(IPAddress[] addresses)
|
||||
: base(DhcpOptionCode.NetworkTimeProtocolServers)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if ((len % 4 != 0) || (len < 4))
|
||||
throw new InvalidDataException();
|
||||
|
||||
_addresses = new IPAddress[len / 4];
|
||||
|
||||
for (int i = 0; i < _addresses.Length; i++)
|
||||
_addresses[i] = new IPAddress(s.ReadBytes(4));
|
||||
_addresses = addresses;
|
||||
}
|
||||
|
||||
public NetworkTimeProtocolServersOption(Stream s)
|
||||
: base(DhcpOptionCode.NetworkTimeProtocolServers, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_addresses.Length * 4));
|
||||
if ((s.Length % 4 != 0) || (s.Length < 4))
|
||||
throw new InvalidDataException();
|
||||
|
||||
_addresses = new IPAddress[s.Length / 4];
|
||||
|
||||
for (int i = 0; i < _addresses.Length; i++)
|
||||
_addresses[i] = new IPAddress(s.ReadBytes(4));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
foreach (IPAddress address in _addresses)
|
||||
s.Write(address.GetAddressBytes());
|
||||
}
|
||||
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
enum OptionOverloadValue : byte
|
||||
{
|
||||
@@ -32,20 +32,29 @@ namespace DnsServerCore.Dhcp
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly OptionOverloadValue _value;
|
||||
OptionOverloadValue _value;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public OptionOverloadOption(Stream s)
|
||||
public OptionOverloadOption(OptionOverloadValue value)
|
||||
: base(DhcpOptionCode.OptionOverload)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
_value = value;
|
||||
}
|
||||
|
||||
if (len != 1)
|
||||
public OptionOverloadOption(Stream s)
|
||||
: base(DhcpOptionCode.OptionOverload, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length != 1)
|
||||
throw new InvalidDataException();
|
||||
|
||||
int value = s.ReadByte();
|
||||
@@ -55,13 +64,8 @@ namespace DnsServerCore.Dhcp
|
||||
_value = (OptionOverloadValue)value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(4);
|
||||
s.WriteByte((byte)_value);
|
||||
}
|
||||
|
||||
@@ -17,32 +17,40 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class ParameterRequestListOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly DhcpOptionCode[] _optionCodes;
|
||||
DhcpOptionCode[] _optionCodes;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public ParameterRequestListOption(Stream s)
|
||||
public ParameterRequestListOption(DhcpOptionCode[] optionCodes)
|
||||
: base(DhcpOptionCode.ParameterRequestList)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
_optionCodes = optionCodes;
|
||||
}
|
||||
|
||||
if (len < 1)
|
||||
public ParameterRequestListOption(Stream s)
|
||||
: base(DhcpOptionCode.ParameterRequestList, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length < 1)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_optionCodes = new DhcpOptionCode[len];
|
||||
_optionCodes = new DhcpOptionCode[s.Length];
|
||||
int optionCode;
|
||||
|
||||
for (int i = 0; i < _optionCodes.Length; i++)
|
||||
@@ -55,14 +63,8 @@ namespace DnsServerCore.Dhcp
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_optionCodes.Length));
|
||||
|
||||
foreach (DhcpOptionCode optionCode in _optionCodes)
|
||||
s.WriteByte((byte)optionCode);
|
||||
}
|
||||
@@ -21,39 +21,47 @@ using System;
|
||||
using System.IO;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class RebindingTimeValueOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly uint _t2Interval;
|
||||
uint _t2Interval;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public RebindingTimeValueOption(Stream s)
|
||||
public RebindingTimeValueOption(uint t2Interval)
|
||||
: base(DhcpOptionCode.RebindingTimeValue)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_t2Interval = BitConverter.ToUInt32(s.ReadBytes(4), 0);
|
||||
_t2Interval = t2Interval;
|
||||
}
|
||||
|
||||
public RebindingTimeValueOption(Stream s)
|
||||
: base(DhcpOptionCode.RebindingTimeValue, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(4);
|
||||
s.Write(BitConverter.GetBytes(_t2Interval));
|
||||
if (s.Length != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
byte[] buffer = s.ReadBytes(4);
|
||||
Array.Reverse(buffer);
|
||||
_t2Interval = BitConverter.ToUInt32(buffer, 0);
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
byte[] buffer = BitConverter.GetBytes(_t2Interval);
|
||||
Array.Reverse(buffer);
|
||||
s.Write(buffer);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -21,39 +21,47 @@ using System;
|
||||
using System.IO;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class RenewalTimeValueOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly uint _t1Interval;
|
||||
uint _t1Interval;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public RenewalTimeValueOption(Stream s)
|
||||
public RenewalTimeValueOption(uint t1Interval)
|
||||
: base(DhcpOptionCode.RenewalTimeValue)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_t1Interval = BitConverter.ToUInt32(s.ReadBytes(4), 0);
|
||||
_t1Interval = t1Interval;
|
||||
}
|
||||
|
||||
public RenewalTimeValueOption(Stream s)
|
||||
: base(DhcpOptionCode.RenewalTimeValue, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(4);
|
||||
s.Write(BitConverter.GetBytes(_t1Interval));
|
||||
if (s.Length != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
byte[] buffer = s.ReadBytes(4);
|
||||
Array.Reverse(buffer);
|
||||
_t1Interval = BitConverter.ToUInt32(buffer, 0);
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
byte[] buffer = BitConverter.GetBytes(_t1Interval);
|
||||
Array.Reverse(buffer);
|
||||
s.Write(buffer);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -21,38 +21,42 @@ using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class RequestedIpAddressOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly IPAddress _address;
|
||||
IPAddress _address;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public RequestedIpAddressOption(Stream s)
|
||||
public RequestedIpAddressOption(IPAddress address)
|
||||
: base(DhcpOptionCode.RequestedIpAddress)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_address = new IPAddress(s.ReadBytes(4));
|
||||
_address = address;
|
||||
}
|
||||
|
||||
public RequestedIpAddressOption(Stream s)
|
||||
: base(DhcpOptionCode.RequestedIpAddress, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_address = new IPAddress(s.ReadBytes(4));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(4);
|
||||
s.Write(_address.GetAddressBytes());
|
||||
}
|
||||
|
||||
@@ -17,47 +17,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class RouterOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly IPAddress[] _addresses;
|
||||
IPAddress[] _addresses;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public RouterOption(Stream s)
|
||||
public RouterOption(IPAddress[] addresses)
|
||||
: base(DhcpOptionCode.Router)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if ((len % 4 != 0) || (len < 4))
|
||||
throw new InvalidDataException();
|
||||
|
||||
_addresses = new IPAddress[len / 4];
|
||||
|
||||
for (int i = 0; i < _addresses.Length; i++)
|
||||
_addresses[i] = new IPAddress(s.ReadBytes(4));
|
||||
_addresses = addresses;
|
||||
}
|
||||
|
||||
public RouterOption(Stream s)
|
||||
: base(DhcpOptionCode.Router, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_addresses.Length * 4));
|
||||
if ((s.Length % 4 != 0) || (s.Length < 4))
|
||||
throw new InvalidDataException();
|
||||
|
||||
_addresses = new IPAddress[s.Length / 4];
|
||||
|
||||
for (int i = 0; i < _addresses.Length; i++)
|
||||
_addresses[i] = new IPAddress(s.ReadBytes(4));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
foreach (IPAddress address in _addresses)
|
||||
s.Write(address.GetAddressBytes());
|
||||
}
|
||||
@@ -21,38 +21,42 @@ using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class ServerIdentifierOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly IPAddress _address;
|
||||
IPAddress _address;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public ServerIdentifierOption(Stream s)
|
||||
public ServerIdentifierOption(IPAddress address)
|
||||
: base(DhcpOptionCode.ServerIdentifier)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_address = new IPAddress(s.ReadBytes(4));
|
||||
_address = address;
|
||||
}
|
||||
|
||||
public ServerIdentifierOption(Stream s)
|
||||
: base(DhcpOptionCode.ServerIdentifier, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_address = new IPAddress(s.ReadBytes(4));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(4);
|
||||
s.Write(_address.GetAddressBytes());
|
||||
}
|
||||
|
||||
@@ -21,38 +21,42 @@ using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
namespace DnsServerCore.Dhcp.Options
|
||||
{
|
||||
class SubnetMaskOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly IPAddress _subnetMask;
|
||||
IPAddress _subnetMask;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public SubnetMaskOption(Stream s)
|
||||
public SubnetMaskOption(IPAddress subnetMask)
|
||||
: base(DhcpOptionCode.SubnetMask)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (len != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_subnetMask = new IPAddress(s.ReadBytes(4));
|
||||
_subnetMask = subnetMask;
|
||||
}
|
||||
|
||||
public SubnetMaskOption(Stream s)
|
||||
: base(DhcpOptionCode.SubnetMask, s)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
protected override void ParseOptionValue(Stream s)
|
||||
{
|
||||
if (s.Length != 4)
|
||||
throw new InvalidDataException();
|
||||
|
||||
_subnetMask = new IPAddress(s.ReadBytes(4));
|
||||
}
|
||||
|
||||
protected override void WriteOptionValue(Stream s)
|
||||
{
|
||||
s.WriteByte(4);
|
||||
s.Write(_subnetMask.GetAddressBytes());
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
Technitium DNS Server
|
||||
Copyright (C) 2019 Shreyas Zare (shreyas@technitium.com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using TechnitiumLibrary.IO;
|
||||
|
||||
namespace DnsServerCore.Dhcp
|
||||
{
|
||||
class StaticRouteOption : DhcpOption
|
||||
{
|
||||
#region variables
|
||||
|
||||
readonly Tuple<IPAddress, IPAddress>[] _routes;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public StaticRouteOption(Stream s)
|
||||
: base(DhcpOptionCode.StaticRoute)
|
||||
{
|
||||
int len = s.ReadByte();
|
||||
if (len < 0)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if ((len % 8 != 0) || (len < 8))
|
||||
throw new InvalidDataException();
|
||||
|
||||
_routes = new Tuple<IPAddress, IPAddress>[len / 8];
|
||||
|
||||
for (int i = 0; i < _routes.Length; i++)
|
||||
_routes[i] = new Tuple<IPAddress, IPAddress>(new IPAddress(s.ReadBytes(4)), new IPAddress(s.ReadBytes(4)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected override void WriteOptionTo(Stream s)
|
||||
{
|
||||
s.WriteByte(Convert.ToByte(_routes.Length * 4));
|
||||
|
||||
foreach (Tuple<IPAddress, IPAddress> route in _routes)
|
||||
{
|
||||
s.Write(route.Item1.GetAddressBytes());
|
||||
s.Write(route.Item2.GetAddressBytes());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region properties
|
||||
|
||||
public Tuple<IPAddress, IPAddress>[] Routes
|
||||
{ get { return _routes; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user