1 /* $NetBSD: tables.c,v 1.4 2022/04/03 01:10:58 christos Exp $ */
2
3 /* tables.c
4
5 Tables of information... */
6
7 /*
8 * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 1995-2003 by Internet Software Consortium
10 *
11 * This Source Code Form is subject to the terms of the Mozilla Public
12 * License, v. 2.0. If a copy of the MPL was not distributed with this
13 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Internet Systems Consortium, Inc.
24 * PO Box 360
25 * Newmarket, NH 03857 USA
26 * <info@isc.org>
27 * https://www.isc.org/
28 *
29 */
30
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: tables.c,v 1.4 2022/04/03 01:10:58 christos Exp $");
33
34 #include "dhcpd.h"
35
36 /* XXXDPN: Moved here from hash.c, when it moved to libomapi. Not sure
37 where these really belong. */
38 HASH_FUNCTIONS (group, const char *, struct group_object, group_hash_t,
39 group_reference, group_dereference, do_string_hash)
40 HASH_FUNCTIONS (universe, const char *, struct universe, universe_hash_t, 0, 0,
41 do_case_hash)
42 HASH_FUNCTIONS (option_name, const char *, struct option, option_name_hash_t,
43 option_reference, option_dereference, do_case_hash)
44 HASH_FUNCTIONS (option_code, const unsigned *, struct option,
45 option_code_hash_t, option_reference, option_dereference,
46 do_number_hash)
47
48 /* DHCP Option names, formats and codes, from RFC1533.
49
50 Format codes:
51
52 I - IPv4 address
53 6 - IPv6 address
54 l - 32-bit signed integer
55 L - 32-bit unsigned integer
56 s - 16-bit signed integer
57 S - 16-bit unsigned integer
58 b - 8-bit signed integer
59 B - 8-bit unsigned integer
60 t - ASCII text
61 T - Lease Time, 32-bit unsigned integer implying a number of seconds from
62 some event. The special all-ones value means 'infinite'. May either
63 be printed as a decimal, eg, "3600", or as this name, eg, "infinite".
64 f - flag (true or false)
65 A - array of all that precedes (e.g., fIA means array of records of
66 a flag and an IP address)
67 a - array of the preceding character (e.g., fIa means a single flag
68 followed by an array of IP addresses)
69 U - name of an option space (universe)
70 F - implicit flag - the presence of the option indicates that the
71 flag is true.
72 o - the preceding value is optional.
73 E - encapsulation, string or colon-separated hex list (the latter
74 two for parsing). E is followed by a text string containing
75 the name of the option space to encapsulate, followed by a '.'.
76 If the E is immediately followed by '.', the applicable vendor
77 option space is used if one is defined.
78 e - If an encapsulation directive is not the first thing in the string,
79 the option scanner requires an efficient way to find the encapsulation.
80 This is done by placing a 'e' at the beginning of the option. The
81 'e' has no other purpose, and is not required if 'E' is the first
82 thing in the option.
83 X - either an ASCII string or binary data. On output, the string is
84 scanned to see if it's printable ASCII and, if so, output as a
85 quoted string. If not, it's output as colon-separated hex. On
86 input, the option can be specified either as a quoted string or as
87 a colon-separated hex list.
88 N - enumeration. N is followed by a text string containing
89 the name of the set of enumeration values to parse or emit,
90 followed by a '.'. The width of the data is specified in the
91 named enumeration. Named enumerations are tracked in parse.c.
92 d - Domain name (e.g., FOO or FOO.BAR) no quotes,
93 on-wire format is RFC 1035.
94 D - Domain list (e.g., "example.com eng.example.com") quoted,
95 on-wire format is RFC 1035.
96 c - When following a 'D' atom, enables compression pointers.
97 Z - Zero-length option
98 k - Key name, unquoted string (e.g. mykey.com or some-text or abc123)
99 parsed with parse_host_name().
100 */
101
102 struct universe dhcp_universe;
103 static struct option dhcp_options[] = {
104 { "subnet-mask", "I", &dhcp_universe, 1, 1 },
105 { "time-offset", "l", &dhcp_universe, 2, 1 },
106 { "routers", "IA", &dhcp_universe, 3, 1 },
107 { "time-servers", "IA", &dhcp_universe, 4, 1 },
108 { "ien116-name-servers", "IA", &dhcp_universe, 5, 1 },
109 { "domain-name-servers", "IA", &dhcp_universe, 6, 1 },
110 { "log-servers", "IA", &dhcp_universe, 7, 1 },
111 { "cookie-servers", "IA", &dhcp_universe, 8, 1 },
112 { "lpr-servers", "IA", &dhcp_universe, 9, 1 },
113 { "impress-servers", "IA", &dhcp_universe, 10, 1 },
114 { "resource-location-servers", "IA", &dhcp_universe, 11, 1 },
115 { "host-name", "t", &dhcp_universe, 12, 1 },
116 { "boot-size", "S", &dhcp_universe, 13, 1 },
117 { "merit-dump", "t", &dhcp_universe, 14, 1 },
118 { "domain-name", "t", &dhcp_universe, 15, 1 },
119 { "swap-server", "I", &dhcp_universe, 16, 1 },
120 { "root-path", "t", &dhcp_universe, 17, 1 },
121 { "extensions-path", "t", &dhcp_universe, 18, 1 },
122 { "ip-forwarding", "f", &dhcp_universe, 19, 1 },
123 { "non-local-source-routing", "f", &dhcp_universe, 20, 1 },
124 { "policy-filter", "IIA", &dhcp_universe, 21, 1 },
125 { "max-dgram-reassembly", "S", &dhcp_universe, 22, 1 },
126 { "default-ip-ttl", "B", &dhcp_universe, 23, 1 },
127 { "path-mtu-aging-timeout", "L", &dhcp_universe, 24, 1 },
128 { "path-mtu-plateau-table", "SA", &dhcp_universe, 25, 1 },
129 { "interface-mtu", "S", &dhcp_universe, 26, 1 },
130 { "all-subnets-local", "f", &dhcp_universe, 27, 1 },
131 { "broadcast-address", "I", &dhcp_universe, 28, 1 },
132 { "perform-mask-discovery", "f", &dhcp_universe, 29, 1 },
133 { "mask-supplier", "f", &dhcp_universe, 30, 1 },
134 { "router-discovery", "f", &dhcp_universe, 31, 1 },
135 { "router-solicitation-address", "I", &dhcp_universe, 32, 1 },
136 { "static-routes", "IIA", &dhcp_universe, 33, 1 },
137 { "trailer-encapsulation", "f", &dhcp_universe, 34, 1 },
138 { "arp-cache-timeout", "L", &dhcp_universe, 35, 1 },
139 { "ieee802-3-encapsulation", "f", &dhcp_universe, 36, 1 },
140 { "default-tcp-ttl", "B", &dhcp_universe, 37, 1 },
141 { "tcp-keepalive-interval", "L", &dhcp_universe, 38, 1 },
142 { "tcp-keepalive-garbage", "f", &dhcp_universe, 39, 1 },
143 { "nis-domain", "t", &dhcp_universe, 40, 1 },
144 { "nis-servers", "IA", &dhcp_universe, 41, 1 },
145 { "ntp-servers", "IA", &dhcp_universe, 42, 1 },
146 { "vendor-encapsulated-options", "E.", &dhcp_universe, 43, 1 },
147 { "netbios-name-servers", "IA", &dhcp_universe, 44, 1 },
148 { "netbios-dd-server", "IA", &dhcp_universe, 45, 1 },
149 { "netbios-node-type", "B", &dhcp_universe, 46, 1 },
150 { "netbios-scope", "t", &dhcp_universe, 47, 1 },
151 { "font-servers", "IA", &dhcp_universe, 48, 1 },
152 { "x-display-manager", "IA", &dhcp_universe, 49, 1 },
153 { "dhcp-requested-address", "I", &dhcp_universe, 50, 1 },
154 { "dhcp-lease-time", "L", &dhcp_universe, 51, 1 },
155 { "dhcp-option-overload", "B", &dhcp_universe, 52, 1 },
156 { "dhcp-message-type", "B", &dhcp_universe, 53, 1 },
157 { "dhcp-server-identifier", "I", &dhcp_universe, 54, 1 },
158 { "dhcp-parameter-request-list", "BA", &dhcp_universe, 55, 1 },
159 { "dhcp-message", "t", &dhcp_universe, 56, 1 },
160 { "dhcp-max-message-size", "S", &dhcp_universe, 57, 1 },
161 { "dhcp-renewal-time", "L", &dhcp_universe, 58, 1 },
162 { "dhcp-rebinding-time", "L", &dhcp_universe, 59, 1 },
163 { "vendor-class-identifier", "X", &dhcp_universe, 60, 1 },
164 { "dhcp-client-identifier", "X", &dhcp_universe, 61, 1 },
165 { "nwip-domain", "t", &dhcp_universe, 62, 1 },
166 { "nwip-suboptions", "Enwip.", &dhcp_universe, 63, 1 },
167 { "nisplus-domain", "t", &dhcp_universe, 64, 1 },
168 { "nisplus-servers", "IA", &dhcp_universe, 65, 1 },
169 { "tftp-server-name", "t", &dhcp_universe, 66, 1 },
170 { "bootfile-name", "t", &dhcp_universe, 67, 1 },
171 { "mobile-ip-home-agent", "IA", &dhcp_universe, 68, 1 },
172 { "smtp-server", "IA", &dhcp_universe, 69, 1 },
173 { "pop-server", "IA", &dhcp_universe, 70, 1 },
174 { "nntp-server", "IA", &dhcp_universe, 71, 1 },
175 { "www-server", "IA", &dhcp_universe, 72, 1 },
176 { "finger-server", "IA", &dhcp_universe, 73, 1 },
177 { "irc-server", "IA", &dhcp_universe, 74, 1 },
178 { "streettalk-server", "IA", &dhcp_universe, 75, 1 },
179 { "streettalk-directory-assistance-server", "IA",
180 &dhcp_universe, 76, 1 },
181 { "user-class", "t", &dhcp_universe, 77, 1 },
182 { "slp-directory-agent", "fIa", &dhcp_universe, 78, 1 },
183 { "slp-service-scope", "fto", &dhcp_universe, 79, 1 },
184 /* 80 is the zero-length rapid-commit (RFC 4039) */
185 { "fqdn", "Efqdn.", &dhcp_universe, 81, 1 },
186 { "relay-agent-information", "Eagent.", &dhcp_universe, 82, 1 },
187 /* 83 is iSNS (RFC 4174) */
188 /* 84 is unassigned */
189 { "nds-servers", "IA", &dhcp_universe, 85, 1 },
190 { "nds-tree-name", "t", &dhcp_universe, 86, 1 },
191 { "nds-context", "t", &dhcp_universe, 87, 1 },
192
193 /* Note: RFC4280 fails to identify if the DHCPv4 option is to use
194 * compression pointers or not. Assume not.
195 */
196 { "bcms-controller-names", "D", &dhcp_universe, 88, 1 },
197 { "bcms-controller-address", "Ia", &dhcp_universe, 89, 1 },
198
199 /* 90 is the authentication option (RFC 3118) */
200
201 { "client-last-transaction-time", "L", &dhcp_universe, 91, 1 },
202 { "associated-ip", "Ia", &dhcp_universe, 92, 1 },
203 #if defined(RFC4578_OPTIONS)
204 /* Defined by RFC 4578 */
205 { "pxe-system-type", "Sa", &dhcp_universe, 93, 1 },
206 { "pxe-interface-id", "BBB", &dhcp_universe, 94, 1 },
207 { "pxe-client-id", "BX", &dhcp_universe, 97, 1 },
208 #endif
209 { "uap-servers", "t", &dhcp_universe, 98, 1 },
210 #if defined(RFC4776_OPTIONS)
211 { "geoconf-civic", "X", &dhcp_universe, 99, 1 },
212 #endif
213 #if defined(RFC4833_OPTIONS)
214 { "pcode", "t", &dhcp_universe, 100, 1 },
215 { "tcode", "t", &dhcp_universe, 101, 1 },
216 #endif
217 #if defined(RFC8925_OPTIONS)
218 { "v6-only-preferred", "L", &dhcp_universe, 108, 1 },
219 #endif
220 { "netinfo-server-address", "Ia", &dhcp_universe, 112, 1 },
221 { "netinfo-server-tag", "t", &dhcp_universe, 113, 1 },
222 { "default-url", "t", &dhcp_universe, 114, 1 },
223 #if defined(RFC2563_OPTIONS)
224 { "auto-config", "B", &dhcp_universe, 116, 1 },
225 #endif
226 #if defined(RFC2937_OPTIONS)
227 { "name-service-search", "Sa", &dhcp_universe, 117, 1 },
228 #endif
229 { "subnet-selection", "I", &dhcp_universe, 118, 1 },
230 { "domain-search", "Dc", &dhcp_universe, 119, 1 },
231 { "vivco", "Evendor-class.", &dhcp_universe, 124, 1 },
232 { "vivso", "Evendor.", &dhcp_universe, 125, 1 },
233 #if 0
234 /* Referenced by RFC 4578.
235 * DO NOT UNCOMMENT THESE DEFINITIONS: these names are placeholders
236 * and will not be used in future versions of the software.
237 */
238 { "pxe-undefined-1", "X", &dhcp_universe, 128, 1 },
239 { "pxe-undefined-2", "X", &dhcp_universe, 129, 1 },
240 { "pxe-undefined-3", "X", &dhcp_universe, 130, 1 },
241 { "pxe-undefined-4", "X", &dhcp_universe, 131, 1 },
242 { "pxe-undefined-5", "X", &dhcp_universe, 132, 1 },
243 { "pxe-undefined-6", "X", &dhcp_universe, 133, 1 },
244 { "pxe-undefined-7", "X", &dhcp_universe, 134, 1 },
245 { "pxe-undefined-8", "X", &dhcp_universe, 135, 1 },
246 #endif
247 #if defined(RFC5192_OPTIONS)
248 {"pana-agent", "Ia", &dhcp_universe, 136, 1 },
249 #endif
250 #if defined(RFC5223_OPTIONS)
251 {"v4-lost", "d", &dhcp_universe, 137, 1 },
252 #endif
253 #if defined(RFC5417_OPTIONS)
254 {"capwap-ac-v4", "Ia", &dhcp_universe, 138, 1 },
255 #endif
256 #if defined(RFC6011_OPTIONS)
257 { "sip-ua-cs-domains", "Dc", &dhcp_universe, 141, 1 },
258 #endif
259 #if defined(RFC6153_OPTIONS)
260 { "ipv4-address-andsf", "IA", &dhcp_universe, 142, 1 },
261 #endif
262 #if defined(RFC6731_OPTIONS)
263 { "rdnss-selection", "BIID", &dhcp_universe, 146, 1 },
264 #endif
265 #if defined(RFC5859_OPTIONS)
266 { "tftp-server-address", "Ia", &dhcp_universe, 150, 1 },
267 #endif
268 #if defined(RFC7618_OPTIONS)
269 { "v4-portparams", "BBS", &dhcp_universe, 159, 1 },
270 #endif
271 #if defined(RFC7710_OPTIONS)
272 { "v4-captive-portal", "t", &dhcp_universe, 160, 1 },
273 #endif
274 #if defined(RFC5071_OPTIONS)
275 #if 0
276 /* Option 208 has been officially deprecated. Do NOT define it */
277 { "pxelinux-magic", "BBBB", &dhcp_universe, 208, 1 },
278 #endif
279 { "loader-configfile", "t", &dhcp_universe, 209, 1 },
280 { "loader-pathprefix", "t", &dhcp_universe, 210, 1 },
281 { "loader-reboottime", "L", &dhcp_universe, 211, 1 },
282 #endif
283 #if defined(RFC5969_OPTIONS)
284 { "option-6rd", "BB6Ia", &dhcp_universe, 212, 1 },
285 #endif
286 #if defined(RFC5986_OPTIONS)
287 {"v4-access-domain", "d", &dhcp_universe, 213, 1 },
288 #endif
289 { NULL, NULL, NULL, 0, 0 }
290 };
291
292 struct universe nwip_universe;
293 static struct option nwip_options[] = {
294 { "illegal-1", "", &nwip_universe, 1, 1 },
295 { "illegal-2", "", &nwip_universe, 2, 1 },
296 { "illegal-3", "", &nwip_universe, 3, 1 },
297 { "illegal-4", "", &nwip_universe, 4, 1 },
298 { "nsq-broadcast", "f", &nwip_universe, 5, 1 },
299 { "preferred-dss", "IA", &nwip_universe, 6, 1 },
300 { "nearest-nwip-server", "IA", &nwip_universe, 7, 1 },
301 { "autoretries", "B", &nwip_universe, 8, 1 },
302 { "autoretry-secs", "B", &nwip_universe, 9, 1 },
303 { "nwip-1-1", "f", &nwip_universe, 10, 1 },
304 { "primary-dss", "I", &nwip_universe, 11, 1 },
305 { NULL, NULL, NULL, 0, 0 }
306 };
307
308 /* Note that the "FQDN suboption space" does not reflect the FQDN option
309 * format - rather, this is a handy "virtualization" of a flat option
310 * which makes manual configuration and presentation of some of its
311 * contents easier (each of these suboptions is a fixed-space field within
312 * the fqdn contents - domain and host names are derived from a common field,
313 * and differ in the left and right hand side of the leftmost dot, fqdn is
314 * the combination of the two).
315 *
316 * Note further that the DHCPv6 and DHCPv4 'fqdn' options use the same
317 * virtualized option space to store their work.
318 */
319
320 struct universe fqdn_universe;
321 struct universe fqdn6_universe;
322 static struct option fqdn_options[] = {
323 { "no-client-update", "f", &fqdn_universe, 1, 1 },
324 { "server-update", "f", &fqdn_universe, 2, 1 },
325 { "encoded", "f", &fqdn_universe, 3, 1 },
326 { "rcode1", "B", &fqdn_universe, 4, 1 },
327 { "rcode2", "B", &fqdn_universe, 5, 1 },
328 { "hostname", "t", &fqdn_universe, 6, 1 },
329 { "domainname", "t", &fqdn_universe, 7, 1 },
330 { "fqdn", "t", &fqdn_universe, 8, 1 },
331 { NULL, NULL, NULL, 0, 0 }
332 };
333
334 struct universe vendor_class_universe;
335 static struct option vendor_class_options[] = {
336 { "isc", "X", &vendor_class_universe, 2495, 1 },
337 { NULL, NULL, NULL, 0, 0 }
338 };
339
340 struct universe vendor_universe;
341 static struct option vendor_options[] = {
342 { "isc", "Eisc.", &vendor_universe, 2495, 1 },
343 { NULL, NULL, NULL, 0, 0 }
344 };
345
346 struct universe isc_universe;
347 static struct option isc_options [] = {
348 { "media", "t", &isc_universe, 1, 1 },
349 { "update-assist", "X", &isc_universe, 2, 1 },
350 { NULL, NULL, NULL, 0, 0 }
351 };
352
353 struct universe dhcpv6_universe;
354 static struct option dhcpv6_options[] = {
355
356 /* RFC3315 OPTIONS */
357
358 /* Client and server DUIDs are opaque fields, but marking them
359 * up somewhat makes configuration easier.
360 */
361 { "client-id", "X", &dhcpv6_universe, 1, 1 },
362 { "server-id", "X", &dhcpv6_universe, 2, 1 },
363
364 /* ia-* options actually have at their ends a space for options
365 * that are specific to this instance of the option. We can not
366 * handle this yet at this stage of development, so the encoding
367 * of these options is unspecified ("X").
368 */
369 { "ia-na", "X", &dhcpv6_universe, 3, 1 },
370 { "ia-ta", "X", &dhcpv6_universe, 4, 1 },
371 { "ia-addr", "X", &dhcpv6_universe, 5, 1 },
372
373 /* "oro" is DHCPv6 speak for "parameter-request-list" */
374 { "oro", "SA", &dhcpv6_universe, 6, 1 },
375
376 { "preference", "B", &dhcpv6_universe, 7, 1 },
377 { "elapsed-time", "S", &dhcpv6_universe, 8, 1 },
378 { "relay-msg", "X", &dhcpv6_universe, 9, 1 },
379
380 /* Option code 10 is curiously unassigned. */
381 /*
382 * In draft-ietf-dhc-dhcpv6-25 there were two OPTION_CLIENT_MSG and
383 * OPTION_SERVER_MSG options. They were eventually unified as
384 * OPTION_RELAY_MSG, hence no option with value of 10.
385 */
386 #if 0
387 /* XXX: missing suitable atoms for the auth option. We may want
388 * to 'virtually encapsulate' this option a la the fqdn option
389 * seeing as it is processed explicitly by the server and unlikely
390 * to be configured by hand by users as such.
391 */
392 { "auth", "Nauth-protocol.Nauth-algorithm.Nrdm-type.LLX",
393 &dhcpv6_universe, 11, 1 },
394 #endif
395 { "unicast", "6", &dhcpv6_universe, 12, 1 },
396 { "status-code", "Nstatus-codes.to", &dhcpv6_universe, 13, 1 },
397 { "rapid-commit", "Z", &dhcpv6_universe, 14, 1 },
398 #if 0
399 /* XXX: user-class contents are of the form "StA" where the
400 * integer describes the length of the text field. We don't have
401 * an atom for pre-determined-length octet strings yet, so we
402 * can't quite do these two.
403 */
404 { "user-class", "X", &dhcpv6_universe, 15, 1 },
405 { "vendor-class", "X", &dhcpv6_universe, 16, 1 },
406 #endif
407 { "vendor-opts", "Evsio.", &dhcpv6_universe, 17, 1 },
408 { "interface-id", "X", &dhcpv6_universe, 18, 1 },
409 { "reconf-msg", "Ndhcpv6-messages.", &dhcpv6_universe, 19, 1 },
410 { "reconf-accept", "Z", &dhcpv6_universe, 20, 1 },
411
412 /* RFC3319 OPTIONS */
413
414 /* Of course: we would HAVE to have a different atom for
415 * domain names without compression. Typical.
416 */
417 { "sip-servers-names", "D", &dhcpv6_universe, 21, 1 },
418 { "sip-servers-addresses", "6A", &dhcpv6_universe, 22, 1 },
419
420 /* RFC3646 OPTIONS */
421
422 { "name-servers", "6A", &dhcpv6_universe, 23, 1 },
423 { "domain-search", "D", &dhcpv6_universe, 24, 1 },
424
425 /* RFC3633 OPTIONS */
426
427 { "ia-pd", "X", &dhcpv6_universe, 25, 1 },
428 { "ia-prefix", "X", &dhcpv6_universe, 26, 1 },
429
430 /* RFC3898 OPTIONS */
431
432 { "nis-servers", "6A", &dhcpv6_universe, 27, 1 },
433 { "nisp-servers", "6A", &dhcpv6_universe, 28, 1 },
434 { "nis-domain-name", "D", &dhcpv6_universe, 29, 1 },
435 { "nisp-domain-name", "D", &dhcpv6_universe, 30, 1 },
436
437 /* RFC4075 OPTIONS */
438 { "sntp-servers", "6A", &dhcpv6_universe, 31, 1 },
439
440 /* RFC4242 OPTIONS */
441
442 { "info-refresh-time", "T", &dhcpv6_universe, 32, 1 },
443
444 /* RFC4280 OPTIONS */
445
446 { "bcms-server-d", "D", &dhcpv6_universe, 33, 1 },
447 { "bcms-server-a", "6A", &dhcpv6_universe, 34, 1 },
448
449 /* Note that 35 is not assigned. */
450
451 #if defined(RFC4776_OPTIONS)
452 /* RFC4776 OPTIONS */
453
454 { "geoconf-civic", "X", &dhcpv6_universe, 36, 1 },
455 #endif
456
457 /* RFC4649 OPTIONS */
458
459 /* The remote-id option looks like the VSIO option, but for all
460 * intents and purposes we only need to treat the entire field
461 * like a globally unique identifier (and if we create such an
462 * option, ensure the first 4 bytes are our enterprise-id followed
463 * by a globally unique ID so long as you're within that enterprise
464 * id). So we'll use "X" for now unless someone grumbles.
465 */
466 { "remote-id", "X", &dhcpv6_universe, 37, 1 },
467
468 /* RFC4580 OPTIONS */
469
470 { "subscriber-id", "X", &dhcpv6_universe, 38, 1 },
471
472 /* RFC4704 OPTIONS */
473
474 /* The DHCPv6 FQDN option is...weird.
475 *
476 * We use the same "virtual" encapsulated space as DHCPv4's FQDN
477 * option, so it can all be configured in one place. Since the
478 * options system does not support multiple inheritance, we use
479 * a 'shill' layer to perform the different protocol conversions,
480 * and to redirect any queries in the DHCPv4 FQDN's space.
481 */
482 { "fqdn", "Efqdn6-if-you-see-me-its-a-bug-bug-bug.",
483 &dhcpv6_universe, 39, 1 },
484
485
486 /* RFC5192 */
487 #if defined(RFC5192_OPTIONS)
488 { "pana-agent", "6A", &dhcpv6_universe, 40, 1 },
489 #endif
490
491 /* RFC4833 OPTIONS */
492 #if defined(RFC4833_OPTIONS)
493 { "new-posix-timezone", "t", &dhcpv6_universe, 41, 1 },
494 { "new-tzdb-timezone", "t", &dhcpv6_universe, 42, 1 },
495 #endif
496
497 /* RFC4994 OPTIONS */
498 #if defined(RFC4994_OPTIONS)
499 { "ero", "SA", &dhcpv6_universe, 43, 1 },
500 #endif
501
502 /* RFC5007 OPTIONS */
503
504 { "lq-query", "X", &dhcpv6_universe, 44, 1 },
505 { "client-data", "X", &dhcpv6_universe, 45, 1 },
506 { "clt-time", "L", &dhcpv6_universe, 46, 1 },
507 { "lq-relay-data", "6X", &dhcpv6_universe, 47, 1 },
508 { "lq-client-link", "6A", &dhcpv6_universe, 48, 1 },
509
510 /* RFC5223 OPTIONS */
511 #if defined(RFC5223_OPTIONS)
512 { "v6-lost", "d", &dhcpv6_universe, 51, 1 },
513 #endif
514
515 /* RFC5417 OPTIONS */
516 #if defined(RFC5417_OPTIONS)
517 { "capwap-ac-v6", "6a", &dhcpv6_universe, 52, 1 },
518 #endif
519
520 /* RFC5460 OPTIONS */
521 #if defined(RFC5460_OPTIONS)
522 { "relay-id", "X", &dhcpv6_universe, 53, 1 },
523 #endif
524
525 /* RFC5986 OPTIONS */
526 #if defined(RFC5986_OPTIONS)
527 { "v6-access-domain", "d", &dhcpv6_universe, 57, 1 },
528 #endif
529
530 /* RFC6011 OPTIONS */
531 #if defined(RFC6011_OPTIONS)
532 { "sip-ua-cs-list", "D", &dhcpv6_universe, 58, 1 },
533 #endif
534
535 /* RFC5970 OPTIONS */
536 #if defined(RFC5970_OPTIONS)
537 { "bootfile-url", "t", &dhcpv6_universe, 59, 1 },
538 { "bootfile-param", "X", &dhcpv6_universe, 60, 1 },
539 { "client-arch-type", "SA", &dhcpv6_universe, 61, 1 },
540 { "nii", "BBB", &dhcpv6_universe, 62, 1 },
541 #endif
542
543 /* RFC6334 OPTIONS */
544 #if defined(RFC6334_OPTIONS)
545 { "aftr-name", "d", &dhcpv6_universe, 64, 1 },
546 #endif
547
548 /* RFC6440 OPTIONS */
549 #if defined(RFC6440_OPTIONS)
550 { "erp-local-domain-name", "d", &dhcpv6_universe, 65, 1 },
551 #endif
552
553 /* RFC6731 OPTIONS */
554 #if defined(RFC6731_OPTIONS)
555 { "rdnss-selection", "6BD", &dhcpv6_universe, 74, 1 },
556 #endif
557
558 /* RFC6939 OPTIONS */
559 #if defined(RFC6939_OPTIONS)
560 { "client-linklayer-addr", "X", &dhcpv6_universe, 79, 1 },
561 #endif
562
563 /* RFC6977 OPTIONS */
564 #if defined(RFC6977_OPTIONS)
565 { "link-address", "6", &dhcpv6_universe, 80, 1 },
566 #endif
567
568 /* RFC7083 OPTIONS */
569 #if defined(RFC7083_OPTIONS)
570 { "solmax-rt", "L", &dhcpv6_universe, 82, 1 },
571 { "inf-max-rt", "L", &dhcpv6_universe, 83, 1 },
572 #endif
573
574 /* RFC7341 OPTIONS */
575 #if defined(RFC7341_OPTIONS)
576 { "dhcpv4-msg", "X", &dhcpv6_universe, 87, 1 },
577 { "dhcp4-o-dhcp6-server", "6A", &dhcpv6_universe, 88, 1 },
578 #endif
579
580 #if defined(RFC7710_OPTIONS)
581 { "v6-captive-portal", "t", &dhcpv6_universe, 103, 1 },
582 #endif
583
584 { "relay-source-port", "S", &dhcpv6_universe, 135, 1 },
585
586 #if defined(RFC6153_OPTIONS)
587 { "ipv6-address-andsf", "6A", &dhcpv6_universe, 143, 1 },
588 #endif
589
590 { NULL, NULL, NULL, 0, 0 }
591 };
592
593 struct enumeration_value dhcpv6_duid_type_values[] = {
594 { "duid-llt", DUID_LLT }, /* Link-Local Plus Time */
595 { "duid-en", DUID_EN }, /* DUID based upon enterprise-ID. */
596 { "duid-ll", DUID_LL }, /* DUID from Link Local address only. */
597 { "duid-uuid", DUID_UUID }, /* DUID based upon UUID */
598 { NULL, 0 }
599 };
600
601 struct enumeration dhcpv6_duid_types = {
602 NULL,
603 "duid-types", 2,
604 dhcpv6_duid_type_values
605 };
606
607 struct enumeration_value dhcpv6_status_code_values[] = {
608 { "success", 0 }, /* Success */
609 { "UnspecFail", 1 }, /* Failure, for unspecified reasons. */
610 { "NoAddrsAvail", 2 }, /* Server has no addresses to assign. */
611 { "NoBinding", 3 }, /* Client record (binding) unavailable. */
612 { "NotOnLink", 4 }, /* Bad prefix for the link. */
613 { "UseMulticast", 5 }, /* Not just good advice. It's the law. */
614 { "NoPrefixAvail", 6 }, /* Server has no prefixes to assign. */
615 { "UnknownQueryType", 7 }, /* Query-type unknown/unsupported. */
616 { "MalformedQuery", 8 }, /* Leasequery not valid. */
617 { "NotConfigured", 9 }, /* The target address is not in config. */
618 { "NotAllowed", 10 }, /* Server doesn't allow the leasequery. */
619 { "QueryTerminated", 11 }, /* Leasequery terminated. */
620 { NULL, 0 }
621 };
622
623 struct enumeration dhcpv6_status_codes = {
624 NULL,
625 "status-codes", 2,
626 dhcpv6_status_code_values
627 };
628
629 struct enumeration_value lq6_query_type_values[] = {
630 { "query-by-address", 1 },
631 { "query-by-clientid", 2 },
632 { "query-by-relay-id", 3 },
633 { "query-by-link-address", 4 },
634 { "query-by-remote-id", 5 },
635 { NULL, 0 }
636 };
637
638 struct enumeration lq6_query_types = {
639 NULL,
640 "query-types", 2,
641 lq6_query_type_values
642 };
643
644 struct enumeration_value dhcpv6_message_values[] = {
645 { "SOLICIT", 1 },
646 { "ADVERTISE", 2 },
647 { "REQUEST", 3 },
648 { "CONFIRM", 4 },
649 { "RENEW", 5 },
650 { "REBIND", 6 },
651 { "REPLY", 7 },
652 { "RELEASE", 8 },
653 { "DECLINE", 9 },
654 { "RECONFIGURE", 10 },
655 { "INFORMATION-REQUEST", 11 },
656 { "RELAY-FORW", 12 },
657 { "RELAY-REPL", 13 },
658 { "LEASEQUERY", 14 },
659 { "LEASEQUERY-REPLY", 15 },
660 { "LEASEQUERY-DONE", 16 },
661 { "LEASEQUERY-DATA", 17 },
662 { "RECONFIGURE-REQUEST", 18 },
663 { "RECONFIGURE-REPLY", 19 },
664 { "DHCPV4-QUERY", 20 },
665 { "DHCPV4-RESPONSE", 21 },
666 { NULL, 0 }
667 };
668
669 /* Some code refers to a different table. */
670 const char *dhcpv6_type_names[] = {
671 NULL,
672 "Solicit",
673 "Advertise",
674 "Request",
675 "Confirm",
676 "Renew",
677 "Rebind",
678 "Reply",
679 "Release",
680 "Decline",
681 "Reconfigure",
682 "Information-request",
683 "Relay-forward",
684 "Relay-reply",
685 "Leasequery",
686 "Leasequery-reply",
687 "Leasequery-done",
688 "Leasequery-data",
689 "Reconfigure-request",
690 "Reconfigure-reply",
691 "Dhcpv4-query",
692 "Dhcpv4-response"
693 };
694 const int dhcpv6_type_name_max =
695 (sizeof(dhcpv6_type_names) / sizeof(dhcpv6_type_names[0]));
696
697 struct enumeration dhcpv6_messages = {
698 NULL,
699 "dhcpv6-messages", 1,
700 dhcpv6_message_values
701 };
702
703 struct universe vsio_universe;
704 static struct option vsio_options[] = {
705 { "isc", "Eisc6.", &vsio_universe, 2495, 1 },
706 { NULL, NULL, NULL, 0, 0 }
707 };
708
709 struct universe isc6_universe;
710 static struct option isc6_options[] = {
711 { "media", "t", &isc6_universe, 1, 1 },
712 { "update-assist", "X", &isc6_universe, 2, 1 },
713 { "4o6-interface", "t", &isc6_universe, 60000, 1 },
714 { "4o6-source-address", "6", &isc6_universe, 60001, 1 },
715 { NULL, NULL, NULL, 0, 0 }
716 };
717
718 const char *hardware_types [] = {
719 "unknown-0",
720 "ethernet",
721 "unknown-2",
722 "unknown-3",
723 "unknown-4",
724 "unknown-5",
725 "token-ring",
726 "unknown-7",
727 "fddi",
728 "unknown-9",
729 "unknown-10",
730 "unknown-11",
731 "unknown-12",
732 "unknown-13",
733 "unknown-14",
734 "unknown-15",
735 "unknown-16",
736 "unknown-17",
737 "unknown-18",
738 "unknown-19",
739 "unknown-20",
740 "unknown-21",
741 "unknown-22",
742 "unknown-23",
743 "unknown-24",
744 "unknown-25",
745 "unknown-26",
746 "unknown-27",
747 "unknown-28",
748 "unknown-29",
749 "unknown-30",
750 "unknown-31",
751 "infiniband",
752 "unknown-33",
753 "unknown-34",
754 "unknown-35",
755 "unknown-36",
756 "unknown-37",
757 "unknown-38",
758 "unknown-39",
759 "unknown-40",
760 "unknown-41",
761 "unknown-42",
762 "unknown-43",
763 "unknown-44",
764 "unknown-45",
765 "unknown-46",
766 "unknown-47",
767 "unknown-48",
768 "unknown-49",
769 "unknown-50",
770 "unknown-51",
771 "unknown-52",
772 "unknown-53",
773 "unknown-54",
774 "unknown-55",
775 "unknown-56",
776 "unknown-57",
777 "unknown-58",
778 "unknown-59",
779 "unknown-60",
780 "unknown-61",
781 "unknown-62",
782 "unknown-63",
783 "unknown-64",
784 "unknown-65",
785 "unknown-66",
786 "unknown-67",
787 "unknown-68",
788 "unknown-69",
789 "unknown-70",
790 "unknown-71",
791 "unknown-72",
792 "unknown-73",
793 "unknown-74",
794 "unknown-75",
795 "unknown-76",
796 "unknown-77",
797 "unknown-78",
798 "unknown-79",
799 "unknown-80",
800 "unknown-81",
801 "unknown-82",
802 "unknown-83",
803 "unknown-84",
804 "unknown-85",
805 "unknown-86",
806 "unknown-87",
807 "unknown-88",
808 "unknown-89",
809 "unknown-90",
810 "unknown-91",
811 "unknown-92",
812 "unknown-93",
813 "unknown-94",
814 "unknown-95",
815 "unknown-96",
816 "unknown-97",
817 "unknown-98",
818 "unknown-99",
819 "unknown-100",
820 "unknown-101",
821 "unknown-102",
822 "unknown-103",
823 "unknown-104",
824 "unknown-105",
825 "unknown-106",
826 "unknown-107",
827 "unknown-108",
828 "unknown-109",
829 "unknown-110",
830 "unknown-111",
831 "unknown-112",
832 "unknown-113",
833 "unknown-114",
834 "unknown-115",
835 "unknown-116",
836 "unknown-117",
837 "unknown-118",
838 "unknown-119",
839 "unknown-120",
840 "unknown-121",
841 "unknown-122",
842 "unknown-123",
843 "unknown-124",
844 "unknown-125",
845 "unknown-126",
846 "unknown-127",
847 "unknown-128",
848 "unknown-129",
849 "unknown-130",
850 "unknown-131",
851 "unknown-132",
852 "unknown-133",
853 "unknown-134",
854 "unknown-135",
855 "unknown-136",
856 "unknown-137",
857 "unknown-138",
858 "unknown-139",
859 "unknown-140",
860 "unknown-141",
861 "unknown-142",
862 "unknown-143",
863 "unknown-144",
864 "unknown-145",
865 "unknown-146",
866 "unknown-147",
867 "unknown-148",
868 "unknown-149",
869 "unknown-150",
870 "unknown-151",
871 "unknown-152",
872 "unknown-153",
873 "unknown-154",
874 "unknown-155",
875 "unknown-156",
876 "unknown-157",
877 "unknown-158",
878 "unknown-159",
879 "unknown-160",
880 "unknown-161",
881 "unknown-162",
882 "unknown-163",
883 "unknown-164",
884 "unknown-165",
885 "unknown-166",
886 "unknown-167",
887 "unknown-168",
888 "unknown-169",
889 "unknown-170",
890 "unknown-171",
891 "unknown-172",
892 "unknown-173",
893 "unknown-174",
894 "unknown-175",
895 "unknown-176",
896 "unknown-177",
897 "unknown-178",
898 "unknown-179",
899 "unknown-180",
900 "unknown-181",
901 "unknown-182",
902 "unknown-183",
903 "unknown-184",
904 "unknown-185",
905 "unknown-186",
906 "unknown-187",
907 "unknown-188",
908 "unknown-189",
909 "unknown-190",
910 "unknown-191",
911 "unknown-192",
912 "unknown-193",
913 "unknown-194",
914 "unknown-195",
915 "unknown-196",
916 "unknown-197",
917 "unknown-198",
918 "unknown-199",
919 "unknown-200",
920 "unknown-201",
921 "unknown-202",
922 "unknown-203",
923 "unknown-204",
924 "unknown-205",
925 "unknown-206",
926 "unknown-207",
927 "unknown-208",
928 "unknown-209",
929 "unknown-210",
930 "unknown-211",
931 "unknown-212",
932 "unknown-213",
933 "unknown-214",
934 "unknown-215",
935 "unknown-216",
936 "unknown-217",
937 "unknown-218",
938 "unknown-219",
939 "unknown-220",
940 "unknown-221",
941 "unknown-222",
942 "unknown-223",
943 "unknown-224",
944 "unknown-225",
945 "unknown-226",
946 "unknown-227",
947 "unknown-228",
948 "unknown-229",
949 "unknown-230",
950 "unknown-231",
951 "unknown-232",
952 "unknown-233",
953 "unknown-234",
954 "unknown-235",
955 "unknown-236",
956 "unknown-237",
957 "unknown-238",
958 "unknown-239",
959 "unknown-240",
960 "unknown-241",
961 "unknown-242",
962 "unknown-243",
963 "unknown-244",
964 "unknown-245",
965 "unknown-246",
966 "unknown-247",
967 "unknown-248",
968 "unknown-249",
969 "unknown-250",
970 "unknown-251",
971 "unknown-252",
972 "unknown-253",
973 "unknown-254",
974 "unknown-255" };
975
976 universe_hash_t *universe_hash;
977 struct universe **universes;
978 int universe_count, universe_max;
979
980 /* Universe containing names of configuration options, which, rather than
981 writing "option universe-name.option-name ...;", can be set by writing
982 "option-name ...;". */
983
984 struct universe *config_universe;
985
986 /* XXX: omapi must die...all the below keeps us from having to make the
987 * option structures omapi typed objects, which is a bigger headache.
988 */
989
990 char *default_option_format = (char *) "X";
991
992 /* Must match hash_reference/dereference types in omapip/hash.h. */
993 int
option_reference(struct option ** dest,struct option * src,const char * file,int line)994 option_reference(struct option **dest, struct option *src,
995 const char * file, int line)
996 {
997 if (!dest || !src)
998 return DHCP_R_INVALIDARG;
999
1000 if (*dest) {
1001 #if defined(POINTER_DEBUG)
1002 log_fatal("%s(%d): reference store into non-null pointer!",
1003 file, line);
1004 #else
1005 return DHCP_R_INVALIDARG;
1006 #endif
1007 }
1008
1009 *dest = src;
1010 src->refcnt++;
1011 rc_register(file, line, dest, src, src->refcnt, 0, RC_MISC);
1012 return(ISC_R_SUCCESS);
1013 }
1014
1015 int
option_dereference(struct option ** dest,const char * file,int line)1016 option_dereference(struct option **dest, const char *file, int line)
1017 {
1018 if (!dest)
1019 return DHCP_R_INVALIDARG;
1020
1021 if (!*dest) {
1022 #if defined (POINTER_DEBUG)
1023 log_fatal("%s(%d): dereference of null pointer!", file, line);
1024 #else
1025 return DHCP_R_INVALIDARG;
1026 #endif
1027 }
1028
1029 if ((*dest)->refcnt <= 0) {
1030 #if defined (POINTER_DEBUG)
1031 log_fatal("%s(%d): dereference of <= 0 refcnt!", file, line);
1032 #else
1033 return DHCP_R_INVALIDARG;
1034 #endif
1035 }
1036
1037 (*dest)->refcnt--;
1038
1039 rc_register(file, line, dest, (*dest), (*dest)->refcnt, 1, RC_MISC);
1040
1041 if ((*dest)->refcnt == 0) {
1042 /* The option name may be packed in the same alloc as the
1043 * option structure.
1044 */
1045 if ((char *) (*dest)->name != (char *) ((*dest) + 1))
1046 dfree((char *) (*dest)->name, file, line);
1047
1048 /* It's either a user-configured format (allocated), or the
1049 * default static format.
1050 */
1051 if (((*dest)->format != NULL) &&
1052 ((*dest)->format != default_option_format)) {
1053 dfree((char *) (*dest)->format, file, line);
1054 }
1055
1056 dfree(*dest, file, line);
1057 }
1058
1059 *dest = NULL;
1060 return ISC_R_SUCCESS;
1061 }
1062
initialize_common_option_spaces()1063 void initialize_common_option_spaces()
1064 {
1065 unsigned code;
1066 int i;
1067
1068 /* The 'universes' table is dynamically grown to contain
1069 * universe as they're configured - except during startup.
1070 * Since we know how many we put down in .c files, we can
1071 * allocate a more-than-right-sized buffer now, leaving some
1072 * space for user-configured option spaces.
1073 *
1074 * 1: dhcp_universe (dhcpv4 options)
1075 * 2: nwip_universe (dhcpv4 NWIP option)
1076 * 3: fqdn_universe (dhcpv4 fqdn option - reusable for v6)
1077 * 4: vendor_class_universe (VIVCO)
1078 * 5: vendor_universe (VIVSO)
1079 * 6: isc_universe (dhcpv4 isc config space)
1080 * 7: dhcpv6_universe (dhcpv6 options)
1081 * 8: vsio_universe (DHCPv6 Vendor-Identified space)
1082 * 9: isc6_universe (ISC's Vendor universe in DHCPv6 VSIO)
1083 * 10: fqdn6_universe (dhcpv6 fqdn option shill to v4)
1084 * 11: agent_universe (dhcpv4 relay agent - see server/stables.c)
1085 * 12: server_universe (server's config, see server/stables.c)
1086 * 13: user-config
1087 * 14: more user-config
1088 * 15: more user-config
1089 * 16: more user-config
1090 */
1091 universe_max = 16;
1092 i = universe_max * sizeof(struct universe *);
1093 if (i <= 0)
1094 log_fatal("Ludicrous initial size option space table.");
1095 universes = dmalloc(i, MDL);
1096 if (universes == NULL)
1097 log_fatal("Can't allocate option space table.");
1098 memset(universes, 0, i);
1099
1100 /* Set up the DHCP option universe... */
1101 dhcp_universe.name = "dhcp";
1102 dhcp_universe.concat_duplicates = 1;
1103 dhcp_universe.lookup_func = lookup_hashed_option;
1104 dhcp_universe.option_state_dereference =
1105 hashed_option_state_dereference;
1106 dhcp_universe.save_func = save_hashed_option;
1107 dhcp_universe.delete_func = delete_hashed_option;
1108 dhcp_universe.encapsulate = hashed_option_space_encapsulate;
1109 dhcp_universe.foreach = hashed_option_space_foreach;
1110 dhcp_universe.decode = parse_option_buffer;
1111 dhcp_universe.length_size = 1;
1112 dhcp_universe.tag_size = 1;
1113 dhcp_universe.get_tag = getUChar;
1114 dhcp_universe.store_tag = putUChar;
1115 dhcp_universe.get_length = getUChar;
1116 dhcp_universe.store_length = putUChar;
1117 dhcp_universe.site_code_min = 0;
1118 dhcp_universe.end = DHO_END;
1119 dhcp_universe.index = universe_count++;
1120 universes [dhcp_universe.index] = &dhcp_universe;
1121 if (!option_name_new_hash(&dhcp_universe.name_hash,
1122 BYTE_NAME_HASH_SIZE, MDL) ||
1123 !option_code_new_hash(&dhcp_universe.code_hash,
1124 BYTE_CODE_HASH_SIZE, MDL))
1125 log_fatal ("Can't allocate dhcp option hash table.");
1126 for (i = 0 ; dhcp_options[i].name ; i++) {
1127 option_code_hash_add(dhcp_universe.code_hash,
1128 &dhcp_options[i].code, 0,
1129 &dhcp_options[i], MDL);
1130 option_name_hash_add(dhcp_universe.name_hash,
1131 dhcp_options [i].name, 0,
1132 &dhcp_options [i], MDL);
1133 }
1134 #if defined(REPORT_HASH_PERFORMANCE)
1135 log_info("DHCP name hash: %s",
1136 option_name_hash_report(dhcp_universe.name_hash));
1137 log_info("DHCP code hash: %s",
1138 option_code_hash_report(dhcp_universe.code_hash));
1139 #endif
1140
1141 /* Set up the Novell option universe (for option 63)... */
1142 nwip_universe.name = "nwip";
1143 nwip_universe.concat_duplicates = 0; /* XXX: reference? */
1144 nwip_universe.lookup_func = lookup_linked_option;
1145 nwip_universe.option_state_dereference =
1146 linked_option_state_dereference;
1147 nwip_universe.save_func = save_linked_option;
1148 nwip_universe.delete_func = delete_linked_option;
1149 nwip_universe.encapsulate = nwip_option_space_encapsulate;
1150 nwip_universe.foreach = linked_option_space_foreach;
1151 nwip_universe.decode = parse_option_buffer;
1152 nwip_universe.length_size = 1;
1153 nwip_universe.tag_size = 1;
1154 nwip_universe.get_tag = getUChar;
1155 nwip_universe.store_tag = putUChar;
1156 nwip_universe.get_length = getUChar;
1157 nwip_universe.store_length = putUChar;
1158 nwip_universe.site_code_min = 0;
1159 nwip_universe.end = 0;
1160 code = DHO_NWIP_SUBOPTIONS;
1161 nwip_universe.enc_opt = NULL;
1162 if (!option_code_hash_lookup(&nwip_universe.enc_opt,
1163 dhcp_universe.code_hash, &code, 0, MDL))
1164 log_fatal("Unable to find NWIP parent option (%s:%d).", MDL);
1165 nwip_universe.index = universe_count++;
1166 universes [nwip_universe.index] = &nwip_universe;
1167 if (!option_name_new_hash(&nwip_universe.name_hash,
1168 NWIP_HASH_SIZE, MDL) ||
1169 !option_code_new_hash(&nwip_universe.code_hash,
1170 NWIP_HASH_SIZE, MDL))
1171 log_fatal ("Can't allocate nwip option hash table.");
1172 for (i = 0 ; nwip_options[i].name ; i++) {
1173 option_code_hash_add(nwip_universe.code_hash,
1174 &nwip_options[i].code, 0,
1175 &nwip_options[i], MDL);
1176 option_name_hash_add(nwip_universe.name_hash,
1177 nwip_options[i].name, 0,
1178 &nwip_options[i], MDL);
1179 }
1180 #if defined(REPORT_HASH_PERFORMANCE)
1181 log_info("NWIP name hash: %s",
1182 option_name_hash_report(nwip_universe.name_hash));
1183 log_info("NWIP code hash: %s",
1184 option_code_hash_report(nwip_universe.code_hash));
1185 #endif
1186
1187 /* Set up the FQDN option universe... */
1188 fqdn_universe.name = "fqdn";
1189 fqdn_universe.concat_duplicates = 0;
1190 fqdn_universe.lookup_func = lookup_linked_option;
1191 fqdn_universe.option_state_dereference =
1192 linked_option_state_dereference;
1193 fqdn_universe.save_func = save_linked_option;
1194 fqdn_universe.delete_func = delete_linked_option;
1195 fqdn_universe.encapsulate = fqdn_option_space_encapsulate;
1196 fqdn_universe.foreach = linked_option_space_foreach;
1197 fqdn_universe.decode = fqdn_universe_decode;
1198 fqdn_universe.length_size = 1;
1199 fqdn_universe.tag_size = 1;
1200 fqdn_universe.get_tag = getUChar;
1201 fqdn_universe.store_tag = putUChar;
1202 fqdn_universe.get_length = getUChar;
1203 fqdn_universe.store_length = putUChar;
1204 fqdn_universe.site_code_min = 0;
1205 fqdn_universe.end = 0;
1206 fqdn_universe.index = universe_count++;
1207 code = DHO_FQDN;
1208 fqdn_universe.enc_opt = NULL;
1209 if (!option_code_hash_lookup(&fqdn_universe.enc_opt,
1210 dhcp_universe.code_hash, &code, 0, MDL))
1211 log_fatal("Unable to find FQDN parent option (%s:%d).", MDL);
1212 universes [fqdn_universe.index] = &fqdn_universe;
1213 if (!option_name_new_hash(&fqdn_universe.name_hash,
1214 FQDN_HASH_SIZE, MDL) ||
1215 !option_code_new_hash(&fqdn_universe.code_hash,
1216 FQDN_HASH_SIZE, MDL))
1217 log_fatal ("Can't allocate fqdn option hash table.");
1218 for (i = 0 ; fqdn_options[i].name ; i++) {
1219 option_code_hash_add(fqdn_universe.code_hash,
1220 &fqdn_options[i].code, 0,
1221 &fqdn_options[i], MDL);
1222 option_name_hash_add(fqdn_universe.name_hash,
1223 fqdn_options[i].name, 0,
1224 &fqdn_options[i], MDL);
1225 }
1226 #if defined(REPORT_HASH_PERFORMANCE)
1227 log_info("FQDN name hash: %s",
1228 option_name_hash_report(fqdn_universe.name_hash));
1229 log_info("FQDN code hash: %s",
1230 option_code_hash_report(fqdn_universe.code_hash));
1231 #endif
1232
1233 /* Set up the Vendor Identified Vendor Class options (for option
1234 * 125)...
1235 */
1236 vendor_class_universe.name = "vendor-class";
1237 vendor_class_universe.concat_duplicates = 0; /* XXX: reference? */
1238 vendor_class_universe.lookup_func = lookup_hashed_option;
1239 vendor_class_universe.option_state_dereference =
1240 hashed_option_state_dereference;
1241 vendor_class_universe.save_func = save_hashed_option;
1242 vendor_class_universe.delete_func = delete_hashed_option;
1243 vendor_class_universe.encapsulate = hashed_option_space_encapsulate;
1244 vendor_class_universe.foreach = hashed_option_space_foreach;
1245 vendor_class_universe.decode = parse_option_buffer;
1246 vendor_class_universe.length_size = 1;
1247 vendor_class_universe.tag_size = 4;
1248 vendor_class_universe.get_tag = getULong;
1249 vendor_class_universe.store_tag = putULong;
1250 vendor_class_universe.get_length = getUChar;
1251 vendor_class_universe.store_length = putUChar;
1252 vendor_class_universe.site_code_min = 0;
1253 vendor_class_universe.end = 0;
1254 code = DHO_VIVCO_SUBOPTIONS;
1255 vendor_class_universe.enc_opt = NULL;
1256 if (!option_code_hash_lookup(&vendor_class_universe.enc_opt,
1257 dhcp_universe.code_hash, &code, 0, MDL))
1258 log_fatal("Unable to find VIVCO parent option (%s:%d).", MDL);
1259 vendor_class_universe.index = universe_count++;
1260 universes[vendor_class_universe.index] = &vendor_class_universe;
1261 if (!option_name_new_hash(&vendor_class_universe.name_hash,
1262 VIVCO_HASH_SIZE, MDL) ||
1263 !option_code_new_hash(&vendor_class_universe.code_hash,
1264 VIVCO_HASH_SIZE, MDL))
1265 log_fatal("Can't allocate Vendor Identified Vendor Class "
1266 "option hash table.");
1267 for (i = 0 ; vendor_class_options[i].name ; i++) {
1268 option_code_hash_add(vendor_class_universe.code_hash,
1269 &vendor_class_options[i].code, 0,
1270 &vendor_class_options[i], MDL);
1271 option_name_hash_add(vendor_class_universe.name_hash,
1272 vendor_class_options[i].name, 0,
1273 &vendor_class_options[i], MDL);
1274 }
1275 #if defined(REPORT_HASH_PERFORMANCE)
1276 log_info("VIVCO name hash: %s",
1277 option_name_hash_report(vendor_class_universe.name_hash));
1278 log_info("VIVCO code hash: %s",
1279 option_code_hash_report(vendor_class_universe.code_hash));
1280 #endif
1281
1282 /* Set up the Vendor Identified Vendor Sub-options (option 126)... */
1283 vendor_universe.name = "vendor";
1284 vendor_universe.concat_duplicates = 0; /* XXX: reference? */
1285 vendor_universe.lookup_func = lookup_hashed_option;
1286 vendor_universe.option_state_dereference =
1287 hashed_option_state_dereference;
1288 vendor_universe.save_func = save_hashed_option;
1289 vendor_universe.delete_func = delete_hashed_option;
1290 vendor_universe.encapsulate = hashed_option_space_encapsulate;
1291 vendor_universe.foreach = hashed_option_space_foreach;
1292 vendor_universe.decode = parse_option_buffer;
1293 vendor_universe.length_size = 1;
1294 vendor_universe.tag_size = 4;
1295 vendor_universe.get_tag = getULong;
1296 vendor_universe.store_tag = putULong;
1297 vendor_universe.get_length = getUChar;
1298 vendor_universe.store_length = putUChar;
1299 vendor_universe.site_code_min = 0;
1300 vendor_universe.end = 0;
1301 code = DHO_VIVSO_SUBOPTIONS;
1302 vendor_universe.enc_opt = NULL;
1303 if (!option_code_hash_lookup(&vendor_universe.enc_opt,
1304 dhcp_universe.code_hash, &code, 0, MDL))
1305 log_fatal("Unable to find VIVSO parent option (%s:%d).", MDL);
1306 vendor_universe.index = universe_count++;
1307 universes[vendor_universe.index] = &vendor_universe;
1308 if (!option_name_new_hash(&vendor_universe.name_hash,
1309 VIVSO_HASH_SIZE, MDL) ||
1310 !option_code_new_hash(&vendor_universe.code_hash,
1311 VIVSO_HASH_SIZE, MDL))
1312 log_fatal("Can't allocate Vendor Identified Vendor Sub-"
1313 "options hash table.");
1314 for (i = 0 ; vendor_options[i].name ; i++) {
1315 option_code_hash_add(vendor_universe.code_hash,
1316 &vendor_options[i].code, 0,
1317 &vendor_options[i], MDL);
1318 option_name_hash_add(vendor_universe.name_hash,
1319 vendor_options[i].name, 0,
1320 &vendor_options[i], MDL);
1321 }
1322 #if defined(REPORT_HASH_PERFORMANCE)
1323 log_info("VIVSO name hash: %s",
1324 option_name_hash_report(vendor_universe.name_hash));
1325 log_info("VIVSO code hash: %s",
1326 option_code_hash_report(vendor_universe.code_hash));
1327 #endif
1328
1329 /* Set up the ISC Vendor-option universe (for option 125.2495)... */
1330 isc_universe.name = "isc";
1331 isc_universe.concat_duplicates = 0; /* XXX: check VIVSO ref */
1332 isc_universe.lookup_func = lookup_linked_option;
1333 isc_universe.option_state_dereference =
1334 linked_option_state_dereference;
1335 isc_universe.save_func = save_linked_option;
1336 isc_universe.delete_func = delete_linked_option;
1337 isc_universe.encapsulate = linked_option_space_encapsulate;
1338 isc_universe.foreach = linked_option_space_foreach;
1339 isc_universe.decode = parse_option_buffer;
1340 isc_universe.length_size = 2;
1341 isc_universe.tag_size = 2;
1342 isc_universe.get_tag = getUShort;
1343 isc_universe.store_tag = putUShort;
1344 isc_universe.get_length = getUShort;
1345 isc_universe.store_length = putUShort;
1346 isc_universe.site_code_min = 0;
1347 isc_universe.end = 0;
1348 code = VENDOR_ISC_SUBOPTIONS;
1349 isc_universe.enc_opt = NULL;
1350 if (!option_code_hash_lookup(&isc_universe.enc_opt,
1351 vendor_universe.code_hash, &code, 0, MDL))
1352 log_fatal("Unable to find ISC parent option (%s:%d).", MDL);
1353 isc_universe.index = universe_count++;
1354 universes[isc_universe.index] = &isc_universe;
1355 if (!option_name_new_hash(&isc_universe.name_hash,
1356 VIV_ISC_HASH_SIZE, MDL) ||
1357 !option_code_new_hash(&isc_universe.code_hash,
1358 VIV_ISC_HASH_SIZE, MDL))
1359 log_fatal("Can't allocate ISC Vendor options hash table.");
1360 for (i = 0 ; isc_options[i].name ; i++) {
1361 option_code_hash_add(isc_universe.code_hash,
1362 &isc_options[i].code, 0,
1363 &isc_options[i], MDL);
1364 option_name_hash_add(isc_universe.name_hash,
1365 isc_options[i].name, 0,
1366 &isc_options[i], MDL);
1367 }
1368 #if defined(REPORT_HASH_PERFORMANCE)
1369 log_info("ISC name hash: %s",
1370 option_name_hash_report(isc_universe.name_hash));
1371 log_info("ISC code hash: %s",
1372 option_code_hash_report(isc_universe.code_hash));
1373 #endif
1374
1375 /* Set up the DHCPv6 root universe. */
1376 dhcpv6_universe.name = "dhcp6";
1377 dhcpv6_universe.concat_duplicates = 0;
1378 dhcpv6_universe.lookup_func = lookup_hashed_option;
1379 dhcpv6_universe.option_state_dereference =
1380 hashed_option_state_dereference;
1381 dhcpv6_universe.save_func = save_hashed_option;
1382 dhcpv6_universe.delete_func = delete_hashed_option;
1383 dhcpv6_universe.encapsulate = hashed_option_space_encapsulate;
1384 dhcpv6_universe.foreach = hashed_option_space_foreach;
1385 dhcpv6_universe.decode = parse_option_buffer;
1386 dhcpv6_universe.length_size = 2;
1387 dhcpv6_universe.tag_size = 2;
1388 dhcpv6_universe.get_tag = getUShort;
1389 dhcpv6_universe.store_tag = putUShort;
1390 dhcpv6_universe.get_length = getUShort;
1391 dhcpv6_universe.store_length = putUShort;
1392 dhcpv6_universe.site_code_min = 0;
1393 /* DHCPv6 has no END option. */
1394 dhcpv6_universe.end = 0x00;
1395 dhcpv6_universe.index = universe_count++;
1396 universes[dhcpv6_universe.index] = &dhcpv6_universe;
1397 if (!option_name_new_hash(&dhcpv6_universe.name_hash,
1398 WORD_NAME_HASH_SIZE, MDL) ||
1399 !option_code_new_hash(&dhcpv6_universe.code_hash,
1400 WORD_CODE_HASH_SIZE, MDL))
1401 log_fatal("Can't allocate dhcpv6 option hash tables.");
1402 for (i = 0 ; dhcpv6_options[i].name ; i++) {
1403 option_code_hash_add(dhcpv6_universe.code_hash,
1404 &dhcpv6_options[i].code, 0,
1405 &dhcpv6_options[i], MDL);
1406 option_name_hash_add(dhcpv6_universe.name_hash,
1407 dhcpv6_options[i].name, 0,
1408 &dhcpv6_options[i], MDL);
1409 }
1410
1411 /* Add DHCPv6 protocol enumeration sets. */
1412 add_enumeration(&dhcpv6_duid_types);
1413 add_enumeration(&dhcpv6_status_codes);
1414 add_enumeration(&dhcpv6_messages);
1415
1416 /* Set up DHCPv6 VSIO universe. */
1417 vsio_universe.name = "vsio";
1418 vsio_universe.concat_duplicates = 0;
1419 vsio_universe.lookup_func = lookup_hashed_option;
1420 vsio_universe.option_state_dereference =
1421 hashed_option_state_dereference;
1422 vsio_universe.save_func = save_hashed_option;
1423 vsio_universe.delete_func = delete_hashed_option;
1424 vsio_universe.encapsulate = hashed_option_space_encapsulate;
1425 vsio_universe.foreach = hashed_option_space_foreach;
1426 vsio_universe.decode = parse_option_buffer;
1427 vsio_universe.length_size = 0;
1428 vsio_universe.tag_size = 4;
1429 vsio_universe.get_tag = getULong;
1430 vsio_universe.store_tag = putULong;
1431 vsio_universe.get_length = NULL;
1432 vsio_universe.store_length = NULL;
1433 vsio_universe.site_code_min = 0;
1434 /* No END option. */
1435 vsio_universe.end = 0x00;
1436 code = D6O_VENDOR_OPTS;
1437 if (!option_code_hash_lookup(&vsio_universe.enc_opt,
1438 dhcpv6_universe.code_hash, &code, 0, MDL))
1439 log_fatal("Unable to find VSIO parent option (%s:%d).", MDL);
1440 vsio_universe.index = universe_count++;
1441 universes[vsio_universe.index] = &vsio_universe;
1442 if (!option_name_new_hash(&vsio_universe.name_hash,
1443 VSIO_HASH_SIZE, MDL) ||
1444 !option_code_new_hash(&vsio_universe.code_hash,
1445 VSIO_HASH_SIZE, MDL))
1446 log_fatal("Can't allocate Vendor Specific Information "
1447 "Options space.");
1448 for (i = 0 ; vsio_options[i].name != NULL ; i++) {
1449 option_code_hash_add(vsio_universe.code_hash,
1450 &vsio_options[i].code, 0,
1451 &vsio_options[i], MDL);
1452 option_name_hash_add(vsio_universe.name_hash,
1453 vsio_options[i].name, 0,
1454 &vsio_options[i], MDL);
1455 }
1456
1457 /* Add ISC VSIO sub-sub-option space. */
1458 isc6_universe.name = "isc6";
1459 isc6_universe.concat_duplicates = 0;
1460 isc6_universe.lookup_func = lookup_hashed_option;
1461 isc6_universe.option_state_dereference =
1462 hashed_option_state_dereference;
1463 isc6_universe.save_func = save_hashed_option;
1464 isc6_universe.delete_func = delete_hashed_option;
1465 isc6_universe.encapsulate = hashed_option_space_encapsulate;
1466 isc6_universe.foreach = hashed_option_space_foreach;
1467 isc6_universe.decode = parse_option_buffer;
1468 isc6_universe.length_size = 0;
1469 isc6_universe.tag_size = 4;
1470 isc6_universe.get_tag = getULong;
1471 isc6_universe.store_tag = putULong;
1472 isc6_universe.get_length = NULL;
1473 isc6_universe.store_length = NULL;
1474 isc6_universe.site_code_min = 0;
1475 /* No END option. */
1476 isc6_universe.end = 0x00;
1477 code = 2495;
1478 if (!option_code_hash_lookup(&isc6_universe.enc_opt,
1479 vsio_universe.code_hash, &code, 0, MDL))
1480 log_fatal("Unable to find ISC parent option (%s:%d).", MDL);
1481 isc6_universe.index = universe_count++;
1482 universes[isc6_universe.index] = &isc6_universe;
1483 if (!option_name_new_hash(&isc6_universe.name_hash,
1484 VIV_ISC_HASH_SIZE, MDL) ||
1485 !option_code_new_hash(&isc6_universe.code_hash,
1486 VIV_ISC_HASH_SIZE, MDL))
1487 log_fatal("Can't allocate Vendor Specific Information "
1488 "Options space.");
1489 for (i = 0 ; isc6_options[i].name != NULL ; i++) {
1490 option_code_hash_add(isc6_universe.code_hash,
1491 &isc6_options[i].code, 0,
1492 &isc6_options[i], MDL);
1493 option_name_hash_add(isc6_universe.name_hash,
1494 isc6_options[i].name, 0,
1495 &isc6_options[i], MDL);
1496 }
1497
1498 /* The fqdn6 option space is a protocol-wrapper shill for the
1499 * old DHCPv4 space.
1500 */
1501 fqdn6_universe.name = "fqdn6-if-you-see-me-its-a-bug-bug-bug";
1502 fqdn6_universe.lookup_func = lookup_fqdn6_option;
1503 fqdn6_universe.option_state_dereference = NULL; /* Covered by v4. */
1504 fqdn6_universe.save_func = save_fqdn6_option;
1505 fqdn6_universe.delete_func = delete_fqdn6_option;
1506 fqdn6_universe.encapsulate = fqdn6_option_space_encapsulate;
1507 fqdn6_universe.foreach = fqdn6_option_space_foreach;
1508 fqdn6_universe.decode = fqdn6_universe_decode;
1509 /* This is not a 'normal' encapsulated space, so these values are
1510 * meaningless.
1511 */
1512 fqdn6_universe.length_size = 0;
1513 fqdn6_universe.tag_size = 0;
1514 fqdn6_universe.get_tag = NULL;
1515 fqdn6_universe.store_tag = NULL;
1516 fqdn6_universe.get_length = NULL;
1517 fqdn6_universe.store_length = NULL;
1518 fqdn6_universe.site_code_min = 0;
1519 fqdn6_universe.end = 0;
1520 fqdn6_universe.index = universe_count++;
1521 code = D6O_CLIENT_FQDN;
1522 fqdn6_universe.enc_opt = NULL;
1523 if (!option_code_hash_lookup(&fqdn6_universe.enc_opt,
1524 dhcpv6_universe.code_hash, &code, 0, MDL))
1525 log_fatal("Unable to find FQDN v6 parent option. (%s:%d).",
1526 MDL);
1527 universes[fqdn6_universe.index] = &fqdn6_universe;
1528 /* The fqdn6 space shares the same option space as the v4 space.
1529 * So there are no name or code hashes on the v6 side.
1530 */
1531 fqdn6_universe.name_hash = NULL;
1532 fqdn6_universe.code_hash = NULL;
1533
1534
1535 /* Set up the hash of DHCPv4 universes. */
1536 universe_new_hash(&universe_hash, UNIVERSE_HASH_SIZE, MDL);
1537 universe_hash_add(universe_hash, dhcp_universe.name, 0,
1538 &dhcp_universe, MDL);
1539 universe_hash_add(universe_hash, nwip_universe.name, 0,
1540 &nwip_universe, MDL);
1541 universe_hash_add(universe_hash, fqdn_universe.name, 0,
1542 &fqdn_universe, MDL);
1543 universe_hash_add(universe_hash, vendor_class_universe.name, 0,
1544 &vendor_class_universe, MDL);
1545 universe_hash_add(universe_hash, vendor_universe.name, 0,
1546 &vendor_universe, MDL);
1547 universe_hash_add(universe_hash, isc_universe.name, 0,
1548 &isc_universe, MDL);
1549
1550 /* Set up hashes for DHCPv6 universes. */
1551 universe_hash_add(universe_hash, dhcpv6_universe.name, 0,
1552 &dhcpv6_universe, MDL);
1553 universe_hash_add(universe_hash, vsio_universe.name, 0,
1554 &vsio_universe, MDL);
1555 universe_hash_add(universe_hash, isc6_universe.name, 0,
1556 &isc6_universe, MDL);
1557 /* previously this wasn't necessary, now that we can send
1558 * v6 encapsulated options it is.
1559 */
1560 universe_hash_add(universe_hash, fqdn6_universe.name, 0,
1561 &fqdn6_universe, MDL);
1562
1563 }
1564