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