Beispiel #1
0
        private void SendAck(DhcpMessage message, AddressLease lease)
        {
            Trace.TraceInformation("{0} Sending Dhcp Acknowledge.", Thread.CurrentThread.ManagedThreadId);

            DhcpMessage response = new DhcpMessage();

            response.Operation             = DhcpOperation.BootReply;
            response.Hardware              = HardwareType.Ethernet;
            response.HardwareAddressLength = 6;
            response.SecondsElapsed        = message.SecondsElapsed;
            response.SessionId             = message.SessionId;

            response.AssignedAddress       = lease.Address.ToArray();
            response.ClientHardwareAddress = message.ClientHardwareAddress;

            response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Ack);
            response.AddOption(DhcpOption.AddressRequest, lease.Address.ToArray());
            AddDhcpOptions(response);

            this.SendReply(response);
            if (OnNewClient != null)
            {
                OnNewClient(this, new OnNewDHCPClientEvent(lease.Owner.ToString(), lease.Address));
            }
            Trace.TraceInformation("{0} Dhcp Acknowledge Sent:{1}", Thread.CurrentThread.ManagedThreadId, lease.Address.ToString());
        }
Beispiel #2
0
        private void SendOffer(DhcpMessage message, AddressLease offer)
        {
            Trace.TraceInformation("{0} Sending Dhcp Offer.", Thread.CurrentThread.ManagedThreadId);

            DhcpMessage response = new DhcpMessage();

            response.Operation             = DhcpOperation.BootReply;
            response.Hardware              = HardwareType.Ethernet;
            response.HardwareAddressLength = 6;
            response.SecondsElapsed        = message.SecondsElapsed;
            response.SessionId             = message.SessionId;
            response.Flags = message.Flags;

            response.AssignedAddress       = offer.Address.ToArray();
            response.ClientHardwareAddress = message.ClientHardwareAddress;

            response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Offer);
            response.AddOption(DhcpOption.AddressRequest, offer.Address.ToArray());
            AddDhcpOptions(response);

            Byte[] paramList = message.GetOptionData(DhcpOption.ParameterList);
            if (paramList != null)
            {
                response.OptionOrdering = paramList;
            }

            this.SendReply(response);
            Trace.TraceInformation("{0} Dhcp Offer Sent.", Thread.CurrentThread.ManagedThreadId);
        }
Beispiel #3
0
        private void SendReply(DhcpMessage response)
        {
            response.AddOption(DhcpOption.DhcpAddress, this.m_DhcpInterfaceAddress.GetAddressBytes());

            Byte[] sessionId = BitConverter.GetBytes(response.SessionId);

            try
            {
                this.m_DhcpSocket.SendTo(response.ToArray(), new IPEndPoint(IPAddress.Broadcast, DhcpClientPort));
            }
            catch (Exception ex)
            {
                TraceException("Error Sending Dhcp Reply", ex);
                throw;
            }
        }
Beispiel #4
0
        private void SendNak(DhcpMessage message)
        {
            Trace.TraceInformation("{0} Sending Dhcp Negative Acknowledge.", Thread.CurrentThread.ManagedThreadId);

            DhcpMessage response = new DhcpMessage();

            response.Operation             = DhcpOperation.BootReply;
            response.Hardware              = HardwareType.Ethernet;
            response.HardwareAddressLength = 6;
            response.SecondsElapsed        = message.SecondsElapsed;
            response.SessionId             = message.SessionId;

            response.ClientHardwareAddress = message.ClientHardwareAddress;

            response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Nak);

            this.SendReply(response);
            Trace.TraceInformation("{0} Dhcp Negative Acknowledge Sent.", Thread.CurrentThread.ManagedThreadId);
        }
