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