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