public void ChangeNetwork(IPAddress startingAddress, IPAddress endingAddress, IPAddress subnetMask) { if (startingAddress.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentException("Address family not supported.", nameof(startingAddress)); } if (endingAddress.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentException("Address family not supported.", nameof(endingAddress)); } if (subnetMask.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentException("Address family not supported.", nameof(subnetMask)); } uint startingAddressNumber = startingAddress.ConvertIpToNumber(); uint endingAddressNumber = endingAddress.ConvertIpToNumber(); if (startingAddressNumber >= endingAddressNumber) { throw new ArgumentException("Ending address must be greater than starting address."); } _startingAddress = startingAddress; _endingAddress = endingAddress; _subnetMask = subnetMask; //compute other parameters uint subnetMaskNumber = _subnetMask.ConvertIpToNumber(); uint networkAddressNumber = startingAddressNumber & subnetMaskNumber; uint broadcastAddressNumber = networkAddressNumber | ~subnetMaskNumber; if (networkAddressNumber == startingAddressNumber) { throw new ArgumentException("Starting address cannot be same as the network address."); } if (broadcastAddressNumber == endingAddressNumber) { throw new ArgumentException("Ending address cannot be same as the broadcast address."); } _networkAddress = IPAddressExtension.ConvertNumberToIp(networkAddressNumber); _broadcastAddress = IPAddressExtension.ConvertNumberToIp(broadcastAddressNumber); _reverseZone = Zone.GetReverseZone(_networkAddress, _subnetMask); lock (_lastAddressOfferedLock) { _lastAddressOffered = IPAddressExtension.ConvertNumberToIp(startingAddressNumber - 1u); } }
internal Lease GetOffer(DhcpMessage request) { if (_leases.TryGetValue(request.ClientIdentifier, out Lease existingLease)) { //lease already exists return(existingLease); } if (_reservedLeases != null) { ClientIdentifierOption clientIdentifierKey = new ClientIdentifierOption(1, request.ClientHardwareAddress); foreach (Lease reservedLease in _reservedLeases) { if (reservedLease.ClientIdentifier.Equals(clientIdentifierKey)) { //reserved address exists IPAddress reservedLeaseAddress = reservedLease.Address; if (!IsAddressAvailable(ref reservedLeaseAddress)) { break; //reserved lease address is already allocated so ignore reserved lease } Lease reservedOffer = new Lease(LeaseType.Reserved, request.ClientIdentifier, request.HostName?.HostName, request.ClientHardwareAddress, reservedLease.Address, null, GetLeaseTime()); return(_offers.AddOrUpdate(request.ClientIdentifier, reservedOffer, delegate(ClientIdentifierOption key, Lease existingValue) { return reservedOffer; })); } } } if (_allowOnlyReservedLeases) { throw new DhcpServerException("DHCP Server failed to offer IP address to " + request.GetClientFullIdentifier() + ": scope allows only reserved lease allocations."); } Lease dummyOffer = new Lease(LeaseType.None, null, null, null, null, null, 0); Lease existingOffer = _offers.GetOrAdd(request.ClientIdentifier, dummyOffer); if (dummyOffer != existingOffer) { if (existingOffer.Type == LeaseType.None) { return(null); //dummy offer so another thread is handling offer; do nothing } //offer already exists existingOffer.ExtendLease(GetLeaseTime()); return(existingOffer); } //find offer ip address IPAddress offerAddress = null; if (request.RequestedIpAddress != null) { //client wish to get this address IPAddress requestedAddress = request.RequestedIpAddress.Address; if (IsAddressInRange(requestedAddress) && IsAddressAvailable(ref requestedAddress)) { offerAddress = requestedAddress; } } if (offerAddress == null) { lock (_lastAddressOfferedLock) { //find free address from scope offerAddress = _lastAddressOffered; uint endingAddressNumber = _endingAddress.ConvertIpToNumber(); bool offerAddressWasResetFromEnd = false; while (true) { uint nextOfferAddressNumber = offerAddress.ConvertIpToNumber() + 1u; if (nextOfferAddressNumber > endingAddressNumber) { if (offerAddressWasResetFromEnd) { throw new DhcpServerException("DHCP Server failed to offer IP address to " + request.GetClientFullIdentifier() + ": address unavailable due to address pool exhaustion."); } offerAddress = IPAddressExtension.ConvertNumberToIp(_startingAddress.ConvertIpToNumber() - 1u); offerAddressWasResetFromEnd = true; continue; } offerAddress = IPAddressExtension.ConvertNumberToIp(nextOfferAddressNumber); if (IsAddressAvailable(ref offerAddress)) { break; } } _lastAddressOffered = offerAddress; } } Lease offerLease = new Lease(LeaseType.Dynamic, request.ClientIdentifier, request.HostName?.HostName, request.ClientHardwareAddress, offerAddress, null, GetLeaseTime()); return(_offers.AddOrUpdate(request.ClientIdentifier, offerLease, delegate(ClientIdentifierOption key, Lease existingValue) { return offerLease; })); }