summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/dhcpv6.h
blob: 6e70f7e6391345f6ac9158087b7a677701dd6363 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
#ifndef _IPXE_DHCPV6_H
#define _IPXE_DHCPV6_H

/** @file
 *
 * Dynamic Host Configuration Protocol for IPv6
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <ipxe/in.h>
#include <ipxe/uuid.h>

/** DHCPv6 server port */
#define DHCPV6_SERVER_PORT 547

/** DHCPv6 client port */
#define DHCPV6_CLIENT_PORT 546

/**
 * A DHCPv6 option
 *
 */
struct dhcpv6_option {
	/** Code */
	uint16_t code;
	/** Length of the data field */
	uint16_t len;
	/** Data */
	uint8_t data[0];
} __attribute__ (( packed ));

/** DHCP unique identifier based on UUID (DUID-UUID) */
struct dhcpv6_duid_uuid {
	/** Type */
	uint16_t type;
	/** UUID */
	union uuid uuid;
} __attribute__ (( packed ));

/** DHCP unique identifier based on UUID (DUID-UUID) */
#define DHCPV6_DUID_UUID 4

/** DHCPv6 client or server identifier option */
struct dhcpv6_duid_option {
	/** Option header */
	struct dhcpv6_option header;
	/** DHCP unique identifier (DUID) */
	uint8_t duid[0];
} __attribute__ (( packed ));

/** DHCPv6 client identifier option */
#define DHCPV6_CLIENT_ID 1

/** DHCPv6 server identifier option */
#define DHCPV6_SERVER_ID 2

/** DHCPv6 identity association for non-temporary address (IA_NA) option */
struct dhcpv6_ia_na_option {
	/** Option header */
	struct dhcpv6_option header;
	/** Identity association identifier (IAID) */
	uint32_t iaid;
	/** Renew time (in seconds) */
	uint32_t renew;
	/** Rebind time (in seconds) */
	uint32_t rebind;
	/** IA_NA options */
	struct dhcpv6_option options[0];
} __attribute__ (( packed ));

/** DHCPv6 identity association for non-temporary address (IA_NA) option */
#define DHCPV6_IA_NA 3

/** DHCPv6 identity association address (IAADDR) option */
struct dhcpv6_iaaddr_option {
	/** Option header */
	struct dhcpv6_option header;
	/** IPv6 address */
	struct in6_addr address;
	/** Preferred lifetime (in seconds) */
	uint32_t preferred;
	/** Valid lifetime (in seconds) */
	uint32_t valid;
	/** IAADDR options */
	struct dhcpv6_option options[0];
} __attribute__ (( packed ));

/** DHCPv6 identity association address (IAADDR) option */
#define DHCPV6_IAADDR 5

/** DHCPv6 option request option */
struct dhcpv6_option_request_option {
	/** Option header */
	struct dhcpv6_option header;
	/** Requested options */
	uint16_t requested[0];
} __attribute__ (( packed ));

/** DHCPv6 option request option */
#define DHCPV6_OPTION_REQUEST 6

/** DHCPv6 elapsed time option */
struct dhcpv6_elapsed_time_option {
	/** Option header */
	struct dhcpv6_option header;
	/** Elapsed time, in centiseconds */
	uint16_t elapsed;
} __attribute__ (( packed ));

/** DHCPv6 elapsed time option */
#define DHCPV6_ELAPSED_TIME 8

/** DHCPv6 status code option */
struct dhcpv6_status_code_option {
	/** Option header */
	struct dhcpv6_option header;
	/** Status code */
	uint16_t status;
	/** Status message */
	char message[0];
} __attribute__ (( packed ));

/** DHCPv6 status code option */
#define DHCPV6_STATUS_CODE 13

/** DHCPv6 user class */
struct dhcpv6_user_class {
	/** Length */
	uint16_t len;
	/** User class string */
	char string[0];
} __attribute__ (( packed ));

/** DHCPv6 user class option */
struct dhcpv6_user_class_option {
	/** Option header */
	struct dhcpv6_option header;
	/** User class */
	struct dhcpv6_user_class user_class[0];
} __attribute__ (( packed ));

/** DHCPv6 user class option */
#define DHCPV6_USER_CLASS 15

/** DHCPv6 vendor class option */
#define DHCPV6_VENDOR_CLASS 16

/** DHCPv6 PXE vendor class
 *
 * The DHCPv6 vendor class includes a field for an IANA enterprise
 * number.  The EDK2 codebase uses the value 343, with the comment:
 *
 *     TODO: IANA TBD: temporarily using Intel's
 *
 * Since this "temporarily" has applied since at least 2010, we assume
 * that it has become a de facto standard.
 */
