57d632697808509edf1a42b5245a037baa38f94d
[people/andreif/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 #include <gpxe/in.h>
13
14 /**
15  * A DHCP packet
16  *
17  */
18 struct dhcp_packet {
19         /** Operation
20          *
21          * This must be either @c BOOTP_REQUEST or @c BOOTP_REPLY.
22          */
23         uint8_t op;
24         /** Hardware address type
25          *
26          * This is an ARPHRD_XXX constant.  Note that ARPHRD_XXX
27          * constants are nominally 16 bits wide; this could be
28          * considered to be a bug in the BOOTP/DHCP specification.
29          */
30         uint8_t htype;
31         /** Hardware address length */
32         uint8_t hlen;
33         /** Number of hops from server */
34         uint8_t hops;
35         /** Transaction ID */
36         uint32_t xid;
37         /** Seconds since start of acquisition */
38         uint16_t secs;
39         /** Flags */
40         uint16_t flags;
41         /** "Client" IP address
42          *
43          * This is filled in if the client already has an IP address
44          * assigned and can respond to ARP requests.
45          */
46         struct in_addr ciaddr;
47         /** "Your" IP address
48          *
49          * This is the IP address assigned by the server to the client.
50          */
51         struct in_addr yiaddr;
52         /** "Server" IP address
53          *
54          * This is the IP address of the next server to be used in the
55          * boot process.
56          */
57         struct in_addr siaddr;
58         /** "Gateway" IP address
59          *
60          * This is the IP address of the DHCP relay agent, if any.
61          */
62         struct in_addr giaddr;
63         /** Client hardware address */
64         uint8_t chaddr[16];
65         /** Server host name (null terminated)
66          *
67          * This field may be overridden and contain DHCP options
68          */
69         uint8_t sname[64];
70         /** Boot file name (null terminated)
71          *
72          * This field may be overridden and contain DHCP options
73          */
74         uint8_t file[128];
75         /** DHCP magic cookie
76          *
77          * Must have the value @c DHCP_MAGIC_COOKIE.
78          */
79         uint32_t magic;
80         /** DHCP options
81          *
82          * Variable length; extends to the end of the packet.
83          */
84         uint8_t options[0];
85 };
86
87 /** Opcode for a request from client to server */
88 #define BOOTP_REQUEST 1
89
90 /** Opcode for a reply from server to client */
91 #define BOOTP_REPLY 2
92
93 /** DHCP magic cookie */
94 #define DHCP_MAGIC_COOKIE 0x63825363UL
95
96 /** Construct a tag value for an encapsulated option
97  *
98  * This tag value can be passed to Etherboot functions when searching
99  * for DHCP options in order to search for a tag within an
100  * encapsulated options block.
101  */
102 #define DHCP_ENCAP_OPT( encapsulator, encapsulated ) \
103         ( ( (encapsulator) << 8 ) | (encapsulated) )
104 /** Extract encapsulating option block tag from encapsulated tag value */
105 #define DHCP_ENCAPSULATOR( encap_opt ) ( (encap_opt) >> 8 )
106 /** Extract encapsulated option tag from encapsulated tag value */
107 #define DHCP_ENCAPSULATED( encap_opt ) ( (encap_opt) & 0xff )
108 /** Option is encapsulated */
109 #define DHCP_IS_ENCAP_OPT( opt ) DHCP_ENCAPSULATOR( opt )
110
111 /**
112  * @defgroup dhcpopts DHCP option tags
113  * @{
114  */
115
116 /** Padding
117  *
118  * This tag does not have a length field; it is always only a single
119  * byte in length.
120  */
121 #define DHCP_PAD 0
122
123 /** Minimum normal DHCP option */
124 #define DHCP_MIN_OPTION 1
125
126 /** Vendor encapsulated options */
127 #define DHCP_VENDOR_ENCAP 43
128
129 /** Option overloading
130  *
131  * The value of this option is the bitwise-OR of zero or more
132  * DHCP_OPTION_OVERLOAD_XXX constants.
133  */
134 #define DHCP_OPTION_OVERLOAD 52
135
136 /** The "file" field is overloaded to contain extra DHCP options */
137 #define DHCP_OPTION_OVERLOAD_FILE 1
138
139 /** The "sname" field is overloaded to contain extra DHCP options */
140 #define DHCP_OPTION_OVERLOAD_SNAME 2
141
142 /** DHCP message type */
143 #define DHCP_MESSAGE_TYPE 53
144 #define DHCPDISCOVER 1
145 #define DHCPOFFER 2
146 #define DHCPREQUEST 3
147 #define DHCPDECLINE 4
148 #define DHCPACK 5
149 #define DHCPNAK 6
150 #define DHCPRELEASE 7
151 #define DHCPINFORM 8
152
153 /** TFTP server name
154  *
155  * This option replaces the fixed "sname" field, when that field is
156  * used to contain overloaded options.
157  */
158 #define DHCP_TFTP_SERVER_NAME 66
159
160 /** Bootfile name
161  *
162  * This option replaces the fixed "file" field, when that field is
163  * used to contain overloaded options.
164  */
165 #define DHCP_BOOTFILE_NAME 67
166
167 /** Etherboot-specific encapsulated options
168  *
169  * This encapsulated options field is used to contain all options
170  * specific to Etherboot (i.e. not assigned by IANA or other standards
171  * bodies).
172  */
173 #define DHCP_EB_ENCAP 175
174
175 /** Priority of this options block
176  *
177  * This is a signed 8-bit integer field indicating the priority of
178  * this block of options.  It can be used to specify the relative
179  * priority of multiple option blocks (e.g. options from non-volatile
180  * storage versus options from a DHCP server).
181  */
182 #define DHCP_EB_PRIORITY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 1 )
183
184 /** "Your" IP address
185  *
186  * This option is used internally to contain the value of the "yiaddr"
187  * field, in order to provide a consistent approach to storing and
188  * processing options.  It should never be present in a DHCP packet.
189  */
190 #define DHCP_EB_YIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 2 )
191
192 /** "Server" IP address
193  *
194  * This option is used internally to contain the value of the "siaddr"
195  * field, in order to provide a consistent approach to storing and
196  * processing options.  It should never be present in a DHCP packet.
197  */
198 #define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 3 )
199
200 /** Maximum normal DHCP option */
201 #define DHCP_MAX_OPTION 254
202
203 /** End of options
204  *
205  * This tag does not have a length field; it is always only a single
206  * byte in length.
207  */
208 #define DHCP_END 255
209
210 /** @} */
211
212 /**
213  * A DHCP option
214  *
215  * DHCP options consist of a mandatory tag, a length field that is
216  * mandatory for all options except @c DHCP_PAD and @c DHCP_END, and a
217  * payload.  
218  */
219 struct dhcp_option {
220         /** Tag
221          *
222          * Must be a @c DHCP_XXX value.
223          */
224         uint8_t tag;
225         /** Length
226          *
227          * This is the length of the data field (i.e. excluding the
228          * tag and length fields).  For the two tags @c DHCP_PAD and
229          * @c DHCP_END, the length field is implicitly zero and is
230          * also missing, i.e. these DHCP options are only a single
231          * byte in length.
232          */
233         uint8_t len;
234         /** Option data
235          *
236          * Interpretation of the content is entirely dependent upon
237          * the tag.  For fields containing a multi-byte integer, the
238          * field is defined to be in network-endian order (unless you
239          * are Intel and feel like violating the spec for fun).
240          */
241         union {
242                 uint8_t byte;
243                 uint16_t word;
244                 uint32_t dword;
245                 uint8_t bytes[0];
246         } data;
247 } __attribute__ (( packed ));
248
249 /**
250  * Length of a DHCP option header
251  *
252  * The header is the portion excluding the data, i.e. the tag and the
253  * length.
254  */
255 #define DHCP_OPTION_HEADER_LEN ( offsetof ( struct dhcp_option, data ) )
256
257 /** Maximum length for a single DHCP option */
258 #define DHCP_MAX_LEN 0xff
259
260 /** A DHCP options block */
261 struct dhcp_option_block {
262         /** List of option blocks */
263         struct list_head list;
264         /** Option block raw data */
265         void *data;
266         /** Option block length */
267         size_t len;
268         /** Option block maximum length */
269         size_t max_len;
270         /** Block priority
271          *
272          * This is determined at the time of the call to
273          * register_options() by searching for the @c DHCP_EB_PRIORITY
274          * option.
275          */
276         signed int priority;
277 };
278
279 /** A DHCP session */
280 struct dhcp_session {
281         /** Network device being configured */
282         struct net_device *netdev;
283         /** Transaction ID, in network-endian order */
284         uint32_t xid;
285 };
286
287 extern unsigned long dhcp_num_option ( struct dhcp_option *option );
288 extern struct dhcp_option *
289 find_dhcp_option ( struct dhcp_option_block *options, unsigned int tag );
290 extern void register_dhcp_options ( struct dhcp_option_block *options );
291 extern void unregister_dhcp_options ( struct dhcp_option_block *options );
292 extern void init_dhcp_options ( struct dhcp_option_block *options,
293                                 void *data, size_t max_len );
294 extern struct dhcp_option_block * alloc_dhcp_options ( size_t max_len );
295 extern void free_dhcp_options ( struct dhcp_option_block *options );
296 extern struct dhcp_option *
297 set_dhcp_option ( struct dhcp_option_block *options, unsigned int tag,
298                   const void *data, size_t len );
299 extern struct dhcp_option * find_global_dhcp_option ( unsigned int tag );
300 extern unsigned long find_dhcp_num_option ( struct dhcp_option_block *options,
301                                             unsigned int tag );
302 extern unsigned long find_global_dhcp_num_option ( unsigned int tag );
303 extern void delete_dhcp_option ( struct dhcp_option_block *options,
304                                  unsigned int tag );
305
306 #endif /* _GPXE_DHCP_H */