Пример #1
0
        public IPAddress GetIPAddress(DhcpOption option)
        {
            byte[] data = this[option];

            CheckSize(data, 4);
            return(DhcpMessage.ReadIPAddress(data, 0));
        }
Пример #2
0
        public ushort GetUInt16(DhcpOption option)
        {
            byte[] data = this[option];

            CheckSize(data, 2);
            return(DhcpMessage.ReadUInt16(data, 0));
        }
Пример #3
0
        public uint GetUInt32(DhcpOption option)
        {
            byte[] data = this[option];

            CheckSize(data, 4);
            return(DhcpMessage.ReadUInt32(data, 0));
        }
Пример #4
0
        private async void SendResponse(UdpClient client, DhcpMessage message)
        {
            if (message.Options.MessageType == DhcpMessageType.Offer || message.Options.MessageType == DhcpMessageType.Acknowledge)
            {
                message.Options.SetValue(DhcpOption.SubnetMask, _subnetMask);
            }
            else if (message.Options.MessageType != DhcpMessageType.NoAcknowledge)
            {
                throw new DhcpMessageException($"Cannot send '{message.Options.MessageType}' messages from a server.", message);
            }

            message.Options.SetValue(DhcpOption.ServerIdentifier, _localEndPoint.Address);

            try {
                byte[] messageBytes   = message.GetBytes();
                var    remoteEndPoint = new IPEndPoint(message.ClientIPAddress.Equals(IPAddress.Any) ? IPAddress.Broadcast : message.ClientIPAddress, ReplyPort);

                await client.SendAsync(messageBytes, messageBytes.Length, remoteEndPoint).ConfigureAwait(false);

                OnResponseSent(message);
            }
            catch (SocketException ex) {
                OnSocketError(ex);
            }
            catch (ObjectDisposedException) { }
        }
Пример #5
0
        internal DhcpMessage CreateMessage()
        {
            //  [X] = handled here
            //  [S] = handled by DhcpServer

            //      Field      DHCPOFFER            DHCPACK              DHCPNAK
            //      -----      ---------            -------              -------

            //  [X] 'op'       BOOTREPLY            BOOTREPLY            BOOTREPLY
            //  [X] 'htype'    Copy                 Copy                 Copy
            //  [X] 'hlen'     Copy                 Copy                 Copy
            //  [ ] 'hops'     -                    -                    -
            //  [X] 'xid'      Copy                 Copy                 Copy
            //  [ ] 'secs'     -                    -                    -
            //  [ ] 'ciaddr'   -                    Copy                 -
            //  [X] 'yiaddr'   IP address offered   IP address assigned  -
            //  [ ] 'siaddr'   -                    -                    -
            //  [X] 'flags'    Copy                 Copy                 Copy
            //  [X] 'giaddr'   Copy                 Copy                 Copy
            //  [X] 'chaddr'   Copy                 Copy                 Copy
            //  [ ] 'sname'    Server name/options  Server name/options  -
            //  [ ] 'file'     Boot file/options    Boot file/options     -
            //  [ ] 'options'  options              options

            //      Option                    DHCPOFFER    DHCPACK            DHCPNAK
            //      ------                    ---------    -------            -------
            //  [ ] Requested IP address      MUST NOT     MUST NOT           MUST NOT
            //  [X] IP address lease time     MUST         MUST (DHCPREQUEST) MUST NOT
            //                                             MUST NOT (DHCPINFORM)
            //  [ ] Use 'file'/'sname' fields MAY          MAY                MUST NOT
            //  [X] DHCP message type         DHCPOFFER    DHCPACK            DHCPNAK
            //  [ ] Parameter request list    MUST NOT     MUST NOT           MUST NOT
            //  [ ] Message                   SHOULD       SHOULD             SHOULD
            //  [ ] Client identifier         MUST NOT     MUST NOT           MAY
            //  [ ] Vendor class identifier   MAY          MAY                MAY
            //  [X] Server identifier         MUST         MUST               MUST
            //  [ ] Maximum message size      MUST NOT     MUST NOT           MUST NOT
            //  [S] Subnet mask               MAY          MAY                MUST NOT
            //  [ ] All others                MAY          MAY                MUST NOT

            var response = new DhcpMessage(DhcpOpcode.BootReply, DhcpMessageType.Offer)
            {
                HardwareAddressType   = SourceMessage.HardwareAddressType,
                HardwareAddressLength = SourceMessage.HardwareAddressLength,
                TransactionID         = SourceMessage.TransactionID,
                YourClientIPAddress   = OfferedIPAddress,
                Flags = SourceMessage.Flags,
                RelayAgentIPAddress = SourceMessage.RelayAgentIPAddress,
                ClientMacAddress    = SourceMessage.ClientMacAddress,
            };

            response.Options.SetValue(DhcpOption.IPAddressLeaseTime, LeaseSeconds);

            return(response);
        }
