common/tables.c

Go to the documentation of this file.
00001 /* tables.c
00002 
00003    Tables of information... */
00004 
00005 /*
00006  * Copyright (c) 2011-2014 by Internet Systems Consortium, Inc. ("ISC")
00007  * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
00008  * Copyright (c) 1995-2003 by Internet Software Consortium
00009  *
00010  * Permission to use, copy, modify, and distribute this software for any
00011  * purpose with or without fee is hereby granted, provided that the above
00012  * copyright notice and this permission notice appear in all copies.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
00015  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00016  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
00017  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00018  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00019  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00020  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00021  *
00022  *   Internet Systems Consortium, Inc.
00023  *   950 Charter Street
00024  *   Redwood City, CA 94063
00025  *   <info@isc.org>
00026  *   https://www.isc.org/
00027  *
00028  */
00029 
00030 #include "dhcpd.h"
00031 
00032 /* XXXDPN: Moved here from hash.c, when it moved to libomapi.  Not sure
00033    where these really belong. */
00034 HASH_FUNCTIONS (group, const char *, struct group_object, group_hash_t,
00035                 group_reference, group_dereference, do_string_hash)
00036 HASH_FUNCTIONS (universe, const char *, struct universe, universe_hash_t, 0, 0,
00037                 do_case_hash)
00038 HASH_FUNCTIONS (option_name, const char *, struct option, option_name_hash_t,
00039                 option_reference, option_dereference, do_case_hash)
00040 HASH_FUNCTIONS (option_code, const unsigned *, struct option,
00041                 option_code_hash_t, option_reference, option_dereference,
00042                 do_number_hash)
00043 
00044 /* DHCP Option names, formats and codes, from RFC1533.
00045 
00046    Format codes:
00047 
00048    I - IPv4 address
00049    R - destination descriptor (RFC3442)
00050    6 - IPv6 address
00051    l - 32-bit signed integer
00052    L - 32-bit unsigned integer
00053    s - 16-bit signed integer
00054    S - 16-bit unsigned integer
00055    b - 8-bit signed integer
00056    B - 8-bit unsigned integer
00057    t - ASCII text
00058    T - Lease Time, 32-bit unsigned integer implying a number of seconds from
00059        some event.  The special all-ones value means 'infinite'.  May either
00060        be printed as a decimal, eg, "3600", or as this name, eg, "infinite".
00061    f - flag (true or false)
00062    A - array of all that precedes (e.g., fIA means array of records of
00063        a flag and an IP address)
00064    a - array of the preceding character (e.g., fIa means a single flag
00065        followed by an array of IP addresses)
00066    U - name of an option space (universe)
00067    F - implicit flag - the presence of the option indicates that the
00068        flag is true.
00069    o - the preceding value is optional.
00070    E - encapsulation, string or colon-separated hex list (the latter
00071        two for parsing).   E is followed by a text string containing
00072        the name of the option space to encapsulate, followed by a '.'.
00073        If the E is immediately followed by '.', the applicable vendor
00074        option space is used if one is defined.
00075    e - If an encapsulation directive is not the first thing in the string,
00076        the option scanner requires an efficient way to find the encapsulation.
00077        This is done by placing a 'e' at the beginning of the option.   The
00078        'e' has no other purpose, and is not required if 'E' is the first
00079        thing in the option.
00080    X - either an ASCII string or binary data.   On output, the string is
00081        scanned to see if it's printable ASCII and, if so, output as a
00082        quoted string.   If not, it's output as colon-separated hex.   On
00083        input, the option can be specified either as a quoted string or as
00084        a colon-separated hex list.
00085    N - enumeration.   N is followed by a text string containing
00086        the name of the set of enumeration values to parse or emit,
00087        followed by a '.'.   The width of the data is specified in the
00088        named enumeration.   Named enumerations are tracked in parse.c.
00089    d - Domain name (i.e., FOO or FOO.BAR).
00090    D - Domain list (i.e., example.com eng.example.com)
00091    c - When following a 'D' atom, enables compression pointers.
00092    Z - Zero-length option
00093 */
00094 
00095 struct universe dhcp_universe;
00096 static struct option dhcp_options[] = {
00097         { "subnet-mask", "I",                   &dhcp_universe,   1, 1 },
00098         { "time-offset", "l",                   &dhcp_universe,   2, 1 },
00099         { "routers", "IA",                      &dhcp_universe,   3, 1 },
00100         { "time-servers", "IA",                 &dhcp_universe,   4, 1 },
00101         { "ien116-name-servers", "IA",          &dhcp_universe,   5, 1 },
00102         { "domain-name-servers", "IA",          &dhcp_universe,   6, 1 },
00103         { "log-servers", "IA",                  &dhcp_universe,   7, 1 },
00104         { "cookie-servers", "IA",               &dhcp_universe,   8, 1 },
00105         { "lpr-servers", "IA",                  &dhcp_universe,   9, 1 },
00106         { "impress-servers", "IA",              &dhcp_universe,  10, 1 },
00107         { "resource-location-servers", "IA",    &dhcp_universe,  11, 1 },
00108         { "host-name", "t",                     &dhcp_universe,  12, 1 },
00109         { "boot-size", "S",                     &dhcp_universe,  13, 1 },
00110         { "merit-dump", "t",                    &dhcp_universe,  14, 1 },
00111         { "domain-name", "t",                   &dhcp_universe,  15, 1 },
00112         { "swap-server", "I",                   &dhcp_universe,  16, 1 },
00113         { "root-path", "t",                     &dhcp_universe,  17, 1 },
00114         { "extensions-path", "t",               &dhcp_universe,  18, 1 },
00115         { "ip-forwarding", "f",                 &dhcp_universe,  19, 1 },
00116         { "non-local-source-routing", "f",      &dhcp_universe,  20, 1 },
00117         { "policy-filter", "IIA",               &dhcp_universe,  21, 1 },
00118         { "max-dgram-reassembly", "S",          &dhcp_universe,  22, 1 },
00119         { "default-ip-ttl", "B",                &dhcp_universe,  23, 1 },
00120         { "path-mtu-aging-timeout", "L",        &dhcp_universe,  24, 1 },
00121         { "path-mtu-plateau-table", "SA",       &dhcp_universe,  25, 1 },
00122         { "interface-mtu", "S",                 &dhcp_universe,  26, 1 },
00123         { "all-subnets-local", "f",             &dhcp_universe,  27, 1 },
00124         { "broadcast-address", "I",             &dhcp_universe,  28, 1 },
00125         { "perform-mask-discovery", "f",        &dhcp_universe,  29, 1 },
00126         { "mask-supplier", "f",                 &dhcp_universe,  30, 1 },
00127         { "router-discovery", "f",              &dhcp_universe,  31, 1 },
00128         { "router-solicitation-address", "I",   &dhcp_universe,  32, 1 },
00129         { "static-routes", "IIA",               &dhcp_universe,  33, 1 },
00130         { "trailer-encapsulation", "f",         &dhcp_universe,  34, 1 },
00131         { "arp-cache-timeout", "L",             &dhcp_universe,  35, 1 },
00132         { "ieee802-3-encapsulation", "f",       &dhcp_universe,  36, 1 },
00133         { "default-tcp-ttl", "B",               &dhcp_universe,  37, 1 },
00134         { "tcp-keepalive-interval", "L",        &dhcp_universe,  38, 1 },
00135         { "tcp-keepalive-garbage", "f",         &dhcp_universe,  39, 1 },
00136         { "nis-domain", "t",                    &dhcp_universe,  40, 1 },
00137         { "nis-servers", "IA",                  &dhcp_universe,  41, 1 },
00138         { "ntp-servers", "IA",                  &dhcp_universe,  42, 1 },
00139         { "vendor-encapsulated-options", "E.",  &dhcp_universe,  43, 1 },
00140         { "netbios-name-servers", "IA",         &dhcp_universe,  44, 1 },
00141         { "netbios-dd-server", "IA",            &dhcp_universe,  45, 1 },
00142         { "netbios-node-type", "B",             &dhcp_universe,  46, 1 },
00143         { "netbios-scope", "t",                 &dhcp_universe,  47, 1 },
00144         { "font-servers", "IA",                 &dhcp_universe,  48, 1 },
00145         { "x-display-manager", "IA",            &dhcp_universe,  49, 1 },
00146         { "dhcp-requested-address", "I",        &dhcp_universe,  50, 1 },
00147         { "dhcp-lease-time", "L",               &dhcp_universe,  51, 1 },
00148         { "dhcp-option-overload", "B",          &dhcp_universe,  52, 1 },
00149         { "dhcp-message-type", "B",             &dhcp_universe,  53, 1 },
00150         { "dhcp-server-identifier", "I",        &dhcp_universe,  54, 1 },
00151         { "dhcp-parameter-request-list", "BA",  &dhcp_universe,  55, 1 },
00152         { "dhcp-message", "t",                  &dhcp_universe,  56, 1 },
00153         { "dhcp-max-message-size", "S",         &dhcp_universe,  57, 1 },
00154         { "dhcp-renewal-time", "L",             &dhcp_universe,  58, 1 },
00155         { "dhcp-rebinding-time", "L",           &dhcp_universe,  59, 1 },
00156         { "vendor-class-identifier", "X",       &dhcp_universe,  60, 1 },
00157         { "dhcp-client-identifier", "X",        &dhcp_universe,  61, 1 },
00158         { "nwip-domain", "t",                   &dhcp_universe,  62, 1 },
00159         { "nwip-suboptions", "Enwip.",          &dhcp_universe,  63, 1 },
00160         { "nisplus-domain", "t",                &dhcp_universe,  64, 1 },
00161         { "nisplus-servers", "IA",              &dhcp_universe,  65, 1 },
00162         { "tftp-server-name", "t",              &dhcp_universe,  66, 1 },
00163         { "bootfile-name", "t",                 &dhcp_universe,  67, 1 },
00164         { "mobile-ip-home-agent", "IA",         &dhcp_universe,  68, 1 },
00165         { "smtp-server", "IA",                  &dhcp_universe,  69, 1 },
00166         { "pop-server", "IA",                   &dhcp_universe,  70, 1 },
00167         { "nntp-server", "IA",                  &dhcp_universe,  71, 1 },
00168         { "www-server", "IA",                   &dhcp_universe,  72, 1 },
00169         { "finger-server", "IA",                &dhcp_universe,  73, 1 },
00170         { "irc-server", "IA",                   &dhcp_universe,  74, 1 },
00171         { "streettalk-server", "IA",            &dhcp_universe,  75, 1 },
00172         { "streettalk-directory-assistance-server", "IA",
00173                                                 &dhcp_universe,  76, 1 },
00174         { "user-class", "t",                    &dhcp_universe,  77, 1 },
00175         { "slp-directory-agent", "fIa",         &dhcp_universe,  78, 1 },
00176         { "slp-service-scope", "fto",           &dhcp_universe,  79, 1 },
00177         /* 80 is the zero-length rapid-commit (RFC 4039) */
00178         { "fqdn", "Efqdn.",                     &dhcp_universe,  81, 1 },
00179         { "relay-agent-information", "Eagent.", &dhcp_universe,  82, 1 },
00180         /* 83 is iSNS (RFC 4174) */
00181         /* 84 is unassigned */
00182         { "nds-servers", "IA",                  &dhcp_universe,  85, 1 },
00183         { "nds-tree-name", "t",                 &dhcp_universe,  86, 1 },
00184         { "nds-context", "t",                   &dhcp_universe,  87, 1 },
00185 
00186         /* Note: RFC4280 fails to identify if the DHCPv4 option is to use
00187          * compression pointers or not.  Assume not.
00188          */
00189         { "bcms-controller-names", "D",         &dhcp_universe,  88, 1 },
00190         { "bcms-controller-address", "Ia",      &dhcp_universe,  89, 1 },
00191 
00192         /* 90 is the authentication option (RFC 3118) */
00193 
00194         { "client-last-transaction-time", "L",  &dhcp_universe,  91, 1 },
00195         { "associated-ip", "Ia",                &dhcp_universe,  92, 1 },
00196 #if 0
00197         /* Defined by RFC 4578 */
00198         { "pxe-system-type", "S",               &dhcp_universe,  93, 1 },
00199         { "pxe-interface-id", "BBB",            &dhcp_universe,  94, 1 },
00200         { "pxe-client-id", "BX",                &dhcp_universe,  97, 1 },
00201 #endif
00202         { "uap-servers", "t",                   &dhcp_universe,  98, 1 },
00203 #if defined(RFC4776_OPTIONS)
00204         { "geoconf-civic", "X",                 &dhcp_universe, 99, 1 },
00205 #endif
00206 #if defined(RFC4833_OPTIONS)
00207         { "pcode", "t",                         &dhcp_universe, 100, 1 },
00208         { "tcode", "t",                         &dhcp_universe, 101, 1 },
00209 #endif
00210         { "netinfo-server-address", "Ia",       &dhcp_universe, 112, 1 },
00211         { "netinfo-server-tag", "t",            &dhcp_universe, 113, 1 },
00212         { "default-url", "t",                   &dhcp_universe, 114, 1 },
00213 #if defined(RFC2937_OPTIONS)
00214         { "name-service-search", "Sa",          &dhcp_universe, 117, 1 },
00215 #endif
00216         { "subnet-selection", "I",              &dhcp_universe, 118, 1 },
00217         { "domain-search", "D",                 &dhcp_universe, 119, 1 },
00218         { "classless-static-routes", "RIA",     &dhcp_universe, 121, 1 },
00219         { "vivco", "Evendor-class.",            &dhcp_universe, 124, 1 },
00220         { "vivso", "Evendor.",                  &dhcp_universe, 125, 1 },
00221 #if 0
00222         /* Referenced by RFC 4578.
00223          * DO NOT UNCOMMENT THESE DEFINITIONS: these names are placeholders
00224          * and will not be used in future versions of the software.
00225          */
00226         { "pxe-undefined-1", "X",               &dhcp_universe, 128, 1 },
00227         { "pxe-undefined-2", "X",               &dhcp_universe, 129, 1 },
00228         { "pxe-undefined-3", "X",               &dhcp_universe, 130, 1 },
00229         { "pxe-undefined-4", "X",               &dhcp_universe, 131, 1 },
00230         { "pxe-undefined-5", "X",               &dhcp_universe, 132, 1 },
00231         { "pxe-undefined-6", "X",               &dhcp_universe, 133, 1 },
00232         { "pxe-undefined-7", "X",               &dhcp_universe, 134, 1 },
00233         { "pxe-undefined-8", "X",               &dhcp_universe, 135, 1 },
00234 #endif
00235 #if defined(RFC5192_OPTIONS)
00236         {"pana-agent", "Ia",                    &dhcp_universe, 136, 1 },
00237 #endif
00238 #if defined(RFC5223_OPTIONS)
00239         {"v4-lost", "d",                        &dhcp_universe, 137, 1 },
00240 #endif
00241 #if defined(RFC5417_OPTIONS)
00242         {"capwap-ac-v4", "Ia",                  &dhcp_universe, 138, 1 },
00243 #endif
00244 #if defined(RFC6731_OPTIONS)
00245         { "rdnss-selection", "BIID",            &dhcp_universe, 146, 1 },
00246 #endif
00247 #if 0
00248         /* Not defined by RFC yet */
00249         { "tftp-server-address", "Ia",          &dhcp_universe, 150, 1 },
00250 #endif
00251 #if 0
00252         /* PXELINUX options: defined by RFC 5071 */
00253         { "pxelinux-magic", "BBBB",             &dhcp_universe, 208, 1 },
00254         { "loader-configfile", "t",             &dhcp_universe, 209, 1 },
00255         { "loader-pathprefix", "t",             &dhcp_universe, 210, 1 },
00256         { "loader-reboottime", "L",             &dhcp_universe, 211, 1 },
00257 #endif
00258 #if defined(RFC5969_OPTIONS)
00259         { "option-6rd", "BB6Ia",                &dhcp_universe, 212, 1 },
00260 #endif
00261 #if defined(RFC5986_OPTIONS)
00262         {"v4-access-domain", "d",               &dhcp_universe, 213, 1 },
00263 #endif
00264         { NULL, NULL, NULL, 0, 0 }
00265 };
00266 
00267 struct universe nwip_universe;
00268 static struct option nwip_options[] = {
00269         { "illegal-1", "",                      &nwip_universe,   1, 1 },
00270         { "illegal-2", "",                      &nwip_universe,   2, 1 },
00271         { "illegal-3", "",                      &nwip_universe,   3, 1 },
00272         { "illegal-4", "",                      &nwip_universe,   4, 1 },
00273         { "nsq-broadcast", "f",                 &nwip_universe,   5, 1 },
00274         { "preferred-dss", "IA",                &nwip_universe,   6, 1 },
00275         { "nearest-nwip-server", "IA",          &nwip_universe,   7, 1 },
00276         { "autoretries", "B",                   &nwip_universe,   8, 1 },
00277         { "autoretry-secs", "B",                &nwip_universe,   9, 1 },
00278         { "nwip-1-1", "f",                      &nwip_universe,  10, 1 },
00279         { "primary-dss", "I",                   &nwip_universe,  11, 1 },
00280         { NULL, NULL, NULL, 0, 0 }
00281 };
00282 
00283 /* Note that the "FQDN suboption space" does not reflect the FQDN option
00284  * format - rather, this is a handy "virtualization" of a flat option
00285  * which makes manual configuration and presentation of some of its
00286  * contents easier (each of these suboptions is a fixed-space field within
00287  * the fqdn contents - domain and host names are derived from a common field,
00288  * and differ in the left and right hand side of the leftmost dot, fqdn is
00289  * the combination of the two).
00290  *
00291  * Note further that the DHCPv6 and DHCPv4 'fqdn' options use the same
00292  * virtualized option space to store their work.
00293  */
00294 
00295 struct universe fqdn_universe;
00296 struct universe fqdn6_universe;
00297 static struct option fqdn_options[] = {
00298         { "no-client-update", "f",              &fqdn_universe,   1, 1 },
00299         { "server-update", "f",                 &fqdn_universe,   2, 1 },
00300         { "encoded", "f",                       &fqdn_universe,   3, 1 },
00301         { "rcode1", "B",                        &fqdn_universe,   4, 1 },
00302         { "rcode2", "B",                        &fqdn_universe,   5, 1 },
00303         { "hostname", "t",                      &fqdn_universe,   6, 1 },
00304         { "domainname", "t",                    &fqdn_universe,   7, 1 },
00305         { "fqdn", "t",                          &fqdn_universe,   8, 1 },
00306         { NULL, NULL, NULL, 0, 0 }
00307 };
00308 
00309 struct universe vendor_class_universe;
00310 static struct option vendor_class_options[] =  {
00311         { "isc", "X",                   &vendor_class_universe,      2495, 1 },
00312         { NULL, NULL, NULL, 0, 0 }
00313 };
00314 
00315 struct universe vendor_universe;
00316 static struct option vendor_options[] = {
00317         { "isc", "Eisc.",               &vendor_universe,            2495, 1 },
00318         { NULL, NULL, NULL, 0, 0 }
00319 };
00320 
00321 struct universe isc_universe;
00322 static struct option isc_options [] = {
00323         { "media", "t",                         &isc_universe,   1, 1 },
00324         { "update-assist", "X",                 &isc_universe,   2, 1 },
00325         { NULL, NULL, NULL, 0, 0 }
00326 };
00327 
00328 struct universe dhcpv6_universe;
00329 static struct option dhcpv6_options[] = {
00330 
00331                                 /* RFC3315 OPTIONS */
00332 
00333         /* Client and server DUIDs are opaque fields, but marking them
00334          * up somewhat makes configuration easier.
00335          */
00336         { "client-id", "X",                     &dhcpv6_universe,  1, 1 },
00337         { "server-id", "X",                     &dhcpv6_universe,  2, 1 },
00338 
00339         /* ia-* options actually have at their ends a space for options
00340          * that are specific to this instance of the option.  We can not
00341          * handle this yet at this stage of development, so the encoding
00342          * of these options is unspecified ("X").
00343          */
00344         { "ia-na", "X",                         &dhcpv6_universe,  3, 1 },
00345         { "ia-ta", "X",                         &dhcpv6_universe,  4, 1 },
00346         { "ia-addr", "X",                       &dhcpv6_universe,  5, 1 },
00347 
00348         /* "oro" is DHCPv6 speak for "parameter-request-list" */
00349         { "oro", "SA",                          &dhcpv6_universe,  6, 1 },
00350 
00351         { "preference", "B",                    &dhcpv6_universe,  7, 1 },
00352         { "elapsed-time", "S",                  &dhcpv6_universe,  8, 1 },
00353         { "relay-msg", "X",                     &dhcpv6_universe,  9, 1 },
00354 
00355         /* Option code 10 is curiously unassigned. */
00356         /* 
00357          * In draft-ietf-dhc-dhcpv6-25 there were two OPTION_CLIENT_MSG and
00358          * OPTION_SERVER_MSG options. They were eventually unified as
00359          * OPTION_RELAY_MSG, hence no option with value of 10. 
00360          */
00361 #if 0
00362         /* XXX: missing suitable atoms for the auth option.  We may want
00363          * to 'virtually encapsulate' this option a la the fqdn option
00364          * seeing as it is processed explicitly by the server and unlikely
00365          * to be configured by hand by users as such.
00366          */
00367         { "auth", "Nauth-protocol.Nauth-algorithm.Nrdm-type.LLX",
00368                                                 &dhcpv6_universe, 11, 1 },
00369 #endif
00370         { "unicast", "6",                       &dhcpv6_universe, 12, 1 },
00371         { "status-code", "Nstatus-codes.to",    &dhcpv6_universe, 13, 1 },
00372         { "rapid-commit", "Z",                  &dhcpv6_universe, 14, 1 },
00373 #if 0
00374         /* XXX: user-class contents are of the form "StA" where the
00375          * integer describes the length of the text field.  We don't have
00376          * an atom for pre-determined-length octet strings yet, so we
00377          * can't quite do these two.
00378          */
00379         { "user-class", "X",                    &dhcpv6_universe, 15, 1 },
00380         { "vendor-class", "X",                  &dhcpv6_universe, 16, 1 },
00381 #endif
00382         { "vendor-opts", "Evsio.",              &dhcpv6_universe, 17, 1 },
00383         { "interface-id", "X",                  &dhcpv6_universe, 18, 1 },
00384         { "reconf-msg", "Ndhcpv6-messages.",    &dhcpv6_universe, 19, 1 },
00385         { "reconf-accept", "Z",                 &dhcpv6_universe, 20, 1 },
00386 
00387                                 /* RFC3319 OPTIONS */
00388 
00389         /* Of course: we would HAVE to have a different atom for
00390          * domain names without compression.  Typical.
00391          */
00392         { "sip-servers-names", "D",             &dhcpv6_universe, 21, 1 },
00393         { "sip-servers-addresses", "6A",        &dhcpv6_universe, 22, 1 },
00394 
00395                                 /* RFC3646 OPTIONS */
00396 
00397         { "name-servers", "6A",                 &dhcpv6_universe, 23, 1 },
00398         { "domain-search", "D",                 &dhcpv6_universe, 24, 1 },
00399 
00400                                 /* RFC3633 OPTIONS */
00401 
00402         { "ia-pd", "X",                         &dhcpv6_universe, 25, 1 },
00403         { "ia-prefix", "X",                     &dhcpv6_universe, 26, 1 },
00404 
00405                                 /* RFC3898 OPTIONS */
00406 
00407         { "nis-servers", "6A",                  &dhcpv6_universe, 27, 1 },
00408         { "nisp-servers", "6A",                 &dhcpv6_universe, 28, 1 },
00409         { "nis-domain-name", "D",               &dhcpv6_universe, 29, 1 },
00410         { "nisp-domain-name", "D",              &dhcpv6_universe, 30, 1 },
00411 
00412                                 /* RFC4075 OPTIONS */
00413         { "sntp-servers", "6A",                 &dhcpv6_universe, 31, 1 },
00414 
00415                                 /* RFC4242 OPTIONS */
00416 
00417         { "info-refresh-time", "T",             &dhcpv6_universe, 32, 1 },
00418 
00419                                 /* RFC4280 OPTIONS */
00420 
00421         { "bcms-server-d", "D",                 &dhcpv6_universe, 33, 1 },
00422         { "bcms-server-a", "6A",                &dhcpv6_universe, 34, 1 },
00423 
00424         /* Note that 35 is not assigned. */
00425 
00426 #if defined(RFC4776_OPTIONS)
00427                         /* RFC4776 OPTIONS */
00428 
00429         { "geoconf-civic", "X",                 &dhcpv6_universe, 36, 1 },
00430 #endif
00431 
00432                                 /* RFC4649 OPTIONS */
00433 
00434         /* The remote-id option looks like the VSIO option, but for all
00435          * intents and purposes we only need to treat the entire field
00436          * like a globally unique identifier (and if we create such an
00437          * option, ensure the first 4 bytes are our enterprise-id followed
00438          * by a globally unique ID so long as you're within that enterprise
00439          * id).  So we'll use "X" for now unless someone grumbles.
00440          */
00441         { "remote-id", "X",                     &dhcpv6_universe, 37, 1 },
00442 
00443                                 /* RFC4580 OPTIONS */
00444 
00445         { "subscriber-id", "X",                 &dhcpv6_universe, 38, 1 },
00446 
00447                                 /* RFC4704 OPTIONS */
00448 
00449         /* The DHCPv6 FQDN option is...weird.
00450          *
00451          * We use the same "virtual" encapsulated space as DHCPv4's FQDN
00452          * option, so it can all be configured in one place.  Since the
00453          * options system does not support multiple inheritance, we use
00454          * a 'shill' layer to perform the different protocol conversions,
00455          * and to redirect any queries in the DHCPv4 FQDN's space.
00456          */
00457         { "fqdn", "Efqdn6-if-you-see-me-its-a-bug-bug-bug.",
00458                                                 &dhcpv6_universe, 39, 1 },
00459 
00460 
00461                         /* RFC5192 */
00462 #if defined(RFC5192_OPTIONS)
00463         { "pana-agent", "6A",                   &dhcpv6_universe, 40, 1 },
00464 #endif
00465 
00466                         /* RFC4833 OPTIONS */
00467 #if defined(RFC4833_OPTIONS)
00468         { "new-posix-timezone", "t",            &dhcpv6_universe, 41, 1 },
00469         { "new-tzdb-timezone", "t",             &dhcpv6_universe, 42, 1 },
00470 #endif
00471 
00472                         /* RFC4994 OPTIONS */
00473 #if defined(RFC4994_OPTIONS)
00474         { "ero", "SA",                          &dhcpv6_universe, 43, 1 },
00475 #endif
00476 
00477                         /* RFC5007 OPTIONS */
00478 
00479         { "lq-query", "X",                      &dhcpv6_universe, 44, 1 },
00480         { "client-data", "X",                   &dhcpv6_universe, 45, 1 },
00481         { "clt-time", "L",                      &dhcpv6_universe, 46, 1 },
00482         { "lq-relay-data", "6X",                &dhcpv6_universe, 47, 1 },
00483         { "lq-client-link", "6A",               &dhcpv6_universe, 48, 1 },
00484 
00485                         /* RFC5223 OPTIONS */
00486 #if defined(RFC5223_OPTIONS)
00487         { "v6-lost", "d",                       &dhcpv6_universe, 51, 1 },
00488 #endif
00489 
00490                         /* RFC5417 OPTIONS */
00491 #if defined(RFC5417_OPTIONS)
00492         { "capwap-ac-v6", "6a",                 &dhcpv6_universe, 52, 1 },
00493 #endif
00494 
00495                         /* RFC5460 OPTIONS */
00496 #if defined(RFC5460_OPTIONS)
00497         { "relay-id", "X",                      &dhcpv6_universe, 53, 1 },
00498 #endif
00499 
00500                         /* RFC5986 OPTIONS */
00501 #if defined(RFC5986_OPTIONS)
00502         { "v6-access-domain", "d",              &dhcpv6_universe, 57, 1 },
00503 #endif
00504 
00505                         /* RFC6011 OPTIONS */
00506 #if defined(RFC6011_OPTIONS)
00507         { "sip-ua-cs-list", "D",                &dhcpv6_universe, 58, 1 },
00508 #endif
00509 
00510                         /* RFC5970 OPTIONS */
00511 #if defined(RFC5970_OPTIONS)
00512         { "bootfile-url", "t",                  &dhcpv6_universe, 59, 1 },
00513         { "bootfile-param", "X",                &dhcpv6_universe, 60, 1 },
00514         { "client-arch-type", "SA",             &dhcpv6_universe, 61, 1 },
00515         { "nii", "BBB",                         &dhcpv6_universe, 62, 1 },
00516 #endif
00517 
00518                         /* RFC6334 OPTIONS */
00519 #if defined(RFC6334_OPTIONS)
00520         { "aftr-name", "d",                     &dhcpv6_universe, 64, 1 },
00521 #endif
00522 
00523                         /* RFC6440 OPTIONS */
00524 #if defined(RFC6440_OPTIONS)
00525         { "erp-local-domain-name", "d",         &dhcpv6_universe, 65, 1 },
00526 #endif
00527 
00528                         /* RFC6731 OPTIONS */
00529 #if defined(RFC6731_OPTIONS)
00530         { "rdnss-selection", "6BD",             &dhcpv6_universe, 74, 1 },
00531 #endif
00532 
00533                         /* RFC6939 OPTIONS */
00534 #if defined(RFC6939_OPTIONS)
00535         { "client-linklayer-addr", "X",         &dhcpv6_universe, 79, 1 },
00536 #endif
00537 
00538                         /* RFC6977 OPTIONS */
00539 #if defined(RFC6977_OPTIONS)
00540         { "link-address", "6",                  &dhcpv6_universe, 80, 1 },
00541 #endif
00542 
00543                         /* RFC7083 OPTIONS */
00544 #if defined(RFC7083_OPTIONS)
00545         { "solmax-rt", "L",                     &dhcpv6_universe, 82, 1 },
00546         { "inf-max-rt", "L",                    &dhcpv6_universe, 83, 1 },
00547 #endif
00548 
00549         { NULL, NULL, NULL, 0, 0 }
00550 };
00551 
00552 struct enumeration_value dhcpv6_duid_type_values[] = {
00553         { "duid-llt",   DUID_LLT }, /* Link-Local Plus Time */
00554         { "duid-en",    DUID_EN },  /* DUID based upon enterprise-ID. */
00555         { "duid-ll",    DUID_LL },  /* DUID from Link Local address only. */
00556         { NULL, 0 }
00557 };
00558 
00559 struct enumeration dhcpv6_duid_types = {
00560         NULL,
00561         "duid-types", 2,
00562         dhcpv6_duid_type_values
00563 };
00564 
00565 struct enumeration_value dhcpv6_status_code_values[] = {
00566         { "success",      0 }, /* Success                               */
00567         { "UnspecFail",   1 }, /* Failure, for unspecified reasons.     */
00568         { "NoAddrsAvail", 2 }, /* Server has no addresses to assign.    */
00569         { "NoBinding",    3 }, /* Client record (binding) unavailable.  */
00570         { "NotOnLink",    4 }, /* Bad prefix for the link.              */
00571         { "UseMulticast", 5 }, /* Not just good advice.  It's the law.  */
00572         { "NoPrefixAvail", 6 }, /* Server has no prefixes to assign.    */
00573         { "UnknownQueryType", 7 }, /* Query-type unknown/unsupported.   */
00574         { "MalformedQuery", 8 }, /* Leasequery not valid.               */
00575         { "NotConfigured", 9 }, /* The target address is not in config. */
00576         { "NotAllowed",  10 }, /* Server doesn't allow the leasequery.  */
00577         { NULL, 0 }
00578 };
00579 
00580 struct enumeration dhcpv6_status_codes = {
00581         NULL,
00582         "status-codes", 2,
00583         dhcpv6_status_code_values
00584 };
00585 
00586 struct enumeration_value lq6_query_type_values[] = {
00587         { "query-by-address", 1 },
00588         { "query-by-clientid", 2 },
00589         { NULL, 0 }
00590 };
00591 
00592 struct enumeration lq6_query_types = {
00593         NULL,
00594         "query-types", 2,
00595         lq6_query_type_values
00596 };
00597 
00598 struct enumeration_value dhcpv6_message_values[] = {
00599         { "SOLICIT", 1 },
00600         { "ADVERTISE", 2 },
00601         { "REQUEST", 3 },
00602         { "CONFIRM", 4 },
00603         { "RENEW", 5 },
00604         { "REBIND", 6 },
00605         { "REPLY", 7 },
00606         { "RELEASE", 8 },
00607         { "DECLINE", 9 },
00608         { "RECONFIGURE", 10 },
00609         { "INFORMATION-REQUEST", 11 },
00610         { "RELAY-FORW", 12 },
00611         { "RELAY-REPL", 13 },
00612         { "LEASEQUERY", 14 },
00613         { "LEASEQUERY-REPLY", 15 },
00614         { NULL, 0 }
00615 };
00616 
00617 /* Some code refers to a different table. */
00618 const char *dhcpv6_type_names[] = {
00619         NULL,
00620         "Solicit",
00621         "Advertise",
00622         "Request",
00623         "Confirm",
00624         "Renew",
00625         "Rebind",
00626         "Reply",
00627         "Release",
00628         "Decline",
00629         "Reconfigure",
00630         "Information-request",
00631         "Relay-forward",
00632         "Relay-reply",
00633         "Leasequery",
00634         "Leasequery-reply"
00635 };
00636 const int dhcpv6_type_name_max =
00637         (sizeof(dhcpv6_type_names) / sizeof(dhcpv6_type_names[0]));
00638 
00639 struct enumeration dhcpv6_messages = {
00640         NULL,
00641         "dhcpv6-messages", 1,
00642         dhcpv6_message_values
00643 };
00644 
00645 struct universe vsio_universe;
00646 static struct option vsio_options[] = {
00647         { "isc", "Eisc6.",              &vsio_universe,              2495, 1 },
00648         { NULL, NULL, NULL, 0, 0 }
00649 };
00650 
00651 struct universe isc6_universe;
00652 static struct option isc6_options[] = {
00653         { "media", "t",                         &isc6_universe,     1, 1 },
00654         { "update-assist", "X",                 &isc6_universe,     2, 1 },
00655         { NULL, NULL, NULL, 0, 0 }
00656 };
00657 
00658 const char *hardware_types [] = {
00659         "unknown-0",
00660         "ethernet",
00661         "unknown-2",
00662         "unknown-3",
00663         "unknown-4",
00664         "unknown-5",
00665         "token-ring",
00666         "unknown-7",
00667         "fddi",
00668         "unknown-9",
00669         "unknown-10",
00670         "unknown-11",
00671         "unknown-12",
00672         "unknown-13",
00673         "unknown-14",
00674         "unknown-15",
00675         "unknown-16",
00676         "unknown-17",
00677         "unknown-18",
00678         "unknown-19",
00679         "unknown-20",
00680         "unknown-21",
00681         "unknown-22",
00682         "unknown-23",
00683         "unknown-24",
00684         "unknown-25",
00685         "unknown-26",
00686         "unknown-27",
00687         "unknown-28",
00688         "unknown-29",
00689         "unknown-30",
00690         "unknown-31",
00691         "infiniband",
00692         "unknown-33",
00693         "unknown-34",
00694         "unknown-35",
00695         "unknown-36",
00696         "unknown-37",
00697         "unknown-38",
00698         "unknown-39",
00699         "unknown-40",
00700         "unknown-41",
00701         "unknown-42",
00702         "unknown-43",
00703         "unknown-44",
00704         "unknown-45",
00705         "unknown-46",
00706         "unknown-47",
00707         "unknown-48",
00708         "unknown-49",
00709         "unknown-50",
00710         "unknown-51",
00711         "unknown-52",
00712         "unknown-53",
00713         "unknown-54",
00714         "unknown-55",
00715         "unknown-56",
00716         "unknown-57",
00717         "unknown-58",
00718         "unknown-59",
00719         "unknown-60",
00720         "unknown-61",
00721         "unknown-62",
00722         "unknown-63",
00723         "unknown-64",
00724         "unknown-65",
00725         "unknown-66",
00726         "unknown-67",
00727         "unknown-68",
00728         "unknown-69",
00729         "unknown-70",
00730         "unknown-71",
00731         "unknown-72",
00732         "unknown-73",
00733         "unknown-74",
00734         "unknown-75",
00735         "unknown-76",
00736         "unknown-77",
00737         "unknown-78",
00738         "unknown-79",
00739         "unknown-80",
00740         "unknown-81",
00741         "unknown-82",
00742         "unknown-83",
00743         "unknown-84",
00744         "unknown-85",
00745         "unknown-86",
00746         "unknown-87",
00747         "unknown-88",
00748         "unknown-89",
00749         "unknown-90",
00750         "unknown-91",
00751         "unknown-92",
00752         "unknown-93",
00753         "unknown-94",
00754         "unknown-95",
00755         "unknown-96",
00756         "unknown-97",
00757         "unknown-98",
00758         "unknown-99",
00759         "unknown-100",
00760         "unknown-101",
00761         "unknown-102",
00762         "unknown-103",
00763         "unknown-104",
00764         "unknown-105",
00765         "unknown-106",
00766         "unknown-107",
00767         "unknown-108",
00768         "unknown-109",
00769         "unknown-110",
00770         "unknown-111",
00771         "unknown-112",
00772         "unknown-113",
00773         "unknown-114",
00774         "unknown-115",
00775         "unknown-116",
00776         "unknown-117",
00777         "unknown-118",
00778         "unknown-119",
00779         "unknown-120",
00780         "unknown-121",
00781         "unknown-122",
00782         "unknown-123",
00783         "unknown-124",
00784         "unknown-125",
00785         "unknown-126",
00786         "unknown-127",
00787         "unknown-128",
00788         "unknown-129",
00789         "unknown-130",
00790         "unknown-131",
00791         "unknown-132",
00792         "unknown-133",
00793         "unknown-134",
00794         "unknown-135",
00795         "unknown-136",
00796         "unknown-137",
00797         "unknown-138",
00798         "unknown-139",
00799         "unknown-140",
00800         "unknown-141",
00801         "unknown-142",
00802         "unknown-143",
00803         "unknown-144",
00804         "unknown-145",
00805         "unknown-146",
00806         "unknown-147",
00807         "unknown-148",
00808         "unknown-149",
00809         "unknown-150",
00810         "unknown-151",
00811         "unknown-152",
00812         "unknown-153",
00813         "unknown-154",
00814         "unknown-155",
00815         "unknown-156",
00816         "unknown-157",
00817         "unknown-158",
00818         "unknown-159",
00819         "unknown-160",
00820         "unknown-161",
00821         "unknown-162",
00822         "unknown-163",
00823         "unknown-164",
00824         "unknown-165",
00825         "unknown-166",
00826         "unknown-167",
00827         "unknown-168",
00828         "unknown-169",
00829         "unknown-170",
00830         "unknown-171",
00831         "unknown-172",
00832         "unknown-173",
00833         "unknown-174",
00834         "unknown-175",
00835         "unknown-176",
00836         "unknown-177",
00837         "unknown-178",
00838         "unknown-179",
00839         "unknown-180",
00840         "unknown-181",
00841         "unknown-182",
00842         "unknown-183",
00843         "unknown-184",
00844         "unknown-185",
00845         "unknown-186",
00846         "unknown-187",
00847         "unknown-188",
00848         "unknown-189",
00849         "unknown-190",
00850         "unknown-191",
00851         "unknown-192",
00852         "unknown-193",
00853         "unknown-194",
00854         "unknown-195",
00855         "unknown-196",
00856         "unknown-197",
00857         "unknown-198",
00858         "unknown-199",
00859         "unknown-200",
00860         "unknown-201",
00861         "unknown-202",
00862         "unknown-203",
00863         "unknown-204",
00864         "unknown-205",
00865         "unknown-206",
00866         "unknown-207",
00867         "unknown-208",
00868         "unknown-209",
00869         "unknown-210",
00870         "unknown-211",
00871         "unknown-212",
00872         "unknown-213",
00873         "unknown-214",
00874         "unknown-215",
00875         "unknown-216",
00876         "unknown-217",
00877         "unknown-218",
00878         "unknown-219",
00879         "unknown-220",
00880         "unknown-221",
00881         "unknown-222",
00882         "unknown-223",
00883         "unknown-224",
00884         "unknown-225",
00885         "unknown-226",
00886         "unknown-227",
00887         "unknown-228",
00888         "unknown-229",
00889         "unknown-230",
00890         "unknown-231",
00891         "unknown-232",
00892         "unknown-233",
00893         "unknown-234",
00894         "unknown-235",
00895         "unknown-236",
00896         "unknown-237",
00897         "unknown-238",
00898         "unknown-239",
00899         "unknown-240",
00900         "unknown-241",
00901         "unknown-242",
00902         "unknown-243",
00903         "unknown-244",
00904         "unknown-245",
00905         "unknown-246",
00906         "unknown-247",
00907         "unknown-248",
00908         "unknown-249",
00909         "unknown-250",
00910         "unknown-251",
00911         "unknown-252",
00912         "unknown-253",
00913         "unknown-254",
00914         "unknown-255" };
00915 
00916 universe_hash_t *universe_hash;
00917 struct universe **universes;
00918 int universe_count, universe_max;
00919 
00920 /* Universe containing names of configuration options, which, rather than
00921    writing "option universe-name.option-name ...;", can be set by writing
00922    "option-name ...;". */
00923 
00924 struct universe *config_universe;
00925 
00926 /* XXX: omapi must die...all the below keeps us from having to make the
00927  * option structures omapi typed objects, which is a bigger headache.
00928  */
00929 
00930 char *default_option_format = (char *) "X";
00931 
00932 /* Must match hash_reference/dereference types in omapip/hash.h. */
00933 int
00934 option_reference(struct option **dest, struct option *src,
00935                  const char * file, int line)
00936 {
00937         if (!dest || !src)
00938                 return DHCP_R_INVALIDARG;
00939 
00940         if (*dest) {
00941 #if defined(POINTER_DEBUG)
00942                 log_fatal("%s(%d): reference store into non-null pointer!",
00943                           file, line);
00944 #else
00945                 return DHCP_R_INVALIDARG;
00946 #endif
00947         }
00948 
00949         *dest = src;
00950         src->refcnt++;
00951         rc_register(file, line, dest, src, src->refcnt, 0, RC_MISC);
00952         return(ISC_R_SUCCESS);
00953 }
00954 
00955 int
00956 option_dereference(struct option **dest, const char *file, int line)
00957 {
00958         if (!dest)
00959                 return DHCP_R_INVALIDARG;
00960 
00961         if (!*dest) {
00962 #if defined (POINTER_DEBUG)
00963                 log_fatal("%s(%d): dereference of null pointer!", file, line);
00964 #else
00965                 return DHCP_R_INVALIDARG;
00966 #endif
00967         }
00968 
00969         if ((*dest)->refcnt <= 0) {
00970 #if defined (POINTER_DEBUG)
00971                 log_fatal("%s(%d): dereference of <= 0 refcnt!", file, line);
00972 #else
00973                 return DHCP_R_INVALIDARG;
00974 #endif
00975         }
00976 
00977         (*dest)->refcnt--;
00978 
00979         rc_register(file, line, dest, (*dest), (*dest)->refcnt, 1, RC_MISC);
00980 
00981         if ((*dest)->refcnt == 0) {
00982                 /* The option name may be packed in the same alloc as the
00983                  * option structure.
00984                  */
00985                 if ((char *) (*dest)->name != (char *) ((*dest) + 1))
00986                         dfree((char *) (*dest)->name, file, line);
00987 
00988                 /* It's either a user-configured format (allocated), or the
00989                  * default static format.
00990                  */
00991                 if (((*dest)->format != NULL) &&
00992                     ((*dest)->format != default_option_format)) {
00993                         dfree((char *) (*dest)->format, file, line);
00994                 }
00995 
00996                 dfree(*dest, file, line);
00997         }
00998 
00999         *dest = NULL;
01000         return ISC_R_SUCCESS;
01001 }
01002 
01003 void initialize_common_option_spaces()
01004 {
01005         unsigned code;
01006         int i;
01007 
01008         /* The 'universes' table is dynamically grown to contain
01009          * universe as they're configured - except during startup.
01010          * Since we know how many we put down in .c files, we can
01011          * allocate a more-than-right-sized buffer now, leaving some
01012          * space for user-configured option spaces.
01013          *
01014          * 1: dhcp_universe (dhcpv4 options)
01015          * 2: nwip_universe (dhcpv4 NWIP option)
01016          * 3: fqdn_universe (dhcpv4 fqdn option - reusable for v6)
01017          * 4: vendor_class_universe (VIVCO)
01018          * 5: vendor_universe (VIVSO)
01019          * 6: isc_universe (dhcpv4 isc config space)
01020          * 7: dhcpv6_universe (dhcpv6 options)
01021          * 8: vsio_universe (DHCPv6 Vendor-Identified space)
01022          * 9: isc6_universe (ISC's Vendor universe in DHCPv6 VSIO)
01023          * 10: fqdn6_universe (dhcpv6 fqdn option shill to v4)
01024          * 11: agent_universe (dhcpv4 relay agent - see server/stables.c)
01025          * 12: server_universe (server's config, see server/stables.c)
01026          * 13: user-config
01027          * 14: more user-config
01028          * 15: more user-config
01029          * 16: more user-config
01030          */
01031         universe_max = 16;
01032         i = universe_max * sizeof(struct universe *);
01033         if (i <= 0)
01034                 log_fatal("Ludicrous initial size option space table.");
01035         universes = dmalloc(i, MDL);
01036         if (universes == NULL)
01037                 log_fatal("Can't allocate option space table.");
01038         memset(universes, 0, i);
01039 
01040         /* Set up the DHCP option universe... */
01041         dhcp_universe.name = "dhcp";
01042         dhcp_universe.concat_duplicates = 1;
01043         dhcp_universe.lookup_func = lookup_hashed_option;
01044         dhcp_universe.option_state_dereference =
01045                 hashed_option_state_dereference;
01046         dhcp_universe.save_func = save_hashed_option;
01047         dhcp_universe.delete_func = delete_hashed_option;
01048         dhcp_universe.encapsulate = hashed_option_space_encapsulate;
01049         dhcp_universe.foreach = hashed_option_space_foreach;
01050         dhcp_universe.decode = parse_option_buffer;
01051         dhcp_universe.length_size = 1;
01052         dhcp_universe.tag_size = 1;
01053         dhcp_universe.get_tag = getUChar;
01054         dhcp_universe.store_tag = putUChar;
01055         dhcp_universe.get_length = getUChar;
01056         dhcp_universe.store_length = putUChar;
01057         dhcp_universe.site_code_min = 0;
01058         dhcp_universe.end = DHO_END;
01059         dhcp_universe.index = universe_count++;
01060         universes [dhcp_universe.index] = &dhcp_universe;
01061         if (!option_name_new_hash(&dhcp_universe.name_hash,
01062                                   BYTE_NAME_HASH_SIZE, MDL) ||
01063             !option_code_new_hash(&dhcp_universe.code_hash,
01064                                   BYTE_CODE_HASH_SIZE, MDL))
01065                 log_fatal ("Can't allocate dhcp option hash table.");
01066         for (i = 0 ; dhcp_options[i].name ; i++) {
01067                 option_code_hash_add(dhcp_universe.code_hash,
01068                                      &dhcp_options[i].code, 0,
01069                                      &dhcp_options[i], MDL);
01070                 option_name_hash_add(dhcp_universe.name_hash,
01071                                      dhcp_options [i].name, 0,
01072                                      &dhcp_options [i], MDL);
01073         }
01074 #if defined(REPORT_HASH_PERFORMANCE)
01075         log_info("DHCP name hash: %s",
01076                  option_name_hash_report(dhcp_universe.name_hash));
01077         log_info("DHCP code hash: %s",
01078                  option_code_hash_report(dhcp_universe.code_hash));
01079 #endif
01080 
01081         /* Set up the Novell option universe (for option 63)... */
01082         nwip_universe.name = "nwip";
01083         nwip_universe.concat_duplicates = 0; /* XXX: reference? */
01084         nwip_universe.lookup_func = lookup_linked_option;
01085         nwip_universe.option_state_dereference =
01086                 linked_option_state_dereference;
01087         nwip_universe.save_func = save_linked_option;
01088         nwip_universe.delete_func = delete_linked_option;
01089         nwip_universe.encapsulate = nwip_option_space_encapsulate;
01090         nwip_universe.foreach = linked_option_space_foreach;
01091         nwip_universe.decode = parse_option_buffer;
01092         nwip_universe.length_size = 1;
01093         nwip_universe.tag_size = 1;
01094         nwip_universe.get_tag = getUChar;
01095         nwip_universe.store_tag = putUChar;
01096         nwip_universe.get_length = getUChar;
01097         nwip_universe.store_length = putUChar;
01098         nwip_universe.site_code_min = 0;
01099         nwip_universe.end = 0;
01100         code = DHO_NWIP_SUBOPTIONS;
01101         nwip_universe.enc_opt = NULL;
01102         if (!option_code_hash_lookup(&nwip_universe.enc_opt,
01103                                      dhcp_universe.code_hash, &code, 0, MDL))
01104                 log_fatal("Unable to find NWIP parent option (%s:%d).", MDL);
01105         nwip_universe.index = universe_count++;
01106         universes [nwip_universe.index] = &nwip_universe;
01107         if (!option_name_new_hash(&nwip_universe.name_hash,
01108                                   NWIP_HASH_SIZE, MDL) ||
01109             !option_code_new_hash(&nwip_universe.code_hash,
01110                                   NWIP_HASH_SIZE, MDL))
01111                 log_fatal ("Can't allocate nwip option hash table.");
01112         for (i = 0 ; nwip_options[i].name ; i++) {
01113                 option_code_hash_add(nwip_universe.code_hash,
01114                                      &nwip_options[i].code, 0,
01115                                      &nwip_options[i], MDL);
01116                 option_name_hash_add(nwip_universe.name_hash,
01117                                      nwip_options[i].name, 0,
01118                                      &nwip_options[i], MDL);
01119         }
01120 #if defined(REPORT_HASH_PERFORMANCE)
01121         log_info("NWIP name hash: %s",
01122                  option_name_hash_report(nwip_universe.name_hash));
01123         log_info("NWIP code hash: %s",
01124                  option_code_hash_report(nwip_universe.code_hash));
01125 #endif
01126 
01127         /* Set up the FQDN option universe... */
01128         fqdn_universe.name = "fqdn";
01129         fqdn_universe.concat_duplicates = 0;
01130         fqdn_universe.lookup_func = lookup_linked_option;
01131         fqdn_universe.option_state_dereference =
01132                 linked_option_state_dereference;
01133         fqdn_universe.save_func = save_linked_option;
01134         fqdn_universe.delete_func = delete_linked_option;
01135         fqdn_universe.encapsulate = fqdn_option_space_encapsulate;
01136         fqdn_universe.foreach = linked_option_space_foreach;
01137         fqdn_universe.decode = fqdn_universe_decode;
01138         fqdn_universe.length_size = 1;
01139         fqdn_universe.tag_size = 1;
01140         fqdn_universe.get_tag = getUChar;
01141         fqdn_universe.store_tag = putUChar;
01142         fqdn_universe.get_length = getUChar;
01143         fqdn_universe.store_length = putUChar;
01144         fqdn_universe.site_code_min = 0;
01145         fqdn_universe.end = 0;
01146         fqdn_universe.index = universe_count++;
01147         code = DHO_FQDN;
01148         fqdn_universe.enc_opt = NULL;
01149         if (!option_code_hash_lookup(&fqdn_universe.enc_opt,
01150                                      dhcp_universe.code_hash, &code, 0, MDL))
01151                 log_fatal("Unable to find FQDN parent option (%s:%d).", MDL);
01152         universes [fqdn_universe.index] = &fqdn_universe;
01153         if (!option_name_new_hash(&fqdn_universe.name_hash,
01154                                   FQDN_HASH_SIZE, MDL) ||
01155             !option_code_new_hash(&fqdn_universe.code_hash,
01156                                   FQDN_HASH_SIZE, MDL))
01157                 log_fatal ("Can't allocate fqdn option hash table.");
01158         for (i = 0 ; fqdn_options[i].name ; i++) {
01159                 option_code_hash_add(fqdn_universe.code_hash,
01160                                      &fqdn_options[i].code, 0,
01161                                      &fqdn_options[i], MDL);
01162                 option_name_hash_add(fqdn_universe.name_hash,
01163                                      fqdn_options[i].name, 0,
01164                                      &fqdn_options[i], MDL);
01165         }
01166 #if defined(REPORT_HASH_PERFORMANCE)
01167         log_info("FQDN name hash: %s",
01168                  option_name_hash_report(fqdn_universe.name_hash));
01169         log_info("FQDN code hash: %s",
01170                  option_code_hash_report(fqdn_universe.code_hash));
01171 #endif
01172 
01173         /* Set up the Vendor Identified Vendor Class options (for option
01174          * 125)...
01175          */
01176         vendor_class_universe.name = "vendor-class";
01177         vendor_class_universe.concat_duplicates = 0; /* XXX: reference? */
01178         vendor_class_universe.lookup_func = lookup_hashed_option;
01179         vendor_class_universe.option_state_dereference =
01180                 hashed_option_state_dereference;
01181         vendor_class_universe.save_func = save_hashed_option;
01182         vendor_class_universe.delete_func = delete_hashed_option;
01183         vendor_class_universe.encapsulate = hashed_option_space_encapsulate;
01184         vendor_class_universe.foreach = hashed_option_space_foreach;
01185         vendor_class_universe.decode = parse_option_buffer;
01186         vendor_class_universe.length_size = 1;
01187         vendor_class_universe.tag_size = 4;
01188         vendor_class_universe.get_tag = getULong;
01189         vendor_class_universe.store_tag = putULong;
01190         vendor_class_universe.get_length = getUChar;
01191         vendor_class_universe.store_length = putUChar;
01192         vendor_class_universe.site_code_min = 0;
01193         vendor_class_universe.end = 0;
01194         code = DHO_VIVCO_SUBOPTIONS;
01195         vendor_class_universe.enc_opt = NULL;
01196         if (!option_code_hash_lookup(&vendor_class_universe.enc_opt,
01197                                      dhcp_universe.code_hash, &code, 0, MDL))
01198                 log_fatal("Unable to find VIVCO parent option (%s:%d).", MDL);
01199         vendor_class_universe.index = universe_count++;
01200         universes[vendor_class_universe.index] = &vendor_class_universe;
01201         if (!option_name_new_hash(&vendor_class_universe.name_hash,
01202                                   VIVCO_HASH_SIZE, MDL) ||
01203             !option_code_new_hash(&vendor_class_universe.code_hash,
01204                                   VIVCO_HASH_SIZE, MDL))
01205                 log_fatal("Can't allocate Vendor Identified Vendor Class "
01206                           "option hash table.");
01207         for (i = 0 ; vendor_class_options[i].name ; i++) {
01208                 option_code_hash_add(vendor_class_universe.code_hash,
01209                                      &vendor_class_options[i].code, 0,
01210                                      &vendor_class_options[i], MDL);
01211                 option_name_hash_add(vendor_class_universe.name_hash,
01212                                      vendor_class_options[i].name, 0,
01213                                      &vendor_class_options[i], MDL);
01214         }
01215 #if defined(REPORT_HASH_PERFORMANCE)
01216         log_info("VIVCO name hash: %s",
01217                  option_name_hash_report(vendor_class_universe.name_hash));
01218         log_info("VIVCO code hash: %s",
01219                  option_code_hash_report(vendor_class_universe.code_hash));
01220 #endif
01221 
01222         /* Set up the Vendor Identified Vendor Sub-options (option 126)... */
01223         vendor_universe.name = "vendor";
01224         vendor_universe.concat_duplicates = 0; /* XXX: reference? */
01225         vendor_universe.lookup_func = lookup_hashed_option;
01226         vendor_universe.option_state_dereference =
01227                 hashed_option_state_dereference;
01228         vendor_universe.save_func = save_hashed_option;
01229         vendor_universe.delete_func = delete_hashed_option;
01230         vendor_universe.encapsulate = hashed_option_space_encapsulate;
01231         vendor_universe.foreach = hashed_option_space_foreach;
01232         vendor_universe.decode = parse_option_buffer;
01233         vendor_universe.length_size = 1;
01234         vendor_universe.tag_size = 4;
01235         vendor_universe.get_tag = getULong;
01236         vendor_universe.store_tag = putULong;
01237         vendor_universe.get_length = getUChar;
01238         vendor_universe.store_length = putUChar;
01239         vendor_universe.site_code_min = 0;
01240         vendor_universe.end = 0;
01241         code = DHO_VIVSO_SUBOPTIONS;
01242         vendor_universe.enc_opt = NULL;
01243         if (!option_code_hash_lookup(&vendor_universe.enc_opt,
01244                                      dhcp_universe.code_hash, &code, 0, MDL))
01245                 log_fatal("Unable to find VIVSO parent option (%s:%d).", MDL);
01246         vendor_universe.index = universe_count++;
01247         universes[vendor_universe.index] = &vendor_universe;
01248         if (!option_name_new_hash(&vendor_universe.name_hash,
01249                                   VIVSO_HASH_SIZE, MDL) ||
01250             !option_code_new_hash(&vendor_universe.code_hash,
01251                                   VIVSO_HASH_SIZE, MDL))
01252                 log_fatal("Can't allocate Vendor Identified Vendor Sub-"
01253                           "options hash table.");
01254         for (i = 0 ; vendor_options[i].name ; i++) {
01255                 option_code_hash_add(vendor_universe.code_hash,
01256                                      &vendor_options[i].code, 0,
01257                                      &vendor_options[i], MDL);
01258                 option_name_hash_add(vendor_universe.name_hash,
01259                                      vendor_options[i].name, 0,
01260                                      &vendor_options[i], MDL);
01261         }
01262 #if defined(REPORT_HASH_PERFORMANCE)
01263         log_info("VIVSO name hash: %s",
01264                  option_name_hash_report(vendor_universe.name_hash));
01265         log_info("VIVSO code hash: %s",
01266                  option_code_hash_report(vendor_universe.code_hash));
01267 #endif
01268 
01269         /* Set up the ISC Vendor-option universe (for option 125.2495)... */
01270         isc_universe.name = "isc";
01271         isc_universe.concat_duplicates = 0; /* XXX: check VIVSO ref */
01272         isc_universe.lookup_func = lookup_linked_option;
01273         isc_universe.option_state_dereference =
01274                 linked_option_state_dereference;
01275         isc_universe.save_func = save_linked_option;
01276         isc_universe.delete_func = delete_linked_option;
01277         isc_universe.encapsulate = linked_option_space_encapsulate;
01278         isc_universe.foreach = linked_option_space_foreach;
01279         isc_universe.decode = parse_option_buffer;
01280         isc_universe.length_size = 2;
01281         isc_universe.tag_size = 2;
01282         isc_universe.get_tag = getUShort;
01283         isc_universe.store_tag = putUShort;
01284         isc_universe.get_length = getUShort;
01285         isc_universe.store_length = putUShort;
01286         isc_universe.site_code_min = 0;
01287         isc_universe.end = 0;
01288         code = VENDOR_ISC_SUBOPTIONS;
01289         isc_universe.enc_opt = NULL;
01290         if (!option_code_hash_lookup(&isc_universe.enc_opt,
01291                                      vendor_universe.code_hash, &code, 0, MDL))
01292                 log_fatal("Unable to find ISC parent option (%s:%d).", MDL);
01293         isc_universe.index = universe_count++;
01294         universes[isc_universe.index] = &isc_universe;
01295         if (!option_name_new_hash(&isc_universe.name_hash,
01296                                   VIV_ISC_HASH_SIZE, MDL) ||
01297             !option_code_new_hash(&isc_universe.code_hash,
01298                                   VIV_ISC_HASH_SIZE, MDL))
01299                 log_fatal("Can't allocate ISC Vendor options hash table.");
01300         for (i = 0 ; isc_options[i].name ; i++) {
01301                 option_code_hash_add(isc_universe.code_hash,
01302                                      &isc_options[i].code, 0,
01303                                      &isc_options[i], MDL);
01304                 option_name_hash_add(isc_universe.name_hash,
01305                                      isc_options[i].name, 0,
01306                                      &isc_options[i], MDL);
01307         }
01308 #if defined(REPORT_HASH_PERFORMANCE)
01309         log_info("ISC name hash: %s",
01310                  option_name_hash_report(isc_universe.name_hash));
01311         log_info("ISC code hash: %s",
01312                  option_code_hash_report(isc_universe.code_hash));
01313 #endif
01314 
01315         /* Set up the DHCPv6 root universe. */
01316         dhcpv6_universe.name = "dhcp6";
01317         dhcpv6_universe.concat_duplicates = 0;
01318         dhcpv6_universe.lookup_func = lookup_hashed_option;
01319         dhcpv6_universe.option_state_dereference =
01320                 hashed_option_state_dereference;
01321         dhcpv6_universe.save_func = save_hashed_option;
01322         dhcpv6_universe.delete_func = delete_hashed_option;
01323         dhcpv6_universe.encapsulate = hashed_option_space_encapsulate;
01324         dhcpv6_universe.foreach = hashed_option_space_foreach;
01325         dhcpv6_universe.decode = parse_option_buffer;
01326         dhcpv6_universe.length_size = 2;
01327         dhcpv6_universe.tag_size = 2;
01328         dhcpv6_universe.get_tag = getUShort;
01329         dhcpv6_universe.store_tag = putUShort;
01330         dhcpv6_universe.get_length = getUShort;
01331         dhcpv6_universe.store_length = putUShort;
01332         dhcpv6_universe.site_code_min = 0;
01333         /* DHCPv6 has no END option. */
01334         dhcpv6_universe.end = 0x00;
01335         dhcpv6_universe.index = universe_count++;
01336         universes[dhcpv6_universe.index] = &dhcpv6_universe;
01337         if (!option_name_new_hash(&dhcpv6_universe.name_hash,
01338                                   WORD_NAME_HASH_SIZE, MDL) ||
01339             !option_code_new_hash(&dhcpv6_universe.code_hash,
01340                                   WORD_CODE_HASH_SIZE, MDL))
01341                 log_fatal("Can't allocate dhcpv6 option hash tables.");
01342         for (i = 0 ; dhcpv6_options[i].name ; i++) {
01343                 option_code_hash_add(dhcpv6_universe.code_hash,
01344                                      &dhcpv6_options[i].code, 0,
01345                                      &dhcpv6_options[i], MDL);
01346                 option_name_hash_add(dhcpv6_universe.name_hash,
01347                                      dhcpv6_options[i].name, 0,
01348                                      &dhcpv6_options[i], MDL);
01349         }
01350 
01351         /* Add DHCPv6 protocol enumeration sets. */
01352         add_enumeration(&dhcpv6_duid_types);
01353         add_enumeration(&dhcpv6_status_codes);
01354         add_enumeration(&dhcpv6_messages);
01355 
01356         /* Set up DHCPv6 VSIO universe. */
01357         vsio_universe.name = "vsio";
01358         vsio_universe.concat_duplicates = 0;
01359         vsio_universe.lookup_func = lookup_hashed_option;
01360         vsio_universe.option_state_dereference =
01361                 hashed_option_state_dereference;
01362         vsio_universe.save_func = save_hashed_option;
01363         vsio_universe.delete_func = delete_hashed_option;
01364         vsio_universe.encapsulate = hashed_option_space_encapsulate;
01365         vsio_universe.foreach = hashed_option_space_foreach;
01366         vsio_universe.decode = parse_option_buffer;
01367         vsio_universe.length_size = 0;
01368         vsio_universe.tag_size = 4;
01369         vsio_universe.get_tag = getULong;
01370         vsio_universe.store_tag = putULong;
01371         vsio_universe.get_length = NULL;
01372         vsio_universe.store_length = NULL;
01373         vsio_universe.site_code_min = 0;
01374         /* No END option. */
01375         vsio_universe.end = 0x00;
01376         code = D6O_VENDOR_OPTS;
01377         if (!option_code_hash_lookup(&vsio_universe.enc_opt,
01378                                      dhcpv6_universe.code_hash, &code, 0, MDL))
01379                 log_fatal("Unable to find VSIO parent option (%s:%d).", MDL);
01380         vsio_universe.index = universe_count++;
01381         universes[vsio_universe.index] = &vsio_universe;
01382         if (!option_name_new_hash(&vsio_universe.name_hash,
01383                                   VSIO_HASH_SIZE, MDL) ||
01384             !option_code_new_hash(&vsio_universe.code_hash,
01385                                   VSIO_HASH_SIZE, MDL))
01386                 log_fatal("Can't allocate Vendor Specific Information "
01387                           "Options space.");
01388         for (i = 0 ; vsio_options[i].name != NULL ; i++) {
01389                 option_code_hash_add(vsio_universe.code_hash,
01390                                      &vsio_options[i].code, 0,
01391                                      &vsio_options[i], MDL);
01392                 option_name_hash_add(vsio_universe.name_hash,
01393                                      vsio_options[i].name, 0,
01394                                      &vsio_options[i], MDL);
01395         }
01396 
01397         /* Add ISC VSIO sub-sub-option space. */
01398         isc6_universe.name = "isc6";
01399         isc6_universe.concat_duplicates = 0;
01400         isc6_universe.lookup_func = lookup_hashed_option;
01401         isc6_universe.option_state_dereference =
01402                 hashed_option_state_dereference;
01403         isc6_universe.save_func = save_hashed_option;
01404         isc6_universe.delete_func = delete_hashed_option;
01405         isc6_universe.encapsulate = hashed_option_space_encapsulate;
01406         isc6_universe.foreach = hashed_option_space_foreach;
01407         isc6_universe.decode = parse_option_buffer;
01408         isc6_universe.length_size = 0;
01409         isc6_universe.tag_size = 4;
01410         isc6_universe.get_tag = getULong;
01411         isc6_universe.store_tag = putULong;
01412         isc6_universe.get_length = NULL;
01413         isc6_universe.store_length = NULL;
01414         isc6_universe.site_code_min = 0;
01415         /* No END option. */
01416         isc6_universe.end = 0x00;
01417         code = 2495;
01418         if (!option_code_hash_lookup(&isc6_universe.enc_opt,
01419                                      vsio_universe.code_hash, &code, 0, MDL))
01420                 log_fatal("Unable to find ISC parent option (%s:%d).", MDL);
01421         isc6_universe.index = universe_count++;
01422         universes[isc6_universe.index] = &isc6_universe;
01423         if (!option_name_new_hash(&isc6_universe.name_hash,
01424                                   VIV_ISC_HASH_SIZE, MDL) ||
01425             !option_code_new_hash(&isc6_universe.code_hash,
01426                                   VIV_ISC_HASH_SIZE, MDL))
01427                 log_fatal("Can't allocate Vendor Specific Information "
01428                           "Options space.");
01429         for (i = 0 ; isc6_options[i].name != NULL ; i++) {
01430                 option_code_hash_add(isc6_universe.code_hash,
01431                                      &isc6_options[i].code, 0,
01432                                      &isc6_options[i], MDL);
01433                 option_name_hash_add(isc6_universe.name_hash,
01434                                      isc6_options[i].name, 0,
01435                                      &isc6_options[i], MDL);
01436         }
01437 
01438         /* The fqdn6 option space is a protocol-wrapper shill for the
01439          * old DHCPv4 space.
01440          */
01441         fqdn6_universe.name = "fqdn6-if-you-see-me-its-a-bug-bug-bug";
01442         fqdn6_universe.lookup_func = lookup_fqdn6_option;
01443         fqdn6_universe.option_state_dereference = NULL; /* Covered by v4. */
01444         fqdn6_universe.save_func = save_fqdn6_option;
01445         fqdn6_universe.delete_func = delete_fqdn6_option;
01446         fqdn6_universe.encapsulate = fqdn6_option_space_encapsulate;
01447         fqdn6_universe.foreach = fqdn6_option_space_foreach;
01448         fqdn6_universe.decode = fqdn6_universe_decode;
01449         /* This is not a 'normal' encapsulated space, so these values are
01450          * meaningless.
01451          */
01452         fqdn6_universe.length_size = 0;
01453         fqdn6_universe.tag_size = 0;
01454         fqdn6_universe.get_tag = NULL;
01455         fqdn6_universe.store_tag = NULL;
01456         fqdn6_universe.get_length = NULL;
01457         fqdn6_universe.store_length = NULL;
01458         fqdn6_universe.site_code_min = 0;
01459         fqdn6_universe.end = 0;
01460         fqdn6_universe.index = universe_count++;
01461         code = D6O_CLIENT_FQDN;
01462         fqdn6_universe.enc_opt = NULL;
01463         if (!option_code_hash_lookup(&fqdn6_universe.enc_opt,
01464                                      dhcpv6_universe.code_hash, &code, 0, MDL))
01465                 log_fatal("Unable to find FQDN v6 parent option. (%s:%d).",
01466                           MDL);
01467         universes[fqdn6_universe.index] = &fqdn6_universe;
01468         /* The fqdn6 space shares the same option space as the v4 space.
01469          * So there are no name or code hashes on the v6 side.
01470          */
01471         fqdn6_universe.name_hash = NULL;
01472         fqdn6_universe.code_hash = NULL;
01473 
01474 
01475         /* Set up the hash of DHCPv4 universes. */
01476         universe_new_hash(&universe_hash, UNIVERSE_HASH_SIZE, MDL);
01477         universe_hash_add(universe_hash, dhcp_universe.name, 0,
01478                           &dhcp_universe, MDL);
01479         universe_hash_add(universe_hash, nwip_universe.name, 0,
01480                           &nwip_universe, MDL);
01481         universe_hash_add(universe_hash, fqdn_universe.name, 0,
01482                           &fqdn_universe, MDL);
01483         universe_hash_add(universe_hash, vendor_class_universe.name, 0,
01484                           &vendor_class_universe, MDL);
01485         universe_hash_add(universe_hash, vendor_universe.name, 0,
01486                           &vendor_universe, MDL);
01487         universe_hash_add(universe_hash, isc_universe.name, 0,
01488                           &isc_universe, MDL);
01489 
01490         /* Set up hashes for DHCPv6 universes. */
01491         universe_hash_add(universe_hash, dhcpv6_universe.name, 0,
01492                           &dhcpv6_universe, MDL);
01493         universe_hash_add(universe_hash, vsio_universe.name, 0,
01494                           &vsio_universe, MDL);
01495         universe_hash_add(universe_hash, isc6_universe.name, 0,
01496                           &isc6_universe, MDL);
01497 /* This should not be necessary.  Listing here just for consistency.
01498  *      universe_hash_add(universe_hash, fqdn6_universe.name, 0,
01499  *                        &fqdn6_universe, MDL);
01500  */
01501 }

Generated on 5 Apr 2014 for ISC DHCP by  doxygen 1.6.1