#define DHCPV6_VENDOR_CLASS_PXE 343

/** DHCPv6 DNS recursive name server option */
#define DHCPV6_DNS_SERVERS 23

/** DHCPv6 domain search list option */
#define DHCPV6_DOMAIN_LIST 24

/** DHCPv6 bootfile URI option */
#define DHCPV6_BOOTFILE_URL 59

/** DHCPv6 bootfile parameters option */
#define DHCPV6_BOOTFILE_PARAM 60

/** DHCPv6 client system architecture option */
#define DHCPV6_CLIENT_ARCHITECTURE 61

/** DHCPv6 client network interface identifier option */
#define DHCPV6_CLIENT_NDI 62

/** DHCPv6 syslog server option
 *
 * This option code has not yet been assigned by IANA.  Please update
 * this definition once an option code has been assigned.
 */
#define DHCPV6_LOG_SERVERS 0xffffffffUL

/** Construct a DHCPv6 byte value */
#define DHCPV6_BYTE_VALUE( value ) ( (value) & 0xff )

/** Construct a DHCPv6 word value */
#define DHCPV6_WORD_VALUE( value ) \
	DHCPV6_BYTE_VALUE ( (value) >> 8 ), DHCPV6_BYTE_VALUE ( (value) >> 0 )

/** Construct a DHCPv6 dword value */
#define DHCPV6_DWORD_VALUE( value ) \
	DHCPV6_WORD_VALUE ( (value) >> 16 ), DHCPV6_WORD_VALUE ( (value) >> 0 )

/** Construct a DHCPv6 option code */
#define DHCPV6_CODE( code ) DHCPV6_WORD_VALUE ( code )

/** Construct a DHCPv6 option length */
#define DHCPV6_LEN( len ) DHCPV6_WORD_VALUE ( len )

/** Construct a DHCPv6 option from a list of bytes */
#define DHCPV6_OPTION( ... ) \
	DHCPV6_LEN ( VA_ARG_COUNT ( __VA_ARGS__ ) ), __VA_ARGS__

/** Construct a DHCPv6 option from a list of characters */
#define DHCPV6_STRING( ... ) DHCPV6_OPTION ( __VA_ARGS__ )

/** Construct a byte-valued DHCPv6 option */
#define DHCPV6_BYTE( value ) DHCPV6_OPTION ( DHCPV6_BYTE_VALUE ( value ) )

/** Construct a word-valued DHCPv6 option */
#define DHCPV6_WORD( value ) DHCPV6_OPTION ( DHCPV6_WORD_VALUE ( value ) )

/** Construct a dword-valued DHCPv6 option */
#define DHCPV6_DWORD( value ) DHCPV6_OPTION ( DHCPV6_DWORD_VALUE ( value ) )

/**
 * Any DHCPv6 option
 *
 */
union dhcpv6_any_option {
	struct dhcpv6_option header;
	struct dhcpv6_duid_option duid;
	struct dhcpv6_ia_na_option ia_na;
	struct dhcpv6_iaaddr_option iaaddr;
	struct dhcpv6_option_request_option option_request;
	struct dhcpv6_elapsed_time_option elapsed_time;
	struct dhcpv6_status_code_option status_code;
	struct dhcpv6_user_class_option user_class;
};

/**
 * A DHCPv6 header
 *
 */
struct dhcpv6_header {
	/** Message type */
	uint8_t type;
	/** Transaction ID */
	uint8_t xid[3];
	/** Options */
	struct dhcpv6_option options[0];
} __attribute__ (( packed ));

/** DHCPv6 solicitation */
#define DHCPV6_SOLICIT 1

/** DHCPv6 advertisement */
#define DHCPV6_ADVERTISE 2

/** DHCPv6 request */
#define DHCPV6_REQUEST 3

/** DHCPv6 reply */
#define DHCPV6_REPLY 7

/** DHCPv6 information request */
#define DHCPV6_INFORMATION_REQUEST 11

/** DHCPv6 settings block name */
#define DHCPV6_SETTINGS_NAME "dhcpv6"

/**
 * Construct all-DHCP-relay-agents-and-servers multicast address
 *
 * @v addr		Zeroed address to construct
 */
static inline void ipv6_all_dhcp_relay_and_servers ( struct in6_addr *addr ) {
	addr->s6_addr16[0] = htons ( 0xff02 );
	addr->s6_addr[13] = 1;
	addr->s6_addr[15] = 2;
}

extern int start_dhcpv6 ( struct interface *job, struct net_device *netdev,
			  int stateful );

#endif /* _IPXE_DHCPV6_H */