예제 #1
0
 public BindingLease(string clientId, PhysicalAddress owner, InternetAddress address, byte[] hostName, DateTime expiration, UInt32 sessionId, LeaseState state)
 {
     this._clientId = clientId;
     this._owner = owner;
     this._address = address;
     this._hostName = hostName;
     this._expiration = expiration;
     this._sessionId = sessionId;
     this._state = state;
 }
예제 #2
0
        internal InternetAddress NextAddress()
        {
            InternetAddress next = this.Copy();

            if (this._address[3] == 255)
            {
                next._address[3] = 0;

                if (this._address[2] == 255)
                {
                    next._address[2] = 0;

                    if (this._address[1] == 255)
                    {
                        next._address[1] = 0;

                        if (this._address[0] == 255)
                        {
                            throw new InvalidOperationException();
                        }
                        else
                        {
                            next._address[0] = (Byte)(this._address[0] + 1);
                        }
                    }
                    else
                    {
                        next._address[1] = (Byte)(this._address[1] + 1);
                    }
                }
                else
                {
                    next._address[2] = (Byte)(this._address[2] + 1);
                }
            }
            else
            {
                next._address[3] = (Byte)(this._address[3] + 1);
            }

            return(next);
        }
예제 #3
0
        public int CompareTo(Object obj)
        {
            InternetAddress other = obj as InternetAddress;

            if (other == null)
            {
                return(1);
            }

            for (int i = 0; i < 4; i++)
            {
                if (this._address[i] > other._address[i])
                {
                    return(1);
                }
                else if (this._address[i] < other._address[i])
                {
                    return(-1);
                }
            }

            return(0);
        }
예제 #4
0
        /// <summary>
        ///  Process INFORM message type.
        /// </summary>
        private void DhcpInform(DhcpMessageEventArgs args)
        {
            #region Pre-Processing
            //  Start pre-process validation

            // 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 INFORM message: "
                                  + "Requested ServerId: " + serverIdentifier.ToString()
                                  + " Local ServerId: " + localServerIdentifier.ToString());
                return; // if processing should not continue
            }

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

            this.SendAck(args);
        }
예제 #5
0
        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);
        }
예제 #6
0
 public bool Contains(InternetAddress item)
 {
     return(this._arrayList.Contains(item));
 }
예제 #7
0
 public int Add(InternetAddress item)
 {
     return(this._arrayList.Add(item));
 }
예제 #8
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 void Add(String IpAddress, String macAddress)
 {
     this._hashTable.Add(PhysicalAddress.Parse(macAddress), InternetAddress.Parse(IpAddress));
 }
예제 #10
0
 /// <summary>
 /// This defines the pool of ip address the client may use.
 /// </summary>
 public void PoolRange(string startAddress, string endAddress)
 {
     if (!StringUtility.IsNullOrEmpty(startAddress) && !StringUtility.IsNullOrEmpty(endAddress))
     {
         _startAddress = new InternetAddress(startAddress);
         _endAddress = new InternetAddress(endAddress);
         _bindmgr.PoolRange(_startAddress, _endAddress);
     }
 }
예제 #11
0
        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));

                }
            }
        }
예제 #12
0
        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);
        }
