File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / common / tables.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:06:54 2012 UTC (11 years, 8 months ago) by misho
Branches: dhcp, MAIN
CVS tags: v4_1_R7p0, v4_1_R7, v4_1_R4, HEAD
dhcp 4.1 r7

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>