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