]>
Commit | Line | Data |
---|---|---|
0cd94b5e | 1 | /* |
82e0ea57 | 2 | * Copyright (c) 2017-2019 by Internet Systems Consortium, Inc. ("ISC") |
0cd94b5e TM |
3 | * |
4 | * Permission to use, copy, modify, and distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | |
14 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | * | |
16 | * Internet Systems Consortium, Inc. | |
17 | * 950 Charter Street | |
18 | * Redwood City, CA 94063 | |
19 | * <info@isc.org> | |
20 | * https://www.isc.org/ | |
21 | * | |
22 | */ | |
23 | ||
24 | #include <assert.h> | |
25 | #include <stdlib.h> | |
26 | #include <string.h> | |
27 | ||
28 | #include "keama.h" | |
29 | ||
30 | TAILQ_HEAD(spaces, space) spaces; | |
31 | TAILQ_HEAD(options, option) options; | |
32 | ||
33 | /* From common/tables.c */ | |
34 | ||
35 | /* Additional format codes: | |
36 | ||
37 | x - ISC DHCP and Kea string | |
38 | Y - force full binary | |
39 | u - undefined (parsed as X) | |
40 | */ | |
41 | ||
42 | /// SPACES | |
43 | struct space_def space_defs[] = { | |
44 | { "dhcp", "dhcp4", 2}, | |
45 | { "nwip", "nwip", 0}, | |
46 | { "agent", "dhcp-agent-options-space", 2}, | |
47 | { "vendor-class", "_vivco_", 0}, | |
48 | { "vendor", "_vivso_", 3}, | |
49 | { "isc", "_isc_", 0}, | |
50 | { "", "vendor-encapsulated-options-space", 1}, | |
51 | { "_docsis3_", "vendor-4491", 1}, | |
52 | { "dhcp6", "dhcp6", 2}, | |
53 | { "vsio", "_vendor-opts-space_", 3}, | |
54 | { "_vsio_", "vendor-opts-space", 1}, | |
55 | { "isc6", "_isc6_", 0}, | |
56 | { "_rsoo_", "rsoo-opts", 1}, | |
57 | { "_isc6_", "vendor-2495", 1}, | |
58 | { "server", "_server_", 0}, | |
59 | { NULL, NULL, 0} | |
60 | }; | |
61 | ||
62 | /// DHCPv4 | |
63 | struct option_def options4[] = { | |
64 | { "subnet-mask", "I", "dhcp", 1, 2}, | |
65 | { "time-offset", "l", "dhcp", 2, 2}, | |
66 | { "routers", "Ia", "dhcp", 3, 2}, | |
67 | { "time-servers", "Ia", "dhcp", 4, 2}, | |
68 | { "ien116-name-servers", "Ia", "dhcp", 5, 2}, | |
69 | /// ien116-name-servers -> name-servers | |
70 | { "domain-name-servers", "Ia", "dhcp", 6, 2}, | |
71 | { "log-servers", "Ia", "dhcp", 7, 2}, | |
72 | { "cookie-servers", "Ia", "dhcp", 8, 2}, | |
73 | { "lpr-servers", "Ia", "dhcp", 9, 2}, | |
74 | { "impress-servers", "Ia", "dhcp", 10, 2}, | |
75 | { "resource-location-servers", "Ia", "dhcp", 11, 2}, | |
76 | { "host-name", "t", "dhcp", 12, 2}, | |
77 | { "boot-size", "S", "dhcp", 13, 2}, | |
78 | { "merit-dump", "t", "dhcp", 14, 2}, | |
79 | { "domain-name", "t", "dhcp", 15, 2}, | |
80 | { "swap-server", "I", "dhcp", 16, 2}, | |
81 | { "root-path", "t", "dhcp", 17, 2}, | |
82 | { "extensions-path", "t", "dhcp", 18, 2}, | |
83 | { "ip-forwarding", "f", "dhcp", 19, 2}, | |
84 | { "non-local-source-routing", "f", "dhcp", 20, 2}, | |
85 | { "policy-filter", "IIa", "dhcp", 21, 2}, | |
86 | { "max-dgram-reassembly", "S", "dhcp", 22, 2}, | |
87 | { "default-ip-ttl", "B", "dhcp", 23, 2}, | |
88 | { "path-mtu-aging-timeout", "L", "dhcp", 24, 2}, | |
89 | { "path-mtu-plateau-table", "Sa", "dhcp", 25, 2}, | |
90 | { "interface-mtu", "S", "dhcp", 26, 2}, | |
91 | { "all-subnets-local", "f", "dhcp", 27, 2}, | |
92 | { "broadcast-address", "I", "dhcp", 28, 2}, | |
93 | { "perform-mask-discovery", "f", "dhcp", 29, 2}, | |
94 | { "mask-supplier", "f", "dhcp", 30, 2}, | |
95 | { "router-discovery", "f", "dhcp", 31, 2}, | |
96 | { "router-solicitation-address", "I", "dhcp", 32, 2}, | |
97 | { "static-routes", "IIa", "dhcp", 33, 2}, | |
98 | { "trailer-encapsulation", "f", "dhcp", 34, 2}, | |
99 | { "arp-cache-timeout", "L", "dhcp", 35, 2}, | |
100 | { "ieee802-3-encapsulation", "f", "dhcp", 36, 2}, | |
101 | { "default-tcp-ttl", "B", "dhcp", 37, 2}, | |
102 | { "tcp-keepalive-interval", "L", "dhcp", 38, 2}, | |
103 | { "tcp-keepalive-garbage", "f", "dhcp", 39, 2}, | |
104 | { "nis-domain", "t", "dhcp", 40, 2}, | |
105 | { "nis-servers", "Ia", "dhcp", 41, 2}, | |
106 | { "ntp-servers", "Ia", "dhcp", 42, 2}, | |
107 | { "vendor-encapsulated-options", "E.", "dhcp", 43, 2}, | |
108 | { "netbios-name-servers", "Ia", "dhcp", 44, 2}, | |
109 | { "netbios-dd-server", "Ia", "dhcp", 45, 2}, | |
110 | { "netbios-node-type", "B", "dhcp", 46, 2}, | |
111 | { "netbios-scope", "t", "dhcp", 47, 2}, | |
112 | { "font-servers", "Ia", "dhcp", 48, 2}, | |
113 | { "x-display-manager", "Ia", "dhcp", 49, 2}, | |
114 | { "dhcp-requested-address", "I", "dhcp", 50, 2}, | |
115 | { "dhcp-lease-time", "L", "dhcp", 51, 2}, | |
116 | { "dhcp-option-overload", "B", "dhcp", 52, 2}, | |
117 | { "dhcp-message-type", "B", "dhcp", 53, 2}, | |
118 | { "dhcp-server-identifier", "I", "dhcp", 54, 2}, | |
119 | { "dhcp-parameter-request-list", "Ba", "dhcp", 55, 2}, | |
120 | { "dhcp-message", "t", "dhcp", 56, 2}, | |
121 | { "dhcp-max-message-size", "S", "dhcp", 57, 2}, | |
122 | { "dhcp-renewal-time", "L", "dhcp", 58, 2}, | |
123 | { "dhcp-rebinding-time", "L", "dhcp", 59, 2}, | |
124 | { "vendor-class-identifier", "x", "dhcp", 60, 2}, | |
125 | { "dhcp-client-identifier", "X", "dhcp", 61, 2}, | |
126 | { "nwip-domain", "t", "dhcp", 62, 2}, | |
127 | /// nwip-domain nwip-domain-name | |
128 | { "nwip-suboptions", "Enwip.", "dhcp", 63, 2}, | |
129 | { "nisplus-domain", "t", "dhcp", 64, 2}, | |
130 | /// nisplus-domain nisplus-domain-name | |
131 | { "nisplus-servers", "Ia", "dhcp", 65, 2}, | |
132 | { "tftp-server-name", "t", "dhcp", 66, 2}, | |
133 | { "bootfile-name", "t", "dhcp", 67, 2}, | |
134 | /// bootfile-name boot-file-name | |
135 | { "mobile-ip-home-agent", "Ia", "dhcp", 68, 2}, | |
136 | { "smtp-server", "Ia", "dhcp", 69, 2}, | |
137 | { "pop-server", "Ia", "dhcp", 70, 2}, | |
138 | { "nntp-server", "Ia", "dhcp", 71, 2}, | |
139 | { "www-server", "Ia", "dhcp", 72, 2}, | |
140 | { "finger-server", "Ia", "dhcp", 73, 2}, | |
141 | { "irc-server", "Ia", "dhcp", 74, 2}, | |
142 | { "streettalk-server", "Ia", "dhcp", 75, 2}, | |
143 | { "streettalk-directory-assistance-server", "Ia", | |
144 | "dhcp", 76, 2}, | |
145 | { "user-class", "tY", "dhcp", 77, 2}, | |
146 | { "slp-directory-agent", "fIa", "dhcp", 78, 2}, | |
147 | { "slp-service-scope", "fto", "dhcp", 79, 2}, | |
148 | /* 80 is the zero-length rapid-commit (RFC 4039) */ | |
149 | { "fqdn", "Efqdn.", "dhcp", 81, 2}, | |
150 | { "relay-agent-information", "Eagent.", "dhcp", 82, 2}, | |
151 | /// relay-agent-information dhcp-agent-options | |
152 | /* 83 is iSNS (RFC 4174) */ | |
153 | /* 84 is unassigned */ | |
154 | { "nds-servers", "Ia", "dhcp", 85, 2}, | |
155 | { "nds-tree-name", "t", "dhcp", 86, 2}, | |
156 | { "nds-context", "t", "dhcp", 87, 2}, | |
157 | { "bcms-controller-names", "D", "dhcp", 88, 2}, | |
158 | { "bcms-controller-address", "Ia", "dhcp", 89, 2}, | |
159 | { "authenticate", "X", "dhcp", 90, 1}, | |
160 | /// not supported by ISC DHCP | |
161 | { "client-last-transaction-time", "L", "dhcp", 91, 2}, | |
162 | { "associated-ip", "Ia", "dhcp", 92, 2}, | |
163 | { "pxe-system-type", "Sa", "dhcp", 93, 2}, | |
164 | // pxe-system-type client-system | |
165 | { "pxe-interface-id", "BBB", "dhcp", 94, 2}, | |
166 | // pxe-interface-id client-ndi | |
167 | { "pxe-client-id", "BX", "dhcp", 97, 2}, | |
168 | // pxe-client-id uuid-guid | |
169 | { "uap-servers", "t", "dhcp", 98, 2}, | |
170 | { "geoconf-civic", "X", "dhcp", 99, 2}, | |
171 | { "pcode", "t", "dhcp", 100, 2}, | |
172 | { "tcode", "t", "dhcp", 101, 2}, | |
25f124c8 | 173 | { "v6-only-preferred", "L", "dhcp", 108, 2}, |
0cd94b5e TM |
174 | { "netinfo-server-address", "Ia", "dhcp", 112, 2}, |
175 | { "netinfo-server-tag", "t", "dhcp", 113, 2}, | |
176 | { "default-url", "t", "dhcp", 114, 2}, | |
177 | { "auto-config", "B", "dhcp", 116, 2}, | |
178 | { "name-service-search", "Sa", "dhcp", 117, 2}, | |
179 | { "subnet-selection", "I", "dhcp", 118, 2}, | |
180 | { "domain-search", "Dc", "dhcp", 119, 2}, | |
181 | { "vivco", "Evendor-class.", "dhcp", 124, 2}, | |
182 | /// vivco vivco-suboptions | |
183 | { "vivso", "Evendor.", "dhcp", 125, 2}, | |
184 | /// vivso vivso-suboptions | |
185 | {"pana-agent", "Ia", "dhcp", 136, 2}, | |
186 | {"v4-lost", "d", "dhcp", 137, 2}, | |
187 | {"capwap-ac-v4", "Ia", "dhcp", 138, 2}, | |
188 | { "sip-ua-cs-domains", "Dc", "dhcp", 141, 2}, | |
189 | { "ipv4-address-andsf", "Ia", "dhcp", 142, 0}, | |
190 | /// not supported by Kea | |
191 | { "rdnss-selection", "BIID", "dhcp", 146, 2}, | |
192 | { "tftp-server-address", "Ia", "dhcp", 150, 0}, | |
193 | /// not supported by Kea | |
194 | { "v4-portparams", "BBS", "dhcp", 159, 2}, | |
195 | { "v4-captive-portal", "t", "dhcp", 160, 2}, | |
196 | { "option-6rd", "BB6Ia", "dhcp", 212, 2}, | |
197 | {"v4-access-domain", "d", "dhcp", 213, 2}, | |
198 | { NULL, NULL, NULL, 0, 0 } | |
199 | }; | |
200 | ||
201 | /// DHCPv6 | |
202 | struct option_def options6[] = { | |
203 | { "client-id", "X", "dhcp6", 1, 2}, | |
204 | /// client-id clientid | |
205 | { "server-id", "X", "dhcp6", 2, 2}, | |
206 | /// server-id serverid | |
207 | { "ia-na", "X", "dhcp6", 3, 2}, | |
208 | { "ia-ta", "X", "dhcp6", 4, 2}, | |
209 | { "ia-addr", "X", "dhcp6", 5, 2}, | |
210 | /// ia-addr iaaddr | |
211 | { "oro", "Sa", "dhcp6", 6, 2}, | |
212 | { "preference", "B", "dhcp6", 7, 2}, | |
213 | { "elapsed-time", "S", "dhcp6", 8, 2}, | |
214 | { "relay-msg", "X", "dhcp6", 9, 2}, | |
215 | /// 10 is unassigned | |
216 | { "auth", "X", "dhcp6", 11, 1}, | |
217 | /// not supported by ISC DHCP | |
218 | { "unicast", "6", "dhcp6", 12, 2}, | |
219 | { "status-code", "Nstatus-codes.to", "dhcp6", 13, 2}, | |
220 | { "rapid-commit", "Z", "dhcp6", 14, 2}, | |
221 | { "user-class", "X", "dhcp6", 15, 1}, | |
222 | /// not supported by ISC DHCP | |
223 | { "vendor-class", "LX", "dhcp6", 16, 1}, | |
224 | /// not supported by ISC DHCP | |
225 | { "vendor-opts", "Evsio.", "dhcp6", 17, 2}, | |
226 | { "interface-id", "X", "dhcp6", 18, 2}, | |
227 | { "reconf-msg", "Ndhcpv6-messages.", "dhcp6", 19, 2}, | |
228 | { "reconf-accept", "Z", "dhcp6", 20, 2}, | |
229 | { "sip-servers-names", "D", "dhcp6", 21, 2}, | |
230 | /// sip-servers-names sip-server-dns | |
231 | { "sip-servers-addresses", "6a", "dhcp6", 22, 2}, | |
232 | /// sip-servers-addresses sip-server-addr | |
233 | { "name-servers", "6a", "dhcp6", 23, 2}, | |
234 | /// name-servers dns-servers | |
235 | { "domain-search", "D", "dhcp6", 24, 2}, | |
236 | { "ia-pd", "X", "dhcp6", 25, 2}, | |
237 | { "ia-prefix", "X", "dhcp6", 26, 2}, | |
238 | /// ia-prefix iaprefix | |
239 | { "nis-servers", "6a", "dhcp6", 27, 2}, | |
240 | { "nisp-servers", "6a", "dhcp6", 28, 2}, | |
241 | { "nis-domain-name", "D", "dhcp6", 29, 2}, | |
242 | { "nisp-domain-name", "D", "dhcp6", 30, 2}, | |
243 | { "sntp-servers", "6a", "dhcp6", 31, 2}, | |
244 | { "info-refresh-time", "T", "dhcp6", 32, 2}, | |
245 | /// info-refresh-time information-refresh-time | |
246 | { "bcms-server-d", "D", "dhcp6", 33, 2}, | |
247 | /// bcms-server-d bcms-server-dns | |
248 | { "bcms-server-a", "6a", "dhcp6", 34, 2}, | |
249 | /// bcms-server-a bcms-server-addr | |
250 | /* Note that 35 is not assigned. */ | |
251 | { "geoconf-civic", "X", "dhcp6", 36, 2}, | |
252 | { "remote-id", "X", "dhcp6", 37, 2}, | |
253 | { "subscriber-id", "X", "dhcp6", 38, 2}, | |
254 | { "fqdn", "Efqdn6-if-you-see-me-its-a-bug-bug-bug.", | |
255 | "dhcp6", 39, 2}, | |
256 | /// fqdn client-fqdn | |
257 | { "pana-agent", "6a", "dhcp6", 40, 2}, | |
258 | { "new-posix-timezone", "t", "dhcp6", 41, 2}, | |
259 | { "new-tzdb-timezone", "t", "dhcp6", 42, 2}, | |
260 | { "ero", "Sa", "dhcp6", 43, 2}, | |
261 | { "lq-query", "X", "dhcp6", 44, 2}, | |
262 | { "client-data", "X", "dhcp6", 45, 2}, | |
263 | { "clt-time", "L", "dhcp6", 46, 2}, | |
264 | { "lq-relay-data", "6X", "dhcp6", 47, 2}, | |
265 | { "lq-client-link", "6a", "dhcp6", 48, 2}, | |
266 | { "v6-lost", "d", "dhcp6", 51, 2}, | |
267 | { "capwap-ac-v6", "6a", "dhcp6", 52, 2}, | |
268 | { "relay-id", "X", "dhcp6", 53, 2}, | |
269 | { "v6-access-domain", "d", "dhcp6", 57, 2}, | |
270 | { "sip-ua-cs-list", "D", "dhcp6", 58, 2}, | |
271 | { "bootfile-url", "t", "dhcp6", 59, 2}, | |
272 | { "bootfile-param", "X", "dhcp6", 60, 2}, | |
273 | { "client-arch-type", "Sa", "dhcp6", 61, 2}, | |
274 | { "nii", "BBB", "dhcp6", 62, 2}, | |
275 | { "aftr-name", "d", "dhcp6", 64, 2}, | |
276 | { "erp-local-domain-name", "d", "dhcp6", 65, 2}, | |
277 | { "rsoo", "Ersoo.", "dhcp6", 66, 1}, | |
278 | /// not supported by ISC DHCP | |
279 | { "pd-exclude", "X", "dhcp6", 67, 1}, | |
280 | /// not supported by ISC DHCP (prefix6 format) | |
281 | { "rdnss-selection", "6BD", "dhcp6", 74, 2}, | |
282 | { "client-linklayer-addr", "X", "dhcp6", 79, 2}, | |
283 | { "link-address", "6", "dhcp6", 80, 2}, | |
284 | { "solmax-rt", "L", "dhcp6", 82, 2}, | |
285 | { "inf-max-rt", "L", "dhcp6", 83, 2}, | |
286 | { "dhcpv4-msg", "X", "dhcp6", 87, 2}, | |
287 | /// dhcpv4-msg dhcpv4-message | |
288 | { "dhcp4-o-dhcp6-server", "6a", "dhcp6", 88, 2}, | |
289 | /// dhcp4-o-dhcp6-server dhcp4o6-server-addr | |
290 | { "v6-captive-portal", "t", "dhcp6", 103, 2}, | |
291 | { "relay-source-port", "S", "dhcp6", 135, 2}, | |
292 | { "ipv6-address-andsf", "6a", "dhcp6", 143, 2}, | |
293 | { NULL, NULL, NULL, 0, 0 } | |
294 | }; | |
295 | ||
296 | /// DHCPv4 AGENT | |
297 | struct option_def agents[] = { | |
298 | /// All not supported by Kea | |
299 | { "circuit-id", "X", "agent", 1, 0}, | |
300 | { "remote-id", "X", "agent", 2, 0}, | |
301 | { "agent-id", "I", "agent", 3, 0}, | |
302 | { "DOCSIS-device-class", "L", "agent", 4, 0}, | |
303 | { "link-selection", "I", "agent", 5, 0}, | |
304 | { "relay-port", "Z", "agent", 19, 0}, | |
305 | { NULL, NULL, NULL, 0, 0 } | |
306 | }; | |
307 | ||
308 | /// SERVER | |
309 | struct option_def configs[] = { | |
310 | { "default-lease-time", "T", "server", 1, 3}, | |
311 | { "max-lease-time", "T", "server", 2, 3}, | |
312 | { "min-lease-time", "T", "server", 3, 3}, | |
313 | { "dynamic-bootp-lease-cutoff", "T", "server", 4, 0}, | |
314 | { "dynamic-bootp-lease-length", "L", "server", 5, 0}, | |
315 | { "boot-unknown-clients", "f", "server", 6, 0}, | |
316 | { "dynamic-bootp", "f", "server", 7, 0}, | |
317 | { "allow-bootp", "f", "server", 8, 0}, | |
318 | { "allow-booting", "f", "server", 9, 0}, | |
319 | { "one-lease-per-client", "f", "server", 10, 0}, | |
320 | { "get-lease-hostnames", "f", "server", 11, 0}, | |
321 | { "use-host-decl-names", "f", "server", 12, 0}, | |
322 | { "use-lease-addr-for-default-route", "f", | |
323 | "server", 13, 0}, | |
324 | { "min-secs", "B", "server", 14, 0}, | |
325 | { "filename", "t", "server", 15, 3}, | |
326 | { "server-name", "t", "server", 16, 3}, | |
327 | { "next-server", "I", "server", 17, 3}, | |
328 | { "authoritative", "f", "server", 18, 3}, | |
329 | { "vendor-option-space", "U", "server", 19, 3}, | |
330 | { "always-reply-rfc1048", "f", "server", 20, 0}, | |
331 | { "site-option-space", "X", "server", 21, 3}, | |
332 | { "always-broadcast", "f", "server", 22, 0}, | |
333 | { "ddns-domainname", "t", "server", 23, 3}, | |
334 | { "ddns-hostname", "t", "server", 24, 0}, | |
335 | { "ddns-rev-domainname", "t", "server", 25, 0}, | |
336 | { "lease-file-name", "t", "server", 26, 0}, | |
337 | { "pid-file-name", "t", "server", 27, 0}, | |
338 | { "duplicates", "f", "server", 28, 0}, | |
339 | { "declines", "f", "server", 29, 0}, | |
340 | { "ddns-updates", "f", "server", 30, 3}, | |
341 | { "omapi-port", "S", "server", 31, 0}, | |
342 | { "local-port", "S", "server", 32, 0}, | |
343 | { "limited-broadcast-address", "I", "server", 33, 0}, | |
344 | { "remote-port", "S", "server", 34, 0}, | |
345 | { "local-address", "I", "server", 35, 0}, | |
346 | { "omapi-key", "d", "server", 36, 0}, | |
347 | { "stash-agent-options", "f", "server", 37, 0}, | |
348 | { "ddns-ttl", "T", "server", 38, 0}, | |
349 | { "ddns-update-style", "Nddns-styles.", "server", 39, 3}, | |
350 | { "client-updates", "f", "server", 40, 0}, | |
351 | { "update-optimization", "f", "server", 41, 0}, | |
352 | { "ping-check", "f", "server", 42, 0}, | |
353 | { "update-static-leases", "f", "server", 43, 0}, | |
354 | { "log-facility", "Nsyslog-facilities.", | |
355 | "server", 44, 0}, | |
356 | { "do-forward-updates", "f", "server", 45, 0}, | |
357 | { "ping-timeout", "T", "server", 46, 0}, | |
358 | { "infinite-is-reserved", "f", "server", 47, 0}, | |
359 | { "update-conflict-detection", "f", "server", 48, 0}, | |
360 | { "leasequery", "f", "server", 49, 0}, | |
361 | { "adaptive-lease-time-threshold", "B", "server", 50, 0}, | |
362 | { "do-reverse-updates", "f", "server", 51, 0}, | |
363 | { "fqdn-reply", "f", "server", 52, 0}, | |
364 | { "preferred-lifetime", "T", "server", 53, 3}, | |
365 | { "dhcpv6-lease-file-name", "t", "server", 54, 0}, | |
366 | { "dhcpv6-pid-file-name", "t", "server", 55, 0}, | |
367 | { "limit-addrs-per-ia", "L", "server", 56, 0}, | |
368 | { "limit-prefs-per-ia", "L", "server", 57, 0}, | |
369 | { "delayed-ack", "S", "server", 58, 0}, | |
370 | { "max-ack-delay", "L", "server", 59, 0}, | |
371 | /* LDAP */ | |
372 | { "dhcp-cache-threshold", "B", "server", 78, 0}, | |
373 | { "dont-use-fsync", "f", "server", 79, 0}, | |
374 | { "ddns-local-address4", "I", "server", 80, 0}, | |
375 | { "ddns-local-address6", "6", "server", 81, 0}, | |
376 | { "ignore-client-uids", "f", "server", 82, 3}, | |
377 | { "log-threshold-low", "B", "server", 83, 0}, | |
378 | { "log-threshold-high", "B", "server", 84, 0}, | |
379 | { "echo-client-id", "f", "server", 85, 3}, | |
380 | { "server-id-check", "f", "server", 86, 0}, | |
381 | { "prefix-length-mode", "Nprefix_length_modes.", | |
382 | "server", 87, 0}, | |
383 | { "dhcpv6-set-tee-times", "f", "server", 88, 0}, | |
384 | { "abandon-lease-time", "T", "server", 89, 0}, | |
385 | { "use-eui-64", "f", "server", 90, 0}, | |
386 | { "check-secs-byte-order", "f", "server", 91, 0}, | |
387 | { "persist-eui-64-leases", "f", "server", 92, 0}, | |
388 | { "ddns-dual-stack-mixed-mode", "f", "server", 93, 0}, | |
389 | { "ddns-guard-id-must-match", "f", "server", 94, 0}, | |
390 | { "ddns-other-guard-is-dynamic", "f", "server", 95, 0}, | |
391 | { "release-on-roam", "f", "server", 96, 0}, | |
392 | { "local-address6", "6", "server", 97, 0}, | |
393 | { "bind-local-address6", "f", "server", 98, 0}, | |
394 | { "ping-cltt-secs", "T", "server", 99, 0}, | |
395 | { "ping-timeout-ms", "T", "server", 100, 0}, | |
396 | { NULL, NULL, NULL, 0, 0 } | |
397 | }; | |
398 | ||
399 | void | |
400 | spaces_init(void) | |
401 | { | |
402 | struct space_def *def; | |
403 | struct space *space; | |
404 | ||
405 | TAILQ_INIT(&spaces); | |
406 | ||
407 | /* Fill spaces */ | |
408 | for (def = space_defs; def->name != NULL; def++) { | |
409 | space = (struct space *)malloc(sizeof(*space)); | |
410 | assert(space != NULL); | |
411 | memset(space, 0, sizeof(*space)); | |
412 | space->old = def->old; | |
413 | space->name = def->name; | |
414 | space->status = def->status; | |
415 | TAILQ_INSERT_TAIL(&spaces, space); | |
416 | } | |
417 | } | |
418 | ||
419 | void | |
420 | options_init(void) | |
421 | { | |
422 | struct option_def *def; | |
423 | struct option *option; | |
424 | ||
425 | TAILQ_INIT(&options); | |
426 | ||
427 | /* Fill DHCPv4 options */ | |
428 | for (def = options4; def->name != NULL; def++) { | |
429 | option = (struct option *)malloc(sizeof(*option)); | |
430 | assert(option != NULL); | |
431 | memset(option, 0, sizeof(*option)); | |
432 | option->old = def->name; | |
433 | switch (def->code) { | |
434 | case 5: | |
435 | option->name = "name-servers"; | |
436 | break; | |
437 | case 62: | |
438 | option->name = "nwip-domain-name"; | |
439 | break; | |
440 | case 64: | |
441 | option->name = "nisplus-domain-name"; | |
442 | break; | |
443 | case 67: | |
444 | option->name = "boot-file-name"; | |
445 | break; | |
446 | case 82: | |
447 | option->name = "dhcp-agent-options"; | |
448 | break; | |
449 | case 93: | |
450 | option->name = "client-system"; | |
451 | break; | |
452 | case 94: | |
453 | option->name = "client-ndi"; | |
454 | break; | |
455 | case 97: | |
456 | option->name = "uuid-guid"; | |
457 | break; | |
458 | case 124: | |
459 | option->name = "vivco-suboptions"; | |
460 | break; | |
461 | case 125: | |
462 | option->name = "vivso-suboptions"; | |
463 | break; | |
464 | default: | |
465 | option->name = def->name; | |
466 | } | |
467 | option->format = def->format; | |
468 | option->space = space_lookup(def->space); | |
469 | assert(option->space != NULL); | |
470 | option->code = def->code; | |
471 | option->status = def->status; | |
472 | TAILQ_INSERT_TAIL(&options, option); | |
473 | } | |
474 | ||
475 | /* Fill DHCPv6 options */ | |
476 | for (def = options6; def->name != NULL; def++) { | |
477 | option = (struct option *)malloc(sizeof(*option)); | |
478 | assert(option != NULL); | |
479 | memset(option, 0, sizeof(*option)); | |
480 | option->old = def->name; | |
481 | switch (def->code) { | |
482 | case 1: | |
483 | option->name = "clientid"; | |
484 | break; | |
485 | case 2: | |
486 | option->name = "serverid"; | |
487 | break; | |
488 | case 5: | |
489 | option->name = "iaaddr"; | |
490 | break; | |
491 | case 21: | |
492 | option->name = "sip-server-dns"; | |
493 | break; | |
494 | case 22: | |
495 | option->name = "sip-server-addr"; | |
496 | break; | |
497 | case 23: | |
498 | option->name = "dns-servers"; | |
499 | break; | |
500 | case 26: | |
501 | option->name = "iaprefix"; | |
502 | break; | |
503 | case 32: | |
504 | option->name = "information-refresh-time"; | |
505 | break; | |
506 | case 33: | |
507 | option->name = "bcms-server-dns"; | |
508 | break; | |
509 | case 34: | |
510 | option->name = "bcms-server-addr "; | |
511 | break; | |
512 | case 39: | |
513 | option->name = "client-fqdn"; | |
514 | break; | |
515 | case 87: | |
516 | option->name = "dhcpv4-message"; | |
517 | break; | |
518 | case 88: | |
519 | option->name = "dhcp4o6-server-addr"; | |
520 | break; | |
521 | default: | |
522 | option->name = def->name; | |
523 | break; | |
524 | } | |
525 | option->format = def->format; | |
526 | option->space = space_lookup(def->space); | |
527 | assert(option->space != NULL); | |
528 | option->code = def->code; | |
529 | option->status = def->status; | |
530 | TAILQ_INSERT_TAIL(&options, option); | |
531 | } | |
532 | ||
533 | /* Fill agent options */ | |
534 | for (def = agents; def->name != NULL; def++) { | |
535 | option = (struct option *)malloc(sizeof(*option)); | |
536 | assert(option != NULL); | |
537 | memset(option, 0, sizeof(*option)); | |
538 | option->old = def->name; | |
539 | option->name = def->name; | |
540 | option->format = def->format; | |
541 | option->space = space_lookup(def->space); | |
542 | assert(option->space != NULL); | |
543 | option->code = def->code; | |
544 | option->status = def->status; | |
545 | TAILQ_INSERT_TAIL(&options, option); | |
546 | } | |
547 | ||
548 | /* Fill server config options */ | |
549 | for (def = configs; def->name != NULL; def++) { | |
550 | option = (struct option *)malloc(sizeof(*option)); | |
551 | assert(option != NULL); | |
552 | memset(option, 0, sizeof(*option)); | |
553 | option->old = def->name; | |
554 | option->name = def->name; | |
555 | option->format = def->format; | |
556 | option->space = space_lookup(def->space); | |
557 | assert(option->space != NULL); | |
558 | option->code = def->code; | |
559 | option->status = def->status; | |
560 | TAILQ_INSERT_TAIL(&options, option); | |
561 | } | |
562 | } | |
563 | ||
564 | struct space * | |
565 | space_lookup(const char *name) | |
566 | { | |
567 | struct space *space; | |
568 | ||
569 | TAILQ_FOREACH(space, &spaces) { | |
570 | if (space->status == isc_dhcp_unknown) | |
571 | continue; | |
572 | if (strcmp(name, space->old) == 0) | |
573 | return space; | |
574 | } | |
575 | return NULL; | |
576 | } | |
577 | ||
578 | struct option * | |
579 | option_lookup_name(const char *space, const char *name) | |
580 | { | |
581 | struct space *universe; | |
582 | struct option *option; | |
583 | ||
584 | universe = space_lookup(space); | |
585 | if (universe == NULL) | |
586 | return NULL; | |
587 | TAILQ_FOREACH(option, &options) { | |
588 | if (option->status == isc_dhcp_unknown) | |
589 | continue; | |
590 | if (universe != option->space) | |
591 | continue; | |
592 | if (strcmp(name, option->old) == 0) | |
593 | return option; | |
594 | } | |
595 | return NULL; | |
596 | } | |
597 | ||
598 | struct option * | |
599 | kea_lookup_name(const char *space, const char *name) | |
600 | { | |
601 | struct space *universe; | |
602 | struct option *option; | |
603 | ||
604 | TAILQ_FOREACH(universe, &spaces) { | |
605 | if (universe->status == kea_unknown) | |
606 | continue; | |
607 | if (strcmp(name, universe->name) == 0) | |
608 | break; | |
609 | } | |
610 | if (universe == NULL) | |
611 | return NULL; | |
612 | TAILQ_FOREACH(option, &options) { | |
613 | if (option->status == kea_unknown) | |
614 | continue; | |
615 | if (universe != option->space) | |
616 | continue; | |
617 | if (strcmp(name, option->name) == 0) | |
618 | return option; | |
619 | } | |
620 | return NULL; | |
621 | } | |
622 | ||
623 | struct option * | |
624 | option_lookup_code(const char *space, unsigned code) | |
625 | { | |
626 | struct space *universe; | |
627 | struct option *option; | |
628 | ||
629 | universe = space_lookup(space); | |
630 | if (universe == NULL) | |
631 | return NULL; | |
632 | TAILQ_FOREACH(option, &options) { | |
633 | if (universe != option->space) | |
634 | continue; | |
635 | if (code == option->code) | |
636 | return option; | |
637 | } | |
638 | return NULL; | |
639 | } | |
640 | ||
641 | void | |
642 | push_space(struct space *space) | |
643 | { | |
644 | space->status = dynamic; | |
645 | TAILQ_INSERT_TAIL(&spaces, space); | |
646 | } | |
647 | ||
648 | void | |
649 | push_option(struct option *option) | |
650 | { | |
651 | assert(option->space != NULL); | |
652 | option->old = option->name; | |
653 | option->status = dynamic; | |
654 | TAILQ_INSERT_TAIL(&options, option); | |
655 | } | |
656 | ||
657 | void | |
658 | add_option_data(struct element *src, struct element *dst) | |
659 | { | |
660 | struct string *sspace; | |
661 | struct element *scode; | |
662 | struct element *name; | |
663 | struct option *option; | |
664 | size_t i; | |
665 | ||
666 | sspace = stringValue(mapGet(src, "space")); | |
667 | scode = mapGet(src, "code"); | |
668 | name = mapGet(src, "name"); | |
669 | assert((scode != NULL) || (name != NULL)); | |
670 | ||
671 | /* We'll use the code so fill it even it should always be available */ | |
672 | if (scode == NULL) { | |
673 | option = kea_lookup_name(sspace->content, | |
674 | stringValue(name)->content); | |
675 | assert(option != NULL); | |
676 | scode = createInt(option->code); | |
677 | mapSet(src, scode, "code"); | |
678 | } | |
679 | assert(intValue(scode) != 0); | |
680 | ||
681 | for (i = 0; i < listSize(dst); i++) { | |
682 | struct element *od; | |
683 | struct element *space; | |
684 | struct element *code; | |
685 | ||
686 | od = listGet(dst, i); | |
687 | space = mapGet(od, "space"); | |
688 | if (!eqString(sspace, stringValue(space))) | |
689 | continue; | |
690 | code = mapGet(od, "code"); | |
691 | if (code == NULL) { | |
692 | name = mapGet(od, "name"); | |
693 | assert(name != NULL); | |
694 | option = kea_lookup_name(sspace->content, | |
695 | stringValue(name)->content); | |
696 | assert(option != NULL); | |
697 | code = createInt(option->code); | |
698 | mapSet(od, code, "code"); | |
699 | } | |
700 | /* check if the option is already present */ | |
701 | if (intValue(scode) == intValue(code)) | |
702 | return; | |
703 | } | |
704 | listPush(dst, copy(src)); | |
705 | } | |
706 | ||
707 | void | |
708 | merge_option_data(struct element *src, struct element *dst) | |
709 | { | |
710 | struct element *od; | |
711 | size_t i; | |
712 | ||
713 | for (i = 0; i < listSize(src); i++) { | |
714 | od = listGet(src, i); | |
715 | add_option_data(od, dst); | |
716 | } | |
717 | } | |
718 | ||
719 | struct comments * | |
720 | get_config_comments(unsigned code) | |
721 | { | |
722 | static struct comments comments; | |
723 | struct comment *comment = NULL; | |
724 | ||
725 | TAILQ_INIT(&comments); | |
726 | switch (code) { | |
727 | case 4: /* dynamic-bootp-lease-cutoff */ | |
728 | case 5: /* dynamic-bootp-lease-length */ | |
729 | case 6: /* boot-unknown-clients */ | |
730 | case 7: /* dynamic-bootp */ | |
731 | case 8: /* allow-bootp */ | |
732 | no_bootp: | |
733 | comment = createComment("/// bootp protocol is not supported"); | |
734 | TAILQ_INSERT_TAIL(&comments, comment); | |
735 | break; | |
736 | ||
737 | case 9: /* allow-booting */ | |
738 | comment = createComment("/// allow-booting is not supported"); | |
739 | TAILQ_INSERT_TAIL(&comments, comment); | |
740 | comment = createComment("/// no concrete usage known?"); | |
741 | TAILQ_INSERT_TAIL(&comments, comment); | |
742 | comment = createComment("/// Reference Kea #239"); | |
743 | TAILQ_INSERT_TAIL(&comments, comment); | |
744 | break; | |
745 | ||
746 | case 10: /* one-lease-per-client */ | |
747 | comment = createComment("/// one-lease-per-client is not " | |
748 | "supported"); | |
749 | TAILQ_INSERT_TAIL(&comments, comment); | |
750 | comment = createComment("/// Reference Kea #238"); | |
751 | TAILQ_INSERT_TAIL(&comments, comment); | |
752 | break; | |
753 | ||
754 | case 11: /* get-lease-hostnames */ | |
755 | comment = createComment("/// get-lease-hostnames is not " | |
756 | "supported"); | |
757 | TAILQ_INSERT_TAIL(&comments, comment); | |
758 | comment = createComment("/// Reference Kea #240"); | |
759 | TAILQ_INSERT_TAIL(&comments, comment); | |
760 | break; | |
761 | ||
762 | case 12: /* use-host-decl-names */ | |
763 | comment = createComment("/// use-host-decl-names defaults " | |
764 | "to always on"); | |
765 | TAILQ_INSERT_TAIL(&comments, comment); | |
766 | break; | |
767 | ||
768 | case 13: /* use-lease-addr-for-default-route */ | |
769 | comment = createComment("/// use-lease-addr-for-default-route " | |
770 | "is obsolete"); | |
771 | TAILQ_INSERT_TAIL(&comments, comment); | |
772 | break; | |
773 | ||
774 | case 14: /* min-secs */ | |
775 | comment = createComment("/// min-secs is not (yet?) " | |
776 | "supported"); | |
777 | TAILQ_INSERT_TAIL(&comments, comment); | |
778 | comment = createComment("/// Reference Kea #223"); | |
779 | TAILQ_INSERT_TAIL(&comments, comment); | |
780 | break; | |
781 | ||
782 | case 20: /* always-reply-rfc1048 */ | |
783 | goto no_bootp; | |
784 | ||
785 | case 22: /* always-broadcast */ | |
786 | comment = createComment("/// always-broadcast is not " | |
787 | "supported"); | |
788 | TAILQ_INSERT_TAIL(&comments, comment); | |
789 | comment = createComment("/// Reference Kea #241"); | |
790 | TAILQ_INSERT_TAIL(&comments, comment); | |
791 | break; | |
792 | ||
793 | case 24: /* ddns-hostname */ | |
794 | comment = createComment("/// ddns-hostname is not supported"); | |
795 | TAILQ_INSERT_TAIL(&comments, comment); | |
796 | comment = createComment("/// Please use hostname in a " | |
797 | "host reservation instead"); | |
798 | TAILQ_INSERT_TAIL(&comments, comment); | |
799 | break; | |
800 | ||
801 | case 25: /* ddns-rev-domainname */ | |
802 | comment = createComment("/// ddns-rev-domainname is an " | |
803 | "obsolete (so not supported) feature"); | |
804 | TAILQ_INSERT_TAIL(&comments, comment); | |
805 | break; | |
806 | ||
807 | case 26: /* lease-file-name */ | |
808 | comment = createComment("/// lease-file-name is an internal " | |
809 | "ISC DHCP feature"); | |
810 | TAILQ_INSERT_TAIL(&comments, comment); | |
811 | break; | |
812 | ||
813 | case 27: /* pid-file-name */ | |
814 | comment = createComment("/// pid-file-nam is an internal " | |
815 | "ISC DHCP feature"); | |
816 | TAILQ_INSERT_TAIL(&comments, comment); | |
817 | break; | |
818 | ||
819 | case 28: /* duplicates */ | |
820 | comment = createComment("/// duplicates is not supported"); | |
821 | TAILQ_INSERT_TAIL(&comments, comment); | |
822 | comment = createComment("/// Kea model is different (and " | |
823 | "stricter)"); | |
824 | TAILQ_INSERT_TAIL(&comments, comment); | |
825 | break; | |
826 | ||
827 | case 29: /* declines */ | |
828 | comment = createComment("/// declines is not supported"); | |
829 | TAILQ_INSERT_TAIL(&comments, comment); | |
830 | comment = createComment("/// Kea honors decline messages " | |
831 | " and holds address for " | |
832 | "decline-probation-period"); | |
833 | TAILQ_INSERT_TAIL(&comments, comment); | |
834 | break; | |
835 | ||
836 | case 31: /* omapi-port */ | |
837 | comment = createComment("/// omapi-port is an internal " | |
838 | "ISC DHCP feature"); | |
839 | TAILQ_INSERT_TAIL(&comments, comment); | |
840 | break; | |
841 | ||
842 | case 32: /* local-port */ | |
843 | comment = createComment("/// local-port is not supported"); | |
844 | TAILQ_INSERT_TAIL(&comments, comment); | |
845 | comment = createComment("/// command line -p parameter " | |
846 | "should be used instead"); | |
847 | TAILQ_INSERT_TAIL(&comments, comment); | |
848 | break; | |
849 | ||
850 | case 33: /* limited-broadcast-address */ | |
851 | comment = createComment("/// limited-broadcast-address " | |
852 | "is not (yet?) supported"); | |
853 | TAILQ_INSERT_TAIL(&comments, comment); | |
854 | comment = createComment("/// Reference Kea #224"); | |
855 | TAILQ_INSERT_TAIL(&comments, comment); | |
856 | break; | |
857 | ||
858 | case 34: /* remote-port */ | |
859 | comment = createComment("/// remote-port is a not portable " | |
860 | "(so not supported) feature"); | |
861 | TAILQ_INSERT_TAIL(&comments, comment); | |
862 | break; | |
863 | ||
864 | case 35: /* local-address */ | |
865 | comment = createComment("/// local-address is not supported"); | |
866 | TAILQ_INSERT_TAIL(&comments, comment); | |
867 | comment = createComment("/// Kea equivalent feature is " | |
868 | "to specify an interface address"); | |
869 | TAILQ_INSERT_TAIL(&comments, comment); | |
870 | break; | |
871 | ||
872 | case 36: /* omapi-key */ | |
873 | comment = createComment("/// omapi-key is an internal " | |
874 | "ISC DHCP feature"); | |
875 | TAILQ_INSERT_TAIL(&comments, comment); | |
876 | break; | |
877 | ||
878 | case 37: /* stash-agent-options */ | |
879 | comment = createComment("/// stash-agent-options is not " | |
880 | "(yet?) supported"); | |
881 | TAILQ_INSERT_TAIL(&comments, comment); | |
882 | comment = createComment("/// Reference Kea #218"); | |
883 | TAILQ_INSERT_TAIL(&comments, comment); | |
884 | break; | |
885 | ||
886 | case 38: /* ddns-ttl */ | |
887 | comment = createComment("/// ddns-ttl is a D2 not (yet?) " | |
888 | "supported feature"); | |
889 | TAILQ_INSERT_TAIL(&comments, comment); | |
890 | comment = createComment("/// Reference Kea #225"); | |
891 | TAILQ_INSERT_TAIL(&comments, comment); | |
892 | break; | |
893 | ||
894 | case 40: /* client-updates */ | |
895 | comment = createComment("/// ddns-ttl client-updates is " | |
896 | "not supported"); | |
897 | TAILQ_INSERT_TAIL(&comments, comment); | |
898 | comment = createComment("/// Kea model is very different"); | |
899 | TAILQ_INSERT_TAIL(&comments, comment); | |
900 | break; | |
901 | ||
902 | case 41: /* update-optimization */ | |
903 | comment = createComment("/// update-optimization is not " | |
904 | "supported"); | |
905 | TAILQ_INSERT_TAIL(&comments, comment); | |
906 | comment = createComment("/// Kea follows RFC 4702"); | |
907 | TAILQ_INSERT_TAIL(&comments, comment); | |
908 | break; | |
909 | ||
910 | case 42: /* ping-check */ | |
911 | comment = createComment("/// ping-check is not supported"); | |
912 | TAILQ_INSERT_TAIL(&comments, comment); | |
913 | no_ping: | |
914 | comment = createComment("/// Kea has no ping probing"); | |
915 | TAILQ_INSERT_TAIL(&comments, comment); | |
916 | break; | |
917 | ||
918 | case 43: /* update-static-leases */ | |
919 | comment = createComment("/// update-static-leases is an " | |
920 | "obsolete feature"); | |
921 | TAILQ_INSERT_TAIL(&comments, comment); | |
922 | break; | |
923 | ||
924 | case 44: /* log-facility */ | |
925 | comment = createComment("/// log-facility is not supported"); | |
926 | TAILQ_INSERT_TAIL(&comments, comment); | |
927 | comment = createComment("/// Please use the " | |
928 | "KEA_LOGGER_DESTINATION environment " | |
929 | "variable instead"); | |
930 | TAILQ_INSERT_TAIL(&comments, comment); | |
931 | break; | |
932 | ||
933 | case 45: /* do-forward-updates */ | |
934 | comment = createComment("/// do-forward-updates is not " | |
935 | "supported"); | |
936 | TAILQ_INSERT_TAIL(&comments, comment); | |
937 | ddns_updates: | |
938 | comment = createComment("/// Kea model is equivalent but " | |
939 | "different"); | |
940 | TAILQ_INSERT_TAIL(&comments, comment); | |
941 | break; | |
942 | ||
943 | case 46: /* ping-timeout */ | |
944 | comment = createComment("/// ping-timeout is not supported"); | |
945 | TAILQ_INSERT_TAIL(&comments, comment); | |
946 | goto no_ping; | |
947 | ||
948 | case 47: /* infinite-is-reserved */ | |
949 | comment = createComment("/// infinite-is-reserved is not " | |
950 | "supported"); | |
951 | TAILQ_INSERT_TAIL(&comments, comment); | |
952 | comment = createComment("/// Kea does not support reserved " | |
953 | "leases"); | |
954 | TAILQ_INSERT_TAIL(&comments, comment); | |
955 | break; | |
956 | ||
957 | case 48: /* update-conflict-detection */ | |
958 | comment = createComment("/// update-conflict-detection is not " | |
959 | "supported"); | |
960 | TAILQ_INSERT_TAIL(&comments, comment); | |
961 | comment = createComment("/// DDNS is handled by the D2 " | |
962 | "server using a dedicated config"); | |
963 | TAILQ_INSERT_TAIL(&comments, comment); | |
964 | break; | |
965 | ||
966 | case 49: /* leasequery */ | |
967 | comment = createComment("/// leasequery is not supported"); | |
968 | TAILQ_INSERT_TAIL(&comments, comment); | |
969 | comment = createComment("/// Kea does not (yet) support " | |
970 | "the leasequery protocol"); | |
971 | TAILQ_INSERT_TAIL(&comments, comment); | |
972 | break; | |
973 | ||
974 | case 50: /* adaptive-lease-time-threshold */ | |
975 | comment = createComment("/// adaptive-lease-time-threshold is " | |
976 | "not supported"); | |
977 | TAILQ_INSERT_TAIL(&comments, comment); | |
978 | comment = createComment("/// Reference Kea #226"); | |
979 | TAILQ_INSERT_TAIL(&comments, comment); | |
980 | break; | |
981 | ||
982 | case 51: /* do-reverse-updates */ | |
983 | comment = createComment("/// do-reverse-updates is not " | |
984 | "supported"); | |
985 | TAILQ_INSERT_TAIL(&comments, comment); | |
986 | goto ddns_updates; | |
987 | ||
988 | case 52: /* fqdn-reply */ | |
989 | comment = createComment("/// fqdn-reply is an obsolete " | |
990 | "feature"); | |
991 | TAILQ_INSERT_TAIL(&comments, comment); | |
992 | break; | |
993 | ||
994 | case 54: /* dhcpv6-lease-file-name */ | |
995 | comment = createComment("/// dhcpv6-lease-file-name " | |
996 | "is an internal ISC DHCP feature"); | |
997 | TAILQ_INSERT_TAIL(&comments, comment); | |
998 | break; | |
999 | ||
1000 | case 55: /* dhcpv6-pid-file-name */ | |
1001 | comment = createComment("/// dhcpv6-pid-file-name " | |
1002 | "is an internal ISC DHCP feature"); | |
1003 | TAILQ_INSERT_TAIL(&comments, comment); | |
1004 | break; | |
1005 | ||
1006 | case 56: /* limit-addrs-per-ia */ | |
1007 | comment = createComment("/// limit-addrs-per-ia " | |
1008 | "is not (yet?) supported"); | |
1009 | TAILQ_INSERT_TAIL(&comments, comment); | |
1010 | limit_resources: | |
1011 | comment = createComment("/// Reference Kea #227"); | |
1012 | TAILQ_INSERT_TAIL(&comments, comment); | |
1013 | break; | |
1014 | ||
1015 | case 57: /* limit-prefs-per-ia */ | |
1016 | comment = createComment("/// limit-prefs-per-ia" | |
1017 | "is not (yet?) supported"); | |
1018 | TAILQ_INSERT_TAIL(&comments, comment); | |
1019 | goto limit_resources; | |
1020 | ||
1021 | case 58: /* delayed-ack */ | |
1022 | case 59: /* max-ack-delay */ | |
1023 | comment = createComment("/// delayed ack no supported"); | |
1024 | TAILQ_INSERT_TAIL(&comments, comment); | |
1025 | break; | |
1026 | ||
1027 | case 78: /* dhcp-cache-threshold */ | |
1028 | comment = createComment("/// dhcp-cache-threshold " | |
1029 | "is not (yet?) supported"); | |
1030 | TAILQ_INSERT_TAIL(&comments, comment); | |
1031 | comment = createComment("/// Reference Kea #228"); | |
1032 | TAILQ_INSERT_TAIL(&comments, comment); | |
1033 | break; | |
1034 | ||
1035 | case 79: /* dont-use-fsync */ | |
1036 | comment = createComment("/// dont-use-fsync is an internal " | |
1037 | "ISC DHCP feature"); | |
1038 | TAILQ_INSERT_TAIL(&comments, comment); | |
1039 | break; | |
1040 | ||
1041 | case 80: /* ddns-local-address4 */ | |
1042 | comment = createComment("/// ddns-local-address4 is not " | |
1043 | "supported"); | |
1044 | TAILQ_INSERT_TAIL(&comments, comment); | |
1045 | d2_ip_address: | |
1046 | comment = createComment("/// Kea D2 equivalent config is " | |
1047 | "ip-address"); | |
1048 | TAILQ_INSERT_TAIL(&comments, comment); | |
1049 | break; | |
1050 | ||
1051 | case 81: /* ddns-local-address6 */ | |
1052 | comment = createComment("/// ddns-local-address6 is not " | |
1053 | "supported"); | |
1054 | TAILQ_INSERT_TAIL(&comments, comment); | |
1055 | goto d2_ip_address; | |
1056 | ||
1057 | case 83: /* log-threshold-low */ | |
1058 | comment = createComment("/// log-threshold-low is not (yet?) " | |
1059 | "supported"); | |
1060 | TAILQ_INSERT_TAIL(&comments, comment); | |
1061 | log_threshold: | |
1062 | comment = createComment("/// Reference Kea #222"); | |
1063 | TAILQ_INSERT_TAIL(&comments, comment); | |
1064 | break; | |
1065 | ||
1066 | case 84: /* log-threshold-high */ | |
1067 | comment = createComment("/// log-threshold-high is not (yet?) " | |
1068 | "supported"); | |
1069 | TAILQ_INSERT_TAIL(&comments, comment); | |
1070 | goto log_threshold; | |
1071 | ||
1072 | case 86: /* server-id-check */ | |
1073 | comment = createComment("/// server-id-check is not (yet?) " | |
1074 | "supported"); | |
1075 | TAILQ_INSERT_TAIL(&comments, comment); | |
1076 | comment = createComment("/// Reference Kea #242"); | |
1077 | TAILQ_INSERT_TAIL(&comments, comment); | |
1078 | break; | |
1079 | ||
1080 | case 87: /* prefix-length-mode */ | |
1081 | comment = createComment("/// prefix-length-mode is not " | |
1082 | "supported"); | |
1083 | TAILQ_INSERT_TAIL(&comments, comment); | |
1084 | comment = createComment("/// Kea model is different (and " | |
1085 | "simpler?)"); | |
1086 | TAILQ_INSERT_TAIL(&comments, comment); | |
1087 | break; | |
1088 | case 88: /* dhcpv6-set-tee-times */ | |
1089 | comment = createComment("/// dhcpv6-set-tee-times is a " | |
1090 | "transitional (so not supported) " | |
1091 | "feature"); | |
1092 | TAILQ_INSERT_TAIL(&comments, comment); | |
1093 | comment = createComment("/// T1 and T2 are .5 and .8 times " | |
1094 | "preferred-lifetime"); | |
1095 | TAILQ_INSERT_TAIL(&comments, comment); | |
1096 | break; | |
1097 | case 89: /* abandon-lease-time */ | |
1098 | comment = createComment("/// abandon-lease-time is not " | |
1099 | "supported"); | |
1100 | TAILQ_INSERT_TAIL(&comments, comment); | |
1101 | comment = createComment("/// Kea support equivalent (and " | |
1102 | "richer) expired-lease-processing " | |
1103 | "and decline-probation-period"); | |
1104 | TAILQ_INSERT_TAIL(&comments, comment); | |
1105 | break; | |
1106 | case 90: /* use-eui-64 */ | |
1107 | comment = createComment("/// EUI-64 is not (yet) supported"); | |
1108 | TAILQ_INSERT_TAIL(&comments, comment); | |
1109 | comment = createComment("/// Reference Kea #265"); | |
1110 | TAILQ_INSERT_TAIL(&comments, comment); | |
1111 | break; | |
1112 | case 96: /* release-on-roam */ | |
1113 | comment = createComment("/// release-on-roam is not (yet) " | |
1114 | "supported"); | |
1115 | TAILQ_INSERT_TAIL(&comments, comment); | |
1116 | comment = createComment("/// Reference Kea #266"); | |
1117 | TAILQ_INSERT_TAIL(&comments, comment); | |
1118 | break; | |
1119 | case 97: /* local-address6 */ | |
1120 | comment = createComment("/// local-address6 is not supported"); | |
1121 | TAILQ_INSERT_TAIL(&comments, comment); | |
1122 | comment = createComment("/// Kea equivalent feature is " | |
1123 | "to specify an interface address"); | |
1124 | TAILQ_INSERT_TAIL(&comments, comment); | |
1125 | break; | |
1126 | case 99: /* ping-cltt-secs */ | |
1127 | comment = createComment("/// ping-cltt-secs is not supported"); | |
1128 | TAILQ_INSERT_TAIL(&comments, comment); | |
1129 | goto no_ping; | |
1130 | case 100: /* ping-timeout-ms */ | |
1131 | comment = createComment("/// ping-timeout-ms is not " | |
1132 | "supported"); | |
1133 | TAILQ_INSERT_TAIL(&comments, comment); | |
1134 | goto no_ping; | |
1135 | } | |
1136 | return &comments; | |
1137 | } | |
1138 | ||
1139 | const char * | |
1140 | display_status(enum option_status status) | |
1141 | { | |
1142 | switch (status) { | |
1143 | case kea_unknown: | |
1144 | case special: | |
1145 | return "known (unknown)"; | |
1146 | case isc_dhcp_unknown: | |
1147 | return "unknown (known)"; | |
1148 | case known: | |
1149 | return "known (known)"; | |
1150 | case dynamic: | |
1151 | return "dynamic (dynamic)"; | |
1152 | default: | |
1153 | return "??? (" "???" ")"; | |
1154 | } | |
1155 | } |