3 Tables of information... */
6 * Copyright (c) 2004-2019 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
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.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
25 * https://www.isc.org/
31 /* XXXDPN: Moved here from hash.c, when it moved to libomapi. Not sure
32 where these really belong. */
33 HASH_FUNCTIONS (group
, const char *, struct group_object
, group_hash_t
,
34 group_reference
, group_dereference
, do_string_hash
)
35 HASH_FUNCTIONS (universe
, const char *, struct universe
, universe_hash_t
, 0, 0,
37 HASH_FUNCTIONS (option_name
, const char *, struct option
, option_name_hash_t
,
38 option_reference
, option_dereference
, do_case_hash
)
39 HASH_FUNCTIONS (option_code
, const unsigned *, struct option
,
40 option_code_hash_t
, option_reference
, option_dereference
,
43 /* DHCP Option names, formats and codes, from RFC1533.
49 l - 32-bit signed integer
50 L - 32-bit unsigned integer
51 s - 16-bit signed integer
52 S - 16-bit unsigned integer
53 b - 8-bit signed integer
54 B - 8-bit unsigned integer
56 T - Lease Time, 32-bit unsigned integer implying a number of seconds from
57 some event. The special all-ones value means 'infinite'. May either
58 be printed as a decimal, eg, "3600", or as this name, eg, "infinite".
59 f - flag (true or false)
60 A - array of all that precedes (e.g., fIA means array of records of
61 a flag and an IP address)
62 a - array of the preceding character (e.g., fIa means a single flag
63 followed by an array of IP addresses)
64 U - name of an option space (universe)
65 F - implicit flag - the presence of the option indicates that the
67 o - the preceding value is optional.
68 E - encapsulation, string or colon-separated hex list (the latter
69 two for parsing). E is followed by a text string containing
70 the name of the option space to encapsulate, followed by a '.'.
71 If the E is immediately followed by '.', the applicable vendor
72 option space is used if one is defined.
73 e - If an encapsulation directive is not the first thing in the string,
74 the option scanner requires an efficient way to find the encapsulation.
75 This is done by placing a 'e' at the beginning of the option. The
76 'e' has no other purpose, and is not required if 'E' is the first
78 X - either an ASCII string or binary data. On output, the string is
79 scanned to see if it's printable ASCII and, if so, output as a
80 quoted string. If not, it's output as colon-separated hex. On
81 input, the option can be specified either as a quoted string or as
82 a colon-separated hex list.
83 N - enumeration. N is followed by a text string containing
84 the name of the set of enumeration values to parse or emit,
85 followed by a '.'. The width of the data is specified in the
86 named enumeration. Named enumerations are tracked in parse.c.
87 d - Domain name (e.g., FOO or FOO.BAR) no quotes,
88 on-wire format is RFC 1035.
89 D - Domain list (e.g., "example.com eng.example.com") quoted,
90 on-wire format is RFC 1035.
91 c - When following a 'D' atom, enables compression pointers.
92 Z - Zero-length option
93 k - Key name, unquoted string (e.g. mykey.com or some-text or abc123)
94 parsed with parse_host_name().
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 /* 80 is the zero-length rapid-commit (RFC 4039) */
180 { "fqdn", "Efqdn.", &dhcp_universe
, 81, 1 },
181 { "relay-agent-information", "Eagent.", &dhcp_universe
, 82, 1 },
182 /* 83 is iSNS (RFC 4174) */
183 /* 84 is unassigned */
184 { "nds-servers", "IA", &dhcp_universe
, 85, 1 },
185 { "nds-tree-name", "t", &dhcp_universe
, 86, 1 },
186 { "nds-context", "t", &dhcp_universe
, 87, 1 },
188 /* Note: RFC4280 fails to identify if the DHCPv4 option is to use
189 * compression pointers or not. Assume not.
191 { "bcms-controller-names", "D", &dhcp_universe
, 88, 1 },
192 { "bcms-controller-address", "Ia", &dhcp_universe
, 89, 1 },
194 /* 90 is the authentication option (RFC 3118) */
196 { "client-last-transaction-time", "L", &dhcp_universe
, 91, 1 },
197 { "associated-ip", "Ia", &dhcp_universe
, 92, 1 },
198 #if defined(RFC4578_OPTIONS)
199 /* Defined by RFC 4578 */
200 { "pxe-system-type", "Sa", &dhcp_universe
, 93, 1 },
201 { "pxe-interface-id", "BBB", &dhcp_universe
, 94, 1 },
202 { "pxe-client-id", "BX", &dhcp_universe
, 97, 1 },
204 { "uap-servers", "t", &dhcp_universe
, 98, 1 },
205 #if defined(RFC4776_OPTIONS)
206 { "geoconf-civic", "X", &dhcp_universe
, 99, 1 },
208 #if defined(RFC4833_OPTIONS)
209 { "pcode", "t", &dhcp_universe
, 100, 1 },
210 { "tcode", "t", &dhcp_universe
, 101, 1 },
212 #if defined(RFC8925_OPTIONS)
213 { "v6-only-preferred", "L", &dhcp_universe
, 108, 1 },
215 { "netinfo-server-address", "Ia", &dhcp_universe
, 112, 1 },
216 { "netinfo-server-tag", "t", &dhcp_universe
, 113, 1 },
217 { "default-url", "t", &dhcp_universe
, 114, 1 },
218 #if defined(RFC2563_OPTIONS)
219 { "auto-config", "B", &dhcp_universe
, 116, 1 },
221 #if defined(RFC2937_OPTIONS)
222 { "name-service-search", "Sa", &dhcp_universe
, 117, 1 },
224 { "subnet-selection", "I", &dhcp_universe
, 118, 1 },
225 { "domain-search", "Dc", &dhcp_universe
, 119, 1 },
226 { "vivco", "Evendor-class.", &dhcp_universe
, 124, 1 },
227 { "vivso", "Evendor.", &dhcp_universe
, 125, 1 },
229 /* Referenced by RFC 4578.
230 * DO NOT UNCOMMENT THESE DEFINITIONS: these names are placeholders
231 * and will not be used in future versions of the software.
233 { "pxe-undefined-1", "X", &dhcp_universe
, 128, 1 },
234 { "pxe-undefined-2", "X", &dhcp_universe
, 129, 1 },
235 { "pxe-undefined-3", "X", &dhcp_universe
, 130, 1 },
236 { "pxe-undefined-4", "X", &dhcp_universe
, 131, 1 },
237 { "pxe-undefined-5", "X", &dhcp_universe
, 132, 1 },
238 { "pxe-undefined-6", "X", &dhcp_universe
, 133, 1 },
239 { "pxe-undefined-7", "X", &dhcp_universe
, 134, 1 },
240 { "pxe-undefined-8", "X", &dhcp_universe
, 135, 1 },
242 #if defined(RFC5192_OPTIONS)
243 {"pana-agent", "Ia", &dhcp_universe
, 136, 1 },
245 #if defined(RFC5223_OPTIONS)
246 {"v4-lost", "d", &dhcp_universe
, 137, 1 },
248 #if defined(RFC5417_OPTIONS)
249 {"capwap-ac-v4", "Ia", &dhcp_universe
, 138, 1 },
251 #if defined(RFC6011_OPTIONS)
252 { "sip-ua-cs-domains", "Dc", &dhcp_universe
, 141, 1 },
254 #if defined(RFC6153_OPTIONS)
255 { "ipv4-address-andsf", "IA", &dhcp_universe
, 142, 1 },
257 #if defined(RFC6731_OPTIONS)
258 { "rdnss-selection", "BIID", &dhcp_universe
, 146, 1 },
260 #if defined(RFC5859_OPTIONS)
261 { "tftp-server-address", "Ia", &dhcp_universe
, 150, 1 },
263 #if defined(RFC7618_OPTIONS)
264 { "v4-portparams", "BBS", &dhcp_universe
, 159, 1 },
266 #if defined(RFC7710_OPTIONS)
267 { "v4-captive-portal", "t", &dhcp_universe
, 160, 1 },
269 #if defined(RFC5071_OPTIONS)
271 /* Option 208 has been officially deprecated. Do NOT define it */
272 { "pxelinux-magic", "BBBB", &dhcp_universe
, 208, 1 },
274 { "loader-configfile", "t", &dhcp_universe
, 209, 1 },
275 { "loader-pathprefix", "t", &dhcp_universe
, 210, 1 },
276 { "loader-reboottime", "L", &dhcp_universe
, 211, 1 },
278 #if defined(RFC5969_OPTIONS)
279 { "option-6rd", "BB6Ia", &dhcp_universe
, 212, 1 },
281 #if defined(RFC5986_OPTIONS)
282 {"v4-access-domain", "d", &dhcp_universe
, 213, 1 },
284 { NULL
, NULL
, NULL
, 0, 0 }
287 struct universe nwip_universe
;
288 static struct option nwip_options
[] = {
289 { "illegal-1", "", &nwip_universe
, 1, 1 },
290 { "illegal-2", "", &nwip_universe
, 2, 1 },
291 { "illegal-3", "", &nwip_universe
, 3, 1 },
292 { "illegal-4", "", &nwip_universe
, 4, 1 },
293 { "nsq-broadcast", "f", &nwip_universe
, 5, 1 },
294 { "preferred-dss", "IA", &nwip_universe
, 6, 1 },
295 { "nearest-nwip-server", "IA", &nwip_universe
, 7, 1 },
296 { "autoretries", "B", &nwip_universe
, 8, 1 },
297 { "autoretry-secs", "B", &nwip_universe
, 9, 1 },
298 { "nwip-1-1", "f", &nwip_universe
, 10, 1 },
299 { "primary-dss", "I", &nwip_universe
, 11, 1 },
300 { NULL
, NULL
, NULL
, 0, 0 }
303 /* Note that the "FQDN suboption space" does not reflect the FQDN option
304 * format - rather, this is a handy "virtualization" of a flat option
305 * which makes manual configuration and presentation of some of its
306 * contents easier (each of these suboptions is a fixed-space field within
307 * the fqdn contents - domain and host names are derived from a common field,
308 * and differ in the left and right hand side of the leftmost dot, fqdn is
309 * the combination of the two).
311 * Note further that the DHCPv6 and DHCPv4 'fqdn' options use the same
312 * virtualized option space to store their work.
315 struct universe fqdn_universe
;
316 struct universe fqdn6_universe
;
317 static struct option fqdn_options
[] = {
318 { "no-client-update", "f", &fqdn_universe
, 1, 1 },
319 { "server-update", "f", &fqdn_universe
, 2, 1 },
320 { "encoded", "f", &fqdn_universe
, 3, 1 },
321 { "rcode1", "B", &fqdn_universe
, 4, 1 },
322 { "rcode2", "B", &fqdn_universe
, 5, 1 },
323 { "hostname", "t", &fqdn_universe
, 6, 1 },
324 { "domainname", "t", &fqdn_universe
, 7, 1 },
325 { "fqdn", "t", &fqdn_universe
, 8, 1 },
326 { NULL
, NULL
, NULL
, 0, 0 }
329 struct universe vendor_class_universe
;
330 static struct option vendor_class_options
[] = {
331 { "isc", "X", &vendor_class_universe
, 2495, 1 },
332 { NULL
, NULL
, NULL
, 0, 0 }
335 struct universe vendor_universe
;
336 static struct option vendor_options
[] = {
337 { "isc", "Eisc.", &vendor_universe
, 2495, 1 },
338 { NULL
, NULL
, NULL
, 0, 0 }
341 struct universe isc_universe
;
342 static struct option isc_options
[] = {
343 { "media", "t", &isc_universe
, 1, 1 },
344 { "update-assist", "X", &isc_universe
, 2, 1 },
345 { NULL
, NULL
, NULL
, 0, 0 }
348 struct universe dhcpv6_universe
;
349 static struct option dhcpv6_options
[] = {
351 /* RFC3315 OPTIONS */
353 /* Client and server DUIDs are opaque fields, but marking them
354 * up somewhat makes configuration easier.
356 { "client-id", "X", &dhcpv6_universe
, 1, 1 },
357 { "server-id", "X", &dhcpv6_universe
, 2, 1 },
359 /* ia-* options actually have at their ends a space for options
360 * that are specific to this instance of the option. We can not
361 * handle this yet at this stage of development, so the encoding
362 * of these options is unspecified ("X").
364 { "ia-na", "X", &dhcpv6_universe
, 3, 1 },
365 { "ia-ta", "X", &dhcpv6_universe
, 4, 1 },
366 { "ia-addr", "X", &dhcpv6_universe
, 5, 1 },
368 /* "oro" is DHCPv6 speak for "parameter-request-list" */
369 { "oro", "SA", &dhcpv6_universe
, 6, 1 },
371 { "preference", "B", &dhcpv6_universe
, 7, 1 },
372 { "elapsed-time", "S", &dhcpv6_universe
, 8, 1 },
373 { "relay-msg", "X", &dhcpv6_universe
, 9, 1 },
375 /* Option code 10 is curiously unassigned. */
377 * In draft-ietf-dhc-dhcpv6-25 there were two OPTION_CLIENT_MSG and
378 * OPTION_SERVER_MSG options. They were eventually unified as
379 * OPTION_RELAY_MSG, hence no option with value of 10.
382 /* XXX: missing suitable atoms for the auth option. We may want
383 * to 'virtually encapsulate' this option a la the fqdn option
384 * seeing as it is processed explicitly by the server and unlikely
385 * to be configured by hand by users as such.
387 { "auth", "Nauth-protocol.Nauth-algorithm.Nrdm-type.LLX",
388 &dhcpv6_universe
, 11, 1 },
390 { "unicast", "6", &dhcpv6_universe
, 12, 1 },
391 { "status-code", "Nstatus-codes.to", &dhcpv6_universe
, 13, 1 },
392 { "rapid-commit", "Z", &dhcpv6_universe
, 14, 1 },
394 /* XXX: user-class contents are of the form "StA" where the
395 * integer describes the length of the text field. We don't have
396 * an atom for pre-determined-length octet strings yet, so we
397 * can't quite do these two.
399 { "user-class", "X", &dhcpv6_universe
, 15, 1 },
400 { "vendor-class", "X", &dhcpv6_universe
, 16, 1 },
402 { "vendor-opts", "Evsio.", &dhcpv6_universe
, 17, 1 },
403 { "interface-id", "X", &dhcpv6_universe
, 18, 1 },
404 { "reconf-msg", "Ndhcpv6-messages.", &dhcpv6_universe
, 19, 1 },
405 { "reconf-accept", "Z", &dhcpv6_universe
, 20, 1 },
407 /* RFC3319 OPTIONS */
409 /* Of course: we would HAVE to have a different atom for
410 * domain names without compression. Typical.
412 { "sip-servers-names", "D", &dhcpv6_universe
, 21, 1 },
413 { "sip-servers-addresses", "6A", &dhcpv6_universe
, 22, 1 },
415 /* RFC3646 OPTIONS */
417 { "name-servers", "6A", &dhcpv6_universe
, 23, 1 },
418 { "domain-search", "D", &dhcpv6_universe
, 24, 1 },
420 /* RFC3633 OPTIONS */
422 { "ia-pd", "X", &dhcpv6_universe
, 25, 1 },
423 { "ia-prefix", "X", &dhcpv6_universe
, 26, 1 },
425 /* RFC3898 OPTIONS */
427 { "nis-servers", "6A", &dhcpv6_universe
, 27, 1 },
428 { "nisp-servers", "6A", &dhcpv6_universe
, 28, 1 },
429 { "nis-domain-name", "D", &dhcpv6_universe
, 29, 1 },
430 { "nisp-domain-name", "D", &dhcpv6_universe
, 30, 1 },
432 /* RFC4075 OPTIONS */
433 { "sntp-servers", "6A", &dhcpv6_universe
, 31, 1 },
435 /* RFC4242 OPTIONS */
437 { "info-refresh-time", "T", &dhcpv6_universe
, 32, 1 },
439 /* RFC4280 OPTIONS */
441 { "bcms-server-d", "D", &dhcpv6_universe
, 33, 1 },
442 { "bcms-server-a", "6A", &dhcpv6_universe
, 34, 1 },
444 /* Note that 35 is not assigned. */
446 #if defined(RFC4776_OPTIONS)
447 /* RFC4776 OPTIONS */
449 { "geoconf-civic", "X", &dhcpv6_universe
, 36, 1 },
452 /* RFC4649 OPTIONS */
454 /* The remote-id option looks like the VSIO option, but for all
455 * intents and purposes we only need to treat the entire field
456 * like a globally unique identifier (and if we create such an
457 * option, ensure the first 4 bytes are our enterprise-id followed
458 * by a globally unique ID so long as you're within that enterprise
459 * id). So we'll use "X" for now unless someone grumbles.
461 { "remote-id", "X", &dhcpv6_universe
, 37, 1 },
463 /* RFC4580 OPTIONS */
465 { "subscriber-id", "X", &dhcpv6_universe
, 38, 1 },
467 /* RFC4704 OPTIONS */
469 /* The DHCPv6 FQDN option is...weird.
471 * We use the same "virtual" encapsulated space as DHCPv4's FQDN
472 * option, so it can all be configured in one place. Since the
473 * options system does not support multiple inheritance, we use
474 * a 'shill' layer to perform the different protocol conversions,
475 * and to redirect any queries in the DHCPv4 FQDN's space.
477 { "fqdn", "Efqdn6-if-you-see-me-its-a-bug-bug-bug.",
478 &dhcpv6_universe
, 39, 1 },
482 #if defined(RFC5192_OPTIONS)
483 { "pana-agent", "6A", &dhcpv6_universe
, 40, 1 },
486 /* RFC4833 OPTIONS */
487 #if defined(RFC4833_OPTIONS)
488 { "new-posix-timezone", "t", &dhcpv6_universe
, 41, 1 },
489 { "new-tzdb-timezone", "t", &dhcpv6_universe
, 42, 1 },
492 /* RFC4994 OPTIONS */
493 #if defined(RFC4994_OPTIONS)
494 { "ero", "SA", &dhcpv6_universe
, 43, 1 },
497 /* RFC5007 OPTIONS */
499 { "lq-query", "X", &dhcpv6_universe
, 44, 1 },
500 { "client-data", "X", &dhcpv6_universe
, 45, 1 },
501 { "clt-time", "L", &dhcpv6_universe
, 46, 1 },
502 { "lq-relay-data", "6X", &dhcpv6_universe
, 47, 1 },
503 { "lq-client-link", "6A", &dhcpv6_universe
, 48, 1 },
505 /* RFC5223 OPTIONS */
506 #if defined(RFC5223_OPTIONS)
507 { "v6-lost", "d", &dhcpv6_universe
, 51, 1 },
510 /* RFC5417 OPTIONS */
511 #if defined(RFC5417_OPTIONS)
512 { "capwap-ac-v6", "6a", &dhcpv6_universe
, 52, 1 },
515 /* RFC5460 OPTIONS */
516 #if defined(RFC5460_OPTIONS)
517 { "relay-id", "X", &dhcpv6_universe
, 53, 1 },
520 /* RFC5986 OPTIONS */
521 #if defined(RFC5986_OPTIONS)
522 { "v6-access-domain", "d", &dhcpv6_universe
, 57, 1 },
525 /* RFC6011 OPTIONS */
526 #if defined(RFC6011_OPTIONS)
527 { "sip-ua-cs-list", "D", &dhcpv6_universe
, 58, 1 },
530 /* RFC5970 OPTIONS */
531 #if defined(RFC5970_OPTIONS)
532 { "bootfile-url", "t", &dhcpv6_universe
, 59, 1 },
533 { "bootfile-param", "X", &dhcpv6_universe
, 60, 1 },
534 { "client-arch-type", "SA", &dhcpv6_universe
, 61, 1 },
535 { "nii", "BBB", &dhcpv6_universe
, 62, 1 },
538 /* RFC6334 OPTIONS */
539 #if defined(RFC6334_OPTIONS)
540 { "aftr-name", "d", &dhcpv6_universe
, 64, 1 },
543 /* RFC6440 OPTIONS */
544 #if defined(RFC6440_OPTIONS)
545 { "erp-local-domain-name", "d", &dhcpv6_universe
, 65, 1 },
548 /* RFC6731 OPTIONS */
549 #if defined(RFC6731_OPTIONS)
550 { "rdnss-selection", "6BD", &dhcpv6_universe
, 74, 1 },
553 /* RFC6939 OPTIONS */
554 #if defined(RFC6939_OPTIONS)
555 { "client-linklayer-addr", "X", &dhcpv6_universe
, 79, 1 },
558 /* RFC6977 OPTIONS */
559 #if defined(RFC6977_OPTIONS)
560 { "link-address", "6", &dhcpv6_universe
, 80, 1 },
563 /* RFC7083 OPTIONS */
564 #if defined(RFC7083_OPTIONS)
565 { "solmax-rt", "L", &dhcpv6_universe
, 82, 1 },
566 { "inf-max-rt", "L", &dhcpv6_universe
, 83, 1 },
569 /* RFC7341 OPTIONS */
570 #if defined(RFC7341_OPTIONS)
571 { "dhcpv4-msg", "X", &dhcpv6_universe
, 87, 1 },
572 { "dhcp4-o-dhcp6-server", "6A", &dhcpv6_universe
, 88, 1 },
575 #if defined(RFC7710_OPTIONS)
576 { "v6-captive-portal", "t", &dhcpv6_universe
, 103, 1 },
579 { "relay-source-port", "S", &dhcpv6_universe
, 135, 1 },
581 #if defined(RFC6153_OPTIONS)
582 { "ipv6-address-andsf", "6A", &dhcpv6_universe
, 143, 1 },
585 { NULL
, NULL
, NULL
, 0, 0 }
588 struct enumeration_value dhcpv6_duid_type_values
[] = {
589 { "duid-llt", DUID_LLT
}, /* Link-Local Plus Time */
590 { "duid-en", DUID_EN
}, /* DUID based upon enterprise-ID. */
591 { "duid-ll", DUID_LL
}, /* DUID from Link Local address only. */
592 { "duid-uuid", DUID_UUID
}, /* DUID based upon UUID */
596 struct enumeration dhcpv6_duid_types
= {
599 dhcpv6_duid_type_values
602 struct enumeration_value dhcpv6_status_code_values
[] = {
603 { "success", 0 }, /* Success */
604 { "UnspecFail", 1 }, /* Failure, for unspecified reasons. */
605 { "NoAddrsAvail", 2 }, /* Server has no addresses to assign. */
606 { "NoBinding", 3 }, /* Client record (binding) unavailable. */
607 { "NotOnLink", 4 }, /* Bad prefix for the link. */
608 { "UseMulticast", 5 }, /* Not just good advice. It's the law. */
609 { "NoPrefixAvail", 6 }, /* Server has no prefixes to assign. */
610 { "UnknownQueryType", 7 }, /* Query-type unknown/unsupported. */
611 { "MalformedQuery", 8 }, /* Leasequery not valid. */
612 { "NotConfigured", 9 }, /* The target address is not in config. */
613 { "NotAllowed", 10 }, /* Server doesn't allow the leasequery. */
614 { "QueryTerminated", 11 }, /* Leasequery terminated. */
618 struct enumeration dhcpv6_status_codes
= {
621 dhcpv6_status_code_values
624 struct enumeration_value lq6_query_type_values
[] = {
625 { "query-by-address", 1 },
626 { "query-by-clientid", 2 },
627 { "query-by-relay-id", 3 },
628 { "query-by-link-address", 4 },
629 { "query-by-remote-id", 5 },
633 struct enumeration lq6_query_types
= {
636 lq6_query_type_values
639 struct enumeration_value dhcpv6_message_values
[] = {
649 { "RECONFIGURE", 10 },
650 { "INFORMATION-REQUEST", 11 },
651 { "RELAY-FORW", 12 },
652 { "RELAY-REPL", 13 },
653 { "LEASEQUERY", 14 },
654 { "LEASEQUERY-REPLY", 15 },
655 { "LEASEQUERY-DONE", 16 },
656 { "LEASEQUERY-DATA", 17 },
657 { "RECONFIGURE-REQUEST", 18 },
658 { "RECONFIGURE-REPLY", 19 },
659 { "DHCPV4-QUERY", 20 },
660 { "DHCPV4-RESPONSE", 21 },
664 /* Some code refers to a different table. */
665 const char *dhcpv6_type_names
[] = {
677 "Information-request",
684 "Reconfigure-request",
689 const int dhcpv6_type_name_max
=
690 (sizeof(dhcpv6_type_names
) / sizeof(dhcpv6_type_names
[0]));
692 struct enumeration dhcpv6_messages
= {
694 "dhcpv6-messages", 1,
695 dhcpv6_message_values
698 struct universe vsio_universe
;
699 static struct option vsio_options
[] = {
700 { "isc", "Eisc6.", &vsio_universe
, 2495, 1 },
701 { NULL
, NULL
, NULL
, 0, 0 }
704 struct universe isc6_universe
;
705 static struct option isc6_options
[] = {
706 { "media", "t", &isc6_universe
, 1, 1 },
707 { "update-assist", "X", &isc6_universe
, 2, 1 },
708 { "4o6-interface", "t", &isc6_universe
, 60000, 1 },
709 { "4o6-source-address", "6", &isc6_universe
, 60001, 1 },
710 { NULL
, NULL
, NULL
, 0, 0 }
713 const char *hardware_types
[] = {
971 universe_hash_t
*universe_hash
;
972 struct universe
**universes
;
973 int universe_count
, universe_max
;
975 /* Universe containing names of configuration options, which, rather than
976 writing "option universe-name.option-name ...;", can be set by writing
977 "option-name ...;". */
979 struct universe
*config_universe
;
981 /* XXX: omapi must die...all the below keeps us from having to make the
982 * option structures omapi typed objects, which is a bigger headache.
985 char *default_option_format
= (char *) "X";
987 /* Must match hash_reference/dereference types in omapip/hash.h. */
989 option_reference(struct option
**dest
, struct option
*src
,
990 const char * file
, int line
)
993 return DHCP_R_INVALIDARG
;
996 #if defined(POINTER_DEBUG)
997 log_fatal("%s(%d): reference store into non-null pointer!",
1000 return DHCP_R_INVALIDARG
;
1006 rc_register(file
, line
, dest
, src
, src
->refcnt
, 0, RC_MISC
);
1007 return(ISC_R_SUCCESS
);
1011 option_dereference(struct option
**dest
, const char *file
, int line
)
1014 return DHCP_R_INVALIDARG
;
1017 #if defined (POINTER_DEBUG)
1018 log_fatal("%s(%d): dereference of null pointer!", file
, line
);
1020 return DHCP_R_INVALIDARG
;
1024 if ((*dest
)->refcnt
<= 0) {
1025 #if defined (POINTER_DEBUG)
1026 log_fatal("%s(%d): dereference of <= 0 refcnt!", file
, line
);
1028 return DHCP_R_INVALIDARG
;
1034 rc_register(file
, line
, dest
, (*dest
), (*dest
)->refcnt
, 1, RC_MISC
);
1036 if ((*dest
)->refcnt
== 0) {
1037 /* The option name may be packed in the same alloc as the
1040 if ((char *) (*dest
)->name
!= (char *) ((*dest
) + 1))
1041 dfree((char *) (*dest
)->name
, file
, line
);
1043 /* It's either a user-configured format (allocated), or the
1044 * default static format.
1046 if (((*dest
)->format
!= NULL
) &&
1047 ((*dest
)->format
!= default_option_format
)) {
1048 dfree((char *) (*dest
)->format
, file
, line
);
1051 dfree(*dest
, file
, line
);
1055 return ISC_R_SUCCESS
;
1058 void initialize_common_option_spaces()
1063 /* The 'universes' table is dynamically grown to contain
1064 * universe as they're configured - except during startup.
1065 * Since we know how many we put down in .c files, we can
1066 * allocate a more-than-right-sized buffer now, leaving some
1067 * space for user-configured option spaces.
1069 * 1: dhcp_universe (dhcpv4 options)
1070 * 2: nwip_universe (dhcpv4 NWIP option)
1071 * 3: fqdn_universe (dhcpv4 fqdn option - reusable for v6)
1072 * 4: vendor_class_universe (VIVCO)
1073 * 5: vendor_universe (VIVSO)
1074 * 6: isc_universe (dhcpv4 isc config space)
1075 * 7: dhcpv6_universe (dhcpv6 options)
1076 * 8: vsio_universe (DHCPv6 Vendor-Identified space)
1077 * 9: isc6_universe (ISC's Vendor universe in DHCPv6 VSIO)
1078 * 10: fqdn6_universe (dhcpv6 fqdn option shill to v4)
1079 * 11: agent_universe (dhcpv4 relay agent - see server/stables.c)
1080 * 12: server_universe (server's config, see server/stables.c)
1082 * 14: more user-config
1083 * 15: more user-config
1084 * 16: more user-config
1087 i
= universe_max
* sizeof(struct universe
*);
1089 log_fatal("Ludicrous initial size option space table.");
1090 universes
= dmalloc(i
, MDL
);
1091 if (universes
== NULL
)
1092 log_fatal("Can't allocate option space table.");
1093 memset(universes
, 0, i
);
1095 /* Set up the DHCP option universe... */
1096 dhcp_universe
.name
= "dhcp";
1097 dhcp_universe
.concat_duplicates
= 1;
1098 dhcp_universe
.lookup_func
= lookup_hashed_option
;
1099 dhcp_universe
.option_state_dereference
=
1100 hashed_option_state_dereference
;
1101 dhcp_universe
.save_func
= save_hashed_option
;
1102 dhcp_universe
.delete_func
= delete_hashed_option
;
1103 dhcp_universe
.encapsulate
= hashed_option_space_encapsulate
;
1104 dhcp_universe
.foreach
= hashed_option_space_foreach
;
1105 dhcp_universe
.decode
= parse_option_buffer
;
1106 dhcp_universe
.length_size
= 1;
1107 dhcp_universe
.tag_size
= 1;
1108 dhcp_universe
.get_tag
= getUChar
;
1109 dhcp_universe
.store_tag
= putUChar
;
1110 dhcp_universe
.get_length
= getUChar
;
1111 dhcp_universe
.store_length
= putUChar
;
1112 dhcp_universe
.site_code_min
= 0;
1113 dhcp_universe
.end
= DHO_END
;
1114 dhcp_universe
.index
= universe_count
++;
1115 universes
[dhcp_universe
.index
] = &dhcp_universe
;
1116 if (!option_name_new_hash(&dhcp_universe
.name_hash
,
1117 BYTE_NAME_HASH_SIZE
, MDL
) ||
1118 !option_code_new_hash(&dhcp_universe
.code_hash
,
1119 BYTE_CODE_HASH_SIZE
, MDL
))
1120 log_fatal ("Can't allocate dhcp option hash table.");
1121 for (i
= 0 ; dhcp_options
[i
].name
; i
++) {
1122 option_code_hash_add(dhcp_universe
.code_hash
,
1123 &dhcp_options
[i
].code
, 0,
1124 &dhcp_options
[i
], MDL
);
1125 option_name_hash_add(dhcp_universe
.name_hash
,
1126 dhcp_options
[i
].name
, 0,
1127 &dhcp_options
[i
], MDL
);
1129 #if defined(REPORT_HASH_PERFORMANCE)
1130 log_info("DHCP name hash: %s",
1131 option_name_hash_report(dhcp_universe
.name_hash
));
1132 log_info("DHCP code hash: %s",
1133 option_code_hash_report(dhcp_universe
.code_hash
));
1136 /* Set up the Novell option universe (for option 63)... */
1137 nwip_universe
.name
= "nwip";
1138 nwip_universe
.concat_duplicates
= 0; /* XXX: reference? */
1139 nwip_universe
.lookup_func
= lookup_linked_option
;
1140 nwip_universe
.option_state_dereference
=
1141 linked_option_state_dereference
;
1142 nwip_universe
.save_func
= save_linked_option
;
1143 nwip_universe
.delete_func
= delete_linked_option
;
1144 nwip_universe
.encapsulate
= nwip_option_space_encapsulate
;
1145 nwip_universe
.foreach
= linked_option_space_foreach
;
1146 nwip_universe
.decode
= parse_option_buffer
;
1147 nwip_universe
.length_size
= 1;
1148 nwip_universe
.tag_size
= 1;
1149 nwip_universe
.get_tag
= getUChar
;
1150 nwip_universe
.store_tag
= putUChar
;
1151 nwip_universe
.get_length
= getUChar
;
1152 nwip_universe
.store_length
= putUChar
;
1153 nwip_universe
.site_code_min
= 0;
1154 nwip_universe
.end
= 0;
1155 code
= DHO_NWIP_SUBOPTIONS
;
1156 nwip_universe
.enc_opt
= NULL
;
1157 if (!option_code_hash_lookup(&nwip_universe
.enc_opt
,
1158 dhcp_universe
.code_hash
, &code
, 0, MDL
))
1159 log_fatal("Unable to find NWIP parent option (%s:%d).", MDL
);
1160 nwip_universe
.index
= universe_count
++;
1161 universes
[nwip_universe
.index
] = &nwip_universe
;
1162 if (!option_name_new_hash(&nwip_universe
.name_hash
,
1163 NWIP_HASH_SIZE
, MDL
) ||
1164 !option_code_new_hash(&nwip_universe
.code_hash
,
1165 NWIP_HASH_SIZE
, MDL
))
1166 log_fatal ("Can't allocate nwip option hash table.");
1167 for (i
= 0 ; nwip_options
[i
].name
; i
++) {
1168 option_code_hash_add(nwip_universe
.code_hash
,
1169 &nwip_options
[i
].code
, 0,
1170 &nwip_options
[i
], MDL
);
1171 option_name_hash_add(nwip_universe
.name_hash
,
1172 nwip_options
[i
].name
, 0,
1173 &nwip_options
[i
], MDL
);
1175 #if defined(REPORT_HASH_PERFORMANCE)
1176 log_info("NWIP name hash: %s",
1177 option_name_hash_report(nwip_universe
.name_hash
));
1178 log_info("NWIP code hash: %s",
1179 option_code_hash_report(nwip_universe
.code_hash
));
1182 /* Set up the FQDN option universe... */
1183 fqdn_universe
.name
= "fqdn";
1184 fqdn_universe
.concat_duplicates
= 0;
1185 fqdn_universe
.lookup_func
= lookup_linked_option
;
1186 fqdn_universe
.option_state_dereference
=
1187 linked_option_state_dereference
;
1188 fqdn_universe
.save_func
= save_linked_option
;
1189 fqdn_universe
.delete_func
= delete_linked_option
;
1190 fqdn_universe
.encapsulate
= fqdn_option_space_encapsulate
;
1191 fqdn_universe
.foreach
= linked_option_space_foreach
;
1192 fqdn_universe
.decode
= fqdn_universe_decode
;
1193 fqdn_universe
.length_size
= 1;
1194 fqdn_universe
.tag_size
= 1;
1195 fqdn_universe
.get_tag
= getUChar
;
1196 fqdn_universe
.store_tag
= putUChar
;
1197 fqdn_universe
.get_length
= getUChar
;
1198 fqdn_universe
.store_length
= putUChar
;
1199 fqdn_universe
.site_code_min
= 0;
1200 fqdn_universe
.end
= 0;
1201 fqdn_universe
.index
= universe_count
++;
1203 fqdn_universe
.enc_opt
= NULL
;
1204 if (!option_code_hash_lookup(&fqdn_universe
.enc_opt
,
1205 dhcp_universe
.code_hash
, &code
, 0, MDL
))
1206 log_fatal("Unable to find FQDN parent option (%s:%d).", MDL
);
1207 universes
[fqdn_universe
.index
] = &fqdn_universe
;
1208 if (!option_name_new_hash(&fqdn_universe
.name_hash
,
1209 FQDN_HASH_SIZE
, MDL
) ||
1210 !option_code_new_hash(&fqdn_universe
.code_hash
,
1211 FQDN_HASH_SIZE
, MDL
))
1212 log_fatal ("Can't allocate fqdn option hash table.");
1213 for (i
= 0 ; fqdn_options
[i
].name
; i
++) {
1214 option_code_hash_add(fqdn_universe
.code_hash
,
1215 &fqdn_options
[i
].code
, 0,
1216 &fqdn_options
[i
], MDL
);
1217 option_name_hash_add(fqdn_universe
.name_hash
,
1218 fqdn_options
[i
].name
, 0,
1219 &fqdn_options
[i
], MDL
);
1221 #if defined(REPORT_HASH_PERFORMANCE)
1222 log_info("FQDN name hash: %s",
1223 option_name_hash_report(fqdn_universe
.name_hash
));
1224 log_info("FQDN code hash: %s",
1225 option_code_hash_report(fqdn_universe
.code_hash
));
1228 /* Set up the Vendor Identified Vendor Class options (for option
1231 vendor_class_universe
.name
= "vendor-class";
1232 vendor_class_universe
.concat_duplicates
= 0; /* XXX: reference? */
1233 vendor_class_universe
.lookup_func
= lookup_hashed_option
;
1234 vendor_class_universe
.option_state_dereference
=
1235 hashed_option_state_dereference
;
1236 vendor_class_universe
.save_func
= save_hashed_option
;
1237 vendor_class_universe
.delete_func
= delete_hashed_option
;
1238 vendor_class_universe
.encapsulate
= hashed_option_space_encapsulate
;
1239 vendor_class_universe
.foreach
= hashed_option_space_foreach
;
1240 vendor_class_universe
.decode
= parse_option_buffer
;
1241 vendor_class_universe
.length_size
= 1;
1242 vendor_class_universe
.tag_size
= 4;
1243 vendor_class_universe
.get_tag
= getULong
;
1244 vendor_class_universe
.store_tag
= putULong
;
1245 vendor_class_universe
.get_length
= getUChar
;
1246 vendor_class_universe
.store_length
= putUChar
;
1247 vendor_class_universe
.site_code_min
= 0;
1248 vendor_class_universe
.end
= 0;
1249 code
= DHO_VIVCO_SUBOPTIONS
;
1250 vendor_class_universe
.enc_opt
= NULL
;
1251 if (!option_code_hash_lookup(&vendor_class_universe
.enc_opt
,
1252 dhcp_universe
.code_hash
, &code
, 0, MDL
))
1253 log_fatal("Unable to find VIVCO parent option (%s:%d).", MDL
);
1254 vendor_class_universe
.index
= universe_count
++;
1255 universes
[vendor_class_universe
.index
] = &vendor_class_universe
;
1256 if (!option_name_new_hash(&vendor_class_universe
.name_hash
,
1257 VIVCO_HASH_SIZE
, MDL
) ||
1258 !option_code_new_hash(&vendor_class_universe
.code_hash
,
1259 VIVCO_HASH_SIZE
, MDL
))
1260 log_fatal("Can't allocate Vendor Identified Vendor Class "
1261 "option hash table.");
1262 for (i
= 0 ; vendor_class_options
[i
].name
; i
++) {
1263 option_code_hash_add(vendor_class_universe
.code_hash
,
1264 &vendor_class_options
[i
].code
, 0,
1265 &vendor_class_options
[i
], MDL
);
1266 option_name_hash_add(vendor_class_universe
.name_hash
,
1267 vendor_class_options
[i
].name
, 0,
1268 &vendor_class_options
[i
], MDL
);
1270 #if defined(REPORT_HASH_PERFORMANCE)
1271 log_info("VIVCO name hash: %s",
1272 option_name_hash_report(vendor_class_universe
.name_hash
));
1273 log_info("VIVCO code hash: %s",
1274 option_code_hash_report(vendor_class_universe
.code_hash
));
1277 /* Set up the Vendor Identified Vendor Sub-options (option 126)... */
1278 vendor_universe
.name
= "vendor";
1279 vendor_universe
.concat_duplicates
= 0; /* XXX: reference? */
1280 vendor_universe
.lookup_func
= lookup_hashed_option
;
1281 vendor_universe
.option_state_dereference
=
1282 hashed_option_state_dereference
;
1283 vendor_universe
.save_func
= save_hashed_option
;
1284 vendor_universe
.delete_func
= delete_hashed_option
;
1285 vendor_universe
.encapsulate
= hashed_option_space_encapsulate
;
1286 vendor_universe
.foreach
= hashed_option_space_foreach
;
1287 vendor_universe
.decode
= parse_option_buffer
;
1288 vendor_universe
.length_size
= 1;
1289 vendor_universe
.tag_size
= 4;
1290 vendor_universe
.get_tag
= getULong
;
1291 vendor_universe
.store_tag
= putULong
;
1292 vendor_universe
.get_length
= getUChar
;
1293 vendor_universe
.store_length
= putUChar
;
1294 vendor_universe
.site_code_min
= 0;
1295 vendor_universe
.end
= 0;
1296 code
= DHO_VIVSO_SUBOPTIONS
;
1297 vendor_universe
.enc_opt
= NULL
;
1298 if (!option_code_hash_lookup(&vendor_universe
.enc_opt
,
1299 dhcp_universe
.code_hash
, &code
, 0, MDL
))
1300 log_fatal("Unable to find VIVSO parent option (%s:%d).", MDL
);
1301 vendor_universe
.index
= universe_count
++;
1302 universes
[vendor_universe
.index
] = &vendor_universe
;
1303 if (!option_name_new_hash(&vendor_universe
.name_hash
,
1304 VIVSO_HASH_SIZE
, MDL
) ||
1305 !option_code_new_hash(&vendor_universe
.code_hash
,
1306 VIVSO_HASH_SIZE
, MDL
))
1307 log_fatal("Can't allocate Vendor Identified Vendor Sub-"
1308 "options hash table.");
1309 for (i
= 0 ; vendor_options
[i
].name
; i
++) {
1310 option_code_hash_add(vendor_universe
.code_hash
,
1311 &vendor_options
[i
].code
, 0,
1312 &vendor_options
[i
], MDL
);
1313 option_name_hash_add(vendor_universe
.name_hash
,
1314 vendor_options
[i
].name
, 0,
1315 &vendor_options
[i
], MDL
);
1317 #if defined(REPORT_HASH_PERFORMANCE)
1318 log_info("VIVSO name hash: %s",
1319 option_name_hash_report(vendor_universe
.name_hash
));
1320 log_info("VIVSO code hash: %s",
1321 option_code_hash_report(vendor_universe
.code_hash
));
1324 /* Set up the ISC Vendor-option universe (for option 125.2495)... */
1325 isc_universe
.name
= "isc";
1326 isc_universe
.concat_duplicates
= 0; /* XXX: check VIVSO ref */
1327 isc_universe
.lookup_func
= lookup_linked_option
;
1328 isc_universe
.option_state_dereference
=
1329 linked_option_state_dereference
;
1330 isc_universe
.save_func
= save_linked_option
;
1331 isc_universe
.delete_func
= delete_linked_option
;
1332 isc_universe
.encapsulate
= linked_option_space_encapsulate
;
1333 isc_universe
.foreach
= linked_option_space_foreach
;
1334 isc_universe
.decode
= parse_option_buffer
;
1335 isc_universe
.length_size
= 2;
1336 isc_universe
.tag_size
= 2;
1337 isc_universe
.get_tag
= getUShort
;
1338 isc_universe
.store_tag
= putUShort
;
1339 isc_universe
.get_length
= getUShort
;
1340 isc_universe
.store_length
= putUShort
;
1341 isc_universe
.site_code_min
= 0;
1342 isc_universe
.end
= 0;
1343 code
= VENDOR_ISC_SUBOPTIONS
;
1344 isc_universe
.enc_opt
= NULL
;
1345 if (!option_code_hash_lookup(&isc_universe
.enc_opt
,
1346 vendor_universe
.code_hash
, &code
, 0, MDL
))
1347 log_fatal("Unable to find ISC parent option (%s:%d).", MDL
);
1348 isc_universe
.index
= universe_count
++;
1349 universes
[isc_universe
.index
] = &isc_universe
;
1350 if (!option_name_new_hash(&isc_universe
.name_hash
,
1351 VIV_ISC_HASH_SIZE
, MDL
) ||
1352 !option_code_new_hash(&isc_universe
.code_hash
,
1353 VIV_ISC_HASH_SIZE
, MDL
))
1354 log_fatal("Can't allocate ISC Vendor options hash table.");
1355 for (i
= 0 ; isc_options
[i
].name
; i
++) {
1356 option_code_hash_add(isc_universe
.code_hash
,
1357 &isc_options
[i
].code
, 0,
1358 &isc_options
[i
], MDL
);
1359 option_name_hash_add(isc_universe
.name_hash
,
1360 isc_options
[i
].name
, 0,
1361 &isc_options
[i
], MDL
);
1363 #if defined(REPORT_HASH_PERFORMANCE)
1364 log_info("ISC name hash: %s",
1365 option_name_hash_report(isc_universe
.name_hash
));
1366 log_info("ISC code hash: %s",
1367 option_code_hash_report(isc_universe
.code_hash
));
1370 /* Set up the DHCPv6 root universe. */
1371 dhcpv6_universe
.name
= "dhcp6";
1372 dhcpv6_universe
.concat_duplicates
= 0;
1373 dhcpv6_universe
.lookup_func
= lookup_hashed_option
;
1374 dhcpv6_universe
.option_state_dereference
=
1375 hashed_option_state_dereference
;
1376 dhcpv6_universe
.save_func
= save_hashed_option
;
1377 dhcpv6_universe
.delete_func
= delete_hashed_option
;
1378 dhcpv6_universe
.encapsulate
= hashed_option_space_encapsulate
;
1379 dhcpv6_universe
.foreach
= hashed_option_space_foreach
;
1380 dhcpv6_universe
.decode
= parse_option_buffer
;
1381 dhcpv6_universe
.length_size
= 2;
1382 dhcpv6_universe
.tag_size
= 2;
1383 dhcpv6_universe
.get_tag
= getUShort
;
1384 dhcpv6_universe
.store_tag
= putUShort
;
1385 dhcpv6_universe
.get_length
= getUShort
;
1386 dhcpv6_universe
.store_length
= putUShort
;
1387 dhcpv6_universe
.site_code_min
= 0;
1388 /* DHCPv6 has no END option. */
1389 dhcpv6_universe
.end
= 0x00;
1390 dhcpv6_universe
.index
= universe_count
++;
1391 universes
[dhcpv6_universe
.index
] = &dhcpv6_universe
;
1392 if (!option_name_new_hash(&dhcpv6_universe
.name_hash
,
1393 WORD_NAME_HASH_SIZE
, MDL
) ||
1394 !option_code_new_hash(&dhcpv6_universe
.code_hash
,
1395 WORD_CODE_HASH_SIZE
, MDL
))
1396 log_fatal("Can't allocate dhcpv6 option hash tables.");
1397 for (i
= 0 ; dhcpv6_options
[i
].name
; i
++) {
1398 option_code_hash_add(dhcpv6_universe
.code_hash
,
1399 &dhcpv6_options
[i
].code
, 0,
1400 &dhcpv6_options
[i
], MDL
);
1401 option_name_hash_add(dhcpv6_universe
.name_hash
,
1402 dhcpv6_options
[i
].name
, 0,
1403 &dhcpv6_options
[i
], MDL
);
1406 /* Add DHCPv6 protocol enumeration sets. */
1407 add_enumeration(&dhcpv6_duid_types
);
1408 add_enumeration(&dhcpv6_status_codes
);
1409 add_enumeration(&dhcpv6_messages
);
1411 /* Set up DHCPv6 VSIO universe. */
1412 vsio_universe
.name
= "vsio";
1413 vsio_universe
.concat_duplicates
= 0;
1414 vsio_universe
.lookup_func
= lookup_hashed_option
;
1415 vsio_universe
.option_state_dereference
=
1416 hashed_option_state_dereference
;
1417 vsio_universe
.save_func
= save_hashed_option
;
1418 vsio_universe
.delete_func
= delete_hashed_option
;
1419 vsio_universe
.encapsulate
= hashed_option_space_encapsulate
;
1420 vsio_universe
.foreach
= hashed_option_space_foreach
;
1421 vsio_universe
.decode
= parse_option_buffer
;
1422 vsio_universe
.length_size
= 0;
1423 vsio_universe
.tag_size
= 4;
1424 vsio_universe
.get_tag
= getULong
;
1425 vsio_universe
.store_tag
= putULong
;
1426 vsio_universe
.get_length
= NULL
;
1427 vsio_universe
.store_length
= NULL
;
1428 vsio_universe
.site_code_min
= 0;
1429 /* No END option. */
1430 vsio_universe
.end
= 0x00;
1431 code
= D6O_VENDOR_OPTS
;
1432 if (!option_code_hash_lookup(&vsio_universe
.enc_opt
,
1433 dhcpv6_universe
.code_hash
, &code
, 0, MDL
))
1434 log_fatal("Unable to find VSIO parent option (%s:%d).", MDL
);
1435 vsio_universe
.index
= universe_count
++;
1436 universes
[vsio_universe
.index
] = &vsio_universe
;
1437 if (!option_name_new_hash(&vsio_universe
.name_hash
,
1438 VSIO_HASH_SIZE
, MDL
) ||
1439 !option_code_new_hash(&vsio_universe
.code_hash
,
1440 VSIO_HASH_SIZE
, MDL
))
1441 log_fatal("Can't allocate Vendor Specific Information "
1443 for (i
= 0 ; vsio_options
[i
].name
!= NULL
; i
++) {
1444 option_code_hash_add(vsio_universe
.code_hash
,
1445 &vsio_options
[i
].code
, 0,
1446 &vsio_options
[i
], MDL
);
1447 option_name_hash_add(vsio_universe
.name_hash
,
1448 vsio_options
[i
].name
, 0,
1449 &vsio_options
[i
], MDL
);
1452 /* Add ISC VSIO sub-sub-option space. */
1453 isc6_universe
.name
= "isc6";
1454 isc6_universe
.concat_duplicates
= 0;
1455 isc6_universe
.lookup_func
= lookup_hashed_option
;
1456 isc6_universe
.option_state_dereference
=
1457 hashed_option_state_dereference
;
1458 isc6_universe
.save_func
= save_hashed_option
;
1459 isc6_universe
.delete_func
= delete_hashed_option
;
1460 isc6_universe
.encapsulate
= hashed_option_space_encapsulate
;
1461 isc6_universe
.foreach
= hashed_option_space_foreach
;
1462 isc6_universe
.decode
= parse_option_buffer
;
1463 isc6_universe
.length_size
= 0;
1464 isc6_universe
.tag_size
= 4;
1465 isc6_universe
.get_tag
= getULong
;
1466 isc6_universe
.store_tag
= putULong
;
1467 isc6_universe
.get_length
= NULL
;
1468 isc6_universe
.store_length
= NULL
;
1469 isc6_universe
.site_code_min
= 0;
1470 /* No END option. */
1471 isc6_universe
.end
= 0x00;
1473 if (!option_code_hash_lookup(&isc6_universe
.enc_opt
,
1474 vsio_universe
.code_hash
, &code
, 0, MDL
))
1475 log_fatal("Unable to find ISC parent option (%s:%d).", MDL
);
1476 isc6_universe
.index
= universe_count
++;
1477 universes
[isc6_universe
.index
] = &isc6_universe
;
1478 if (!option_name_new_hash(&isc6_universe
.name_hash
,
1479 VIV_ISC_HASH_SIZE
, MDL
) ||
1480 !option_code_new_hash(&isc6_universe
.code_hash
,
1481 VIV_ISC_HASH_SIZE
, MDL
))
1482 log_fatal("Can't allocate Vendor Specific Information "
1484 for (i
= 0 ; isc6_options
[i
].name
!= NULL
; i
++) {
1485 option_code_hash_add(isc6_universe
.code_hash
,
1486 &isc6_options
[i
].code
, 0,
1487 &isc6_options
[i
], MDL
);
1488 option_name_hash_add(isc6_universe
.name_hash
,
1489 isc6_options
[i
].name
, 0,
1490 &isc6_options
[i
], MDL
);
1493 /* The fqdn6 option space is a protocol-wrapper shill for the
1496 fqdn6_universe
.name
= "fqdn6-if-you-see-me-its-a-bug-bug-bug";
1497 fqdn6_universe
.lookup_func
= lookup_fqdn6_option
;
1498 fqdn6_universe
.option_state_dereference
= NULL
; /* Covered by v4. */
1499 fqdn6_universe
.save_func
= save_fqdn6_option
;
1500 fqdn6_universe
.delete_func
= delete_fqdn6_option
;
1501 fqdn6_universe
.encapsulate
= fqdn6_option_space_encapsulate
;
1502 fqdn6_universe
.foreach
= fqdn6_option_space_foreach
;
1503 fqdn6_universe
.decode
= fqdn6_universe_decode
;
1504 /* This is not a 'normal' encapsulated space, so these values are
1507 fqdn6_universe
.length_size
= 0;
1508 fqdn6_universe
.tag_size
= 0;
1509 fqdn6_universe
.get_tag
= NULL
;
1510 fqdn6_universe
.store_tag
= NULL
;
1511 fqdn6_universe
.get_length
= NULL
;
1512 fqdn6_universe
.store_length
= NULL
;
1513 fqdn6_universe
.site_code_min
= 0;
1514 fqdn6_universe
.end
= 0;
1515 fqdn6_universe
.index
= universe_count
++;
1516 code
= D6O_CLIENT_FQDN
;
1517 fqdn6_universe
.enc_opt
= NULL
;
1518 if (!option_code_hash_lookup(&fqdn6_universe
.enc_opt
,
1519 dhcpv6_universe
.code_hash
, &code
, 0, MDL
))
1520 log_fatal("Unable to find FQDN v6 parent option. (%s:%d).",
1522 universes
[fqdn6_universe
.index
] = &fqdn6_universe
;
1523 /* The fqdn6 space shares the same option space as the v4 space.
1524 * So there are no name or code hashes on the v6 side.
1526 fqdn6_universe
.name_hash
= NULL
;
1527 fqdn6_universe
.code_hash
= NULL
;
1530 /* Set up the hash of DHCPv4 universes. */
1531 universe_new_hash(&universe_hash
, UNIVERSE_HASH_SIZE
, MDL
);
1532 universe_hash_add(universe_hash
, dhcp_universe
.name
, 0,
1533 &dhcp_universe
, MDL
);
1534 universe_hash_add(universe_hash
, nwip_universe
.name
, 0,
1535 &nwip_universe
, MDL
);
1536 universe_hash_add(universe_hash
, fqdn_universe
.name
, 0,
1537 &fqdn_universe
, MDL
);
1538 universe_hash_add(universe_hash
, vendor_class_universe
.name
, 0,
1539 &vendor_class_universe
, MDL
);
1540 universe_hash_add(universe_hash
, vendor_universe
.name
, 0,
1541 &vendor_universe
, MDL
);
1542 universe_hash_add(universe_hash
, isc_universe
.name
, 0,
1543 &isc_universe
, MDL
);
1545 /* Set up hashes for DHCPv6 universes. */
1546 universe_hash_add(universe_hash
, dhcpv6_universe
.name
, 0,
1547 &dhcpv6_universe
, MDL
);
1548 universe_hash_add(universe_hash
, vsio_universe
.name
, 0,
1549 &vsio_universe
, MDL
);
1550 universe_hash_add(universe_hash
, isc6_universe
.name
, 0,
1551 &isc6_universe
, MDL
);
1552 /* previously this wasn't necessary, now that we can send
1553 * v6 encapsulated options it is.
1555 universe_hash_add(universe_hash
, fqdn6_universe
.name
, 0,
1556 &fqdn6_universe
, MDL
);