Пример #6
0
        private DhcpDiscoverResult(DhcpMessage sourceMessage, IPAddress offeredIPAddress, uint leaseSeconds)
        {
            if (sourceMessage.Options.MessageType != DhcpMessageType.Discover)
            {
                throw new ArgumentException("Source message must be a Discover type.", nameof(sourceMessage));
            }

            SourceMessage    = sourceMessage;
            OfferedIPAddress = offeredIPAddress;
            LeaseSeconds     = leaseSeconds;
        }
        private DhcpRequestResult(DhcpMessage sourceMessage, string errorMessage)
        {
            if (sourceMessage.Options.MessageType != DhcpMessageType.Request)
            {
                throw new ArgumentException("Source message must be a Request type.", nameof(sourceMessage));
            }

            SourceMessage = sourceMessage;
            MessageType   = DhcpMessageType.NoAcknowledge;

            ErrorMessage = errorMessage;
        }
        private DhcpRequestResult(DhcpMessage sourceMessage, IPAddress assignedIPAddress, uint leaseSeconds)
        {
            if (sourceMessage.Options.MessageType != DhcpMessageType.Request)
            {
                throw new ArgumentException("Source message must be a Request type.", nameof(sourceMessage));
            }

            SourceMessage = sourceMessage;
            MessageType   = DhcpMessageType.Acknowledge;

            AssignedIPAddress = assignedIPAddress;
            LeaseSeconds      = leaseSeconds;
        }
Пример #9
0
 /// <summary>
 /// This method is called when a request message is recieved.
 /// </summary>
 /// <param name="message">The request message recived.</param>
 /// <returns>The acknowledge or no-acknowledge message to respond with, otherwise null for no response.</returns>
 protected abstract DhcpRequestResult?OnRequestReceived(DhcpMessage message);
Пример #10
0
 /// <summary>
 /// Creates an offer based on a source request message.
 /// </summary>
 public static DhcpDiscoverResult CreateOffer(DhcpMessage sourceMessage, IPAddress offeredIPAddress, uint leaseSeconds)
 {
     return(new DhcpDiscoverResult(sourceMessage, offeredIPAddress, leaseSeconds));
 }
Пример #11
0
        private async void RunReceiveLoopAsync(UdpClient udpClient)
        {
            while (true)
            {
                UdpReceiveResult result;

                try {
                    result = await udpClient.ReceiveAsync().ConfigureAwait(false);
                }
                catch (SocketException ex) {
                    Stop();
                    OnSocketError(ex);

                    return;
                }
                catch (ObjectDisposedException) {
                    return;
                }

                DhcpMessage message;

                try {
                    message = new DhcpMessage(result.Buffer);
                }
                catch (InvalidDataException ex) {
                    OnMessageError(ex);
                    continue;
                }

                if (!message.RelayAgentIPAddress.Equals(IPAddress.Any))
                {
                    OnMessageError(new DhcpMessageException("Relayed DHCP messages are not supported.", message));
                    continue;
                }

                if (message.OpCode != DhcpOpcode.BootRequest)
                {
                    OnMessageError(new DhcpMessageException("Invalid op code.", message));
                    continue;
                }

                switch (message.Options.MessageType)
                {
                case DhcpMessageType.Discover:
                    var discoverResult = OnDiscoverReceived(message);

                    if (discoverResult != null)
                    {
                        SendResponse(udpClient, discoverResult.CreateMessage());
                    }

                    break;

                case DhcpMessageType.Request:
                    if (message.Options.ServerIdentifier?.Equals(_localEndPoint.Address) == false)
                    {
                        continue;
                    }

                    var requestResult = OnRequestReceived(message);

                    if (requestResult != null)
                    {
                        SendResponse(udpClient, requestResult.CreateMessage());
                    }

                    break;

                case DhcpMessageType.Release:
                    OnReleaseReceived(message);
                    break;

                case DhcpMessageType.Decline:
                    OnDeclineReceived(message);
                    break;

                default:
                    OnMessageError(new DhcpMessageException("Invalid DhcpMessageType received.", message));
                    break;
                }
            }
        }
Пример #12
0
 /// <summary>
 /// This method is called anytime a response has been successfully sent.
 /// </summary>
 /// <param name="message">The response sent.</param>
 protected abstract void OnResponseSent(DhcpMessage message);
Пример #13
0
 /// <summary>
 /// This method is called when an inform message is received.
 /// </summary>
 /// <param name="message">The inform message received.</param>
 protected abstract void OnInformReceived(DhcpMessage message);
Пример #14
0
 /// <summary>
 /// This method is called when a release message is received.
 /// </summary>
 /// <param name="message">The release message received.</param>
 protected abstract void OnReleaseReceived(DhcpMessage message);
Пример #15
0
 /// <summary>
 /// This method is called when a decline message is received.
 /// </summary>
 /// <param name="message">The decline message received.</param>
 protected abstract void OnDeclineReceived(DhcpMessage message);
 public static DhcpRequestResult CreateAcknowledgement(DhcpMessage sourceMessage, IPAddress assignedIPAddress, uint leaseSeconds)
 {
     return(new DhcpRequestResult(sourceMessage, assignedIPAddress, leaseSeconds));
 }
 public static DhcpRequestResult CreateNoAcknowledgement(DhcpMessage sourceMessage, string errorMessage)
 {
     return(new DhcpRequestResult(sourceMessage, errorMessage));
 }
Пример #18
0
 /// <summary>
 /// This method is called when a discover message is received.
 /// </summary>
 /// <param name="message">The discover message received.</param>
 /// <returns>An offer message to respond with, otherwise null for no response.</returns>
 protected abstract DhcpDiscoverResult?OnDiscoverReceived(DhcpMessage message);