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