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