Exemple #1
0
        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);
            }
        }
Exemple #2
0
        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;
            }));
        }