6 * Dynamic Host Configuration Protocol
11 #include <gpxe/list.h>
21 * This must be either @c BOOTP_REQUEST or @c BOOTP_REPLY.
24 /** Hardware address type
26 * This is an ARPHRD_XXX constant.
29 /** Hardware address length */
31 /** Number of hops from server */
35 /** Seconds since start of acquisition */
39 /** "Client" IP address
41 * This is filled in if the client already has an IP address
42 * assigned and can respond to ARP requests.
44 struct in_addr ciaddr;
47 * This is the IP address assigned by the server to the client.
49 struct in_addr yiaddr;
50 /** "Server" IP address
52 * This is the IP address of the next server to be used in the
55 struct in_addr siaddr;
56 /** "Gateway" IP address
58 * This is the IP address of the DHCP relay agent, if any.
60 struct in_addr giaddr;
61 /** Client hardware address */
63 /** Server host name (null terminated)
65 * This field may be overridden and contain DHCP options
68 /** Boot file name (null terminated)
70 * This field may be overridden and contain DHCP options
75 * Must have the value @c DHCP_MAGIC_COOKIE.
80 * Variable length; extends to the end of the packet.
85 /** Opcode for a request from client to server */
86 #define BOOTP_REQUEST 1
88 /** Opcode for a reply from server to client */
91 /** DHCP magic cookie */
92 #define DHCP_MAGIC_COOKIE 0x63825363UL
94 /** Construct a tag value for an encapsulated option
96 * This tag value can be passed to Etherboot functions when searching
97 * for DHCP options in order to search for a tag within an
98 * encapsulated options block.
100 #define DHCP_ENCAP_OPT( encapsulator, encapsulated ) \
101 ( ( (encapsulator) << 8 ) | (encapsulated) )
102 /** Extract encapsulating option block tag from encapsulated tag value */
103 #define DHCP_ENCAPSULATOR( encap_opt ) ( (encap_opt) >> 8 )
104 /** Extract encapsulated option tag from encapsulated tag value */
105 #define DHCP_ENCAPSULATED( encap_opt ) ( (encap_opt) & 0xff )
106 /** Option is encapsulated */
107 #define DHCP_IS_ENCAP_OPT( opt ) DHCP_ENCAPSULATOR( opt )
110 * @defgroup dhcpopts DHCP option tags
116 * This tag does not have a length field; it is always only a single
121 /** Minimum normal DHCP option */
122 #define DHCP_MIN_OPTION 1
124 /** Vendor encapsulated options */
125 #define DHCP_VENDOR_ENCAP 43
127 /** Option overloading
129 * The value of this option is the bitwise-OR of zero or more
130 * DHCP_OPTION_OVERLOAD_XXX constants.
132 #define DHCP_OPTION_OVERLOAD 52
134 /** The "file" field is overloaded to contain extra DHCP options */
135 #define DHCP_OPTION_OVERLOAD_FILE 1
137 /** The "sname" field is overloaded to contain extra DHCP options */
138 #define DHCP_OPTION_OVERLOAD_SNAME 2
140 /** DHCP message type */
141 #define DHCP_MESSAGE_TYPE 53
142 #define DHCPDISCOVER 1
144 #define DHCPREQUEST 3
145 #define DHCPDECLINE 4
148 #define DHCPRELEASE 7
153 * This option replaces the fixed "sname" field, when that field is
154 * used to contain overloaded options.
156 #define DHCP_TFTP_SERVER_NAME 66
160 * This option replaces the fixed "file" field, when that field is
161 * used to contain overloaded options.
163 #define DHCP_BOOTFILE_NAME 67
165 /** Etherboot-specific encapsulated options
167 * This encapsulated options field is used to contain all options
168 * specific to Etherboot (i.e. not assigned by IANA or other standards
171 #define DHCP_EB_ENCAP 175
173 /** Priority of this options block
175 * This is a signed 8-bit integer field indicating the priority of
176 * this block of options. It can be used to specify the relative
177 * priority of multiple option blocks (e.g. options from non-volatile
178 * storage versus options from a DHCP server).
180 #define DHCP_EB_PRIORITY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 1 )
182 /** "Your" IP address
184 * This option is used internally to contain the value of the "yiaddr"
185 * field, in order to provide a consistent approach to storing and
186 * processing options. It should never be present in a DHCP packet.
188 #define DHCP_EB_YIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 2 )
190 /** "Server" IP address
192 * This option is used internally to contain the value of the "siaddr"
193 * field, in order to provide a consistent approach to storing and
194 * processing options. It should never be present in a DHCP packet.
196 #define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 3 )
198 /** Maximum normal DHCP option */
199 #define DHCP_MAX_OPTION 254
203 * This tag does not have a length field; it is always only a single
213 * DHCP options consist of a mandatory tag, a length field that is
214 * mandatory for all options except @c DHCP_PAD and @c DHCP_END, and a
220 * Must be a @c DHCP_XXX value.
225 * This is the length of the data field (i.e. excluding the
226 * tag and length fields). For the two tags @c DHCP_PAD and
227 * @c DHCP_END, the length field is implicitly zero and is
228 * also missing, i.e. these DHCP options are only a single
234 * Interpretation of the content is entirely dependent upon
235 * the tag. For fields containing a multi-byte integer, the
236 * field is defined to be in network-endian order (unless you
237 * are Intel and feel like violating the spec for fun).
245 } __attribute__ (( packed ));
248 * Length of a DHCP option header
250 * The header is the portion excluding the data, i.e. the tag and the
253 #define DHCP_OPTION_HEADER_LEN ( offsetof ( struct dhcp_option, data ) )
255 /** Maximum length for a single DHCP option */
256 #define DHCP_MAX_LEN 0xff
258 /** A DHCP options block */
259 struct dhcp_option_block {
260 /** List of option blocks */
261 struct list_head list;
262 /** Option block raw data */
264 /** Option block length */
266 /** Option block maximum length */
270 * This is determined at the time of the call to
271 * register_options() by searching for the @c DHCP_EB_PRIORITY
277 extern unsigned long dhcp_num_option ( struct dhcp_option *option );
278 extern struct dhcp_option *
279 find_dhcp_option ( struct dhcp_option_block *options, unsigned int tag );
280 extern struct dhcp_option * find_global_dhcp_option ( unsigned int tag );
281 extern void register_dhcp_options ( struct dhcp_option_block *options );
282 extern void unregister_dhcp_options ( struct dhcp_option_block *options );
283 extern void init_dhcp_options ( struct dhcp_option_block *options,
284 void *data, size_t max_len );
285 extern struct dhcp_option_block * alloc_dhcp_options ( size_t max_len );
286 extern void free_dhcp_options ( struct dhcp_option_block *options );
287 extern struct dhcp_option *
288 set_dhcp_option ( struct dhcp_option_block *options, unsigned int tag,
289 const void *data, size_t len );
292 * Find DHCP numerical option, and return its value
294 * @v options DHCP options block
295 * @v tag DHCP option tag to search for
296 * @ret value Numerical value of the option, or 0 if not found
298 * This function exists merely as a notational shorthand for a call to
299 * find_dhcp_option() followed by a call to dhcp_num_option(). It is
300 * not possible to distinguish between the cases "option not found"
301 * and "option has a value of zero" using this function; if this
302 * matters to you then issue the two constituent calls directly and
303 * check that find_dhcp_option() returns a non-NULL value.
305 static inline unsigned long
306 find_dhcp_num_option ( struct dhcp_option_block *options, unsigned int tag ) {
307 return dhcp_num_option ( find_dhcp_option ( options, tag ) );
311 * Find DHCP numerical option, and return its value
313 * @v tag DHCP option tag to search for
314 * @ret value Numerical value of the option, or 0 if not found
316 * This function exists merely as a notational shorthand for a call to
317 * find_global_dhcp_option() followed by a call to dhcp_num_option().
318 * It is not possible to distinguish between the cases "option not
319 * found" and "option has a value of zero" using this function; if
320 * this matters to you then issue the two constituent calls directly
321 * and check that find_global_dhcp_option() returns a non-NULL value.
323 static inline unsigned long
324 find_global_dhcp_num_option ( unsigned int tag ) {
325 return dhcp_num_option ( find_global_dhcp_option ( tag ) );
331 * @v options DHCP options block
332 * @v tag DHCP option tag
334 static inline void delete_dhcp_option ( struct dhcp_option_block *options,
336 set_dhcp_option ( options, tag, NULL, 0 );
339 #endif /* _GPXE_DHCP_H */