Beispiel #5
0
        static void Main(string[] args)
        {
            Int32 sessionId = (Int32)DateTime.Now.Ticks;

            using (Socket dhcpClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                dhcpClientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                dhcpClientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
                dhcpClientSocket.Bind(new IPEndPoint(IPAddress.Parse("0.0.0.0"), 68));

                DhcpMessage discoverMessage = new DhcpMessage();

                discoverMessage.SessionId = sessionId;
                discoverMessage.Operation = DhcpOperation.BootRequest;
                discoverMessage.Hardware = HardwareType.Ethernet;
                discoverMessage.Flags = 128;

                Byte[] physicalAddr = NetworkInterface.GetAllNetworkInterfaces()[0].GetPhysicalAddress().GetAddressBytes();
                discoverMessage.ClientHardwareAddress = physicalAddr;

                discoverMessage.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Discover);

                Byte[] clientId = new Byte[physicalAddr.Length + 1];
                clientId[0] = (Byte)1;
                physicalAddr.CopyTo(clientId, 1);
                discoverMessage.AddOption(DhcpOption.AutoConfig, 1);
                discoverMessage.AddOption(DhcpOption.Hostname, Encoding.ASCII.GetBytes(Environment.MachineName));
                discoverMessage.AddOption(DhcpOption.ClassId, 77, 83, 70, 84, 32, 53, 46, 48);
                discoverMessage.AddOption(DhcpOption.ClientId, clientId);
                discoverMessage.AddOption(DhcpOption.ParameterList, 1, 15, 3, 6, 44, 46, 47, 31, 33, 121, 249, 43);

                dhcpClientSocket.SendTo(discoverMessage.ToArray(), new IPEndPoint(IPAddress.Broadcast, 67));

                Byte[] buffer = new Byte[1024];
                Int32 len = dhcpClientSocket.Receive(buffer);
                Byte[] messageData = new Byte[len];
                Array.Copy(buffer, messageData, Math.Min(len, buffer.Length));
                DhcpMessage responseMessage = new DhcpMessage(messageData);

                Console.ReadLine();
            }
        }
Beispiel #6
0
        private void AddDhcpOptions(DhcpMessage response)
        {
            response.AddOption(DhcpOption.AddressTime, DhcpMessage.ReverseByteOrder(BitConverter.GetBytes((Int32)this.m_LeaseDuration.TotalSeconds)));
            response.AddOption(DhcpOption.Router, this.m_Gateway.ToArray());
            response.AddOption(DhcpOption.SubnetMask, this.m_Subnet.ToArray());

            if (!String.IsNullOrEmpty(this.m_DnsSuffix))
            {
                response.AddOption(DhcpOption.DomainNameSuffix, Encoding.ASCII.GetBytes(this.m_DnsSuffix));
            }

            if (this.m_DnsServers.Count > 0)
            {
                Byte[] dnsServerAddresses = new Byte[this.m_DnsServers.Count * 4];
                for (Int32 i = 0; i < this.m_DnsServers.Count; i++)
                {
                    this.m_DnsServers[i].ToArray().CopyTo(dnsServerAddresses, i * 4);
                }

                response.AddOption(DhcpOption.DomainNameServer, dnsServerAddresses);
            }
        }
Beispiel #7
0
        private void SendReply(DhcpMessage response)
        {
            response.AddOption(DhcpOption.DhcpAddress, this.m_DhcpInterfaceAddress.GetAddressBytes());

            Byte[] sessionId = BitConverter.GetBytes(response.SessionId);

            try
            {
                this.m_DhcpSocket.SendTo(response.ToArray(), new IPEndPoint(IPAddress.Broadcast, DhcpClientPort));
            }
            catch (Exception ex)
            {
                TraceException("Error Sending Dhcp Reply", ex);
                throw;
            }
        }
Beispiel #8
0
        private void SendOffer(DhcpMessage message, AddressLease offer)
        {
            Trace.TraceInformation("{0} Sending Dhcp Offer.", Thread.CurrentThread.ManagedThreadId);

            DhcpMessage response = new DhcpMessage();
            response.Operation = DhcpOperation.BootReply;
            response.Hardware = HardwareType.Ethernet;
            response.HardwareAddressLength = 6;
            response.SecondsElapsed = message.SecondsElapsed;
            response.SessionId = message.SessionId;
            response.Flags = message.Flags;

            response.AssignedAddress = offer.Address.ToArray();
            response.ClientHardwareAddress = message.ClientHardwareAddress;

            response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Offer);
            response.AddOption(DhcpOption.AddressRequest, offer.Address.ToArray());
            AddDhcpOptions(response);

            Byte[] paramList = message.GetOptionData(DhcpOption.ParameterList);
            if (paramList != null)
            {
                response.OptionOrdering = paramList;
            }

            this.SendReply(response);
            Trace.TraceInformation("{0} Dhcp Offer Sent.", Thread.CurrentThread.ManagedThreadId);
        }
