/// <summary>
        ///  Process DECLINE message type.
        /// </summary>
        private void DhcpDecline(DhcpMessageEventArgs args)
        {
            #region Pre-Processing
            //  Start pre-process validation

            if (args.RequestOptions.AddressRequest == null)
            {
                Logger.WriteDebug(this, "Ignoring DECLINE message: "
                                  + "Requested IP option is null");
                return; // if processin should not continue
            }

            // End pre-Process validation
            #endregion Pre-Processing

            if (args.RequestOptions.AddressRequest != null)
            {
                args.ResponseBinding.Address = new InternetAddress(args.RequestOptions.AddressRequest);
            }

            BindingLease lease = _bindmgr.SetDeclined(args.ResponseBinding);

            // no reply for v4 decline
            if (lease == null)
            {
                Logger.WriteDebug(this, "DECLINE message: "
                                  + "No binding available for client to decline");
            }
            else
            {
                this.OnLeaseDeclined(this, new DhcpLeaseEventArgs(lease.Address, lease));
            }
        }
        /// <summary>
        ///  Process RELEASE message type.
        /// </summary>
        private void DhcpRelease(DhcpMessageEventArgs args)
        {
            #region Pre-Processing
            //  Start pre-process validation

            if (args.RequestMessage.ClientAddress.Equals(InternetAddress.Any))
            {
                Logger.WriteDebug(this, "Ignoring RELEASE message: "
                                  + "ciAddr is zero");
                return; // if processing should not continue
            }

            // End pre-Process validation
            #endregion Pre-Processing

            BindingLease lease = _bindmgr.SetReleased(args.ResponseBinding);

            // no reply for v4 release
            if (lease == null)
            {
                Logger.WriteDebug(this, "RELEASE message: "
                                  + "No binding available for client to release");
            }
            else
            {
                this.OnLeaseReleased(this, new DhcpLeaseEventArgs(lease.Address, lease));
            }
        }
        /// <summary>
        ///     Initializes a new instance of the <see cref="DhcpMessageEventArgs"/> class.
        /// </summary>
        /// <param name="channel">Socket channel request is recived on.</param>
        /// <param name="data">Raw data received from socket.</param>
        public DhcpMessageEventArgs(SocketChannel channel, SocketBuffer data)
        {
            if (channel == null) throw new ArgumentNullException("channel");
            this.Channel = channel;

            if (data == null) throw new ArgumentNullException("data");
            this.ChannelBuffer = data;

            try
            {
                // Parse the dhcp message
                this.RequestMessage = new DhcpMessage(data.Buffer);

                // get message options
                MessageOptions options = new MessageOptions();

                options.MessageType = this.RequestMessage.GetOptionData(DhcpOption.DhcpMessageType);
                // get message type option
                options.ClientId = this.RequestMessage.GetOptionData(DhcpOption.ClientId);
                if (options.ClientId == null)
                {
                    // if the client id is not provided use the client hardware address from the message
                    options.ClientId = this.RequestMessage.ClientHardwareAddress.ToArray();
                }
                // get host name option
                options.HostName = this.RequestMessage.GetOptionData(DhcpOption.Hostname);
                // get address request option
                options.AddressRequest = this.RequestMessage.GetOptionData(DhcpOption.AddressRequest);
                //get server identifier option
                options.ServerIdentifier = this.RequestMessage.GetOptionData(DhcpOption.ServerIdentifier);
                // get paramerter list opiton
                options.ParameterList = this.RequestMessage.GetOptionData(DhcpOption.ParameterList);

                // set the response options object
                this.RequestOptions = options;

                // set the response binding object
                ResponseBinding = new BindingLease(
                    ByteUtility.GetString(this.RequestOptions.ClientId),
                    this.RequestMessage.ClientHardwareAddress,
                    this.RequestMessage.ClientAddress,
                    this.RequestOptions.HostName,
                    DateTime.MinValue,
                    this.RequestMessage.SessionId,
                    LeaseState.Unassigned);

                // log that the packet was successfully parsed
                Logger.WriteDebug(this, "PACKET with message id " +
                        this.RequestMessage.SessionId.ToHexString("0x") + " successfully parsed from client endpoint " +
                        this.Channel.RemoteEndpoint.ToString());

                Logger.WriteDebug(this.RequestMessage.ToString());
            }
            catch (Exception ex)
            {
                Logger.WriteError(this, "Error parsing message:" + ex.Message.ToString(), ex);
                return;
            }
        }
        public void Load()
        {
            if (!StringUtility.IsNullOrEmpty(_filePath))
            {
                try
                {
                    if (File.Exists(_filePath))
                    {
                        Logger.WriteInfo(this, "Binding file is enabled using " + _filePath);
                        using (var fileStream = new FileStream(_filePath, FileMode.Open))
                        {
                            byte[] data      = new byte[10000];
                            int    readCount = fileStream.Read(data, 0, data.Length);

                            FileStore deserializedData = (FileStore)Reflection.Deserialize((data), typeof(FileStore));

                            if (deserializedData != null && deserializedData.Count > 0)
                            {
                                lock (this._bindingSync)
                                {
                                    foreach (FileStore endPoint in deserializedData)
                                    {
                                        BindingLease lease = new BindingLease(
                                            new PhysicalAddress(endPoint.Owner),
                                            new InternetAddress(endPoint.Address));

                                        lease.ClientId   = endPoint.ClientId;
                                        lease.Expiration = endPoint.Expiration;
                                        lease.State      = endPoint.State;
                                        lease.SessionId  = endPoint.SessionId;
                                        lease.HostName   = endPoint.HostName;

                                        if (!_assignedTable.Contains(lease.Address))
                                        {
                                            _assignedTable.Add(lease.Address, lease);
                                            Logger.WriteDebug("Binding Loaded | " + lease.ToString());
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        Logger.WriteDebug(this, "Bindings file is disabled. Failed to accesss file " + _filePath);
                    }
                }
                catch (Exception ex)
                {
                    Logger.WriteError(this, "Error Message:" + ex.Message.ToString(), ex);
                }
            }
            else
            {
                Logger.WriteInfo(this, "Binding file is disabled");
            }
        }
        /// <summary>
        ///  Send ACK message back to remote client.
        /// </summary>
        private void SendAck(DhcpMessageEventArgs args, BindingLease lease)
        {
            // set header
            args.ResponseMessage.AssignedAddress = lease.Address;

            // set lease options
            this.SetLeaseOptions(args);

            this.SendAck(args);
        }
 private BindingLease SaveBinding(BindingLease binding)
 {
     if (this._assignedTable.Contains(binding.ClientId))
     {
         lock (_bindingSync)
         {
             _assignedTable[binding.ClientId] = binding;
         }
         this.Save();
         return((BindingLease)_assignedTable[binding.ClientId]);
     }
     return(null);
 }
 public void Reservation(InternetAddress address, PhysicalAddress macAddress)
 {
     lock (_bindingSync)
     {
         if (_reservationTable.Contains(address))
         {
             _reservationTable[address] = new BindingLease(RANDOM.Next(int.MaxValue).ToString(), macAddress, address, new byte[0], DateTime.MaxValue, 0, LeaseState.Static);
         }
         else
         {
             _reservationTable.Add(address, new BindingLease(RANDOM.Next(int.MaxValue).ToString(), macAddress, address, new byte[0], DateTime.MaxValue, 0, LeaseState.Static));
         }
     }
 }
        private BindingLease CreateBinding(BindingLease binding, InternetAddress address)
        {
            if (!_assignedTable.Contains(binding.ClientId) && _unassignedTable.Contains(address))
            {
                lock (_bindingSync)
                {
                    _unassignedTable.Remove(address);
                    _assignedTable.Add(binding.ClientId, binding);
                }
                this.Save();

                return((BindingLease)_assignedTable[binding.ClientId]);
            }

            return(null);
        }
 public BindingLease SetDeclined(BindingLease binding)
 {
     if (!binding.Address.Equals(InternetAddress.Any))
     {
         if (_assignedTable.Contains(binding.ClientId))
         {
             BindingLease lease = (BindingLease)_assignedTable[binding.ClientId];
             if (lease.Owner.Equals(binding.Owner) && lease.State != LeaseState.Static)
             {
                 binding.ClientId   = "-1";
                 binding.Expiration = DateTime.Now.AddSeconds(_declinedTimeout);
                 binding.State      = LeaseState.Declined;
                 return(this.SaveBinding(binding));
             }
         }
     }
     return(null);
 }
        /// <summary>
        ///  Send OFFER message back to remote client.
        /// </summary>
        private void SendOffer(DhcpMessageEventArgs args, BindingLease offer)
        {
            // set header
            args.ResponseMessage.AssignedAddress   = offer.Address;
            args.ResponseMessage.NextServerAddress = args.ResponseMessage.NextServerAddress;
            args.ResponseMessage.AddOption(DhcpOption.DhcpMessageType, (Byte)MessageType.Offer);

            this.SetLeaseOptions(args);
            this.SetClientOptions(args);

            byte[] paramList = args.RequestOptions.ParameterList;
            if (paramList != null)
            {
                args.ResponseMessage.OptionOrdering = paramList;
            }

            Logger.WriteInfo(this, "OFFER for message id " + args.RequestMessage.SessionId.ToHexString("0x") + " sent on thread(#" + Thread.CurrentThread.ManagedThreadId + ")");
            this.SendReply(args);
        }
        private void RemoveBinding(BindingLease binding)
        {
            if (this._assignedTable.Contains(binding.ClientId))
            {
                lock (_bindingSync)
                {
                    _assignedTable.Remove(binding.ClientId);

                    binding.ClientId   = RANDOM.Next(int.MaxValue).ToString();
                    binding.SessionId  = 0;
                    binding.HostName   = new byte[0];
                    binding.Owner      = new PhysicalAddress(0, 0, 0, 0, 0, 0);
                    binding.State      = LeaseState.Unassigned;
                    binding.Expiration = DateTime.MaxValue;
                    if (!_unassignedTable.Contains(binding.Address))
                    {
                        _unassignedTable.Add(binding.Address, binding);
                    }
                }
                //this.Save();
            }
        }
        /// <summary>
        ///  Process DISCOVERY message type.
        /// </summary>
        private void DhcpDiscover(DhcpMessageEventArgs args)
        {
            #region Pre-Processing
            //  Start pre-process validation

            if (!args.RequestMessage.ClientAddress.Equals(InternetAddress.Any))
            {
                Logger.WriteDebug(this, "Ignoring DISCOVER message: ciAddr field is non-zero: "
                                  + args.RequestMessage.ClientAddress.ToString());
                return; // if processing not should continue
            }

            if (args.RequestOptions.ServerIdentifier != null)
            {
                Logger.WriteDebug(this, "Ignoring DISCOVER message: ServerId option is not null");
                return; // if processing should not continue
            }

            // End pre-Process validation
            #endregion Pre-Processing

            if (args.ResponseBinding.Address.Equals(InternetAddress.Any) && args.RequestOptions.AddressRequest != null)
            {
                args.ResponseBinding.Address = new InternetAddress(args.RequestOptions.AddressRequest);
            }

            BindingLease offer = _bindmgr.GetOffer(args.ResponseBinding);
            if (offer == null)
            {
                Logger.WriteDebug(this, "DISCOVER message: "
                                  + "No binding available for client");
            }
            else
            {
                this.SendOffer(args, offer);
            }
        }
        public BindingLease GetAssigned(BindingLease binding)
        {
            // assign reservations binding
            if (_reservationTable.Contains(binding.Owner))
            {
                InternetAddress ipAddress = (InternetAddress)_reservationTable[binding.Owner];

                BindingLease lease = (BindingLease)_reservationTable[ipAddress];

                if (lease.Address.Equals(binding.Address) &&
                    lease.Owner.Equals(binding.Owner) &&
                    lease.State.Equals(LeaseState.Static))
                {
                    binding.Expiration = DateTime.MaxValue;
                    binding.State      = LeaseState.Static;

                    return(this.SaveBinding(binding));
                }
            }

            // assign binding
            if (_assignedTable.Contains(binding.ClientId))
            {
                BindingLease lease = (BindingLease)_assignedTable[binding.ClientId];

                if (lease.Owner.Equals(binding.Owner))
                {
                    binding.Expiration = DateTime.Now.AddSeconds(_leaseDuration);
                    binding.State      = LeaseState.Assigned;

                    return(this.SaveBinding(binding));
                }
            }

            return(null);
        }
 public BindingLease SetReleased(BindingLease binding)
 {
     if (!binding.Address.Equals(InternetAddress.Any))
     {
         if (_assignedTable.Contains(binding.ClientId))
         {
             BindingLease lease = (BindingLease)_assignedTable[binding.ClientId];
             if (lease.Owner.Equals(binding.Owner))
             {
                 if (lease.State == LeaseState.Static)
                 {
                     return(lease);
                 }
                 else
                 {
                     binding.Expiration = lease.Expiration;
                     binding.State      = LeaseState.Released;
                     return(this.SaveBinding(binding));
                 }
             }
         }
     }
     return(null);
 }
        private BindingLease CreateBinding(BindingLease binding, InternetAddress address)
        {
            if (!_assignedTable.Contains(binding.ClientId) && _unassignedTable.Contains(address))
            {
                lock (_bindingSync)
                {
                    _unassignedTable.Remove(address);
                    _assignedTable.Add(binding.ClientId, binding);
                }
                this.Save();

                return (BindingLease)_assignedTable[binding.ClientId];
            }

            return null;
        }
 public BindingLease SetReleased(BindingLease binding)
 {
     if (!binding.Address.Equals(InternetAddress.Any))
     {
         if (_assignedTable.Contains(binding.ClientId))
         {
             BindingLease lease = (BindingLease)_assignedTable[binding.ClientId];
             if (lease.Owner.Equals(binding.Owner))
             {
                 if (lease.State == LeaseState.Static)
                 {
                     return lease;
                 }
                 else
                 {
                     binding.Expiration = lease.Expiration;
                     binding.State = LeaseState.Released;
                     return this.SaveBinding(binding);
                 }
             }
         }
     }
     return null;
 }
 public BindingLease SetDeclined(BindingLease binding)
 {
     if (!binding.Address.Equals(InternetAddress.Any))
     {
         if (_assignedTable.Contains(binding.ClientId))
         {
             BindingLease lease = (BindingLease)_assignedTable[binding.ClientId];
             if (lease.Owner.Equals(binding.Owner) && lease.State != LeaseState.Static)
             {
                 binding.ClientId = "-1";
                 binding.Expiration = DateTime.Now.AddSeconds(_declinedTimeout);
                 binding.State = LeaseState.Declined;
                 return this.SaveBinding(binding);
             }
         }
     }
     return null;
 }
        public void Reservation(InternetAddress address, PhysicalAddress macAddress)
        {
            lock (_bindingSync)
            {
                if (_reservationTable.Contains(address))
                {
                    _reservationTable[address] = new BindingLease(RANDOM.Next(int.MaxValue).ToString(), macAddress, address, new byte[0], DateTime.MaxValue, 0, LeaseState.Static);
                }
                else
                {
                    _reservationTable.Add(address, new BindingLease(RANDOM.Next(int.MaxValue).ToString(), macAddress, address, new byte[0], DateTime.MaxValue, 0, LeaseState.Static));

                }
            }
        }
        public void Load()
        {
            if (!StringUtility.IsNullOrEmpty(_filePath))
            {
                try
                {
                    if (File.Exists(_filePath))
                    {
                        Logger.WriteInfo(this, "Binding file is enabled using " + _filePath);
                        using (var fileStream = new FileStream(_filePath, FileMode.Open))
                        {
                            byte[] data = new byte[10000];
                            int readCount = fileStream.Read(data, 0, data.Length);

                            FileStore deserializedData = (FileStore)Reflection.Deserialize((data), typeof(FileStore));

                            if (deserializedData != null && deserializedData.Count > 0)
                            {
                                lock (this._bindingSync)
                                {
                                    foreach (FileStore endPoint in deserializedData)
                                    {
                                        BindingLease lease = new BindingLease(
                                            new PhysicalAddress(endPoint.Owner),
                                            new InternetAddress(endPoint.Address));

                                        lease.ClientId = endPoint.ClientId;
                                        lease.Expiration = endPoint.Expiration;
                                        lease.State = endPoint.State;
                                        lease.SessionId = endPoint.SessionId;
                                        lease.HostName = endPoint.HostName;

                                        if (!_assignedTable.Contains(lease.Address))
                                        {
                                            _assignedTable.Add(lease.Address, lease);
                                            Logger.WriteDebug("Binding Loaded | " + lease.ToString());
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        Logger.WriteDebug(this, "Bindings file is disabled. Failed to accesss file " + _filePath);
                    }
                }
                catch (Exception ex)
                {
                    Logger.WriteError(this, "Error Message:" + ex.Message.ToString(), ex);
                }
            }
            else
            {
                Logger.WriteInfo(this, "Binding file is disabled");
            }
        }
        public BindingLease GetOffer(BindingLease binding)
        {
            // offer reservations binding
            if (_reservationTable.Contains(binding.Owner))
            {
                InternetAddress ipAddress = (InternetAddress)_reservationTable[binding.Owner];
                BindingLease lease = (BindingLease)_reservationTable[ipAddress];

                if (lease.Owner.Equals(binding.Owner)
                    && lease.State.Equals(LeaseState.Static))
                {
                    binding.Address = lease.Address;
                    binding.Expiration = DateTime.MaxValue;
                    binding.State = LeaseState.Static;
                    return this.SaveBinding(binding);
                }
            }

            // offer discovery request with existing ip binding
            if (!binding.Address.Equals(InternetAddress.Any))
            {
                // check for active address
                if (_assignedTable.Contains(binding.ClientId))
                {
                    BindingLease lease = (BindingLease)_assignedTable[binding.ClientId];

                    if (lease.State.Equals(LeaseState.Released) || lease.State.Equals(LeaseState.Offered))
                    {
                        binding.Address = lease.Address;
                        binding.Expiration = DateTime.Now.AddSeconds(_offerTimeout);
                        binding.State = LeaseState.Offered;

                        return this.SaveBinding(binding);
                    }
                    else
                    {
                        this.RemoveBinding(binding);
                    }
                }
                // check for unassigned address
                else if (_unassignedTable.Contains(binding.Address))
                {
                    binding.Expiration = DateTime.Now.AddSeconds(_offerTimeout);
                    binding.State = LeaseState.Offered;

                    return this.CreateBinding(binding, binding.Address);
                }
            }

            // offer next open binding address for invalid or no request
            foreach (BindingLease lease in _unassignedTable.Values)
            {
                binding.Address = lease.Address;
                binding.Expiration = DateTime.Now.AddSeconds(_offerTimeout);
                binding.State = LeaseState.Offered;

                return this.CreateBinding(binding, lease.Address);
            }

            return null;
        }
        public BindingLease GetAssigned(BindingLease binding)
        {
            // assign reservations binding
            if (_reservationTable.Contains(binding.Owner))
            {
                InternetAddress ipAddress = (InternetAddress)_reservationTable[binding.Owner];

                BindingLease lease = (BindingLease)_reservationTable[ipAddress];

                if (lease.Address.Equals(binding.Address)
                    && lease.Owner.Equals(binding.Owner)
                    && lease.State.Equals(LeaseState.Static))
                {
                    binding.Expiration = DateTime.MaxValue;
                    binding.State = LeaseState.Static;

                    return this.SaveBinding(binding);
                }
            }

            // assign binding
            if (_assignedTable.Contains(binding.ClientId))
            {
                BindingLease lease = (BindingLease)_assignedTable[binding.ClientId];

                if (lease.Owner.Equals(binding.Owner))
                {
                    binding.Expiration = DateTime.Now.AddSeconds(_leaseDuration);
                    binding.State = LeaseState.Assigned;

                    return this.SaveBinding(binding);
                }
            }

            return null;
        }
Beispiel #22
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="DhcpLeaseEventArgs"/> class.
 /// </summary>
 /// <param name="address">The IP addres of remote client.</param>
 /// <param name="lease">The binding lease of the remote client.</param>
 public DhcpLeaseEventArgs(InternetAddress address, BindingLease lease)
 {
     this.Address = address.ToString();
     this.Lease   = lease;
 }
        public BindingLease GetOffer(BindingLease binding)
        {
            // offer reservations binding
            if (_reservationTable.Contains(binding.Owner))
            {
                InternetAddress ipAddress = (InternetAddress)_reservationTable[binding.Owner];
                BindingLease    lease     = (BindingLease)_reservationTable[ipAddress];

                if (lease.Owner.Equals(binding.Owner) &&
                    lease.State.Equals(LeaseState.Static))
                {
                    binding.Address    = lease.Address;
                    binding.Expiration = DateTime.MaxValue;
                    binding.State      = LeaseState.Static;
                    return(this.SaveBinding(binding));
                }
            }

            // offer discovery request with existing ip binding
            if (!binding.Address.Equals(InternetAddress.Any))
            {
                // check for active address
                if (_assignedTable.Contains(binding.ClientId))
                {
                    BindingLease lease = (BindingLease)_assignedTable[binding.ClientId];

                    if (lease.State.Equals(LeaseState.Released) || lease.State.Equals(LeaseState.Offered))
                    {
                        binding.Address    = lease.Address;
                        binding.Expiration = DateTime.Now.AddSeconds(_offerTimeout);
                        binding.State      = LeaseState.Offered;

                        return(this.SaveBinding(binding));
                    }
                    else
                    {
                        this.RemoveBinding(binding);
                    }
                }
                // check for unassigned address
                else if (_unassignedTable.Contains(binding.Address))
                {
                    binding.Expiration = DateTime.Now.AddSeconds(_offerTimeout);
                    binding.State      = LeaseState.Offered;

                    return(this.CreateBinding(binding, binding.Address));
                }
            }

            // offer next open binding address for invalid or no request
            foreach (BindingLease lease in _unassignedTable.Values)
            {
                binding.Address    = lease.Address;
                binding.Expiration = DateTime.Now.AddSeconds(_offerTimeout);
                binding.State      = LeaseState.Offered;

                return(this.CreateBinding(binding, lease.Address));
            }

            return(null);
        }
Beispiel #24
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="DhcpMessageEventArgs"/> class.
        /// </summary>
        /// <param name="channel">Socket channel request is recived on.</param>
        /// <param name="data">Raw data received from socket.</param>
        public DhcpMessageEventArgs(SocketChannel channel, SocketBuffer data)
        {
            if (channel == null)
            {
                throw new ArgumentNullException("channel");
            }
            this.Channel = channel;

            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            this.ChannelBuffer = data;

            try
            {
                // Parse the dhcp message
                this.RequestMessage = new DhcpMessage(data.Buffer);

                // get message options
                MessageOptions options = new MessageOptions();

                options.MessageType = this.RequestMessage.GetOptionData(DhcpOption.DhcpMessageType);
                // get message type option
                options.ClientId = this.RequestMessage.GetOptionData(DhcpOption.ClientId);
                if (options.ClientId == null)
                {
                    // if the client id is not provided use the client hardware address from the message
                    options.ClientId = this.RequestMessage.ClientHardwareAddress.ToArray();
                }
                // get host name option
                options.HostName = this.RequestMessage.GetOptionData(DhcpOption.Hostname);
                // get address request option
                options.AddressRequest = this.RequestMessage.GetOptionData(DhcpOption.AddressRequest);
                //get server identifier option
                options.ServerIdentifier = this.RequestMessage.GetOptionData(DhcpOption.ServerIdentifier);
                // get paramerter list opiton
                options.ParameterList = this.RequestMessage.GetOptionData(DhcpOption.ParameterList);

                // set the response options object
                this.RequestOptions = options;

                // set the response binding object
                ResponseBinding = new BindingLease(
                    ByteUtility.GetString(this.RequestOptions.ClientId),
                    this.RequestMessage.ClientHardwareAddress,
                    this.RequestMessage.ClientAddress,
                    this.RequestOptions.HostName,
                    DateTime.MinValue,
                    this.RequestMessage.SessionId,
                    LeaseState.Unassigned);

                // log that the packet was successfully parsed
                Logger.WriteDebug(this, "PACKET with message id " +
                                  this.RequestMessage.SessionId.ToHexString("0x") + " successfully parsed from client endpoint " +
                                  this.Channel.RemoteEndpoint.ToString());

                Logger.WriteDebug(this.RequestMessage.ToString());
            }
            catch (Exception ex)
            {
                Logger.WriteError(this, "Error parsing message:" + ex.Message.ToString(), ex);
                return;
            }
        }
Beispiel #25
0
        /// <summary>
        ///  Send OFFER message back to remote client.
        /// </summary>
        private void SendOffer(DhcpMessageEventArgs args, BindingLease offer)
        {
            // set header
            args.ResponseMessage.AssignedAddress = offer.Address;
            args.ResponseMessage.NextServerAddress = args.ResponseMessage.NextServerAddress;
            args.ResponseMessage.AddOption(DhcpOption.DhcpMessageType, (Byte)MessageType.Offer);

            this.SetLeaseOptions(args);
            this.SetClientOptions(args);

            byte[] paramList = args.RequestOptions.ParameterList;
            if (paramList != null)
            {
                args.ResponseMessage.OptionOrdering = paramList;
            }

            Logger.WriteInfo(this, "OFFER for message id " + args.RequestMessage.SessionId.ToHexString("0x") + " sent on thread(#" + Thread.CurrentThread.ManagedThreadId + ")");
            this.SendReply(args);
        }
        private void RemoveBinding(BindingLease binding)
        {
            if (this._assignedTable.Contains(binding.ClientId))
            {
                lock (_bindingSync)
                {
                    _assignedTable.Remove(binding.ClientId);

                    binding.ClientId = RANDOM.Next(int.MaxValue).ToString();
                    binding.SessionId = 0;
                    binding.HostName = new byte[0];
                    binding.Owner = new PhysicalAddress(0, 0, 0, 0, 0, 0);
                    binding.State = LeaseState.Unassigned;
                    binding.Expiration = DateTime.MaxValue;
                    if (!_unassignedTable.Contains(binding.Address))
                    {
                        _unassignedTable.Add(binding.Address, binding);
                    }
                }
                //this.Save();
            }
        }
Beispiel #27
0
        /// <summary>
        ///  Send ACK message back to remote client.
        /// </summary>
        private void SendAck(DhcpMessageEventArgs args, BindingLease lease)
        {
            // set header
            args.ResponseMessage.AssignedAddress = lease.Address;

            // set lease options
            this.SetLeaseOptions(args);

            this.SendAck(args);
        }
 private BindingLease SaveBinding(BindingLease binding)
 {
     if (this._assignedTable.Contains(binding.ClientId))
     {
         lock (_bindingSync)
         {
             _assignedTable[binding.ClientId] = binding;
         }
         this.Save();
         return (BindingLease)_assignedTable[binding.ClientId];
     }
     return null;
 }
        /// <summary>
        ///  Process REQUEST message type.
        /// </summary>
        private void DhcpRequest(DhcpMessageEventArgs args)
        {
            RequestState requestState;

            #region Pre-Processing
            //  Start pre-process validation
            //---------------------------------------------------------------------
            //|              |INIT-REBOOT  |SELECTING    |RENEWING     |REBINDING |
            //---------------------------------------------------------------------
            //|broad/unicast |broadcast    |broadcast    |unicast      |broadcast |
            //|server-ip     |MUST NOT     |MUST         |MUST NOT     |MUST NOT  |
            //|requested-ip  |MUST         |MUST         |MUST NOT     |MUST NOT  |
            //|ciaddr        |zero         |zero         |IP address   |IP address|
            //---------------------------------------------------------------------
            // first determine what KIND of request we are dealing with
            if (args.RequestMessage.ClientAddress.Equals(InternetAddress.Any))
            {
                // the ciAddr MUST be 0.0.0.0 for Init-Reboot and Selecting
                if (args.RequestOptions.AddressRequest == null)
                {
                    // init-reboot MUST NOT have server-id option
                    requestState = RequestState.InitReboot;
                }
                else
                {
                    // selecting MUST have server-id option
                    requestState = RequestState.Selecting;
                }
            }
            else
            {
                // the ciAddr MUST NOT be 0.0.0.0 for Renew and Rebind
                if (!args.RequestMessage.IsBroadcast)
                {
                    // renew is unicast
                    // NOTE: this will not happen if the v4 broadcast interface used at startup,
                    //		 but handling of DHCPv4 renew/rebind is the same anyway
                    requestState = RequestState.Renewing;
                }
                else
                {
                    // rebind is broadcast
                    requestState = RequestState.Rebinding;
                }
            }

            if ((requestState == RequestState.InitReboot) || (requestState == RequestState.Selecting))
            {
                if (args.RequestOptions.AddressRequest == null)
                {
                    Logger.WriteDebug(this, "Ignoring REQUEST " + RequestStateString.GetName(requestState) + " message: Requested IP option is null");
                    return; // if processing should not continue
                }

                if (requestState == RequestState.Selecting)
                {
                    // if the client provided a ServerID option, then it MUST
                    // match our configured ServerID, otherwise ignore the request
                    InternetAddress serverIdentifier = new InternetAddress(args.RequestOptions.ServerIdentifier);
                    //InternetAddress localServerIdentifier = new InternetAddress(((IPEndPoint)_dhcpSocket.LocalEndPoint).Address.GetAddressBytes());
                    InternetAddress localServerIdentifier = new InternetAddress(this.InterfaceAddress);
                    if (!serverIdentifier.Equals(localServerIdentifier))
                    {
                        Logger.WriteDebug(this, "Ignoring REQUEST " + RequestStateString.GetName(requestState) + " message: "
                                          + "Requested ServerId: " + serverIdentifier.ToString()
                                          + " Local ServerId: " + localServerIdentifier.ToString());
                        return; // if processing should not continue
                    }
                }
            }
            else
            {   // type == Renewing or Rebinding
                if (args.RequestOptions.AddressRequest != null)
                {
                    Logger.WriteDebug(this, "Ignoring REQUEST " + RequestStateString.GetName(requestState) + " message: "
                                      + "Requested IP option is not null");
                    return; // if processing should not continue
                }
            }

            //  End pre-process validation
            #endregion Pre-Processing

            Logger.WriteDebug(this, "Processing REQUEST " + RequestStateString.GetName(requestState) + " message");

            //TODO:  should also check for ip on link

            if (args.RequestOptions.AddressRequest != null)
            {
                args.ResponseBinding.Address = new InternetAddress(args.RequestOptions.AddressRequest);
            }

            BindingLease assignment = _bindmgr.GetAssigned(args.ResponseBinding);
            if (assignment == null)
            {
                args.ResponseMessage.AddOption(DhcpOption.DhcpMessage, Encoding.UTF8.GetBytes("No binding available for client"));
                Logger.WriteDebug(this, "REQUEST " + RequestStateString.GetName(requestState) + " message: No binding available for client sending NAK");
                this.SendNak(args);
            }
            else
            {
                this.SendAck(args, assignment);
                this.OnLeaseAcknowledged(this, new DhcpLeaseEventArgs(assignment.Address, assignment));
            }
        }