internal Lease(BinaryReader bR) { switch (bR.ReadByte()) { case 1: _type = (LeaseType)bR.ReadByte(); _clientIdentifier = DhcpOption.Parse(bR.BaseStream) as ClientIdentifierOption; _clientIdentifier.ParseOptionValue(); _hostName = bR.ReadShortString(); if (_hostName == "") { _hostName = null; } _hardwareAddress = bR.ReadBuffer(); _address = IPAddressExtension.Parse(bR); _leaseObtained = bR.ReadDate(); _leaseExpires = bR.ReadDate(); break; default: throw new InvalidDataException("Lease data format version not supported."); } }
internal Lease(LeaseType type, ClientIdentifierOption clientIdentifier, string hostName, byte[] hardwareAddress, IPAddress address, uint leaseTime) { _type = type; _clientIdentifier = clientIdentifier; _hostName = hostName; _hardwareAddress = hardwareAddress; _address = address; _leaseObtained = DateTime.UtcNow; ExtendLease(leaseTime); }
internal Lease GetReservedLease(ClientIdentifierOption clientIdentifier) { if (_reservedLeases.TryGetValue(clientIdentifier, out Lease reservedLease)) { //reserved address exists if (IsAddressAlreadyAllocated(reservedLease)) { return(null); //reserved lease address is already allocated so ignore reserved lease } return(reservedLease); } return(null); }
internal Lease(BinaryReader bR) { byte version = bR.ReadByte(); switch (version) { case 1: case 2: _type = (LeaseType)bR.ReadByte(); _clientIdentifier = DhcpOption.Parse(bR.BaseStream) as ClientIdentifierOption; _clientIdentifier.ParseOptionValue(); _hostName = bR.ReadShortString(); if (string.IsNullOrWhiteSpace(_hostName)) { _hostName = null; } _hardwareAddress = bR.ReadBuffer(); _address = IPAddressExtension.Parse(bR); if (version >= 2) { _comments = bR.ReadShortString(); if (string.IsNullOrWhiteSpace(_comments)) { _comments = null; } } _leaseObtained = bR.ReadDateTime(); _leaseExpires = bR.ReadDateTime(); break; default: throw new InvalidDataException("Lease data format version not supported."); } }
public void ConvertToDynamicLease(HttpListenerRequest request) { string scopeName = request.QueryString["name"]; if (string.IsNullOrEmpty(scopeName)) { throw new DnsWebServiceException("Parameter 'name' missing."); } Scope scope = _dnsWebService.DhcpServer.GetScope(scopeName); if (scope == null) { throw new DnsWebServiceException("DHCP scope does not exists: " + scopeName); } string strClientIdentifier = request.QueryString["clientIdentifier"]; string strHardwareAddress = request.QueryString["hardwareAddress"]; if (!string.IsNullOrEmpty(strClientIdentifier)) { scope.ConvertToDynamicLease(ClientIdentifierOption.Parse(strClientIdentifier)); } else if (!string.IsNullOrEmpty(strHardwareAddress)) { scope.ConvertToDynamicLease(strHardwareAddress); } else { throw new DnsWebServiceException("Parameter 'hardwareAddress' or 'clientIdentifier' missing. At least one of them must be specified."); } _dnsWebService.DhcpServer.SaveScope(scopeName); _dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] DHCP scope's lease was unreserved successfully: " + scopeName); }
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; })); }
private void ParseOptions(Stream s, List <DhcpOption> options) { while (true) { DhcpOption option = DhcpOption.Parse(s); if (option.Code == DhcpOptionCode.End) { break; } if (option.Code == DhcpOptionCode.Pad) { continue; } bool optionExists = false; foreach (DhcpOption existingOption in options) { if (existingOption.Code == option.Code) { //option already exists so append current option value into existing option existingOption.AppendOptionValue(option); optionExists = true; break; } } if (optionExists) { continue; } //add option to list options.Add(option); switch (option.Code) { case DhcpOptionCode.DhcpMessageType: _dhcpMessageType = option as DhcpMessageTypeOption; break; case DhcpOptionCode.ClientIdentifier: _clientIdentifier = option as ClientIdentifierOption; break; case DhcpOptionCode.HostName: _hostName = option as HostNameOption; break; case DhcpOptionCode.ClientFullyQualifiedDomainName: _clientFullyQualifiedDomainName = option as ClientFullyQualifiedDomainNameOption; break; case DhcpOptionCode.ParameterRequestList: _parameterRequestList = option as ParameterRequestListOption; break; case DhcpOptionCode.MaximumDhcpMessageSize: _maximumDhcpMessageSize = option as MaximumDhcpMessageSizeOption; break; case DhcpOptionCode.ServerIdentifier: _serverIdentifier = option as ServerIdentifierOption; break; case DhcpOptionCode.RequestedIpAddress: _requestedIpAddress = option as RequestedIpAddressOption; break; case DhcpOptionCode.OptionOverload: _optionOverload = option as OptionOverloadOption; break; } } }
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]; _xid = s.ReadBytes(4); s.ReadBytes(buffer, 0, 4); _secs = new byte[2]; Buffer.BlockCopy(buffer, 0, _secs, 0, 2); Array.Reverse(buffer); _flags = (DhcpMessageFlags)BitConverter.ToUInt16(buffer, 0); 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); _clientHardwareAddress = new byte[_hlen]; Buffer.BlockCopy(_chaddr, 0, _clientHardwareAddress, 0, _hlen); _sname = s.ReadBytes(64); _file = s.ReadBytes(128); //read options List <DhcpOption> options = new List <DhcpOption>(); _options = options; s.ReadBytes(buffer, 0, 4); uint magicCookie = BitConverter.ToUInt32(buffer, 0); if (magicCookie == MAGIC_COOKIE) { ParseOptions(s, options); if (_optionOverload != null) { if (_optionOverload.Value.HasFlag(OptionOverloadValue.FileFieldUsed)) { using (MemoryStream mS = new MemoryStream(_file)) { ParseOptions(mS, options); } } if (_optionOverload.Value.HasFlag(OptionOverloadValue.SnameFieldUsed)) { using (MemoryStream mS = new MemoryStream(_sname)) { ParseOptions(mS, options); } } } //parse all option values foreach (DhcpOption option in options) { option.ParseOptionValue(); } } if (_clientIdentifier == null) { _clientIdentifier = new ClientIdentifierOption((byte)_htype, _clientHardwareAddress); } if (_maximumDhcpMessageSize != null) { _maximumDhcpMessageSize = new MaximumDhcpMessageSizeOption(576); } }