First stab at DHCP option handling in a way that will allow us to have
[people/xl0/gpxe.git] / src / include / gpxe / dhcp.h
1 #ifndef _GPXE_DHCP_H
2 #define _GPXE_DHCP_H
3
4 /** @file
5  *
6  * Dynamic Host Configuration Protocol
7  *
8  */
9
10 #include <stdint.h>
11 #include <gpxe/list.h>
12
13 /** Construct a tag value for an encapsulated option
14  *
15  * This tag value can be passed to Etherboot functions when searching
16  * for DHCP options in order to search for a tag within an
17  * encapsulated options block.
18  */
19 #define DHCP_ENCAP_OPT( encapsulator, encapsulated ) \
20         ( ( (encapsulator) << 8 ) | (encapsulated) )
21 /** Extract encapsulating option block tag from encapsulated tag value */
22 #define DHCP_ENCAPSULATOR( encap_opt ) ( (encap_opt) >> 8 )
23 /** Extract encapsulated option tag from encapsulated tag value */
24 #define DHCP_ENCAPSULATED( encap_opt ) ( (encap_opt) & 0xff )
25
26 /**
27  * @defgroup dhcpopts DHCP option tags
28  * @{
29  */
30
31 #define DHCP_PAD 0
32 #define DHCP_END 255
33
34 #define DHCP_EB_ENCAP 175
35
36 #define DHCP_EB_PRIORITY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 1 )
37
38 /** @} */
39
40 /**
41  * A DHCP option
42  *
43  * DHCP options consist of a mandatory tag, a length field that is
44  * mandatory for all options except @c DHCP_PAD and @c DHCP_END, and a
45  * payload.  
46  */
47 struct dhcp_option {
48         /** Tag
49          *
50          * Must be a @c DHCP_XXX value.
51          */
52         uint8_t tag;
53         /** Length
54          *
55          * This is the length of the data field (i.e. excluding the
56          * tag and length fields).  For the two tags @c DHCP_PAD and
57          * @c DHCP_END, the length field is implicitly zero and is
58          * also missing, i.e. these DHCP options are only a single
59          * byte in length.
60          */
61         uint8_t len;
62         /** Option data
63          *
64          * Interpretation of the content is entirely dependent upon
65          * the tag.  For fields containing a multi-byte integer, the
66          * field is defined to be in network-endian order (unless you
67          * are Intel and feel like violating the spec for fun).
68          */
69         union {
70                 uint8_t byte;
71                 uint16_t word;
72                 uint32_t dword;
73                 uint8_t bytes[0];
74         } data;
75 } __attribute__ (( packed ));
76
77 /** A DHCP options block */
78 struct dhcp_option_block {
79         /** List of option blocks */
80         struct list_head list;
81         /** Option block raw data */
82         void *data;
83         /** Option block length */
84         size_t len;
85 };
86
87 #endif /* _GPXE_DHCP_H */