Beispiel #9
0
        private void SendNak(DhcpMessage message)
        {
            Trace.TraceInformation("{0} Sending Dhcp Negative Acknowledge.", Thread.CurrentThread.ManagedThreadId);

            DhcpMessage response = new DhcpMessage();
            response.Operation = DhcpOperation.BootReply;
            response.Hardware = HardwareType.Ethernet;
            response.HardwareAddressLength = 6;
            response.SecondsElapsed = message.SecondsElapsed;
            response.SessionId = message.SessionId;

            response.ClientHardwareAddress = message.ClientHardwareAddress;

            response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Nak);

            this.SendReply(response);
            Trace.TraceInformation("{0} Dhcp Negative Acknowledge Sent.", Thread.CurrentThread.ManagedThreadId);
        }
Beispiel #10
0
        private void SendAck(DhcpMessage message, AddressLease lease)
        {
            Trace.TraceInformation("{0} Sending Dhcp Acknowledge.", Thread.CurrentThread.ManagedThreadId);

            DhcpMessage response = new DhcpMessage();
            response.Operation = DhcpOperation.BootReply;
            response.Hardware = HardwareType.Ethernet;
            response.HardwareAddressLength = 6;
            response.SecondsElapsed = message.SecondsElapsed;
            response.SessionId = message.SessionId;

            response.AssignedAddress = lease.Address.ToArray();
            response.ClientHardwareAddress = message.ClientHardwareAddress;

            response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Ack);
            response.AddOption(DhcpOption.AddressRequest, lease.Address.ToArray());
            AddDhcpOptions(response);

            this.SendReply(response);
            if (OnNewClient != null)
                OnNewClient(this, new OnNewDHCPClientEvent(lease.Owner.ToString(), lease.Address));
            Trace.TraceInformation("{0} Dhcp Acknowledge Sent:{1}", Thread.CurrentThread.ManagedThreadId, lease.Address.ToString());
        }
Beispiel #11
0
        private void DhcpRequest(DhcpMessage message)
        {
            Byte[] addressRequestData = message.GetOptionData(DhcpOption.AddressRequest);
            if (addressRequestData == null)
            {
                addressRequestData = message.ClientAddress;
            }

            InternetAddress addressRequest = new InternetAddress(addressRequestData);

            if (addressRequest.IsEmpty)
            {
                this.SendNak(message);
                return;
            }

            // Assume we're on an ethernet network
            Byte[] hardwareAddressData = new Byte[6];
            Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6);
            PhysicalAddress clientHardwareAddress = new PhysicalAddress(hardwareAddressData);

            AddressLease assignment = null;
            Boolean ack = false;

            // If this client is explicitly allowed, or they are not denied and the allow any flag is set
            if (this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_Acl[clientHardwareAddress] ||
                !this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_AllowAny)
            {
                if (this.m_Reservations.ContainsKey(clientHardwareAddress))
                {
                    assignment = new AddressLease(clientHardwareAddress, this.m_Reservations[clientHardwareAddress], DateTime.Now.Add(this.m_LeaseDuration));
                    if (addressRequest.Equals(assignment.Address))
                    {
                        ack = true;
                    }
                }
                else
                {
                    lock (this.m_LeaseSync)
                    {
                        if (this.m_ActiveLeases.ContainsKey(addressRequest) &&
                            (this.m_ActiveLeases[addressRequest].Owner.Equals(clientHardwareAddress) || this.m_ActiveLeases[addressRequest].SessionId == message.SessionId))
                        {
                            assignment = this.m_ActiveLeases[addressRequest];
                            assignment.Acknowledged = true;
                            assignment.Owner = clientHardwareAddress;
                            assignment.Expiration = DateTime.Now.Add(this.m_LeaseDuration);
                            ack = true;
                        }
                    }
                }
            }

            if (ack)
            {
                this.SendAck(message, assignment);
            }
            else
            {
                this.SendNak(message);
            }
        }
