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