1 /** @file
2 * @brief DHCPv4 Client Handler
3 */
4
5 /*
6 * Copyright (c) 2016 Intel Corporation
7 *
8 * SPDX-License-Identifier: Apache-2.0
9 */
10
11 #ifndef ZEPHYR_INCLUDE_NET_DHCPV4_H_
12 #define ZEPHYR_INCLUDE_NET_DHCPV4_H_
13
14 #include <zephyr/sys/slist.h>
15 #include <zephyr/types.h>
16
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20
21 /**
22 * @brief DHCPv4
23 * @defgroup dhcpv4 DHCPv4
24 * @since 1.7
25 * @version 0.8.0
26 * @ingroup networking
27 * @{
28 */
29
30 /** @cond INTERNAL_HIDDEN */
31
32 /** Current state of DHCPv4 client address negotiation.
33 *
34 * Additions removals and reorders in this definition must be
35 * reflected within corresponding changes to net_dhcpv4_state_name.
36 */
37 enum net_dhcpv4_state {
38 NET_DHCPV4_DISABLED,
39 NET_DHCPV4_INIT,
40 NET_DHCPV4_SELECTING,
41 NET_DHCPV4_REQUESTING,
42 NET_DHCPV4_RENEWING,
43 NET_DHCPV4_REBINDING,
44 NET_DHCPV4_BOUND,
45 NET_DHCPV4_DECLINE,
46 } __packed;
47
48 /** @endcond */
49
50 /**
51 * @brief DHCPv4 message types
52 *
53 * These enumerations represent RFC2131 defined msy type codes, hence
54 * they should not be renumbered.
55 *
56 * Additions, removald and reorders in this definition must be reflected
57 * within corresponding changes to net_dhcpv4_msg_type_name.
58 */
59 enum net_dhcpv4_msg_type {
60 NET_DHCPV4_MSG_TYPE_DISCOVER = 1, /**< Discover message */
61 NET_DHCPV4_MSG_TYPE_OFFER = 2, /**< Offer message */
62 NET_DHCPV4_MSG_TYPE_REQUEST = 3, /**< Request message */
63 NET_DHCPV4_MSG_TYPE_DECLINE = 4, /**< Decline message */
64 NET_DHCPV4_MSG_TYPE_ACK = 5, /**< Acknowledge message */
65 NET_DHCPV4_MSG_TYPE_NAK = 6, /**< Negative acknowledge message */
66 NET_DHCPV4_MSG_TYPE_RELEASE = 7, /**< Release message */
67 NET_DHCPV4_MSG_TYPE_INFORM = 8, /**< Inform message */
68 };
69
70 struct net_dhcpv4_option_callback;
71
72 /**
73 * @typedef net_dhcpv4_option_callback_handler_t
74 * @brief Define the application callback handler function signature
75 *
76 * @param cb Original struct net_dhcpv4_option_callback owning this handler
77 * @param length The length of data returned by the server. If this is
78 * greater than cb->max_length, only cb->max_length bytes
79 * will be available in cb->data
80 * @param msg_type Type of DHCP message that triggered the callback
81 * @param iface The interface on which the DHCP message was received
82 *
83 * Note: cb pointer can be used to retrieve private data through
84 * CONTAINER_OF() if original struct net_dhcpv4_option_callback is stored in
85 * another private structure.
86 */
87 typedef void (*net_dhcpv4_option_callback_handler_t)(struct net_dhcpv4_option_callback *cb,
88 size_t length,
89 enum net_dhcpv4_msg_type msg_type,
90 struct net_if *iface);
91
92 /** @cond INTERNAL_HIDDEN */
93
94 /**
95 * @brief DHCP option callback structure
96 *
97 * Used to register a callback in the DHCPv4 client callback list.
98 * As many callbacks as needed can be added as long as each of them
99 * are unique pointers of struct net_dhcpv4_option_callback.
100 * Beware such structure should not be allocated on stack.
101 *
102 * Note: To help setting it, see net_dhcpv4_init_option_callback() below
103 */
104 struct net_dhcpv4_option_callback {
105 /** This is meant to be used internally and the user should not
106 * mess with it.
107 */
108 sys_snode_t node;
109
110 /** Actual callback function being called when relevant. */
111 net_dhcpv4_option_callback_handler_t handler;
112
113 /** The DHCP option this callback is attached to. */
114 uint8_t option;
115
116 /** Maximum length of data buffer. */
117 size_t max_length;
118
119 /** Pointer to a buffer of size max_length that is used to store the
120 * option data.
121 */
122 void *data;
123 };
124
125 /** @endcond */
126
127 /**
128 * @brief Helper to initialize a struct net_dhcpv4_option_callback properly
129 * @param callback A valid Application's callback structure pointer.
130 * @param handler A valid handler function pointer.
131 * @param option The DHCP option the callback responds to.
132 * @param data A pointer to a buffer for max_length bytes.
133 * @param max_length The maximum length of the data returned.
134 */
net_dhcpv4_init_option_callback(struct net_dhcpv4_option_callback * callback,net_dhcpv4_option_callback_handler_t handler,uint8_t option,void * data,size_t max_length)135 static inline void net_dhcpv4_init_option_callback(struct net_dhcpv4_option_callback *callback,
136 net_dhcpv4_option_callback_handler_t handler,
137 uint8_t option,
138 void *data,
139 size_t max_length)
140 {
141 __ASSERT(callback, "Callback pointer should not be NULL");
142 __ASSERT(handler, "Callback handler pointer should not be NULL");
143 __ASSERT(data, "Data pointer should not be NULL");
144
145 callback->handler = handler;
146 callback->option = option;
147 callback->data = data;
148 callback->max_length = max_length;
149 }
150
151 /**
152 * @brief Add an application callback.
153 * @param cb A valid application's callback structure pointer.
154 * @return 0 if successful, negative errno code on failure.
155 */
156 int net_dhcpv4_add_option_callback(struct net_dhcpv4_option_callback *cb);
157
158 /**
159 * @brief Remove an application callback.
160 * @param cb A valid application's callback structure pointer.
161 * @return 0 if successful, negative errno code on failure.
162 */
163 int net_dhcpv4_remove_option_callback(struct net_dhcpv4_option_callback *cb);
164
165 /**
166 * @brief Helper to initialize a struct net_dhcpv4_option_callback for encapsulated vendor-specific
167 * options properly
168 * @param callback A valid Application's callback structure pointer.
169 * @param handler A valid handler function pointer.
170 * @param option The DHCP encapsulated vendor-specific option the callback responds to.
171 * @param data A pointer to a buffer for max_length bytes.
172 * @param max_length The maximum length of the data returned.
173 */
174 static inline void
net_dhcpv4_init_option_vendor_callback(struct net_dhcpv4_option_callback * callback,net_dhcpv4_option_callback_handler_t handler,uint8_t option,void * data,size_t max_length)175 net_dhcpv4_init_option_vendor_callback(struct net_dhcpv4_option_callback *callback,
176 net_dhcpv4_option_callback_handler_t handler, uint8_t option,
177 void *data, size_t max_length)
178 {
179 __ASSERT(callback, "Callback pointer should not be NULL");
180 __ASSERT(handler, "Callback handler pointer should not be NULL");
181 __ASSERT(data, "Data pointer should not be NULL");
182
183 callback->handler = handler;
184 callback->option = option;
185 callback->data = data;
186 callback->max_length = max_length;
187 }
188
189 /**
190 * @brief Add an application callback for encapsulated vendor-specific options.
191 * @param cb A valid application's callback structure pointer.
192 * @return 0 if successful, negative errno code on failure.
193 */
194 int net_dhcpv4_add_option_vendor_callback(struct net_dhcpv4_option_callback *cb);
195
196 /**
197 * @brief Remove an application callback for encapsulated vendor-specific options.
198 * @param cb A valid application's callback structure pointer.
199 * @return 0 if successful, negative errno code on failure.
200 */
201 int net_dhcpv4_remove_option_vendor_callback(struct net_dhcpv4_option_callback *cb);
202
203 /**
204 * @brief Start DHCPv4 client on an iface
205 *
206 * @details Start DHCPv4 client on a given interface. DHCPv4 client
207 * will start negotiation for IPv4 address. Once the negotiation is
208 * success IPv4 address details will be added to interface.
209 *
210 * @param iface A valid pointer on an interface
211 */
212 void net_dhcpv4_start(struct net_if *iface);
213
214 /**
215 * @brief Stop DHCPv4 client on an iface
216 *
217 * @details Stop DHCPv4 client on a given interface. DHCPv4 client
218 * will remove all configuration obtained from a DHCP server from the
219 * interface and stop any further negotiation with the server.
220 *
221 * @param iface A valid pointer on an interface
222 */
223 void net_dhcpv4_stop(struct net_if *iface);
224
225 /**
226 * @brief Restart DHCPv4 client on an iface
227 *
228 * @details Restart DHCPv4 client on a given interface. DHCPv4 client
229 * will restart the state machine without any of the initial delays
230 * used in start.
231 *
232 * @param iface A valid pointer on an interface
233 */
234 void net_dhcpv4_restart(struct net_if *iface);
235
236 /** @cond INTERNAL_HIDDEN */
237
238 /**
239 * @brief DHCPv4 state name
240 *
241 * @internal
242 */
243 const char *net_dhcpv4_state_name(enum net_dhcpv4_state state);
244
245 /** @endcond */
246
247 /**
248 * @brief Return a text representation of the msg_type
249 *
250 * @param msg_type The msg_type to be converted to text
251 * @return A text representation of msg_type
252 */
253 const char *net_dhcpv4_msg_type_name(enum net_dhcpv4_msg_type msg_type);
254
255 /**
256 * @}
257 */
258
259 #ifdef __cplusplus
260 }
261 #endif
262
263 #endif /* ZEPHYR_INCLUDE_NET_DHCPV4_H_ */
264