From 5083cbd3d0fc7e328e9898ad3ce10066918c33ac Mon Sep 17 00:00:00 2001 From: Firewolf1337 <18141890+Firewolf1337@users.noreply.github.com> Date: Mon, 28 Jul 2025 12:17:23 +0200 Subject: [PATCH] Added feature to disable reserved leases in DHCP server. --- DnsServerCore/Dhcp/Lease.cs | 17 ++++++++++++----- DnsServerCore/Dhcp/Scope.cs | 26 +++++++++++++++++--------- DnsServerCore/WebServiceDhcpApi.cs | 9 +++++---- DnsServerCore/www/index.html | 3 ++- DnsServerCore/www/js/dhcp.js | 8 ++++---- 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/DnsServerCore/Dhcp/Lease.cs b/DnsServerCore/Dhcp/Lease.cs index 4df19b57..ce65729a 100644 --- a/DnsServerCore/Dhcp/Lease.cs +++ b/DnsServerCore/Dhcp/Lease.cs @@ -46,6 +46,7 @@ public class Lease : IComparable readonly byte[] _hardwareAddress; readonly IPAddress _address; string _comments; + bool _isEnabled; readonly DateTime _leaseObtained; DateTime _leaseExpires; @@ -53,7 +54,7 @@ public class Lease : IComparable #region constructor - internal Lease(LeaseType type, ClientIdentifierOption clientIdentifier, string hostName, byte[] hardwareAddress, IPAddress address, string comments, uint leaseTime) + internal Lease(LeaseType type, ClientIdentifierOption clientIdentifier, string hostName, byte[] hardwareAddress, IPAddress address, string comments, uint leaseTime, bool isEnabled) { _type = type; _clientIdentifier = clientIdentifier; @@ -61,17 +62,18 @@ internal Lease(LeaseType type, ClientIdentifierOption clientIdentifier, string h _hardwareAddress = hardwareAddress; _address = address; _comments = comments; + _isEnabled = isEnabled; _leaseObtained = DateTime.UtcNow; ExtendLease(leaseTime); } - internal Lease(LeaseType type, string hostName, DhcpMessageHardwareAddressType hardwareAddressType, byte[] hardwareAddress, IPAddress address, string comments) - : this(type, new ClientIdentifierOption((byte)hardwareAddressType, hardwareAddress), hostName, hardwareAddress, address, comments, 0) + internal Lease(LeaseType type, string hostName, DhcpMessageHardwareAddressType hardwareAddressType, byte[] hardwareAddress, IPAddress address, string comments, bool isEnabled) + : this(type, new ClientIdentifierOption((byte)hardwareAddressType, hardwareAddress), hostName, hardwareAddress, address, comments, 0, isEnabled) { } - internal Lease(LeaseType type, string hostName, DhcpMessageHardwareAddressType hardwareAddressType, string hardwareAddress, IPAddress address, string comments) - : this(type, hostName, hardwareAddressType, ParseHardwareAddress(hardwareAddress), address, comments) + internal Lease(LeaseType type, string hostName, DhcpMessageHardwareAddressType hardwareAddressType, string hardwareAddress, IPAddress address, string comments, bool isEnabled) + : this(type, hostName, hardwareAddressType, ParseHardwareAddress(hardwareAddress), address, comments, isEnabled) { } internal Lease(BinaryReader bR) @@ -101,6 +103,7 @@ internal Lease(BinaryReader bR) _leaseObtained = bR.ReadDateTime(); _leaseExpires = bR.ReadDateTime(); + _isEnabled = bR.ReadBoolean(); break; default: @@ -169,6 +172,7 @@ public void WriteTo(BinaryWriter bW) bW.Write(_leaseObtained); bW.Write(_leaseExpires); + bW.Write(_isEnabled); } public string GetClientInfo() @@ -205,6 +209,9 @@ public byte[] HardwareAddress public IPAddress Address { get { return _address; } } + public bool IsEnabled + { get { return _isEnabled; } } + public string Comments { get { return _comments; } diff --git a/DnsServerCore/Dhcp/Scope.cs b/DnsServerCore/Dhcp/Scope.cs index 2fe29f9a..5ccd2126 100644 --- a/DnsServerCore/Dhcp/Scope.cs +++ b/DnsServerCore/Dhcp/Scope.cs @@ -612,7 +612,7 @@ private void ConvertToReservedLease(Lease lease) lease.ConvertToReserved(); //add reserved lease - Lease reservedLease = new Lease(LeaseType.Reserved, null, DhcpMessageHardwareAddressType.Ethernet, lease.HardwareAddress, lease.Address, null); + Lease reservedLease = new Lease(LeaseType.Reserved, null, DhcpMessageHardwareAddressType.Ethernet, lease.HardwareAddress, lease.Address, null, lease.IsEnabled); _reservedLeases[reservedLease.ClientIdentifier] = reservedLease; } @@ -622,7 +622,7 @@ private void ConvertToDynamicLease(Lease lease) lease.ConvertToDynamic(); //remove reserved lease - Lease reservedLease = new Lease(LeaseType.Reserved, null, DhcpMessageHardwareAddressType.Ethernet, lease.HardwareAddress, lease.Address, null); + Lease reservedLease = new Lease(LeaseType.Reserved, null, DhcpMessageHardwareAddressType.Ethernet, lease.HardwareAddress, lease.Address, null, lease.IsEnabled); _reservedLeases.TryRemove(reservedLease.ClientIdentifier, out _); //remove any old single address exclusion entry @@ -908,7 +908,7 @@ internal bool IsAddressReserved(IPAddress address) { foreach (KeyValuePair reservedLease in _reservedLeases) { - if (address.Equals(reservedLease.Value.Address)) + if (address.Equals(reservedLease.Value.Address) && reservedLease.Value.IsEnabled) return true; } @@ -951,7 +951,7 @@ internal async Task GetOfferAsync(DhcpMessage request) if (existingLease.Type == LeaseType.Reserved) { Lease existingReservedLease = GetReservedLease(request); - if ((existingReservedLease is not null) && (existingReservedLease.Address == existingLease.Address)) + if ((existingReservedLease is not null) && (existingReservedLease.Address == existingLease.Address) && (existingReservedLease.IsEnabled)) return existingLease; //return existing reserved lease //reserved lease address was changed; proceed to offer new lease @@ -975,9 +975,17 @@ internal async Task GetOfferAsync(DhcpMessage request) Lease reservedLease = GetReservedLease(request); if (reservedLease != null) { - Lease reservedOffer = new Lease(LeaseType.Reserved, clientIdentifier, null, request.ClientHardwareAddress, reservedLease.Address, null, GetLeaseTime()); - _offers[clientIdentifier] = reservedOffer; - return reservedOffer; + if (reservedLease.IsEnabled) + { + Lease reservedOffer = new Lease(LeaseType.Reserved, clientIdentifier, null, request.ClientHardwareAddress, reservedLease.Address, null, GetLeaseTime(), reservedLease.IsEnabled); + _offers[clientIdentifier] = reservedOffer; + return reservedOffer; + } + else + { + if (_log is not null) + _log.Write("DHCP Server skipped to offer IP address to " + request.GetClientFullIdentifier() + " for scope '" + _name + "': the reserved lease is disabled."); + } } if (_allowOnlyReservedLeases) @@ -999,7 +1007,7 @@ internal async Task GetOfferAsync(DhcpMessage request) } } - Lease dummyOffer = new Lease(LeaseType.None, null, null, null, null, null, 0); + Lease dummyOffer = new Lease(LeaseType.None, null, null, null, null, null, 0, false); Lease existingOffer = _offers.GetOrAdd(clientIdentifier, dummyOffer); if (dummyOffer != existingOffer) @@ -1076,7 +1084,7 @@ internal async Task GetOfferAsync(DhcpMessage request) } } - Lease offerLease = new Lease(LeaseType.Dynamic, clientIdentifier, null, request.ClientHardwareAddress, offerAddress, null, GetLeaseTime()); + Lease offerLease = new Lease(LeaseType.Dynamic, clientIdentifier, null, request.ClientHardwareAddress, offerAddress, null, GetLeaseTime(), true); return _offers[clientIdentifier] = offerLease; } diff --git a/DnsServerCore/WebServiceDhcpApi.cs b/DnsServerCore/WebServiceDhcpApi.cs index 4fa6101f..b2e2dd30 100644 --- a/DnsServerCore/WebServiceDhcpApi.cs +++ b/DnsServerCore/WebServiceDhcpApi.cs @@ -360,7 +360,7 @@ public void GetDhcpScope(HttpContext context) jsonWriter.WriteString("hardwareAddress", BitConverter.ToString(reservedLease.HardwareAddress)); jsonWriter.WriteString("address", reservedLease.Address.ToString()); jsonWriter.WriteString("comments", reservedLease.Comments); - + jsonWriter.WriteString("isEnabled", reservedLease.IsEnabled.ToString()); jsonWriter.WriteEndObject(); } @@ -630,8 +630,8 @@ public async Task SetDhcpScopeAsync(HttpContext context) string[] strReservedLeaseParts = strReservedLeases.Split('|'); List reservedLeases = new List(); - for (int i = 0; i < strReservedLeaseParts.Length; i += 4) - reservedLeases.Add(new Lease(LeaseType.Reserved, strReservedLeaseParts[i + 0], DhcpMessageHardwareAddressType.Ethernet, strReservedLeaseParts[i + 1], IPAddress.Parse(strReservedLeaseParts[i + 2]), strReservedLeaseParts[i + 3])); + for (int i = 0; i < strReservedLeaseParts.Length; i += 5) + reservedLeases.Add(new Lease(LeaseType.Reserved, strReservedLeaseParts[i + 0], DhcpMessageHardwareAddressType.Ethernet, strReservedLeaseParts[i + 1], IPAddress.Parse(strReservedLeaseParts[i + 2]), strReservedLeaseParts[i + 3], Convert.ToBoolean(strReservedLeaseParts[i + 4]))); scope.ReservedLeases = reservedLeases; } @@ -686,8 +686,9 @@ public void AddReservedLease(HttpContext context) string hardwareAddress = request.GetQueryOrForm("hardwareAddress"); string strIpAddress = request.GetQueryOrForm("ipAddress"); string comments = request.QueryOrForm("comments"); + bool isEnabled = Convert.ToBoolean(request.QueryOrForm("isEnabled")); - Lease reservedLease = new Lease(LeaseType.Reserved, hostName, DhcpMessageHardwareAddressType.Ethernet, hardwareAddress, IPAddress.Parse(strIpAddress), comments); + Lease reservedLease = new Lease(LeaseType.Reserved, hostName, DhcpMessageHardwareAddressType.Ethernet, hardwareAddress, IPAddress.Parse(strIpAddress), comments, isEnabled); if (!scope.AddReservedLease(reservedLease)) throw new DnsWebServiceException("Failed to add reserved lease for scope: " + scopeName); diff --git a/DnsServerCore/www/index.html b/DnsServerCore/www/index.html index 2b4634a8..9f754040 100644 --- a/DnsServerCore/www/index.html +++ b/DnsServerCore/www/index.html @@ -2645,7 +2645,8 @@

