mirror of
https://github.com/fergalmoran/DnsServer.git
synced 2026-01-02 06:47:50 +00:00
319 lines
9.1 KiB
C#
319 lines
9.1 KiB
C#
/*
|
|
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 DnsServerCore.Dhcp.Options;
|
|
using System;
|
|
using System.IO;
|
|
using TechnitiumLibrary.IO;
|
|
|
|
namespace DnsServerCore.Dhcp
|
|
{
|
|
public 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,
|
|
ClientFullyQualifiedDomainName = 81,
|
|
ClasslessStaticRoute = 121,
|
|
End = 255
|
|
}
|
|
|
|
public class DhcpOption
|
|
{
|
|
#region variables
|
|
|
|
readonly DhcpOptionCode _code;
|
|
byte[] _value;
|
|
|
|
#endregion
|
|
|
|
#region constructor
|
|
|
|
protected DhcpOption(DhcpOptionCode code, Stream s)
|
|
{
|
|
_code = code;
|
|
|
|
int len = s.ReadByte();
|
|
if (len < 0)
|
|
throw new EndOfStreamException();
|
|
|
|
_value = s.ReadBytes(len);
|
|
}
|
|
|
|
protected DhcpOption(DhcpOptionCode code)
|
|
{
|
|
_code = code;
|
|
}
|
|
|
|
#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.VendorSpecificInformation:
|
|
return new VendorSpecificInformationOption(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.MaximumDhcpMessageSize:
|
|
return new MaximumDhcpMessageSizeOption(s);
|
|
|
|
case DhcpOptionCode.RenewalTimeValue:
|
|
return new RenewalTimeValueOption(s);
|
|
|
|
case DhcpOptionCode.RebindingTimeValue:
|
|
return new RebindingTimeValueOption(s);
|
|
|
|
case DhcpOptionCode.VendorClassIdentifier:
|
|
return new VendorClassIdentifierOption(s);
|
|
|
|
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);
|
|
|
|
default:
|
|
//unknown option
|
|
return new DhcpOption(optionCode, s);
|
|
}
|
|
}
|
|
|
|
#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);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region protected
|
|
|
|
protected virtual void ParseOptionValue(Stream s)
|
|
{ }
|
|
|
|
protected virtual void WriteOptionValue(Stream s)
|
|
{
|
|
if (_value == null)
|
|
throw new NotImplementedException();
|
|
|
|
s.Write(_value);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public
|
|
|
|
public void WriteTo(Stream s)
|
|
{
|
|
switch (_code)
|
|
{
|
|
case DhcpOptionCode.Pad:
|
|
case DhcpOptionCode.End:
|
|
s.WriteByte((byte)_code);
|
|
break;
|
|
|
|
default:
|
|
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;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region properties
|
|
|
|
public DhcpOptionCode Code
|
|
{ get { return _code; } }
|
|
|
|
#endregion
|
|
}
|
|
}
|