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