Beispiel #12
0
        private void DhcpDiscover(DhcpMessage message)
        {
            Byte[] addressRequestData = message.GetOptionData(DhcpOption.AddressRequest);
            if (addressRequestData == null)
            {
                addressRequestData = message.ClientAddress;
            }

            InternetAddress addressRequest = new InternetAddress(addressRequestData);

            // Assume we're on an ethernet network
            Byte[] hardwareAddressData = new Byte[6];
            Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6);
            PhysicalAddress clientHardwareAddress = new PhysicalAddress(hardwareAddressData);

            AddressLease offer = null;

            // If this client is explicitly allowed, or they are not denied and the allow any flag is set
            if (this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_Acl[clientHardwareAddress] ||
                !this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_AllowAny)
            {
                if (this.m_Reservations.ContainsKey(clientHardwareAddress))
                {
                    offer = new AddressLease(clientHardwareAddress, this.m_Reservations[clientHardwareAddress], DateTime.Now.Add(this.m_LeaseDuration));
                }
                else
                {
                    lock (this.m_LeaseSync)
                    {
                        if (!addressRequest.Equals(InternetAddress.Empty))
                        {
                            if (this.m_InactiveLeases.ContainsKey(addressRequest))
                            {
                                offer = this.m_InactiveLeases[addressRequest];
                                this.m_InactiveLeases.Remove(addressRequest);
                                this.m_ActiveLeases.Add(addressRequest, offer);
                            }
                            else if (this.m_ActiveLeases.ContainsKey(addressRequest) && this.m_ActiveLeases[addressRequest].Owner.Equals(clientHardwareAddress))
                            {
                                offer = this.m_ActiveLeases[addressRequest];
                            }
                        }
                        else if (this.m_InactiveLeases.Count > 0)
                        {
                            offer = this.m_InactiveLeases.Values[0];
                            this.m_InactiveLeases.Remove(offer.Address);
                            this.m_ActiveLeases.Add(offer.Address, offer);
                        }
                    }
                }
            }

            if (offer == null)
            {
                this.SendNak(message);
            }
            else
            {
                offer.Acknowledged = false;
                offer.Expiration = DateTime.Now.Add(this.m_OfferTimeout);
                offer.SessionId = message.SessionId;
                offer.Owner = clientHardwareAddress;
                this.SendOffer(message, offer);
            }
        }
Beispiel #13
0
        private void CompleteRequest(Object state)
        {
            DhcpData messageData = (DhcpData)state;
            EndPoint source = new IPEndPoint(0, 0);

            this.m_AbortLock.AcquireReaderLock(-1);

            try {
                if (this.m_Abort) {
                    return;
                }
                messageData.BufferSize = this.m_DhcpSocket.EndReceiveFrom(messageData.Result, ref source);
                messageData.Source = (IPEndPoint)source;
            } catch (ArgumentException ex) {
                Trace.TraceInformation("DHCP: "+ex.Message);
                return;
            } finally
            {
                this.m_AbortLock.ReleaseLock();
            }

            DhcpMessage message;

            try
            {
                message = new DhcpMessage(messageData);
            }
            catch (ArgumentException ex)
            {
                TraceException("Error Parsing Dhcp Message", ex);
                return;
            }
            catch (InvalidCastException ex)
            {
                TraceException("Error Parsing Dhcp Message", ex);
                return;
            }
            catch (IndexOutOfRangeException ex)
            {
                TraceException("Error Parsing Dhcp Message", ex);
                return;
            }
            catch (Exception ex)
            {
                TraceException("Error Parsing Dhcp Message", ex);
                throw;
            }

            if (message.Operation == DhcpOperation.BootRequest)
            {
                Byte[] messageTypeData = message.GetOptionData(DhcpOption.DhcpMessageType);

                if (messageTypeData != null && messageTypeData.Length == 1)
                {
                    DhcpMessageType messageType = (DhcpMessageType)messageTypeData[0];

                    switch (messageType)
                    {
                        case DhcpMessageType.Discover:
                            Trace.TraceInformation("{0} Dhcp DISCOVER Message Received.", Thread.CurrentThread.ManagedThreadId);
                            this.DhcpDiscover(message);
                            Trace.TraceInformation("{0} Dhcp DISCOVER Message Processed.", Thread.CurrentThread.ManagedThreadId);
                            break;
                        case DhcpMessageType.Request:
                            Trace.TraceInformation("{0} Dhcp REQUEST Message Received.", Thread.CurrentThread.ManagedThreadId);
                            this.DhcpRequest(message);
                            Trace.TraceInformation("{0} Dhcp REQUEST Message Processed.", Thread.CurrentThread.ManagedThreadId);
                            break;
                        default:
                            Trace.TraceWarning("Unknown Dhcp Message ({0}) Received, Ignoring.", messageType.ToString());
                            break;
                    }
                }
                else
                {
                    Trace.TraceWarning("Unknown Dhcp Data Received, Ignoring.");
                }
            }
        }