Edit Scope

MAC Address IP Address Comments - + Active + diff --git a/DnsServerCore/www/js/dhcp.js b/DnsServerCore/www/js/dhcp.js index 336d9e1c..3d3f332d 100644 --- a/DnsServerCore/www/js/dhcp.js +++ b/DnsServerCore/www/js/dhcp.js @@ -270,7 +270,7 @@ function addDhcpScopeExclusionRow(startingAddress, endingAddress) { $("#tableDhcpScopeExclusions").append(tableHtmlRows); } -function addDhcpScopeReservedLeaseRow(hostName, hardwareAddress, address, comments) { +function addDhcpScopeReservedLeaseRow(hostName, hardwareAddress, address, comments, isEnabled) { var id = Math.floor(Math.random() * 10000); var tableHtmlRows = ""; @@ -278,8 +278,8 @@ function addDhcpScopeReservedLeaseRow(hostName, hardwareAddress, address, commen tableHtmlRows += ""; tableHtmlRows += ""; tableHtmlRows += ""; + tableHtmlRows += ""; tableHtmlRows += ""; - $("#tableDhcpScopeReservedLeases").append(tableHtmlRows); } @@ -431,7 +431,7 @@ function showEditDhcpScope(scopeName) { if (responseJSON.response.reservedLeases != null) { for (var i = 0; i < responseJSON.response.reservedLeases.length; i++) { - addDhcpScopeReservedLeaseRow(responseJSON.response.reservedLeases[i].hostName, responseJSON.response.reservedLeases[i].hardwareAddress, responseJSON.response.reservedLeases[i].address, responseJSON.response.reservedLeases[i].comments); + addDhcpScopeReservedLeaseRow(responseJSON.response.reservedLeases[i].hostName, responseJSON.response.reservedLeases[i].hardwareAddress, responseJSON.response.reservedLeases[i].address, responseJSON.response.reservedLeases[i].comments, responseJSON.response.reservedLeases[i].isEnabled); } } @@ -508,7 +508,7 @@ function saveDhcpScope() { if (exclusions === false) return; - var reservedLeases = serializeTableData($("#tableDhcpScopeReservedLeases"), 4); + var reservedLeases = serializeTableData($("#tableDhcpScopeReservedLeases"), 5); if (reservedLeases === false) return;