What is DHCP?
The dynamic host configuration protocol is one of two main ways a host can assign an IP address to itself when it is present in a local area network (the other being statically). DHCP follows a state machine model to obtain, maintain, and update the IP address over time. The server leases the address to the host for a certain amount of time determined by the server and the state machine handles the lease expiry and other eventualities such as a drop in the link or if the server becomes inaccessible.
When the DHCP process begins (typically after the host boots), the client sends out a series of
DHCPDISCOVER messages to the broadcast address (255.255.255.255) prompting a server to provide it with configuration parameters. The server is expected to supply the client with as much of the requested information as it can provide and does this by populating a
DHCPOFFER message with the information and sending it to the client. If the client chooses to accept these parameters, it sends the server a
DHCPREQUEST and after the server acknowledges it the IP address is considered to be bound to the host.
Figure 1: DHCP state machine. Only the
BOUND states are relevant to this blog.
How Can µC/OS Modules Be Reconfigured?
Internally, µC/DHCPc prompts the server for a predetermined set of request parameters (
DHCP_OPT_PARAMETER_REQUEST_LIST) that include the subnet mask, the server identifier (router), the domain nme server, and the time zone offset. These, and other request parameters can be solicited and later used to re-configure other uC modules such as µC/DNSc, µC/TFTPc, µC/SNTPc, µC/SNMPc, and µC/Clk at run time in case there are changes in the local area network. This can be achieved by way of invoking the
DHCPc_Start(), and the
DHCPc_GetOptVal() API functions as shown in Figure 3. Please note that the number of parameters to be requested cannot exceed the value configured by the
DHCPc_CFG_PARAM_REQ_TBL_SIZE macro. Also, in order for this to work at runtime, the instantiated configuration structures for each module should not be declared with the
From the Application’s Perspective
A µC/TCP-IP-based application can synchronously or asynchronously update these parameters. For instance, there can be a task that is dedicated to stop and start the DHCP process directly or alternatively after the TCP/IP stack is initialized the application may use
NetIF_LinkStateSubscribe() to monitor link state changes via a callback function that posts to a task pending on a global semaphore object. The former scenario is demonstrated in Figure 3 where a task (
AppTask_DHCP_Update()) running every 24 hours requests some parameters and reconfigures the DNS and NTP server information. Note that
req_param are not fed to
DHCPc_GetOptVal() and are only there for illustrative purposes. It is also important to mention that as previously stated, the server might not know a subset of the requested parameters and thus when the client is bound and
DHCPc_GetOptVal() is called requesting said parameter, the API returns a
DHCPc_ERR_IF_OPT_NONE error and the old value is kept in the module’s configuration structure.
Figure 2: Wireshark capture showing new parameters requested by second
DHCPDISCOVER message when DHCPc is restarted.
Figure 3: Sample application task that restarts DHCP process with new request parameters.