Beispiel #14
0
        private void AddDhcpOptions(DhcpMessage response)
        {
            response.AddOption(DhcpOption.AddressTime, DhcpMessage.ReverseByteOrder(BitConverter.GetBytes((Int32)this.m_LeaseDuration.TotalSeconds)));
            response.AddOption(DhcpOption.Router, this.m_Gateway.ToArray());
            response.AddOption(DhcpOption.SubnetMask, this.m_Subnet.ToArray());

            if (!String.IsNullOrEmpty(this.m_DnsSuffix))
            {
                response.AddOption(DhcpOption.DomainNameSuffix, Encoding.ASCII.GetBytes(this.m_DnsSuffix));
            }

            if (this.m_DnsServers.Count > 0)
            {
                Byte[] dnsServerAddresses = new Byte[this.m_DnsServers.Count * 4];
                for (Int32 i = 0; i < this.m_DnsServers.Count; i++)
                {
                    this.m_DnsServers[i].ToArray().CopyTo(dnsServerAddresses, i * 4);
                }

                response.AddOption(DhcpOption.DomainNameServer, dnsServerAddresses);
            }
        }
Beispiel #15
0
        private void CompleteRequest(Object state)
        {
            DhcpData messageData = (DhcpData)state;
            EndPoint source      = new IPEndPoint(0, 0);

            this.m_AbortLock.AcquireReaderLock(-1);

            try {
                if (this.m_Abort)
                {
                    return;
                }
                messageData.BufferSize = this.m_DhcpSocket.EndReceiveFrom(messageData.Result, ref source);
                messageData.Source     = (IPEndPoint)source;
            } catch (ArgumentException ex) {
                Trace.TraceInformation("DHCP: " + ex.Message);
                return;
            } finally
            {
                this.m_AbortLock.ReleaseLock();
            }

            DhcpMessage message;

            try
            {
                message = new DhcpMessage(messageData);
            }
            catch (ArgumentException ex)
            {
                TraceException("Error Parsing Dhcp Message", ex);
                return;
            }
            catch (InvalidCastException ex)
            {
                TraceException("Error Parsing Dhcp Message", ex);
                return;
            }
            catch (IndexOutOfRangeException ex)
            {
                TraceException("Error Parsing Dhcp Message", ex);
                return;
            }
            catch (Exception ex)
            {
                TraceException("Error Parsing Dhcp Message", ex);
                throw;
            }

            if (message.Operation == DhcpOperation.BootRequest)
            {
                Byte[] messageTypeData = message.GetOptionData(DhcpOption.DhcpMessageType);

                if (messageTypeData != null && messageTypeData.Length == 1)
                {
                    DhcpMessageType messageType = (DhcpMessageType)messageTypeData[0];

                    switch (messageType)
                    {
                    case DhcpMessageType.Discover:
                        Trace.TraceInformation("{0} Dhcp DISCOVER Message Received.", Thread.CurrentThread.ManagedThreadId);
                        this.DhcpDiscover(message);
                        Trace.TraceInformation("{0} Dhcp DISCOVER Message Processed.", Thread.CurrentThread.ManagedThreadId);
                        break;

                    case DhcpMessageType.Request:
                        Trace.TraceInformation("{0} Dhcp REQUEST Message Received.", Thread.CurrentThread.ManagedThreadId);
                        this.DhcpRequest(message);
                        Trace.TraceInformation("{0} Dhcp REQUEST Message Processed.", Thread.CurrentThread.ManagedThreadId);
                        break;

                    default:
                        Trace.TraceWarning("Unknown Dhcp Message ({0}) Received, Ignoring.", messageType.ToString());
                        break;
                    }
                }
                else
                {
                    Trace.TraceWarning("Unknown Dhcp Data Received, Ignoring.");
                }
            }
        }