예제 #13
0
        /// <summary>
        ///  Send response message back to remote client.
        /// </summary>
        private void SendReply(DhcpMessageEventArgs args)
        {
            // set global headers
            args.ResponseMessage.Operation             = OperationCode.BootReply;
            args.ResponseMessage.Hardware              = args.RequestMessage.Hardware;
            args.ResponseMessage.HardwareAddressLength = args.RequestMessage.HardwareAddressLength;
            args.ResponseMessage.SessionId             = args.RequestMessage.SessionId;
            args.ResponseMessage.Flags                 = args.RequestMessage.Flags;
            args.ResponseMessage.RelayAgentAddress     = args.RequestMessage.RelayAgentAddress;
            args.ResponseMessage.ClientHardwareAddress = args.RequestMessage.ClientHardwareAddress;

            if (!StringUtility.IsNullOrEmpty(this._serverName))
            {
                args.ResponseMessage.ServerName = Encoding.UTF8.GetBytes(this._serverName);
            }

            if (!StringUtility.IsNullOrEmpty(this._bootFileName))
            {
                args.ResponseMessage.BootFileName = Encoding.UTF8.GetBytes(this._bootFileName);
            }

            // set global options
            //args.ResponseMessage.AddOption(DhcpOption.ServerIdentifier, ((IPEndPoint)_dhcpSocket.LocalEndPoint).Address.GetAddressBytes());
            args.ResponseMessage.AddOption(DhcpOption.ServerIdentifier, (this.InterfaceAddress.GetAddressBytes()));

            // determin the proper ip address and port for sendto
            InternetAddress relayAgentAddress = args.RequestMessage.RelayAgentAddress;
            InternetAddress clientAddress     = args.RequestMessage.ClientAddress;

            if (!relayAgentAddress.Equals(InternetAddress.Any))
            {
                args.Channel.RemoteEndpoint = new IPEndPoint(relayAgentAddress.ToIPAddress(), Constants.DHCP_SERVICE_PORT);
            }
            else
            {
                if (!clientAddress.Equals(InternetAddress.Any))
                {
                    args.Channel.RemoteEndpoint = new IPEndPoint(clientAddress.ToIPAddress(), Constants.DHCP_CLIENT_PORT);
                }
                else
                {
                    args.Channel.RemoteEndpoint = new IPEndPoint(InternetAddress.Broadcast.ToIPAddress(), Constants.DHCP_CLIENT_PORT);
                }
            }

            try
            {
                args.Channel.SendTo(args.ResponseMessage.ToArray(), args.Channel.RemoteEndpoint);
                Logger.WriteDebug(this, "PACKET with message id " +
                                  args.ResponseMessage.SessionId.ToHexString("0x") + " successfully sent to client endpoint " +
                                  args.Channel.RemoteEndpoint.ToString());

                Logger.WriteDebug(args.ResponseMessage.ToString());

                OnDhcpMessageSent(this, args);
            }
            catch (SocketException ex)
            {
                Logger.WriteError(this, ex.Message + "Socket Error Code: " + ex.ErrorCode.ToString(), ex);
            }
            catch (Exception ex)
            {
                Logger.WriteError(this, "Error Message:" + ex.Message.ToString(), ex);
            }
        }
예제 #14
0
        /// <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));
            }
        }
예제 #15
0
 /// <summary>
 /// This defines a static ip address reservation the client may use.
 /// </summary>
 public void PoolReservation(string address, string macAddress)
 {
     _bindmgr.Reservation(InternetAddress.Parse(address), PhysicalAddress.Parse(macAddress));
 }
예제 #16
0
        /// <summary>
        ///  Process INFORM message type.
        /// </summary>
        private void DhcpInform(DhcpMessageEventArgs args)
        {
            #region Pre-Processing
            //  Start pre-process validation

            // 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 INFORM message: "
                    + "Requested ServerId: " + serverIdentifier.ToString()
                    + " Local ServerId: " + localServerIdentifier.ToString());
                return; // if processing should not continue
            }

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

            this.SendAck(args);
        }
예제 #17
0
        /// <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));
            }
        }
예제 #18
0
 public void Remove(InternetAddress item)
 {
     this._arrayList.Remove(item);
 }
예제 #19
0
 public BindingLease(PhysicalAddress owner, InternetAddress address)
     : this(RANDOM.Next(int.MaxValue).ToString(), owner, address, new byte[0], DateTime.Now.AddDays(7), 0, LeaseState.Unassigned)
 {
 }
예제 #20
0
 public BindingLease(PhysicalAddress owner, InternetAddress address)
     : this(RANDOM.Next(int.MaxValue).ToString(), owner, address, new byte[0], DateTime.Now.AddDays(7), 0, LeaseState.Unassigned)
 {
 }
예제 #21
0
 public void PoolRange(InternetAddress startAddress, InternetAddress endAddress)
 {
     lock (_bindingSync)
     {
         for (InternetAddress address = startAddress.Copy(); address.CompareTo(endAddress) <= 0; address = address.NextAddress())
         {
             if (!_unassignedTable.Contains(address))
             {
                 _unassignedTable.Add(address, new BindingLease(RANDOM.Next(int.MaxValue).ToString(), new PhysicalAddress(), address, new byte[0], DateTime.MaxValue, 0, LeaseState.Unassigned));
             }
         }
     }
 }
 public void Add(InternetAddress ipAddress, PhysicalAddress macAddress)
 {
     this._hashTable[ipAddress] = macAddress;
 }
예제 #23
0
        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;
        }
예제 #24
0
 public bool Contains(InternetAddress item)
 {
     return this._arrayList.Contains(item);
 }
예제 #25
0
 public int Add(InternetAddress item)
 {
     return this._arrayList.Add(item);
 }
예제 #26
0
 public bool Equals(InternetAddress other)
 {
     return _address == null ||
         _address[0] == other._address[0] &&
         _address[1] == other._address[1] &&
         _address[2] == other._address[2] &&
         _address[3] == other._address[3];
 }
예제 #27
0
 public void Remove(InternetAddress item)
 {
     this._arrayList.Remove(item);
 }
 public void Add(InternetAddress ipAddress, PhysicalAddress macAddress)
 {
     this._hashTable[ipAddress] = macAddress;
 }