Dhcp Message and Options datagram parsers added

This commit is contained in:
Shreyas Zare
2019-06-02 20:29:23 +05:30
parent f11133025a
commit ebcf49f315
22 changed files with 1965 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
/*
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.Net;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dhcp
{
class BroadcastAddressOption : DhcpOption
{
#region variables
readonly IPAddress _broadcastAddress;
#endregion
#region constructor
public BroadcastAddressOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(4);
s.Write(_broadcastAddress.GetAddressBytes());
}
#endregion
#region properties
public IPAddress BroadcastAddress
{ get { return _broadcastAddress; } }
#endregion
}
}

View File

@@ -0,0 +1,78 @@
/*
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
}
}

View File

@@ -0,0 +1,265 @@
/*
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 System.Net.Sockets;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dhcp
{
enum DhcpMessageOpCode : byte
{
BootRequest = 1,
BootReply = 2
}
enum DhcpMessageHardwareAddressType : byte
{
Ethernet = 1
}
enum DhcpMessageFlags : ushort
{
Broadcast = 0x8000
}
class DhcpMessage
{
#region variables
const uint MAGIC_COOKIE = 0x63825363;
readonly DhcpMessageOpCode _op;
readonly DhcpMessageHardwareAddressType _htype;
readonly byte _hlen;
readonly byte _hops;
readonly uint _xid;
readonly ushort _secs;
readonly DhcpMessageFlags _flags;
readonly IPAddress _ciaddr;
readonly IPAddress _yiaddr;
readonly IPAddress _siaddr;
readonly IPAddress _giaddr;
readonly byte[] _chaddr;
readonly byte[] _sname;
readonly byte[] _file;
readonly List<DhcpOption> _options;
#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)
{
if (ciaddr.AddressFamily != AddressFamily.InterNetwork)
throw new ArgumentException("Address family not supported.", "ciaddr");
if (yiaddr.AddressFamily != AddressFamily.InterNetwork)
throw new ArgumentException("Address family not supported.", "yiaddr");
if (siaddr.AddressFamily != AddressFamily.InterNetwork)
throw new ArgumentException("Address family not supported.", "siaddr");
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 (chaddr.Length < 16)
{
byte[] newchaddr = new byte[16];
Buffer.BlockCopy(chaddr, 0, newchaddr, 0, chaddr.Length);
chaddr = newchaddr;
}
}
_op = op;
_htype = DhcpMessageHardwareAddressType.Ethernet;
_hlen = 6;
_hops = 0;
_xid = xid;
_secs = secs;
_flags = flags;
_ciaddr = ciaddr;
_yiaddr = yiaddr;
_siaddr = siaddr;
_giaddr = giaddr;
_chaddr = chaddr;
_sname = new byte[64];
_file = new byte[128];
_options = options;
}
public DhcpMessage(Stream s)
{
byte[] buffer = new byte[4];
s.ReadBytes(buffer, 0, 4);
_op = (DhcpMessageOpCode)buffer[0];
_htype = (DhcpMessageHardwareAddressType)buffer[1];
_hlen = buffer[2];
_hops = buffer[3];
s.ReadBytes(buffer, 0, 4);
_xid = BitConverter.ToUInt32(buffer, 0);
s.ReadBytes(buffer, 0, 4);
_secs = BitConverter.ToUInt16(buffer, 0);
_flags = (DhcpMessageFlags)BitConverter.ToUInt16(buffer, 2);
s.ReadBytes(buffer, 0, 4);
_ciaddr = new IPAddress(buffer);
s.ReadBytes(buffer, 0, 4);
_yiaddr = new IPAddress(buffer);
s.ReadBytes(buffer, 0, 4);
_siaddr = new IPAddress(buffer);
s.ReadBytes(buffer, 0, 4);
_giaddr = new IPAddress(buffer);
_chaddr = s.ReadBytes(16);
_sname = s.ReadBytes(64);
_file = s.ReadBytes(128);
//read options
_options = new List<DhcpOption>();
s.ReadBytes(buffer, 0, 4);
Array.Reverse(buffer);
uint magicCookie = BitConverter.ToUInt32(buffer, 0);
if (magicCookie == MAGIC_COOKIE)
{
while (true)
{
DhcpOption option = DhcpOption.Parse(s);
if (option.Code == DhcpOptionCode.End)
break;
_options.Add(option);
}
}
}
#endregion
#region public
public void WriteTo(Stream s)
{
s.WriteByte((byte)_op);
s.WriteByte((byte)_htype);
s.WriteByte(_hlen);
s.WriteByte(_hops);
s.Write(BitConverter.GetBytes(_xid));
s.Write(BitConverter.GetBytes(_secs));
s.Write(BitConverter.GetBytes((ushort)_flags));
s.Write(_ciaddr.GetAddressBytes());
s.Write(_yiaddr.GetAddressBytes());
s.Write(_siaddr.GetAddressBytes());
s.Write(_giaddr.GetAddressBytes());
s.Write(_chaddr);
s.Write(_sname);
s.Write(_file);
//write options
s.Write(BitConverter.GetBytes(MAGIC_COOKIE));
foreach (DhcpOption option in _options)
option.WriteTo(s);
}
#endregion
#region properties
public DhcpMessageOpCode OpCode
{ get { return _op; } }
public DhcpMessageHardwareAddressType HardwareAddressType
{ get { return _htype; } }
public byte HardwareAddressLength
{ get { return _hlen; } }
public byte Hops
{ get { return _hops; } }
public uint TransactionId
{ get { return _xid; } }
public ushort SecondsElapsed
{ get { return _secs; } }
public DhcpMessageFlags Flags
{ get { return _flags; } }
public IPAddress ClientIpAddress
{ get { return _ciaddr; } }
public IPAddress YourClientIpAddress
{ get { return _yiaddr; } }
public IPAddress NextServerIpAddress
{ get { return _siaddr; } }
public IPAddress RelayAgentIpAddress
{ get { return _giaddr; } }
public byte[] ClientHardwareAddress
{ get { return _chaddr; } }
public byte[] ServerHostName
{ get { return _sname; } }
public byte[] BootFileName
{ get { return _file; } }
public IReadOnlyList<DhcpOption> Options
{ get { return _options; } }
#endregion
}
}

View File

@@ -0,0 +1,82 @@
/*
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;
namespace DnsServerCore.Dhcp
{
enum DhcpMessageType : byte
{
Discover = 1,
Offer = 2,
Request = 3,
Decline = 4,
Ack = 5,
Nak = 6,
Release = 7,
Inform = 8
}
class DhcpMessageTypeOption : DhcpOption
{
#region variables
readonly DhcpMessageType _messageType;
#endregion
#region constructor
public DhcpMessageTypeOption(Stream s)
: base(DhcpOptionCode.DhcpMessageType)
{
int len = s.ReadByte();
if (len < 0)
throw new EndOfStreamException();
if (len != 1)
throw new InvalidDataException();
int type = s.ReadByte();
if (type < 0)
throw new EndOfStreamException();
_messageType = (DhcpMessageType)type;
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(1);
s.WriteByte((byte)_messageType);
}
#endregion
#region properties
public DhcpMessageType MessageType
{ get { return _messageType; } }
#endregion
}
}

View File

@@ -0,0 +1,260 @@
/*
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
{
enum DhcpOptionCode : byte
{
Pad = 0,
SubnetMask = 1,
TimeOffset = 2,
Router = 3,
TimeServer = 4,
NameServer = 5,
DomainNameServer = 6,
LogServer = 7,
CookieServer = 8,
LprServer = 9,
ImpressServer = 10,
ResourceLocationServer = 11,
HostName = 12,
BootFileSize = 13,
MeritDump = 14,
DomainName = 15,
SwapServer = 16,
RootPath = 17,
ExtensionPath = 18,
IpForwarding = 19,
NonLocalSourceRouting = 20,
PolicyFilter = 21,
MaximumDatagramReassemblySize = 22,
DefaultIpTtl = 23,
PathMtuAgingTimeout = 24,
PathMtuPlateauTable = 25,
InterfaceMtu = 26,
AllSubnetAreLocal = 27,
BroadcastAddress = 28,
PerformMaskDiscovery = 29,
MaskSupplier = 30,
PerformRouterDiscovery = 31,
RouterSolicitationAddress = 32,
StaticRoute = 33,
TrailerEncapsulation = 34,
ArpCacheTimeout = 35,
EthernetEncapsulation = 36,
TcpDefaultTtl = 37,
TcpKeepAliveInterval = 38,
TcpKeepAliveGarbage = 39,
NetworkInformationServiceDomain = 40,
NetworkInformationServers = 41,
NetworkTimeProtocolServers = 42,
VendorSpecificInformation = 43,
NetBiosOverTcpIpNameServer = 44,
NetBiosOverTcpIpDatagramDistributionServer = 45,
NetBiosOverTcpIpNodeType = 46,
NetBiosOverTcpIpScope = 47,
XWindowSystemFontServer = 48,
XWindowSystemDisplayManager = 49,
RequestedIpAddress = 50,
IpAddressLeaseTime = 51,
OptionOverload = 52,
DhcpMessageType = 53,
ServerIdentifier = 54,
ParameterRequestList = 55,
Message = 56,
MaximumDhcpMessageSize = 57,
RenewalTimeValue = 58,
RebindingTimeValue = 59,
VendorClassIdentifier = 60,
ClientIdentifier = 61,
NetworkInformationServicePlusDomain = 64,
NetworkInformationServicePlusServers = 65,
TftpServerName = 66,
BootfileName = 67,
MobileIpHomeAgent = 68,
SmtpServer = 69,
Pop3Server = 70,
NntpServer = 71,
DefaultWwwServer = 72,
DefaultFingerServer = 73,
DefaultIrc = 74,
StreetTalkServer = 75,
StreetTalkDirectoryAssistance = 76,
End = 255
}
class DhcpOption
{
#region variables
readonly DhcpOptionCode _code;
readonly byte[] _value;
#endregion
#region constructor
protected DhcpOption(DhcpOptionCode type)
{
_code = type;
}
private DhcpOption(DhcpOptionCode type, byte[] value)
{
_code = type;
_value = value;
}
#endregion
#region static
public static DhcpOption CreateEndOption()
{
return new DhcpOption(DhcpOptionCode.End);
}
public static DhcpOption Parse(Stream s)
{
int code = s.ReadByte();
if (code < 0)
throw new EndOfStreamException();
DhcpOptionCode optionCode = (DhcpOptionCode)code;
switch (optionCode)
{
case DhcpOptionCode.SubnetMask:
return new SubnetMaskOption(s);
case DhcpOptionCode.Router:
return new RouterOption(s);
case DhcpOptionCode.DomainNameServer:
return new DomainNameServerOption(s);
case DhcpOptionCode.HostName:
return new HostNameOption(s);
case DhcpOptionCode.DomainName:
return new DomainNameOption(s);
case DhcpOptionCode.BroadcastAddress:
return new BroadcastAddressOption(s);
case DhcpOptionCode.StaticRoute:
return new StaticRouteOption(s);
case DhcpOptionCode.NetBiosOverTcpIpNameServer:
return new NetBiosNameServerOption(s);
case DhcpOptionCode.RequestedIpAddress:
return new RequestedIpAddressOption(s);
case DhcpOptionCode.IpAddressLeaseTime:
return new IpAddressLeaseTimeOption(s);
case DhcpOptionCode.OptionOverload:
return new OptionOverloadOption(s);
case DhcpOptionCode.DhcpMessageType:
return new DhcpMessageTypeOption(s);
case DhcpOptionCode.ServerIdentifier:
return new ServerIdentifierOption(s);
case DhcpOptionCode.ParameterRequestList:
return new ParameterRequestListOption(s);
case DhcpOptionCode.Message:
return new MessageOption(s);
case DhcpOptionCode.MaximumDhcpMessageSize:
return new MaximumDhcpMessageSizeOption(s);
case DhcpOptionCode.RenewalTimeValue:
return new RenewalTimeValueOption(s);
case DhcpOptionCode.RebindingTimeValue:
return new RebindingTimeValueOption(s);
case DhcpOptionCode.ClientIdentifier:
return new ClientIdentifierOption(s);
case DhcpOptionCode.Pad:
case DhcpOptionCode.End:
return new DhcpOption(optionCode, null);
default:
//unknown option
int len = s.ReadByte();
if (len < 0)
throw new EndOfStreamException();
return new DhcpOption(optionCode, s.ReadBytes(len));
}
}
#endregion
#region protected
protected virtual void WriteOptionTo(Stream s)
{
if (_value == null)
throw new NotImplementedException();
s.WriteByte(Convert.ToByte(_value.Length));
s.Write(_value);
}
#endregion
#region public
public void WriteTo(Stream s)
{
s.WriteByte((byte)_code);
switch (_code)
{
case DhcpOptionCode.Pad:
case DhcpOptionCode.End:
break;
default:
WriteOptionTo(s);
break;
}
}
#endregion
#region properties
public DhcpOptionCode Code
{ get { return _code; } }
#endregion
}
}

View File

@@ -0,0 +1,69 @@
/*
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.Text;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dhcp
{
class DomainNameOption : DhcpOption
{
#region variables
readonly string _domainName;
#endregion
#region constructor
public DomainNameOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(Convert.ToByte(_domainName.Length));
s.Write(Encoding.ASCII.GetBytes(_domainName));
}
#endregion
#region properties
public string DomainName
{ get { return _domainName; } }
#endregion
}
}

View File

@@ -0,0 +1,74 @@
/*
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 DomainNameServerOption : DhcpOption
{
#region variables
readonly IPAddress[] _addresses;
#endregion
#region constructor
public DomainNameServerOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(Convert.ToByte(_addresses.Length * 4));
foreach (IPAddress address in _addresses)
s.Write(address.GetAddressBytes());
}
#endregion
#region properties
public IPAddress[] Addresses
{ get { return _addresses; } }
#endregion
}
}

View File

@@ -0,0 +1,69 @@
/*
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.Text;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dhcp
{
class HostNameOption : DhcpOption
{
#region variables
readonly string _hostName;
#endregion
#region constructor
public HostNameOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(Convert.ToByte(_hostName.Length));
s.Write(Encoding.ASCII.GetBytes(_hostName));
}
#endregion
#region properties
public string HostName
{ get { return _hostName; } }
#endregion
}
}

View File

@@ -0,0 +1,68 @@
/*
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 IpAddressLeaseTimeOption : DhcpOption
{
#region variables
readonly uint _leaseTime;
#endregion
#region constructor
public IpAddressLeaseTimeOption(Stream s)
: 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);
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(4);
s.Write(BitConverter.GetBytes(_leaseTime));
}
#endregion
#region properties
public uint LeaseTime
{ get { return _leaseTime; } }
#endregion
}
}

View File

@@ -0,0 +1,68 @@
/*
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 MaximumDhcpMessageSizeOption : DhcpOption
{
#region variables
readonly ushort _length;
#endregion
#region constructor
public MaximumDhcpMessageSizeOption(Stream s)
: base(DhcpOptionCode.MaximumDhcpMessageSize)
{
int len = s.ReadByte();
if (len < 0)
throw new EndOfStreamException();
if (len != 2)
throw new InvalidDataException();
_length = BitConverter.ToUInt16(s.ReadBytes(2), 0);
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(2);
s.Write(BitConverter.GetBytes(_length));
}
#endregion
#region properties
public uint Length
{ get { return _length; } }
#endregion
}
}

View File

@@ -0,0 +1,69 @@
/*
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.Text;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dhcp
{
class MessageOption : DhcpOption
{
#region variables
readonly string _text;
#endregion
#region constructor
public MessageOption(Stream s)
: base(DhcpOptionCode.Message)
{
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)
{
s.WriteByte(Convert.ToByte(_text.Length));
s.Write(Encoding.ASCII.GetBytes(_text));
}
#endregion
#region properties
public string Text
{ get { return _text; } }
#endregion
}
}

View File

@@ -0,0 +1,74 @@
/*
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 NetBiosNameServerOption : DhcpOption
{
#region variables
readonly IPAddress[] _addresses;
#endregion
#region constructor
public NetBiosNameServerOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(Convert.ToByte(_addresses.Length * 4));
foreach (IPAddress address in _addresses)
s.Write(address.GetAddressBytes());
}
#endregion
#region properties
public IPAddress[] Addresses
{ get { return _addresses; } }
#endregion
}
}

View File

@@ -0,0 +1,74 @@
/*
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 NetworkTimeProtocolServersOption : DhcpOption
{
#region variables
readonly IPAddress[] _addresses;
#endregion
#region constructor
public NetworkTimeProtocolServersOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(Convert.ToByte(_addresses.Length * 4));
foreach (IPAddress address in _addresses)
s.Write(address.GetAddressBytes());
}
#endregion
#region properties
public IPAddress[] Addresses
{ get { return _addresses; } }
#endregion
}
}

View File

@@ -0,0 +1,77 @@
/*
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;
namespace DnsServerCore.Dhcp
{
enum OptionOverloadValue : byte
{
FileFieldUsed = 1,
SnameFieldUsed = 2,
BothFieldsUsed = 3
}
class OptionOverloadOption : DhcpOption
{
#region variables
readonly OptionOverloadValue _value;
#endregion
#region constructor
public OptionOverloadOption(Stream s)
: base(DhcpOptionCode.OptionOverload)
{
int len = s.ReadByte();
if (len < 0)
throw new EndOfStreamException();
if (len != 1)
throw new InvalidDataException();
int value = s.ReadByte();
if (value < 0)
throw new EndOfStreamException();
_value = (OptionOverloadValue)value;
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(4);
s.WriteByte((byte)_value);
}
#endregion
#region properties
public OptionOverloadValue Value
{ get { return _value; } }
#endregion
}
}

View File

@@ -0,0 +1,79 @@
/*
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;
namespace DnsServerCore.Dhcp
{
class ParameterRequestListOption : DhcpOption
{
#region variables
readonly DhcpOptionCode[] _optionCodes;
#endregion
#region constructor
public ParameterRequestListOption(Stream s)
: base(DhcpOptionCode.ParameterRequestList)
{
int len = s.ReadByte();
if (len < 0)
throw new EndOfStreamException();
if (len < 1)
throw new InvalidDataException();
_optionCodes = new DhcpOptionCode[len];
int optionCode;
for (int i = 0; i < _optionCodes.Length; i++)
{
optionCode = s.ReadByte();
if (optionCode < 0)
throw new EndOfStreamException();
_optionCodes[i] = (DhcpOptionCode)optionCode;
}
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(Convert.ToByte(_optionCodes.Length));
foreach (DhcpOptionCode optionCode in _optionCodes)
s.WriteByte((byte)optionCode);
}
#endregion
#region properties
public DhcpOptionCode[] OptionCodes
{ get { return _optionCodes; } }
#endregion
}
}

View File

@@ -0,0 +1,68 @@
/*
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 RebindingTimeValueOption : DhcpOption
{
#region variables
readonly uint _t2Interval;
#endregion
#region constructor
public RebindingTimeValueOption(Stream s)
: 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);
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(4);
s.Write(BitConverter.GetBytes(_t2Interval));
}
#endregion
#region properties
public uint T2Interval
{ get { return _t2Interval; } }
#endregion
}
}

View File

@@ -0,0 +1,68 @@
/*
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 RenewalTimeValueOption : DhcpOption
{
#region variables
readonly uint _t1Interval;
#endregion
#region constructor
public RenewalTimeValueOption(Stream s)
: 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);
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(4);
s.Write(BitConverter.GetBytes(_t1Interval));
}
#endregion
#region properties
public uint T1Interval
{ get { return _t1Interval; } }
#endregion
}
}

View File

@@ -0,0 +1,68 @@
/*
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.Net;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dhcp
{
class RequestedIpAddressOption : DhcpOption
{
#region variables
readonly IPAddress _address;
#endregion
#region constructor
public RequestedIpAddressOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(4);
s.Write(_address.GetAddressBytes());
}
#endregion
#region properties
public IPAddress Address
{ get { return _address; } }
#endregion
}
}

View File

@@ -0,0 +1,74 @@
/*
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 RouterOption : DhcpOption
{
#region variables
readonly IPAddress[] _addresses;
#endregion
#region constructor
public RouterOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(Convert.ToByte(_addresses.Length * 4));
foreach (IPAddress address in _addresses)
s.Write(address.GetAddressBytes());
}
#endregion
#region properties
public IPAddress[] Addresses
{ get { return _addresses; } }
#endregion
}
}

View File

@@ -0,0 +1,68 @@
/*
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.Net;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dhcp
{
class ServerIdentifierOption : DhcpOption
{
#region variables
readonly IPAddress _address;
#endregion
#region constructor
public ServerIdentifierOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(4);
s.Write(_address.GetAddressBytes());
}
#endregion
#region properties
public IPAddress Address
{ get { return _address; } }
#endregion
}
}

View File

@@ -0,0 +1,77 @@
/*
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
}
}

View File

@@ -0,0 +1,68 @@
/*
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.Net;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dhcp
{
class SubnetMaskOption : DhcpOption
{
#region variables
readonly IPAddress _subnetMask;
#endregion
#region constructor
public SubnetMaskOption(Stream s)
: 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));
}
#endregion
#region protected
protected override void WriteOptionTo(Stream s)
{
s.WriteByte(4);
s.Write(_subnetMask.GetAddressBytes());
}
#endregion
#region properties
public IPAddress SubnetMask
{ get { return _subnetMask; } }
#endregion
}
}