1 /** @file
2  *  @brief DHCPv4 Server API
3  */
4 
5 /*
6  * Copyright (c) 2024 Nordic Semiconductor ASA
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #ifndef ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_
12 #define ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_
13 
14 #include <zephyr/net/net_ip.h>
15 #include <zephyr/sys_clock.h>
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 /**
22  * @brief DHCPv4 server
23  * @defgroup dhcpv4_server DHCPv4 server
24  * @since 3.6
25  * @version 0.8.0
26  * @ingroup networking
27  * @{
28  */
29 
30 /** @cond INTERNAL_HIDDEN */
31 
32 struct net_if;
33 
34 #define DHCPV4_CLIENT_ID_MAX_SIZE 20
35 
36 enum dhcpv4_server_addr_state {
37 	DHCPV4_SERVER_ADDR_FREE,
38 	DHCPV4_SERVER_ADDR_RESERVED,
39 	DHCPV4_SERVER_ADDR_ALLOCATED,
40 	DHCPV4_SERVER_ADDR_DECLINED,
41 };
42 
43 struct dhcpv4_client_id {
44 	uint8_t buf[DHCPV4_CLIENT_ID_MAX_SIZE];
45 	uint8_t len;
46 };
47 
48 struct dhcpv4_addr_slot {
49 	enum dhcpv4_server_addr_state state;
50 	struct dhcpv4_client_id client_id;
51 	struct in_addr addr;
52 	uint32_t lease_time;
53 	k_timepoint_t expiry;
54 };
55 
56 /** @endcond */
57 
58 /**
59  *  @brief Start DHCPv4 server instance on an iface
60  *
61  *  @details Start DHCPv4 server on a given interface. The server will start
62  *  listening for DHCPv4 Discover/Request messages on the interface and assign
63  *  IPv4 addresses from the configured address pool accordingly.
64  *
65  *  @param iface A valid pointer on an interface
66  *  @param base_addr First IPv4 address from the DHCPv4 address pool. The number
67  *  of addresses in the pool is configured statically with Kconfig
68  *  (CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT).
69  *
70  *  @return 0 on success, a negative error code otherwise.
71  */
72 int net_dhcpv4_server_start(struct net_if *iface, struct in_addr *base_addr);
73 
74 /**
75  *  @brief Stop DHCPv4 server instance on an iface
76  *
77  *  @details Stop DHCPv4 server on a given interface. DHCPv4 requests will no
78  *  longer be handled on the interface, and all of the allocations are cleared.
79  *
80  *  @param iface A valid pointer on an interface
81  *
82  *  @return 0 on success, a negative error code otherwise.
83  */
84 int net_dhcpv4_server_stop(struct net_if *iface);
85 
86 /**
87  * @typedef net_dhcpv4_lease_cb_t
88  * @brief Callback used while iterating over active DHCPv4 address leases
89  *
90  * @param iface Pointer to the network interface
91  * @param lease Pointer to the DHPCv4 address lease slot
92  * @param user_data A valid pointer to user data or NULL
93  */
94 typedef void (*net_dhcpv4_lease_cb_t)(struct net_if *iface,
95 				      struct dhcpv4_addr_slot *lease,
96 				      void *user_data);
97 
98 /**
99  * @brief Iterate over all DHCPv4 address leases on a given network interface
100  * and call callback for each lease. In case no network interface is provided
101  * (NULL interface pointer), will iterate over all interfaces running DHCPv4
102  * server instance.
103  *
104  * @param iface Pointer to the network interface, can be NULL
105  * @param cb User-supplied callback function to call
106  * @param user_data User specified data
107  */
108 int net_dhcpv4_server_foreach_lease(struct net_if *iface,
109 				    net_dhcpv4_lease_cb_t cb,
110 				    void *user_data);
111 
112 /**
113  * @typedef net_dhcpv4_server_provider_cb_t
114  * @brief Callback used to let application provide an address for a given
115  * client ID
116  * @details This function is called before assigning an address to a client,
117  * and lets the application override the address for a given client. If the
118  * callback returns 0, addr needs to be a valid address and will be assigned
119  * to the client. If the callback returns anything non-zero, the client will
120  * be assigned an address from the pool.
121  *
122  * @param iface Pointer to the network interface
123  * @param client_id Pointer to client requesting an address
124  * @param addr Address to be assigned to client
125  * @param user_data A valid pointer to user data or NULL
126  */
127 typedef int (*net_dhcpv4_server_provider_cb_t)(struct net_if *iface,
128 					       const struct dhcpv4_client_id *client_id,
129 					       struct in_addr *addr,
130 					       void *user_data);
131 /**
132  * @brief Set the callback used to provide addresses to the DHCP server.
133  *
134  * @param cb User-supplied callback function to call
135  * @param user_data A valid pointer to user data or NULL
136  */
137 void net_dhcpv4_server_set_provider_cb(net_dhcpv4_server_provider_cb_t cb,
138 				       void *user_data);
139 
140 /**
141  * @}
142  */
143 
144 #ifdef __cplusplus
145 }
146 #endif
147 
148 #endif /* ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_ */
149