Beispiel #16
0
        private void DhcpDiscover(DhcpMessage message)
        {
            Byte[] addressRequestData = message.GetOptionData(DhcpOption.AddressRequest);
            if (addressRequestData == null)
            {
                addressRequestData = message.ClientAddress;
            }

            InternetAddress addressRequest = new InternetAddress(addressRequestData);

            // Assume we're on an ethernet network
            Byte[] hardwareAddressData = new Byte[6];
            Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6);
            PhysicalAddress clientHardwareAddress = new PhysicalAddress(hardwareAddressData);

            AddressLease offer = null;

            // If this client is explicitly allowed, or they are not denied and the allow any flag is set
            if (this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_Acl[clientHardwareAddress] ||
                !this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_AllowAny)
            {
                if (this.m_Reservations.ContainsKey(clientHardwareAddress))
                {
                    offer = new AddressLease(clientHardwareAddress, this.m_Reservations[clientHardwareAddress], DateTime.Now.Add(this.m_LeaseDuration));
                }
                else
                {
                    lock (this.m_LeaseSync)
                    {
                        if (!addressRequest.Equals(InternetAddress.Empty))
                        {
                            if (this.m_InactiveLeases.ContainsKey(addressRequest))
                            {
                                offer = this.m_InactiveLeases[addressRequest];
                                this.m_InactiveLeases.Remove(addressRequest);
                                this.m_ActiveLeases.Add(addressRequest, offer);
                            }
                            else if (this.m_ActiveLeases.ContainsKey(addressRequest) && this.m_ActiveLeases[addressRequest].Owner.Equals(clientHardwareAddress))
                            {
                                offer = this.m_ActiveLeases[addressRequest];
                            }
                        }
                        else if (this.m_InactiveLeases.Count > 0)
                        {
                            offer = this.m_InactiveLeases.Values[0];
                            this.m_InactiveLeases.Remove(offer.Address);
                            this.m_ActiveLeases.Add(offer.Address, offer);
                        }
                    }
                }
            }

            if (offer == null)
            {
                this.SendNak(message);
            }
            else
            {
                offer.Acknowledged = false;
                offer.Expiration   = DateTime.Now.Add(this.m_OfferTimeout);
                offer.SessionId    = message.SessionId;
                offer.Owner        = clientHardwareAddress;
                this.SendOffer(message, offer);
            }
        }
Beispiel #17
0
        private void DhcpRequest(DhcpMessage message)
        {
            Byte[] addressRequestData = message.GetOptionData(DhcpOption.AddressRequest);
            if (addressRequestData == null)
            {
                addressRequestData = message.ClientAddress;
            }

            InternetAddress addressRequest = new InternetAddress(addressRequestData);

            if (addressRequest.IsEmpty)
            {
                this.SendNak(message);
                return;
            }

            // Assume we're on an ethernet network
            Byte[] hardwareAddressData = new Byte[6];
            Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6);
            PhysicalAddress clientHardwareAddress = new PhysicalAddress(hardwareAddressData);

            AddressLease assignment = null;
            Boolean      ack        = false;

            // If this client is explicitly allowed, or they are not denied and the allow any flag is set
            if (this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_Acl[clientHardwareAddress] ||
                !this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_AllowAny)
            {
                if (this.m_Reservations.ContainsKey(clientHardwareAddress))
                {
                    assignment = new AddressLease(clientHardwareAddress, this.m_Reservations[clientHardwareAddress], DateTime.Now.Add(this.m_LeaseDuration));
                    if (addressRequest.Equals(assignment.Address))
                    {
                        ack = true;
                    }
                }
                else
                {
                    lock (this.m_LeaseSync)
                    {
                        if (this.m_ActiveLeases.ContainsKey(addressRequest) &&
                            (this.m_ActiveLeases[addressRequest].Owner.Equals(clientHardwareAddress) || this.m_ActiveLeases[addressRequest].SessionId == message.SessionId))
                        {
                            assignment = this.m_ActiveLeases[addressRequest];
                            assignment.Acknowledged = true;
                            assignment.Owner        = clientHardwareAddress;
                            assignment.Expiration   = DateTime.Now.Add(this.m_LeaseDuration);
                            ack = true;
                        }
                    }
                }
            }

            if (ack)
            {
                this.SendAck(message, assignment);
            }
            else
            {
                this.SendNak(message);
            }
        }