1 /* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 /* define this to get facilitynames */
22 static volatile int mem_recover = 0;
23 static jmp_buf mem_jmp;
24 static int one_file(char *file, int hard_opt);
26 /* Solaris headers don't have facility names. */
27 #ifdef HAVE_SOLARIS_NETWORK
35 { "daemon", LOG_DAEMON },
37 { "syslog", LOG_SYSLOG },
41 { "audit", LOG_AUDIT },
43 { "local0", LOG_LOCAL0 },
44 { "local1", LOG_LOCAL1 },
45 { "local2", LOG_LOCAL2 },
46 { "local3", LOG_LOCAL3 },
47 { "local4", LOG_LOCAL4 },
48 { "local5", LOG_LOCAL5 },
49 { "local6", LOG_LOCAL6 },
50 { "local7", LOG_LOCAL7 },
55 #ifndef HAVE_GETOPT_LONG
64 #define OPTSTRING "951yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:4:6:7:8:0:3:"
66 /* options which don't have a one-char version */
67 #define LOPT_RELOAD 256
68 #define LOPT_NO_NAMES 257
70 #define LOPT_SECURE 259
71 #define LOPT_PREFIX 260
73 #define LOPT_BRIDGE 262
74 #define LOPT_TFTP_MAX 263
75 #define LOPT_FORCE 264
76 #define LOPT_NOBLOCK 265
77 #define LOPT_LOG_OPTS 266
78 #define LOPT_MAX_LOGS 267
79 #define LOPT_CIRCUIT 268
80 #define LOPT_REMOTE 269
81 #define LOPT_SUBSCR 270
82 #define LOPT_INTNAME 271
84 #define LOPT_DHCP_HOST 273
85 #define LOPT_APREF 274
86 #define LOPT_OVERRIDE 275
87 #define LOPT_TFTPPORTS 276
88 #define LOPT_REBIND 277
89 #define LOPT_NOLAST 278
91 #define LOPT_DHCP_OPTS 280
92 #define LOPT_MATCH 281
93 #define LOPT_BROADCAST 282
94 #define LOPT_NEGTTL 283
95 #define LOPT_ALTPORT 284
96 #define LOPT_SCRIPTUSR 285
97 #define LOPT_LOCAL 286
98 #define LOPT_NAPTR 287
99 #define LOPT_MINPORT 288
100 #define LOPT_DHCP_FQDN 289
101 #define LOPT_CNAME 290
102 #define LOPT_PXE_PROMT 291
103 #define LOPT_PXE_SERV 292
104 #define LOPT_TEST 293
105 #define LOPT_TAG_IF 294
106 #define LOPT_PROXY 295
107 #define LOPT_GEN_NAMES 296
108 #define LOPT_MAXTTL 297
109 #define LOPT_NO_REBIND 298
110 #define LOPT_LOC_REBND 299
111 #define LOPT_ADD_MAC 300
112 #define LOPT_DNSSEC 301
113 #define LOPT_INCR_ADDR 302
114 #define LOPT_CONNTRACK 303
115 #define LOPT_FQDN 304
116 #define LOPT_LUASCRIPT 305
118 #define LOPT_DUID 307
119 #define LOPT_HOST_REC 308
120 #define LOPT_TFTP_LC 309
122 #define LOPT_CLVERBIND 311
123 #define LOPT_MAXCTTL 312
124 #define LOPT_AUTHZONE 313
125 #define LOPT_AUTHSERV 314
126 #define LOPT_AUTHTTL 315
127 #define LOPT_AUTHSOA 316
128 #define LOPT_AUTHSFS 317
129 #define LOPT_AUTHPEER 318
130 #define LOPT_IPSET 319
131 #define LOPT_SYNTH 320
132 #define LOPT_RELAY 323
133 #define LOPT_RA_PARAM 324
134 #define LOPT_ADD_SBNET 325
135 #define LOPT_QUIET_DHCP 326
136 #define LOPT_QUIET_DHCP6 327
137 #define LOPT_QUIET_RA 328
138 #define LOPT_SEC_VALID 329
139 #define LOPT_TRUST_ANCHOR 330
140 #define LOPT_DNSSEC_DEBUG 331
141 #define LOPT_REV_SERV 332
142 #define LOPT_SERVERS_FILE 333
143 #define LOPT_DNSSEC_CHECK 334
144 #define LOPT_LOCAL_SERVICE 335
145 #define LOPT_DNSSEC_TIME 336
146 #define LOPT_LOOP_DETECT 337
147 #define LOPT_IGNORE_ADDR 338
148 #define LOPT_MINCTTL 339
149 #define LOPT_DHCP_INOTIFY 340
150 #define LOPT_DHOPT_INOTIFY 341
151 #define LOPT_HOST_INOTIFY 342
152 #define LOPT_DNSSEC_STAMP 343
153 #define LOPT_TFTP_NO_FAIL 344
154 #define LOPT_MAXPORT 345
155 #define LOPT_CPE_ID 346
156 #define LOPT_SCRIPT_ARP 347
157 #define LOPT_DHCPTTL 348
158 #define LOPT_TFTP_MTU 349
159 #define LOPT_REPLY_DELAY 350
160 #define LOPT_RAPID_COMMIT 351
161 #define LOPT_DUMPFILE 352
162 #define LOPT_DUMPMASK 353
163 #define LOPT_UBUS 354
164 #define LOPT_NAME_MATCH 355
166 #define LOPT_SHARED_NET 357
167 #define LOPT_IGNORE_CLID 358
168 #define LOPT_SINGLE_PORT 359
169 #define LOPT_SCRIPT_TIME 360
170 #define LOPT_PXE_VENDOR 361
171 #define LOPT_DYNHOST 362
172 #define LOPT_LOG_DEBUG 363
173 #define LOPT_UMBRELLA 364
174 #define LOPT_CMARK_ALST_EN 365
175 #define LOPT_CMARK_ALST 366
176 #define LOPT_QUIET_TFTP 367
177 #define LOPT_NFTSET 368
178 #define LOPT_FILTER_A 369
179 #define LOPT_FILTER_AAAA 370
180 #define LOPT_STRIP_SBNET 371
181 #define LOPT_STRIP_MAC 372
182 #define LOPT_CONF_OPT 373
183 #define LOPT_CONF_SCRIPT 374
184 #define LOPT_RANDPORT_LIM 375
185 #define LOPT_FAST_RETRY 376
186 #define LOPT_STALE_CACHE 377
187 #define LOPT_NORR 378
189 #ifdef HAVE_GETOPT_LONG
190 static const struct option opts[] =
192 static const struct myoption opts[] =
195 { "version", 0, 0, 'v' },
196 { "no-hosts", 0, 0, 'h' },
197 { "no-poll", 0, 0, 'n' },
198 { "help", 0, 0, 'w' },
199 { "no-daemon", 0, 0, 'd' },
200 { "log-queries", 2, 0, 'q' },
201 { "user", 2, 0, 'u' },
202 { "group", 2, 0, 'g' },
203 { "resolv-file", 2, 0, 'r' },
204 { "servers-file", 1, 0, LOPT_SERVERS_FILE },
205 { "mx-host", 1, 0, 'm' },
206 { "mx-target", 1, 0, 't' },
207 { "cache-size", 2, 0, 'c' },
208 { "port", 1, 0, 'p' },
209 { "dhcp-leasefile", 2, 0, 'l' },
210 { "dhcp-lease", 1, 0, 'l' },
211 { "dhcp-host", 1, 0, 'G' },
212 { "dhcp-range", 1, 0, 'F' },
213 { "dhcp-option", 1, 0, 'O' },
214 { "dhcp-boot", 1, 0, 'M' },
215 { "domain", 1, 0, 's' },
216 { "domain-suffix", 1, 0, 's' },
217 { "interface", 1, 0, 'i' },
218 { "listen-address", 1, 0, 'a' },
219 { "local-service", 0, 0, LOPT_LOCAL_SERVICE },
220 { "bogus-priv", 0, 0, 'b' },
221 { "bogus-nxdomain", 1, 0, 'B' },
222 { "ignore-address", 1, 0, LOPT_IGNORE_ADDR },
223 { "selfmx", 0, 0, 'e' },
224 { "filterwin2k", 0, 0, 'f' },
225 { "filter-A", 0, 0, LOPT_FILTER_A },
226 { "filter-AAAA", 0, 0, LOPT_FILTER_AAAA },
227 { "pid-file", 2, 0, 'x' },
228 { "strict-order", 0, 0, 'o' },
229 { "server", 1, 0, 'S' },
230 { "rev-server", 1, 0, LOPT_REV_SERV },
231 { "local", 1, 0, LOPT_LOCAL },
232 { "address", 1, 0, 'A' },
233 { "conf-file", 2, 0, 'C' },
234 { "conf-script", 1, 0, LOPT_CONF_SCRIPT },
235 { "no-resolv", 0, 0, 'R' },
236 { "expand-hosts", 0, 0, 'E' },
237 { "localmx", 0, 0, 'L' },
238 { "local-ttl", 1, 0, 'T' },
239 { "no-negcache", 0, 0, 'N' },
240 { "no-round-robin", 0, 0, LOPT_NORR },
241 { "addn-hosts", 1, 0, 'H' },
242 { "hostsdir", 1, 0, LOPT_HOST_INOTIFY },
243 { "query-port", 1, 0, 'Q' },
244 { "except-interface", 1, 0, 'I' },
245 { "no-dhcp-interface", 1, 0, '2' },
246 { "domain-needed", 0, 0, 'D' },
247 { "dhcp-lease-max", 1, 0, 'X' },
248 { "bind-interfaces", 0, 0, 'z' },
249 { "read-ethers", 0, 0, 'Z' },
250 { "alias", 1, 0, 'V' },
251 { "dhcp-vendorclass", 1, 0, 'U' },
252 { "dhcp-userclass", 1, 0, 'j' },
253 { "dhcp-ignore", 1, 0, 'J' },
254 { "edns-packet-max", 1, 0, 'P' },
255 { "keep-in-foreground", 0, 0, 'k' },
256 { "dhcp-authoritative", 0, 0, 'K' },
257 { "srv-host", 1, 0, 'W' },
258 { "localise-queries", 0, 0, 'y' },
259 { "txt-record", 1, 0, 'Y' },
260 { "caa-record", 1, 0 , LOPT_CAA },
261 { "dns-rr", 1, 0, LOPT_RR },
262 { "enable-dbus", 2, 0, '1' },
263 { "enable-ubus", 2, 0, LOPT_UBUS },
264 { "bootp-dynamic", 2, 0, '3' },
265 { "dhcp-mac", 1, 0, '4' },
266 { "no-ping", 0, 0, '5' },
267 { "dhcp-script", 1, 0, '6' },
268 { "conf-dir", 1, 0, '7' },
269 { "log-facility", 1, 0 ,'8' },
270 { "leasefile-ro", 0, 0, '9' },
271 { "script-on-renewal", 0, 0, LOPT_SCRIPT_TIME},
272 { "dns-forward-max", 1, 0, '0' },
273 { "clear-on-reload", 0, 0, LOPT_RELOAD },
274 { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES },
275 { "enable-tftp", 2, 0, LOPT_TFTP },
276 { "tftp-secure", 0, 0, LOPT_SECURE },
277 { "tftp-no-fail", 0, 0, LOPT_TFTP_NO_FAIL },
278 { "tftp-unique-root", 2, 0, LOPT_APREF },
279 { "tftp-root", 1, 0, LOPT_PREFIX },
280 { "tftp-max", 1, 0, LOPT_TFTP_MAX },
281 { "tftp-mtu", 1, 0, LOPT_TFTP_MTU },
282 { "tftp-lowercase", 0, 0, LOPT_TFTP_LC },
283 { "tftp-single-port", 0, 0, LOPT_SINGLE_PORT },
284 { "ptr-record", 1, 0, LOPT_PTR },
285 { "naptr-record", 1, 0, LOPT_NAPTR },
286 { "bridge-interface", 1, 0 , LOPT_BRIDGE },
287 { "shared-network", 1, 0, LOPT_SHARED_NET },
288 { "dhcp-option-force", 1, 0, LOPT_FORCE },
289 { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK },
290 { "log-dhcp", 0, 0, LOPT_LOG_OPTS },
291 { "log-async", 2, 0, LOPT_MAX_LOGS },
292 { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT },
293 { "dhcp-remoteid", 1, 0, LOPT_REMOTE },
294 { "dhcp-subscrid", 1, 0, LOPT_SUBSCR },
295 { "dhcp-pxe-vendor", 1, 0, LOPT_PXE_VENDOR },
296 { "interface-name", 1, 0, LOPT_INTNAME },
297 { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST },
298 { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS },
299 { "dhcp-hostsdir", 1, 0, LOPT_DHCP_INOTIFY },
300 { "dhcp-optsdir", 1, 0, LOPT_DHOPT_INOTIFY },
301 { "dhcp-no-override", 0, 0, LOPT_OVERRIDE },
302 { "tftp-port-range", 1, 0, LOPT_TFTPPORTS },
303 { "stop-dns-rebind", 0, 0, LOPT_REBIND },
304 { "rebind-domain-ok", 1, 0, LOPT_NO_REBIND },
305 { "all-servers", 0, 0, LOPT_NOLAST },
306 { "dhcp-match", 1, 0, LOPT_MATCH },
307 { "dhcp-name-match", 1, 0, LOPT_NAME_MATCH },
308 { "dhcp-broadcast", 2, 0, LOPT_BROADCAST },
309 { "neg-ttl", 1, 0, LOPT_NEGTTL },
310 { "max-ttl", 1, 0, LOPT_MAXTTL },
311 { "min-cache-ttl", 1, 0, LOPT_MINCTTL },
312 { "max-cache-ttl", 1, 0, LOPT_MAXCTTL },
313 { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT },
314 { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR },
315 { "min-port", 1, 0, LOPT_MINPORT },
316 { "max-port", 1, 0, LOPT_MAXPORT },
317 { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN },
318 { "cname", 1, 0, LOPT_CNAME },
319 { "pxe-prompt", 1, 0, LOPT_PXE_PROMT },
320 { "pxe-service", 1, 0, LOPT_PXE_SERV },
321 { "test", 0, 0, LOPT_TEST },
322 { "tag-if", 1, 0, LOPT_TAG_IF },
323 { "dhcp-proxy", 2, 0, LOPT_PROXY },
324 { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES },
325 { "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND },
326 { "add-mac", 2, 0, LOPT_ADD_MAC },
327 { "strip-mac", 0, 0, LOPT_STRIP_MAC },
328 { "add-subnet", 2, 0, LOPT_ADD_SBNET },
329 { "strip-subnet", 0, 0, LOPT_STRIP_SBNET },
330 { "add-cpe-id", 1, 0 , LOPT_CPE_ID },
331 { "proxy-dnssec", 0, 0, LOPT_DNSSEC },
332 { "dhcp-sequential-ip", 0, 0, LOPT_INCR_ADDR },
333 { "conntrack", 0, 0, LOPT_CONNTRACK },
334 { "dhcp-client-update", 0, 0, LOPT_FQDN },
335 { "dhcp-luascript", 1, 0, LOPT_LUASCRIPT },
336 { "enable-ra", 0, 0, LOPT_RA },
337 { "dhcp-duid", 1, 0, LOPT_DUID },
338 { "host-record", 1, 0, LOPT_HOST_REC },
339 { "bind-dynamic", 0, 0, LOPT_CLVERBIND },
340 { "auth-zone", 1, 0, LOPT_AUTHZONE },
341 { "auth-server", 1, 0, LOPT_AUTHSERV },
342 { "auth-ttl", 1, 0, LOPT_AUTHTTL },
343 { "auth-soa", 1, 0, LOPT_AUTHSOA },
344 { "auth-sec-servers", 1, 0, LOPT_AUTHSFS },
345 { "auth-peer", 1, 0, LOPT_AUTHPEER },
346 { "ipset", 1, 0, LOPT_IPSET },
347 { "nftset", 1, 0, LOPT_NFTSET },
348 { "connmark-allowlist-enable", 2, 0, LOPT_CMARK_ALST_EN },
349 { "connmark-allowlist", 1, 0, LOPT_CMARK_ALST },
350 { "synth-domain", 1, 0, LOPT_SYNTH },
351 { "dnssec", 0, 0, LOPT_SEC_VALID },
352 { "trust-anchor", 1, 0, LOPT_TRUST_ANCHOR },
353 { "dnssec-debug", 0, 0, LOPT_DNSSEC_DEBUG },
354 { "dnssec-check-unsigned", 2, 0, LOPT_DNSSEC_CHECK },
355 { "dnssec-no-timecheck", 0, 0, LOPT_DNSSEC_TIME },
356 { "dnssec-timestamp", 1, 0, LOPT_DNSSEC_STAMP },
357 { "dhcp-relay", 1, 0, LOPT_RELAY },
358 { "ra-param", 1, 0, LOPT_RA_PARAM },
359 { "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP },
360 { "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6 },
361 { "quiet-ra", 0, 0, LOPT_QUIET_RA },
362 { "dns-loop-detect", 0, 0, LOPT_LOOP_DETECT },
363 { "script-arp", 0, 0, LOPT_SCRIPT_ARP },
364 { "dhcp-ttl", 1, 0 , LOPT_DHCPTTL },
365 { "dhcp-reply-delay", 1, 0, LOPT_REPLY_DELAY },
366 { "dhcp-rapid-commit", 0, 0, LOPT_RAPID_COMMIT },
367 { "dumpfile", 1, 0, LOPT_DUMPFILE },
368 { "dumpmask", 1, 0, LOPT_DUMPMASK },
369 { "dhcp-ignore-clid", 0, 0, LOPT_IGNORE_CLID },
370 { "dynamic-host", 1, 0, LOPT_DYNHOST },
371 { "log-debug", 0, 0, LOPT_LOG_DEBUG },
372 { "umbrella", 2, 0, LOPT_UMBRELLA },
373 { "quiet-tftp", 0, 0, LOPT_QUIET_TFTP },
374 { "port-limit", 1, 0, LOPT_RANDPORT_LIM },
375 { "fast-dns-retry", 2, 0, LOPT_FAST_RETRY },
376 { "use-stale-cache", 2, 0 , LOPT_STALE_CACHE },
381 #define ARG_DUP OPT_LAST
382 #define ARG_ONE OPT_LAST + 1
383 #define ARG_USED_CL OPT_LAST + 2
384 #define ARG_USED_FILE OPT_LAST + 3
389 char * const flagdesc;
393 { 'a', ARG_DUP, "<ipaddr>", gettext_noop("Specify local address(es) to listen on."), NULL },
394 { 'A', ARG_DUP, "/<domain>/<ipaddr>", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL },
395 { 'b', OPT_BOGUSPRIV, NULL, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL },
396 { 'B', ARG_DUP, "<ipaddr>", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL },
397 { 'c', ARG_ONE, "<integer>", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
398 { 'C', ARG_DUP, "<path>", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE },
399 { 'd', OPT_DEBUG, NULL, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL },
400 { 'D', OPT_NODOTS_LOCAL, NULL, gettext_noop("Do NOT forward queries with no domain part."), NULL },
401 { 'e', OPT_SELFMX, NULL, gettext_noop("Return self-pointing MX records for local hosts."), NULL },
402 { 'E', OPT_EXPAND, NULL, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL },
403 { 'f', OPT_FILTER, NULL, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL },
404 { LOPT_FILTER_A, OPT_FILTER_A, NULL, gettext_noop("Don't include IPv4 addresses in DNS answers."), NULL },
405 { LOPT_FILTER_AAAA, OPT_FILTER_AAAA, NULL, gettext_noop("Don't include IPv6 addresses in DNS answers."), NULL },
406 { 'F', ARG_DUP, "<ipaddr>,...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL },
407 { 'g', ARG_ONE, "<groupname>", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP },
408 { 'G', ARG_DUP, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL },
409 { LOPT_DHCP_HOST, ARG_DUP, "<path>", gettext_noop("Read DHCP host specs from file."), NULL },
410 { LOPT_DHCP_OPTS, ARG_DUP, "<path>", gettext_noop("Read DHCP option specs from file."), NULL },
411 { LOPT_DHCP_INOTIFY, ARG_DUP, "<path>", gettext_noop("Read DHCP host specs from a directory."), NULL },
412 { LOPT_DHOPT_INOTIFY, ARG_DUP, "<path>", gettext_noop("Read DHCP options from a directory."), NULL },
413 { LOPT_TAG_IF, ARG_DUP, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL },
414 { 'h', OPT_NO_HOSTS, NULL, gettext_noop("Do NOT load %s file."), HOSTSFILE },
415 { 'H', ARG_DUP, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE },
416 { LOPT_HOST_INOTIFY, ARG_DUP, "<path>", gettext_noop("Read hosts files from a directory."), NULL },
417 { 'i', ARG_DUP, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL },
418 { 'I', ARG_DUP, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL },
419 { 'j', ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL },
420 { LOPT_CIRCUIT, ARG_DUP, "set:<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL },
421 { LOPT_REMOTE, ARG_DUP, "set:<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL },
422 { LOPT_SUBSCR, ARG_DUP, "set:<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL },
423 { LOPT_PXE_VENDOR, ARG_DUP, "<vendor>[,...]", gettext_noop("Specify vendor class to match for PXE requests."), NULL },
424 { 'J', ARG_DUP, "tag:<tag>...", gettext_noop("Don't do DHCP for hosts with tag set."), NULL },
425 { LOPT_BROADCAST, ARG_DUP, "[=tag:<tag>...]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL },
426 { 'k', OPT_NO_FORK, NULL, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL },
427 { 'K', OPT_AUTHORITATIVE, NULL, gettext_noop("Assume we are the only DHCP server on the local network."), NULL },
428 { 'l', ARG_ONE, "<path>", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE },
429 { 'L', OPT_LOCALMX, NULL, gettext_noop("Return MX records for local hosts."), NULL },
430 { 'm', ARG_DUP, "<host_name>,<target>,<pref>", gettext_noop("Specify an MX record."), NULL },
431 { 'M', ARG_DUP, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL },
432 { 'n', OPT_NO_POLL, NULL, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE },
433 { 'N', OPT_NO_NEG, NULL, gettext_noop("Do NOT cache failed search results."), NULL },
434 { LOPT_STALE_CACHE, ARG_ONE, "[=<max_expired>]", gettext_noop("Use expired cache data for faster reply."), NULL },
435 { 'o', OPT_ORDER, NULL, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE },
436 { 'O', ARG_DUP, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL },
437 { LOPT_FORCE, ARG_DUP, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL},
438 { 'p', ARG_ONE, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL },
439 { 'P', ARG_ONE, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
440 { 'q', ARG_DUP, NULL, gettext_noop("Log DNS queries."), NULL },
441 { 'Q', ARG_ONE, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL },
442 { LOPT_RANDPORT_LIM, ARG_ONE, "#ports", gettext_noop("Set maximum number of random originating ports for a query."), NULL },
443 { 'R', OPT_NO_RESOLV, NULL, gettext_noop("Do NOT read resolv.conf."), NULL },
444 { 'r', ARG_DUP, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE },
445 { LOPT_SERVERS_FILE, ARG_ONE, "<path>", gettext_noop("Specify path to file with server= options"), NULL },
446 { 'S', ARG_DUP, "/<domain>/<ipaddr>", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL },
447 { LOPT_REV_SERV, ARG_DUP, "<addr>/<prefix>,<ipaddr>", gettext_noop("Specify address of upstream servers for reverse address queries"), NULL },
448 { LOPT_LOCAL, ARG_DUP, "/<domain>/", gettext_noop("Never forward queries to specified domains."), NULL },
449 { 's', ARG_DUP, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL },
450 { 't', ARG_ONE, "<host_name>", gettext_noop("Specify default target in an MX record."), NULL },
451 { 'T', ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL },
452 { LOPT_NEGTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL },
453 { LOPT_MAXTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL },
454 { LOPT_MAXCTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live ceiling for cache."), NULL },
455 { LOPT_MINCTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live floor for cache."), NULL },
456 { LOPT_FAST_RETRY, ARG_ONE, "<milliseconds>", gettext_noop("Retry DNS queries after this many milliseconds."), NULL},
457 { 'u', ARG_ONE, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER },
458 { 'U', ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL },
459 { 'v', 0, NULL, gettext_noop("Display dnsmasq version and copyright information."), NULL },
460 { 'V', ARG_DUP, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL },
461 { 'W', ARG_DUP, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL },
462 { 'w', 0, NULL, gettext_noop("Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."), NULL },
463 { 'x', ARG_ONE, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE },
464 { 'X', ARG_ONE, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
465 { 'y', OPT_LOCALISE, NULL, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL },
466 { 'Y', ARG_DUP, "<name>,<txt>[,<txt]", gettext_noop("Specify TXT DNS record."), NULL },
467 { LOPT_PTR, ARG_DUP, "<name>,<target>", gettext_noop("Specify PTR DNS record."), NULL },
468 { LOPT_INTNAME, ARG_DUP, "<name>,<interface>", gettext_noop("Give DNS name to IPv4 address of interface."), NULL },
469 { 'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL },
470 { 'Z', OPT_ETHERS, NULL, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE },
471 { '1', ARG_ONE, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL },
472 { LOPT_UBUS, ARG_ONE, "[=<busname>]", gettext_noop("Enable the UBus interface."), NULL },
473 { '2', ARG_DUP, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL },
474 { '3', ARG_DUP, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL },
475 { '4', ARG_DUP, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL },
476 { LOPT_BRIDGE, ARG_DUP, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL },
477 { LOPT_SHARED_NET, ARG_DUP, "<iface>|<addr>,<addr>", gettext_noop("Specify extra networks sharing a broadcast domain for DHCP"), NULL},
478 { '5', OPT_NO_PING, NULL, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL },
479 { '6', ARG_ONE, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL },
480 { LOPT_LUASCRIPT, ARG_DUP, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL },
481 { LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL },
482 { LOPT_SCRIPT_ARP, OPT_SCRIPT_ARP, NULL, gettext_noop("Call dhcp-script with changes to local ARP table."), NULL },
483 { '7', ARG_DUP, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL },
484 { LOPT_CONF_SCRIPT, ARG_DUP, "<path>", gettext_noop("Execute file and read configuration from stdin."), NULL },
485 { '8', ARG_ONE, "<facility>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL },
486 { '9', OPT_LEASE_RO, NULL, gettext_noop("Do not use leasefile."), NULL },
487 { '0', ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
488 { LOPT_RELOAD, OPT_RELOAD, NULL, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE },
489 { LOPT_NO_NAMES, ARG_DUP, "[=tag:<tag>]...", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL },
490 { LOPT_OVERRIDE, OPT_NO_OVERRIDE, NULL, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL },
491 { LOPT_TFTP, ARG_DUP, "[=<intr>[,<intr>]]", gettext_noop("Enable integrated read-only TFTP server."), NULL },
492 { LOPT_PREFIX, ARG_DUP, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL },
493 { LOPT_APREF, ARG_DUP, "[=ip|mac]", gettext_noop("Add client IP or hardware address to tftp-root."), NULL },
494 { LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },
495 { LOPT_TFTP_NO_FAIL, OPT_TFTP_NO_FAIL, NULL, gettext_noop("Do not terminate the service if TFTP directories are inaccessible."), NULL },
496 { LOPT_TFTP_MAX, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent TFTP transfers (defaults to %s)."), "#" },
497 { LOPT_TFTP_MTU, ARG_ONE, "<integer>", gettext_noop("Maximum MTU to use for TFTP transfers."), NULL },
498 { LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL },
499 { LOPT_TFTP_LC, OPT_TFTP_LC, NULL, gettext_noop("Convert TFTP filenames to lowercase"), NULL },
500 { LOPT_TFTPPORTS, ARG_ONE, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL },
501 { LOPT_SINGLE_PORT, OPT_SINGLE_PORT, NULL, gettext_noop("Use only one port for TFTP server."), NULL },
502 { LOPT_LOG_OPTS, OPT_LOG_OPTS, NULL, gettext_noop("Extra logging for DHCP."), NULL },
503 { LOPT_MAX_LOGS, ARG_ONE, "[=<integer>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL },
504 { LOPT_REBIND, OPT_NO_REBIND, NULL, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL },
505 { LOPT_LOC_REBND, OPT_LOCAL_REBIND, NULL, gettext_noop("Allow rebinding of 127.0.0.0/8, for RBL servers."), NULL },
506 { LOPT_NO_REBIND, ARG_DUP, "/<domain>/", gettext_noop("Inhibit DNS-rebind protection on this domain."), NULL },
507 { LOPT_NOLAST, OPT_ALL_SERVERS, NULL, gettext_noop("Always perform DNS queries to all servers."), NULL },
508 { LOPT_MATCH, ARG_DUP, "set:<tag>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL },
509 { LOPT_NAME_MATCH, ARG_DUP, "set:<tag>,<string>[*]", gettext_noop("Set tag if client provides given name."), NULL },
510 { LOPT_ALTPORT, ARG_ONE, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL },
511 { LOPT_NAPTR, ARG_DUP, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL },
512 { LOPT_MINPORT, ARG_ONE, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL },
513 { LOPT_MAXPORT, ARG_ONE, "<port>", gettext_noop("Specify highest port available for DNS query transmission."), NULL },
514 { LOPT_DHCP_FQDN, OPT_DHCP_FQDN, NULL, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL },
515 { LOPT_GEN_NAMES, ARG_DUP, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL},
516 { LOPT_PROXY, ARG_DUP, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL },
517 { LOPT_RELAY, ARG_DUP, "<local-addr>,<server>[,<iface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL},
518 { LOPT_CNAME, ARG_DUP, "<alias>,<target>[,<ttl>]", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
519 { LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL },
520 { LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
521 { LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },
522 { LOPT_ADD_MAC, ARG_DUP, "[=base64|text]", gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL },
523 { LOPT_STRIP_MAC, OPT_STRIP_MAC, NULL, gettext_noop("Strip MAC information from queries."), NULL },
524 { LOPT_ADD_SBNET, ARG_ONE, "<v4 pref>[,<v6 pref>]", gettext_noop("Add specified IP subnet to forwarded DNS queries."), NULL },
525 { LOPT_STRIP_SBNET, OPT_STRIP_ECS, NULL, gettext_noop("Strip ECS information from queries."), NULL },
526 { LOPT_CPE_ID, ARG_ONE, "<text>", gettext_noop("Add client identification to forwarded DNS queries."), NULL },
527 { LOPT_DNSSEC, OPT_DNSSEC_PROXY, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },
528 { LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },
529 { LOPT_IGNORE_CLID, OPT_IGNORE_CLID, NULL, gettext_noop("Ignore client identifier option sent by DHCP clients."), NULL },
530 { LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
531 { LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
532 { LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
533 { LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
534 { LOPT_HOST_REC, ARG_DUP, "<name>,<address>[,<ttl>]", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
535 { LOPT_DYNHOST, ARG_DUP, "<name>,[<IPv4>][,<IPv6>],<interface-name>", gettext_noop("Specify host record in interface subnet"), NULL },
536 { LOPT_CAA, ARG_DUP, "<name>,<flags>,<tag>,<value>", gettext_noop("Specify certification authority authorization record"), NULL },
537 { LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
538 { LOPT_CLVERBIND, OPT_CLEVERBIND, NULL, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL },
539 { LOPT_AUTHSERV, ARG_ONE, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL },
540 { LOPT_AUTHZONE, ARG_DUP, "<domain>,[<subnet>...]", gettext_noop("Domain to export to global DNS"), NULL },
541 { LOPT_AUTHTTL, ARG_ONE, "<integer>", gettext_noop("Set TTL for authoritative replies"), NULL },
542 { LOPT_AUTHSOA, ARG_ONE, "<serial>[,...]", gettext_noop("Set authoritative zone information"), NULL },
543 { LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
544 { LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
545 { LOPT_IPSET, ARG_DUP, "/<domain>[/<domain>...]/<ipset>...", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
546 { LOPT_NFTSET, ARG_DUP, "/<domain>[/<domain>...]/<nftset>...", gettext_noop("Specify nftables sets to which matching domains should be added"), NULL },
547 { LOPT_CMARK_ALST_EN, ARG_ONE, "[=<mask>]", gettext_noop("Enable filtering of DNS queries with connection-track marks."), NULL },
548 { LOPT_CMARK_ALST, ARG_DUP, "<connmark>[/<mask>][,<pattern>[/<pattern>...]]", gettext_noop("Set allowed DNS patterns for a connection-track mark."), NULL },
549 { LOPT_SYNTH, ARG_DUP, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL },
550 { LOPT_SEC_VALID, OPT_DNSSEC_VALID, NULL, gettext_noop("Activate DNSSEC validation"), NULL },
551 { LOPT_TRUST_ANCHOR, ARG_DUP, "<domain>,[<class>],...", gettext_noop("Specify trust anchor key digest."), NULL },
552 { LOPT_DNSSEC_DEBUG, OPT_DNSSEC_DEBUG, NULL, gettext_noop("Disable upstream checking for DNSSEC debugging."), NULL },
553 { LOPT_DNSSEC_CHECK, ARG_DUP, NULL, gettext_noop("Ensure answers without DNSSEC are in unsigned zones."), NULL },
554 { LOPT_DNSSEC_TIME, OPT_DNSSEC_TIME, NULL, gettext_noop("Don't check DNSSEC signature timestamps until first cache-reload"), NULL },
555 { LOPT_DNSSEC_STAMP, ARG_ONE, "<path>", gettext_noop("Timestamp file to verify system clock for DNSSEC"), NULL },
556 { LOPT_RA_PARAM, ARG_DUP, "<iface>,[mtu:<value>|<interface>|off,][<prio>,]<intval>[,<lifetime>]", gettext_noop("Set MTU, priority, resend-interval and router-lifetime"), NULL },
557 { LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
558 { LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
559 { LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
560 { LOPT_LOG_DEBUG, OPT_LOG_DEBUG, NULL, gettext_noop("Log debugging information."), NULL },
561 { LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks."), NULL },
562 { LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops."), NULL },
563 { LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL },
564 { LOPT_DHCPTTL, ARG_ONE, "<ttl>", gettext_noop("Set TTL in DNS responses with DHCP-derived addresses."), NULL },
565 { LOPT_REPLY_DELAY, ARG_ONE, "<integer>", gettext_noop("Delay DHCP replies for at least number of seconds."), NULL },
566 { LOPT_RAPID_COMMIT, OPT_RAPID_COMMIT, NULL, gettext_noop("Enables DHCPv4 Rapid Commit option."), NULL },
567 { LOPT_DUMPFILE, ARG_ONE, "<path>", gettext_noop("Path to debug packet dump file"), NULL },
568 { LOPT_DUMPMASK, ARG_ONE, "<hex>", gettext_noop("Mask which packets to dump"), NULL },
569 { LOPT_SCRIPT_TIME, OPT_LEASE_RENEW, NULL, gettext_noop("Call dhcp-script when lease expiry changes."), NULL },
570 { LOPT_UMBRELLA, ARG_ONE, "[=<optspec>]", gettext_noop("Send Cisco Umbrella identifiers including remote IP."), NULL },
571 { LOPT_QUIET_TFTP, OPT_QUIET_TFTP, NULL, gettext_noop("Do not log routine TFTP."), NULL },
572 { LOPT_NORR, OPT_NORR, NULL, gettext_noop("Suppress round-robin ordering of DNS records."), NULL },
573 { 0, 0, NULL, NULL, NULL }
576 /* We hide metacharacters in quoted strings by mapping them into the ASCII control
577 character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the
578 following sequence so that they map to themselves: it is therefore possible to call
579 unhide_metas repeatedly on string without breaking things.
580 The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a
581 couple of other places.
582 Note that space is included here so that
583 --dhcp-option=3, string
584 has five characters, whilst
585 --dhcp-option=3," string"
589 static const char meta[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
591 static char hide_meta(char c)
595 for (i = 0; i < (sizeof(meta) - 1); i++)
602 static char unhide_meta(char cr)
606 if (c < (sizeof(meta) - 1))
612 static void unhide_metas(char *cp)
616 *cp = unhide_meta(*cp);
619 static void *opt_malloc(size_t size)
625 ret = whine_malloc(size);
630 ret = safe_malloc(size);
635 static char *opt_string_alloc(const char *cp)
640 if (cp && (len = strlen(cp)) != 0)
642 ret = opt_malloc(len+1);
643 memcpy(ret, cp, len+1);
645 /* restore hidden metachars */
653 /* find next comma, split string with zero and eliminate spaces.
654 return start of string following comma */
656 static char *split_chr(char *s, char c)
660 if (!s || !(comma = strchr(s, c)))
666 for (; *comma == ' '; comma++);
668 for (; (p >= s) && *p == ' '; p--)
674 static char *split(char *s)
676 return split_chr(s, ',');
679 static char *canonicalise_opt(char *s)
688 return opt_malloc(1); /* Heap-allocated empty string */
691 if (!(ret = canonicalise(s, &nomem)) && nomem)
696 die(_("could not get memory"), NULL, EC_NOMEM);
702 static int numeric_check(char *a)
712 if (*p < '0' || *p > '9')
718 static int atoi_check(char *a, int *res)
720 if (!numeric_check(a))
726 static int strtoul_check(char *a, u32 *res)
730 if (!numeric_check(a))
732 x = strtoul(a, NULL, 10);
733 if (errno || x > UINT32_MAX) {
741 static int atoi_check16(char *a, int *res)
743 if (!(atoi_check(a, res)) ||
752 static int atoi_check8(char *a, int *res)
754 if (!(atoi_check(a, res)) ||
764 static void add_txt(char *name, char *txt, int stat)
766 struct txt_record *r = opt_malloc(sizeof(struct txt_record));
770 size_t len = strlen(txt);
771 r->txt = opt_malloc(len+1);
774 memcpy((r->txt)+1, txt, len);
778 r->name = opt_string_alloc(name);
779 r->next = daemon->txt;
785 static void do_usage(void)
798 { '#', TFTP_MAX_CONNECTIONS },
802 printf(_("Usage: dnsmasq [options]\n\n"));
803 #ifndef HAVE_GETOPT_LONG
804 printf(_("Use short options only on the command line.\n"));
806 printf(_("Valid options are:\n"));
808 for (i = 0; usage[i].opt != 0; i++)
810 char *desc = usage[i].flagdesc;
813 if (!desc || *desc == '[')
819 for ( j = 0; opts[j].name; j++)
820 if (opts[j].val == usage[i].opt)
822 if (usage[i].opt < 256)
823 sprintf(buff, "-%c, ", usage[i].opt);
827 sprintf(buff+4, "--%s%s%s", opts[j].name, eq, desc);
828 printf("%-55.55s", buff);
832 safe_strncpy(buff, usage[i].arg, sizeof(buff));
833 for (j = 0; tab[j].handle; j++)
834 if (tab[j].handle == *(usage[i].arg))
835 sprintf(buff, "%d", tab[j].val);
837 printf(_(usage[i].desc), buff);
842 #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
843 #define ret_err_free(x,m) do { strcpy(errstr, (x)); free((m)); return 0; } while (0)
844 #define goto_err(x) do { strcpy(errstr, (x)); goto on_error; } while (0)
846 static char *parse_mysockaddr(char *arg, union mysockaddr *addr)
848 if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
849 addr->sa.sa_family = AF_INET;
850 else if (inet_pton(AF_INET6, arg, &addr->in6.sin6_addr) > 0)
851 addr->sa.sa_family = AF_INET6;
853 return _("bad address");
858 char *parse_server(char *arg, struct server_details *sdetails)
860 sdetails->serv_port = NAMESERVER_PORT;
863 struct addrinfo hints;
865 memset(&hints, 0, sizeof(struct addrinfo));
867 *sdetails->interface = 0;
868 sdetails->addr_type = AF_UNSPEC;
870 if (strcmp(arg, "#") == 0)
873 *sdetails->flags |= SERV_USE_RESOLV;
874 sdetails->addr_type = AF_LOCAL;
879 if ((sdetails->source = split_chr(arg, '@')) && /* is there a source. */
880 (portno = split_chr(sdetails->source, '#')) &&
881 !atoi_check16(portno, &sdetails->source_port))
882 return _("bad port");
884 if ((portno = split_chr(arg, '#')) && /* is there a port no. */
885 !atoi_check16(portno, &sdetails->serv_port))
886 return _("bad port");
888 sdetails->scope_id = split_chr(arg, '%');
890 if (sdetails->source) {
891 sdetails->interface_opt = split_chr(sdetails->source, '@');
893 if (sdetails->interface_opt)
895 #if defined(SO_BINDTODEVICE)
896 safe_strncpy(sdetails->interface, sdetails->source, IF_NAMESIZE);
897 sdetails->source = sdetails->interface_opt;
899 return _("interface binding not supported");
904 if (inet_pton(AF_INET, arg, &sdetails->addr->in.sin_addr) > 0)
905 sdetails->addr_type = AF_INET;
906 else if (inet_pton(AF_INET6, arg, &sdetails->addr->in6.sin6_addr) > 0)
907 sdetails->addr_type = AF_INET6;
910 /* if the argument is neither an IPv4 not an IPv6 address, it might be a
911 hostname and we should try to resolve it to a suitable address. */
912 memset(&hints, 0, sizeof(hints));
913 /* The AI_ADDRCONFIG flag ensures that then IPv4 addresses are returned in
914 the result only if the local system has at least one IPv4 address
915 configured, and IPv6 addresses are returned only if the local system
916 has at least one IPv6 address configured. The loopback address is not
917 considered for this case as valid as a configured address. This flag is
918 useful on, for example, IPv4-only systems, to ensure that getaddrinfo()
919 does not return IPv6 socket addresses that would always fail in
920 subsequent connect() or bind() attempts. */
921 hints.ai_flags = AI_ADDRCONFIG;
922 #if defined(HAVE_IDN) && defined(AI_IDN)
923 /* If the AI_IDN flag is specified and we have glibc 2.3.4 or newer, then
924 the node name given in node is converted to IDN format if necessary.
925 The source encoding is that of the current locale. */
926 hints.ai_flags |= AI_IDN;
928 /* The value AF_UNSPEC indicates that getaddrinfo() should return socket
929 addresses for any address family (either IPv4 or IPv6, for example)
930 that can be used with node <arg> and service "domain". */
931 hints.ai_family = AF_UNSPEC;
933 /* Get addresses suitable for sending datagrams. We assume that we can use the
934 same addresses for TCP connections. Settting this to zero gets each address
935 threes times, for SOCK_STREAM, SOCK_RAW and SOCK_DGRAM, which is not useful. */
936 hints.ai_socktype = SOCK_DGRAM;
938 /* Get address associated with this hostname */
939 ecode = getaddrinfo(arg, NULL, &hints, &sdetails->hostinfo);
942 /* The getaddrinfo() function allocated and initialized a linked list of
943 addrinfo structures, one for each network address that matches node
944 and service, subject to the restrictions imposed by our <hints>
945 above, and returns a pointer to the start of the list in <hostinfo>.
946 The items in the linked list are linked by the <ai_next> field. */
948 sdetails->orig_hostinfo = sdetails->hostinfo;
953 /* Lookup failed, return human readable error string */
954 if (ecode == EAI_AGAIN)
955 return _("Cannot resolve server name");
957 return _((char*)gai_strerror(ecode));
965 char *parse_server_addr(struct server_details *sdetails)
967 if (sdetails->addr_type == AF_INET)
969 sdetails->addr->in.sin_port = htons(sdetails->serv_port);
970 sdetails->addr->sa.sa_family = sdetails->source_addr->sa.sa_family = AF_INET;
971 #ifdef HAVE_SOCKADDR_SA_LEN
972 sdetails->source_addr->in.sin_len = sdetails->addr->in.sin_len = sizeof(struct sockaddr_in);
974 sdetails->source_addr->in.sin_addr.s_addr = INADDR_ANY;
975 sdetails->source_addr->in.sin_port = htons(daemon->query_port);
977 if (sdetails->source)
980 *sdetails->flags |= SERV_HAS_SOURCE;
981 sdetails->source_addr->in.sin_port = htons(sdetails->source_port);
982 if (inet_pton(AF_INET, sdetails->source, &sdetails->source_addr->in.sin_addr) == 0)
984 if (inet_pton(AF_INET6, sdetails->source, &sdetails->source_addr->in6.sin6_addr) == 1)
986 sdetails->source_addr->sa.sa_family = AF_INET6;
987 /* When resolving a server IP by hostname, we can simply skip mismatching
988 server / source IP pairs. Otherwise, when an IP address is given directly,
989 this is a fatal error. */
990 if (!sdetails->orig_hostinfo)
991 return _("cannot use IPv4 server address with IPv6 source address");
995 #if defined(SO_BINDTODEVICE)
996 if (sdetails->interface_opt)
997 return _("interface can only be specified once");
999 sdetails->source_addr->in.sin_addr.s_addr = INADDR_ANY;
1000 safe_strncpy(sdetails->interface, sdetails->source, IF_NAMESIZE);
1002 return _("interface binding not supported");
1008 else if (sdetails->addr_type == AF_INET6)
1010 if (sdetails->scope_id && (sdetails->scope_index = if_nametoindex(sdetails->scope_id)) == 0)
1011 return _("bad interface name");
1013 sdetails->addr->in6.sin6_port = htons(sdetails->serv_port);
1014 sdetails->addr->in6.sin6_scope_id = sdetails->scope_index;
1015 sdetails->source_addr->in6.sin6_addr = in6addr_any;
1016 sdetails->source_addr->in6.sin6_port = htons(daemon->query_port);
1017 sdetails->source_addr->in6.sin6_scope_id = 0;
1018 sdetails->addr->sa.sa_family = sdetails->source_addr->sa.sa_family = AF_INET6;
1019 sdetails->addr->in6.sin6_flowinfo = sdetails->source_addr->in6.sin6_flowinfo = 0;
1020 #ifdef HAVE_SOCKADDR_SA_LEN
1021 sdetails->addr->in6.sin6_len = sdetails->source_addr->in6.sin6_len = sizeof(sdetails->addr->in6);
1023 if (sdetails->source)
1025 if (sdetails->flags)
1026 *sdetails->flags |= SERV_HAS_SOURCE;
1027 sdetails->source_addr->in6.sin6_port = htons(sdetails->source_port);
1028 if (inet_pton(AF_INET6, sdetails->source, &sdetails->source_addr->in6.sin6_addr) == 0)
1030 if (inet_pton(AF_INET, sdetails->source, &sdetails->source_addr->in.sin_addr) == 1)
1032 sdetails->source_addr->sa.sa_family = AF_INET;
1033 /* When resolving a server IP by hostname, we can simply skip mismatching
1034 server / source IP pairs. Otherwise, when an IP address is given directly,
1035 this is a fatal error. */
1036 if(!sdetails->orig_hostinfo)
1037 return _("cannot use IPv6 server address with IPv4 source address");
1041 #if defined(SO_BINDTODEVICE)
1042 if (sdetails->interface_opt)
1043 return _("interface can only be specified once");
1045 sdetails->source_addr->in6.sin6_addr = in6addr_any;
1046 safe_strncpy(sdetails->interface, sdetails->source, IF_NAMESIZE);
1048 return _("interface binding not supported");
1054 else if (sdetails->addr_type != AF_LOCAL)
1055 return _("bad address");
1060 int parse_server_next(struct server_details *sdetails)
1062 /* Looping over resolved addresses? */
1063 if (sdetails->hostinfo)
1065 /* Get address type */
1066 sdetails->addr_type = sdetails->hostinfo->ai_family;
1069 if (sdetails->addr_type == AF_INET)
1070 memcpy(&sdetails->addr->in.sin_addr,
1071 &((struct sockaddr_in *) sdetails->hostinfo->ai_addr)->sin_addr,
1072 sizeof(sdetails->addr->in.sin_addr));
1073 else if (sdetails->addr_type == AF_INET6)
1074 memcpy(&sdetails->addr->in6.sin6_addr,
1075 &((struct sockaddr_in6 *) sdetails->hostinfo->ai_addr)->sin6_addr,
1076 sizeof(sdetails->addr->in6.sin6_addr));
1078 /* Iterate to the next available address */
1079 sdetails->valid = sdetails->hostinfo->ai_next != NULL;
1080 sdetails->hostinfo = sdetails->hostinfo->ai_next;
1083 else if (sdetails->valid)
1085 /* When using an IP address, we return the address only once */
1086 sdetails->valid = 0;
1089 /* Stop iterating here, we used all available addresses */
1093 static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int size)
1099 char domain[29]; /* strlen("xxx.yyy.zzz.ttt.in-addr.arpa")+1 */
1100 union mysockaddr serv_addr, source_addr;
1101 char interface[IF_NAMESIZE+1];
1102 int count = 1, rem, addrbytes, addrbits;
1103 struct server_details sdetails;
1105 memset(&sdetails, 0, sizeof(struct server_details));
1106 sdetails.addr = &serv_addr;
1107 sdetails.source_addr = &source_addr;
1108 sdetails.interface = interface;
1109 sdetails.flags = &flags;
1112 flags = SERV_LITERAL_ADDRESS;
1113 else if ((string = parse_server(server, &sdetails)))
1117 flags |= SERV_FROM_FILE;
1120 addrbytes = (32 - size) >> 3;
1121 addrbits = (32 - size) & 7;
1123 if (size > 32 || size < 1)
1124 return _("bad IPv4 prefix length");
1126 /* Zero out last address bits according to CIDR mask */
1127 ((u8 *)addr4)[3-addrbytes] &= ~((1 << addrbits)-1);
1132 count = 1 << (8 - rem);
1134 for (i = 0; i < count; i++)
1140 for (j = (rem == 0) ? msize-1 : msize; j >= 0; j--)
1142 int dig = ((unsigned char *)addr4)[j];
1147 string += sprintf(string, "%d.", dig);
1150 sprintf(string, "in-addr.arpa");
1152 if (flags & SERV_LITERAL_ADDRESS)
1154 if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
1159 while (parse_server_next(&sdetails))
1161 if ((string = parse_server_addr(&sdetails)))
1164 if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
1168 if (sdetails.orig_hostinfo)
1169 freeaddrinfo(sdetails.orig_hostinfo);
1176 static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, int size)
1182 char domain[73]; /* strlen("32*<n.>ip6.arpa")+1 */
1183 union mysockaddr serv_addr, source_addr;
1184 char interface[IF_NAMESIZE+1];
1185 int count = 1, rem, addrbytes, addrbits;
1186 struct server_details sdetails;
1188 memset(&sdetails, 0, sizeof(struct server_details));
1189 sdetails.addr = &serv_addr;
1190 sdetails.source_addr = &source_addr;
1191 sdetails.interface = interface;
1192 sdetails.flags = &flags;
1195 flags = SERV_LITERAL_ADDRESS;
1196 else if ((string = parse_server(server, &sdetails)))
1200 flags |= SERV_FROM_FILE;
1203 addrbytes = (128 - size) >> 3;
1204 addrbits = (128 - size) & 7;
1206 if (size > 128 || size < 1)
1207 return _("bad IPv6 prefix length");
1209 /* Zero out last address bits according to CIDR mask */
1210 addr6->s6_addr[15-addrbytes] &= ~((1 << addrbits) - 1);
1215 count = 1 << (4 - rem);
1217 for (i = 0; i < count; i++)
1223 for (j = (rem == 0) ? msize-1 : msize; j >= 0; j--)
1225 int dig = ((unsigned char *)addr6)[j>>1];
1227 dig = j & 1 ? dig & 15 : dig >> 4;
1232 string += sprintf(string, "%.1x.", dig);
1235 sprintf(string, "ip6.arpa");
1237 if (flags & SERV_LITERAL_ADDRESS)
1239 if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
1244 while (parse_server_next(&sdetails))
1246 if ((string = parse_server_addr(&sdetails)))
1249 if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
1253 if (sdetails.orig_hostinfo)
1254 freeaddrinfo(sdetails.orig_hostinfo);
1263 static int is_tag_prefix(char *arg)
1265 if (arg && (strstr(arg, "net:") == arg || strstr(arg, "tag:") == arg))
1271 static char *set_prefix(char *arg)
1273 if (strstr(arg, "set:") == arg)
1279 static struct dhcp_netid *dhcp_netid_create(const char *net, struct dhcp_netid *next)
1281 struct dhcp_netid *tt;
1282 tt = opt_malloc(sizeof (struct dhcp_netid));
1283 tt->net = opt_string_alloc(net);
1288 static void dhcp_netid_free(struct dhcp_netid *nid)
1292 struct dhcp_netid *tmp = nid;
1299 /* Parse one or more tag:s before parameters.
1300 * Moves arg to the end of tags. */
1301 static struct dhcp_netid * dhcp_tags(char **arg)
1303 struct dhcp_netid *id = NULL;
1305 while (is_tag_prefix(*arg))
1307 char *comma = split(*arg);
1308 id = dhcp_netid_create((*arg)+4, id);
1313 dhcp_netid_free(id);
1319 static void dhcp_netid_list_free(struct dhcp_netid_list *netid)
1323 struct dhcp_netid_list *tmplist = netid;
1324 netid = netid->next;
1325 dhcp_netid_free(tmplist->list);
1330 static void dhcp_config_free(struct dhcp_config *config)
1334 struct hwaddr_config *hwaddr = config->hwaddr;
1338 struct hwaddr_config *tmp = hwaddr;
1339 hwaddr = hwaddr->next;
1343 dhcp_netid_list_free(config->netid);
1344 dhcp_netid_free(config->filter);
1346 if (config->flags & CONFIG_CLID)
1348 if (config->flags & CONFIG_NAME)
1349 free(config->hostname);
1352 if (config->flags & CONFIG_ADDR6)
1354 struct addrlist *addr, *tmp;
1356 for (addr = config->addr6; addr; addr = tmp)
1368 static void dhcp_context_free(struct dhcp_context *ctx)
1372 dhcp_netid_free(ctx->filter);
1373 free(ctx->netid.net);
1375 free(ctx->template_interface);
1381 static void dhcp_opt_free(struct dhcp_opt *opt)
1383 if (opt->flags & DHOPT_VENDOR)
1384 free(opt->u.vendor_class);
1385 dhcp_netid_free(opt->netid);
1391 /* This is too insanely large to keep in-line in the switch */
1392 static int parse_dhcp_opt(char *errstr, char *arg, int flags)
1394 struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt));
1395 char lenchar = 0, *cp;
1396 int addrs, digs, is_addr, is_addr6, is_hex, is_dec, is_string, dots;
1412 for (cp = arg; *cp; cp++)
1413 if (*cp < '0' || *cp > '9')
1418 new->opt = atoi(arg);
1424 if (strstr(arg, "option:") == arg)
1426 if ((new->opt = lookup_dhcp_opt(AF_INET, arg+7)) != -1)
1428 opt_len = lookup_dhcp_len(AF_INET, new->opt);
1429 /* option:<optname> must follow tag and vendor string. */
1430 if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
1436 else if (strstr(arg, "option6:") == arg)
1438 for (cp = arg+8; *cp; cp++)
1439 if (*cp < '0' || *cp > '9')
1444 new->opt = atoi(arg+8);
1450 if ((new->opt = lookup_dhcp_opt(AF_INET6, arg+8)) != -1)
1452 opt_len = lookup_dhcp_len(AF_INET6, new->opt);
1453 if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
1457 /* option6:<opt>|<optname> must follow tag and vendor string. */
1462 else if (strstr(arg, "vendor:") == arg)
1464 new->u.vendor_class = (unsigned char *)opt_string_alloc(arg+7);
1465 new->flags |= DHOPT_VENDOR;
1466 if ((new->flags & DHOPT_ENCAPSULATE) || flags == DHOPT_MATCH)
1467 goto_err(_("inappropriate vendor:"));
1469 else if (strstr(arg, "encap:") == arg)
1471 new->u.encap = atoi(arg+6);
1472 new->flags |= DHOPT_ENCAPSULATE;
1473 if ((new->flags & DHOPT_VENDOR) || flags == DHOPT_MATCH)
1474 goto_err(_("inappropriate encap:"));
1476 else if (strstr(arg, "vi-encap:") == arg)
1478 new->u.encap = atoi(arg+9);
1479 new->flags |= DHOPT_RFC3925;
1480 if (flags == DHOPT_MATCH)
1488 /* allow optional "net:" or "tag:" for consistency */
1489 const char *name = (is_tag_prefix(arg)) ? arg+4 : set_prefix(arg);
1490 new->netid = dhcp_netid_create(name, new->netid);
1499 if (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))
1500 goto_err(_("unsupported encapsulation for IPv6 option"));
1503 !(new->flags & DHOPT_RFC3925))
1504 opt_len = lookup_dhcp_len(AF_INET6, new->opt);
1509 !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
1510 opt_len = lookup_dhcp_len(AF_INET, new->opt);
1512 /* option may be missing with rfc3925 match */
1514 goto_err(_("bad dhcp-option"));
1518 /* characterise the value */
1520 int found_dig = 0, found_colon = 0;
1521 is_addr = is_addr6 = is_hex = is_dec = is_string = 1;
1524 for (cp = comma; (c = *cp); cp++)
1528 is_dec = is_hex = 0;
1533 is_dec = is_addr = 0;
1538 is_addr6 = is_dec = is_hex = 0;
1539 if (cp == comma) /* leading / means a pathname */
1544 is_dec = is_hex = 0;
1548 is_hex = is_addr = is_addr6 = 0;
1550 is_dec = is_hex = 0;
1551 else if (!(c >='0' && c <= '9'))
1554 if (cp[1] == 0 && is_dec &&
1555 (c == 'b' || c == 's' || c == 'i'))
1562 if (!((c >='A' && c <= 'F') ||
1563 (c >='a' && c <= 'f') ||
1564 (c == '*' && (flags & DHOPT_MATCH))))
1567 if (c != '[' && c != ']')
1575 is_dec = is_addr = 0;
1581 /* NTP server option takes hex, addresses or FQDN */
1582 if (is6 && new->opt == OPTION6_NTP_SERVER && !is_hex)
1583 opt_len |= is_addr6 ? OT_ADDR_LIST : OT_RFC1035_NAME;
1586 /* We know that some options take addresses */
1587 if (opt_len & OT_ADDR_LIST)
1589 is_string = is_dec = is_hex = 0;
1591 if (!is6 && (!is_addr || dots == 0))
1592 goto_err(_("bad IP address"));
1594 if (is6 && !is_addr6)
1595 goto_err(_("bad IPv6 address"));
1598 else if (opt_len & (OT_NAME | OT_RFC1035_NAME | OT_CSTRING))
1599 is_addr6 = is_addr = is_dec = is_hex = 0;
1601 if (found_dig && (opt_len & OT_TIME) && strlen(comma) > 0)
1605 switch (comma[strlen(comma) - 1])
1625 comma[strlen(comma) - 1] = 0;
1629 new->val = opt_malloc(4);
1631 *((int *)new->val) = htonl(val * fac);
1633 else if (is_hex && digs > 1)
1636 new->val = opt_malloc(new->len);
1637 parse_hex(comma, new->val, digs, (flags & DHOPT_MATCH) ? &new->u.wildcard_mask : NULL, NULL);
1638 new->flags |= DHOPT_HEX;
1642 int i, val = atoi(comma);
1643 /* assume numeric arg is 1 byte except for
1644 options where it is known otherwise.
1645 For vendor class option, we have to hack. */
1648 else if (val & 0xffff0000)
1650 else if (val & 0xff00)
1657 else if (lenchar == 's')
1659 else if (lenchar == 'i')
1662 new->val = opt_malloc(new->len);
1663 for (i=0; i<new->len; i++)
1664 new->val[i] = val>>((new->len - i - 1)*8);
1666 else if (is_addr && !is6)
1671 /* max length of address/subnet descriptor is five bytes,
1672 add one for the option 120 enc byte too */
1673 new->val = op = opt_malloc((5 * addrs) + 1);
1674 new->flags |= DHOPT_ADDR;
1676 if (!(new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR | DHOPT_RFC3925)) &&
1677 new->opt == OPTION_SIP_SERVER)
1679 *(op++) = 1; /* RFC 3361 "enc byte" */
1680 new->flags &= ~DHOPT_ADDR;
1686 slash = split_chr(cp, '/');
1687 if (!inet_pton(AF_INET, cp, &in))
1688 goto_err(_("bad IPv4 address"));
1691 memcpy(op, &in, INADDRSZ);
1696 unsigned char *p = (unsigned char *)∈
1697 int netsize = atoi(slash);
1707 new->flags &= ~DHOPT_ADDR; /* cannot re-write descriptor format */
1710 new->len = op - new->val;
1712 else if (is_addr6 && is6)
1715 new->val = op = opt_malloc(16 * addrs);
1716 new->flags |= DHOPT_ADDR6;
1722 /* check for [1234::7] */
1725 if (strlen(cp) > 1 && cp[strlen(cp)-1] == ']')
1726 cp[strlen(cp)-1] = 0;
1728 if (inet_pton(AF_INET6, cp, op))
1734 goto_err(_("bad IPv6 address"));
1736 new->len = op - new->val;
1741 if ((new->opt == OPTION_DOMAIN_SEARCH || new->opt == OPTION_SIP_SERVER) &&
1742 !is6 && !(new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR | DHOPT_RFC3925)))
1744 /* dns search, RFC 3397, or SIP, RFC 3361 */
1745 unsigned char *q, *r, *tail;
1746 unsigned char *p, *m = NULL, *newp;
1747 size_t newlen, len = 0;
1748 int header_size = (new->opt == OPTION_DOMAIN_SEARCH) ? 0 : 1;
1755 char *in, *dom = NULL;
1757 /* Allow "." as an empty domain */
1758 if (strcmp (arg, ".") != 0)
1760 if (!(dom = canonicalise_opt(arg)))
1761 goto_err(_("bad domain in dhcp-option"));
1763 domlen = strlen(dom) + 2;
1766 newp = opt_malloc(len + domlen + header_size);
1769 memcpy(newp, m, header_size + len);
1773 p = m + header_size;
1776 /* add string on the end in RFC1035 format */
1777 for (in = dom; in && *in;)
1779 unsigned char *cp = q++;
1781 for (j = 0; *in && (*in != '.'); in++, j++)
1790 /* Now tail-compress using earlier names. */
1792 for (tail = p + len; *tail; tail += (*tail) + 1)
1793 for (r = p; r - p < (int)len; r += (*r) + 1)
1794 if (strcmp((char *)r, (char *)tail) == 0)
1796 PUTSHORT((r - p) | 0xc000, tail);
1807 /* RFC 3361, enc byte is zero for names */
1808 if (new->opt == OPTION_SIP_SERVER && m)
1810 new->len = (int) len + header_size;
1814 else if (comma && (opt_len & OT_CSTRING))
1816 /* length fields are two bytes so need 16 bits for each string */
1818 unsigned char *p, *newp;
1820 for (i = 0; comma[i]; i++)
1821 if (comma[i] == ',')
1824 newp = opt_malloc(strlen(comma)+(2*commas));
1831 u16 len = strlen(arg);
1834 memcpy(p, arg, len);
1842 new->len = p - newp;
1844 else if (comma && (opt_len & OT_RFC1035_NAME))
1846 unsigned char *p = NULL, *q, *newp, *end;
1848 int header_size = (is6 && new->opt == OPTION6_NTP_SERVER) ? 4 : 0;
1854 char *dom = canonicalise_opt(arg);
1856 goto_err(_("bad domain in dhcp-option"));
1858 newp = opt_malloc(len + header_size + strlen(dom) + 2);
1862 memcpy(newp, p, len);
1868 end = do_rfc1035_name(q + header_size, dom, NULL);
1870 if (is6 && new->opt == OPTION6_NTP_SERVER)
1872 PUTSHORT(NTP_SUBOPTION_SRV_FQDN, q);
1873 PUTSHORT(end - q - 2, q);
1888 new->len = strlen(comma);
1889 /* keep terminating zero on string */
1890 new->val = (unsigned char *)opt_string_alloc(comma);
1891 new->flags |= DHOPT_STRING;
1897 ((new->len > 255) ||
1898 (new->len > 253 && (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))) ||
1899 (new->len > 250 && (new->flags & DHOPT_RFC3925))))
1900 goto_err(_("dhcp-option too long"));
1902 if (flags == DHOPT_MATCH)
1904 if ((new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)) ||
1907 goto_err(_("illegal dhcp-match"));
1911 new->next = daemon->dhcp_match6;
1912 daemon->dhcp_match6 = new;
1916 new->next = daemon->dhcp_match;
1917 daemon->dhcp_match = new;
1922 new->next = daemon->dhcp_opts6;
1923 daemon->dhcp_opts6 = new;
1927 new->next = daemon->dhcp_opts;
1928 daemon->dhcp_opts = new;
1939 void set_option_bool(unsigned int opt)
1941 option_var(opt) |= option_val(opt);
1944 void reset_option_bool(unsigned int opt)
1946 option_var(opt) &= ~(option_val(opt));
1949 static int one_opt(int option, char *arg, char *errstr, char *gen_err, int command_line, int servers_only)
1957 for (i=0; usage[i].opt != 0; i++)
1958 if (usage[i].opt == option)
1960 int rept = usage[i].rept;
1965 if (rept == ARG_USED_CL)
1966 ret_err(_("illegal repeated flag"));
1967 if (rept == ARG_ONE)
1968 usage[i].rept = ARG_USED_CL;
1972 /* allow file to override command line */
1973 if (rept == ARG_USED_FILE)
1974 ret_err(_("illegal repeated keyword"));
1975 if (rept == ARG_USED_CL || rept == ARG_ONE)
1976 usage[i].rept = ARG_USED_FILE;
1979 if (rept != ARG_DUP && rept != ARG_ONE && rept != ARG_USED_CL)
1981 set_option_bool(rept);
1990 case 'C': /* --conf-file */
1992 char *file = opt_string_alloc(arg);
2001 case LOPT_CONF_SCRIPT: /* --conf-script */
2003 char *file = opt_string_alloc(arg);
2006 one_file(file, LOPT_CONF_SCRIPT);
2012 case '7': /* --conf-dir */
2016 char *directory, *path;
2020 } *ignore_suffix = NULL, *match_suffix = NULL, *files = NULL, *li;
2023 if (!(directory = opt_string_alloc(arg)))
2026 for (arg = comma; arg; arg = comma)
2029 if (strlen(arg) != 0)
2031 li = opt_malloc(sizeof(struct list));
2034 /* "*" with no suffix is a no-op */
2039 li->next = match_suffix;
2041 /* Have to copy: buffer is overwritten */
2042 li->name = opt_string_alloc(arg+1);
2047 li->next = ignore_suffix;
2049 /* Have to copy: buffer is overwritten */
2050 li->name = opt_string_alloc(arg);
2055 if (!(dir_stream = opendir(directory)))
2056 die(_("cannot access directory %s: %s"), directory, EC_FILE);
2058 while ((ent = readdir(dir_stream)))
2060 size_t len = strlen(ent->d_name);
2063 /* ignore emacs backups and dotfiles */
2065 ent->d_name[len - 1] == '~' ||
2066 (ent->d_name[0] == '#' && ent->d_name[len - 1] == '#') ||
2067 ent->d_name[0] == '.')
2072 for (li = match_suffix; li; li = li->next)
2074 /* check for required suffices */
2075 size_t ls = strlen(li->name);
2077 strcmp(li->name, &ent->d_name[len - ls]) == 0)
2084 for (li = ignore_suffix; li; li = li->next)
2086 /* check for proscribed suffices */
2087 size_t ls = strlen(li->name);
2089 strcmp(li->name, &ent->d_name[len - ls]) == 0)
2095 path = opt_malloc(strlen(directory) + len + 2);
2096 strcpy(path, directory);
2098 strcat(path, ent->d_name);
2100 /* files must be readable */
2101 if (stat(path, &buf) == -1)
2102 die(_("cannot access %s: %s"), path, EC_FILE);
2104 /* only reg files allowed. */
2105 if (S_ISREG(buf.st_mode))
2107 /* sort files into order. */
2108 struct list **up, *new = opt_malloc(sizeof(struct list));
2111 for (up = &files, li = files; li; up = &li->next, li = li->next)
2112 if (strcmp(li->name, path) >=0)
2123 for (li = files; li; li = li->next)
2124 one_file(li->name, 0);
2126 closedir(dir_stream);
2128 for(; ignore_suffix; ignore_suffix = li)
2130 li = ignore_suffix->next;
2131 free(ignore_suffix->name);
2132 free(ignore_suffix);
2134 for(; match_suffix; match_suffix = li)
2136 li = match_suffix->next;
2137 free(match_suffix->name);
2140 for(; files; files = li)
2149 case LOPT_ADD_SBNET: /* --add-subnet */
2150 set_option_bool(OPT_CLIENT_SUBNET);
2156 struct mysubnet* new = opt_malloc(sizeof(struct mysubnet));
2157 if ((end = split_chr(arg, '/')))
2159 /* has subnet+len */
2160 err = parse_mysockaddr(arg, &new->addr);
2162 ret_err_free(err, new);
2163 if (!atoi_check(end, &new->mask))
2164 ret_err_free(gen_err, new);
2167 else if (!atoi_check(arg, &new->mask))
2168 ret_err_free(gen_err, new);
2170 daemon->add_subnet4 = new;
2174 new = opt_malloc(sizeof(struct mysubnet));
2175 if ((end = split_chr(comma, '/')))
2177 /* has subnet+len */
2178 err = parse_mysockaddr(comma, &new->addr);
2180 ret_err_free(err, new);
2181 if (!atoi_check(end, &new->mask))
2182 ret_err_free(gen_err, new);
2187 if (!atoi_check(comma, &new->mask))
2188 ret_err_free(gen_err, new);
2191 daemon->add_subnet6 = new;
2196 case '1': /* --enable-dbus */
2197 set_option_bool(OPT_DBUS);
2199 daemon->dbus_name = opt_string_alloc(arg);
2201 daemon->dbus_name = DNSMASQ_SERVICE;
2204 case LOPT_UBUS: /* --enable-ubus */
2205 set_option_bool(OPT_UBUS);
2207 daemon->ubus_name = opt_string_alloc(arg);
2209 daemon->ubus_name = DNSMASQ_UBUS_NAME;
2212 case '8': /* --log-facility */
2213 /* may be a filename */
2214 if (strchr(arg, '/') || strcmp (arg, "-") == 0)
2215 daemon->log_file = opt_string_alloc(arg);
2219 ret_err(_("setting log facility is not possible under Android"));
2221 for (i = 0; facilitynames[i].c_name; i++)
2222 if (hostname_isequal((char *)facilitynames[i].c_name, arg))
2225 if (facilitynames[i].c_name)
2226 daemon->log_fac = facilitynames[i].c_val;
2228 ret_err(_("bad log facility"));
2233 case 'x': /* --pid-file */
2234 daemon->runfile = opt_string_alloc(arg);
2237 case 'r': /* --resolv-file */
2239 char *name = opt_string_alloc(arg);
2240 struct resolvc *new, *list = daemon->resolv_files;
2242 if (list && list->is_default)
2244 /* replace default resolv file - possibly with nothing */
2247 list->is_default = 0;
2255 new = opt_malloc(sizeof(struct resolvc));
2258 new->is_default = 0;
2263 daemon->resolv_files = list;
2267 case LOPT_SERVERS_FILE:
2268 daemon->servers_file = opt_string_alloc(arg);
2271 case 'm': /* --mx-host */
2274 struct mx_srv_record *new;
2275 char *name, *target = NULL;
2277 if ((comma = split(arg)))
2280 if ((prefstr = split(comma)) && !atoi_check16(prefstr, &pref))
2281 ret_err(_("bad MX preference"));
2284 if (!(name = canonicalise_opt(arg)) ||
2285 (comma && !(target = canonicalise_opt(comma))))
2289 ret_err(_("bad MX name"));
2292 new = opt_malloc(sizeof(struct mx_srv_record));
2293 new->next = daemon->mxnames;
2294 daemon->mxnames = new;
2297 new->target = target; /* may be NULL */
2302 case 't': /* --mx-target */
2303 if (!(daemon->mxtarget = canonicalise_opt(arg)))
2304 ret_err(_("bad MX target"));
2307 case LOPT_DUMPFILE: /* --dumpfile */
2308 daemon->dump_file = opt_string_alloc(arg);
2311 case LOPT_DUMPMASK: /* --dumpmask */
2312 daemon->dump_mask = strtol(arg, NULL, 0);
2316 case 'l': /* --dhcp-leasefile */
2317 daemon->lease_file = opt_string_alloc(arg);
2320 /* Sorry about the gross pre-processor abuse */
2321 case '6': /* --dhcp-script */
2322 case LOPT_LUASCRIPT: /* --dhcp-luascript */
2323 # if !defined(HAVE_SCRIPT)
2324 ret_err(_("recompile with HAVE_SCRIPT defined to enable lease-change scripts"));
2326 if (option == LOPT_LUASCRIPT)
2327 # if !defined(HAVE_LUASCRIPT)
2328 ret_err(_("recompile with HAVE_LUASCRIPT defined to enable Lua scripts"));
2330 daemon->luascript = opt_string_alloc(arg);
2333 daemon->lease_change_command = opt_string_alloc(arg);
2336 #endif /* HAVE_DHCP */
2338 case LOPT_DHCP_HOST: /* --dhcp-hostsfile */
2339 case LOPT_DHCP_OPTS: /* --dhcp-optsfile */
2340 case 'H': /* --addn-hosts */
2342 struct hostsfile *new = opt_malloc(sizeof(struct hostsfile));
2343 new->fname = opt_string_alloc(arg);
2344 new->index = daemon->host_index++;
2348 new->next = daemon->addn_hosts;
2349 daemon->addn_hosts = new;
2351 else if (option == LOPT_DHCP_HOST)
2353 new->next = daemon->dhcp_hosts_file;
2354 daemon->dhcp_hosts_file = new;
2356 else if (option == LOPT_DHCP_OPTS)
2358 new->next = daemon->dhcp_opts_file;
2359 daemon->dhcp_opts_file = new;
2365 case LOPT_DHCP_INOTIFY: /* --dhcp-hostsdir */
2366 case LOPT_DHOPT_INOTIFY: /* --dhcp-optsdir */
2367 case LOPT_HOST_INOTIFY: /* --hostsdir */
2369 struct dyndir *new = opt_malloc(sizeof(struct dyndir));
2370 new->dname = opt_string_alloc(arg);
2372 new->next = daemon->dynamic_dirs;
2373 daemon->dynamic_dirs = new;
2374 if (option == LOPT_DHCP_INOTIFY)
2375 new->flags |= AH_DHCP_HST;
2376 else if (option == LOPT_DHOPT_INOTIFY)
2377 new->flags |= AH_DHCP_OPT;
2378 else if (option == LOPT_HOST_INOTIFY)
2379 new->flags |= AH_HOSTS;
2384 case LOPT_AUTHSERV: /* --auth-server */
2387 daemon->authserver = opt_string_alloc(arg);
2389 while ((arg = comma))
2391 struct iname *new = opt_malloc(sizeof(struct iname));
2395 if (inet_pton(AF_INET, arg, &new->addr.in.sin_addr) > 0)
2396 new->addr.sa.sa_family = AF_INET;
2397 else if (inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr) > 0)
2398 new->addr.sa.sa_family = AF_INET6;
2401 char *fam = split_chr(arg, '/');
2402 new->name = opt_string_alloc(arg);
2403 new->addr.sa.sa_family = 0;
2406 if (strcmp(fam, "4") == 0)
2407 new->addr.sa.sa_family = AF_INET;
2408 else if (strcmp(fam, "6") == 0)
2409 new->addr.sa.sa_family = AF_INET6;
2413 ret_err_free(gen_err, new);
2417 new->next = daemon->authinterface;
2418 daemon->authinterface = new;
2423 case LOPT_AUTHSFS: /* --auth-sec-servers */
2425 struct name_list *new;
2429 new = opt_malloc(sizeof(struct name_list));
2430 new->name = opt_string_alloc(arg);
2431 new->next = daemon->secondary_forward_server;
2432 daemon->secondary_forward_server = new;
2438 case LOPT_AUTHZONE: /* --auth-zone */
2440 struct auth_zone *new;
2444 new = opt_malloc(sizeof(struct auth_zone));
2445 new->domain = canonicalise_opt(arg);
2447 ret_err_free(_("invalid auth-zone"), new);
2449 new->exclude = NULL;
2450 new->interface_names = NULL;
2451 new->next = daemon->auth_zones;
2452 daemon->auth_zones = new;
2454 while ((arg = comma))
2459 struct addrlist *subnet = NULL;
2460 union all_addr addr;
2463 prefix = split_chr(arg, '/');
2465 if (prefix && !atoi_check(prefix, &prefixlen))
2468 if (strstr(arg, "exclude:") == arg)
2474 if (inet_pton(AF_INET, arg, &addr.addr4))
2476 subnet = opt_malloc(sizeof(struct addrlist));
2477 subnet->prefixlen = (prefixlen == 0) ? 24 : prefixlen;
2478 subnet->flags = ADDRLIST_LITERAL;
2480 else if (inet_pton(AF_INET6, arg, &addr.addr6))
2482 subnet = opt_malloc(sizeof(struct addrlist));
2483 subnet->prefixlen = (prefixlen == 0) ? 64 : prefixlen;
2484 subnet->flags = ADDRLIST_LITERAL | ADDRLIST_IPV6;
2488 struct auth_name_list *name = opt_malloc(sizeof(struct auth_name_list));
2489 name->name = opt_string_alloc(arg);
2490 name->flags = AUTH4 | AUTH6;
2491 name->next = new->interface_names;
2492 new->interface_names = name;
2496 name->flags &= ~AUTH6;
2497 else if (prefixlen == 6)
2498 name->flags &= ~AUTH4;
2506 subnet->addr = addr;
2510 subnet->next = new->exclude;
2511 new->exclude = subnet;
2515 subnet->next = new->subnet;
2516 new->subnet = subnet;
2523 case LOPT_AUTHSOA: /* --auth-soa */
2525 daemon->soa_sn = (u32)atoi(arg);
2531 daemon->hostmaster = opt_string_alloc(arg);
2532 for (cp = daemon->hostmaster; cp && *cp; cp++)
2540 daemon->soa_refresh = (u32)atoi(arg);
2545 daemon->soa_retry = (u32)atoi(arg);
2547 daemon->soa_expiry = (u32)atoi(comma);
2554 case 's': /* --domain */
2555 case LOPT_SYNTH: /* --synth-domain */
2556 if (strcmp (arg, "#") == 0)
2557 set_option_bool(OPT_RESOLV_DOMAIN);
2560 char *d, *d_raw = arg;
2562 if (!(d = canonicalise_opt(d_raw)))
2566 free(d); /* allocate this again below. */
2569 struct cond_domain *new = opt_malloc(sizeof(struct cond_domain));
2576 unhide_metas(comma);
2577 if ((netpart = split_chr(comma, '/')))
2581 arg = split(netpart);
2582 if (!atoi_check(netpart, &msize))
2583 ret_err_free(gen_err, new);
2584 else if (inet_pton(AF_INET, comma, &new->start))
2589 ret_err_free(_("bad prefix length"), new);
2591 mask = (1 << (32 - msize)) - 1;
2593 new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask);
2594 new->end.s_addr = new->start.s_addr | htonl(mask);
2599 if (!(new->prefix = canonicalise_opt(arg)) ||
2600 strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
2601 ret_err_free(_("bad prefix"), new);
2603 else if (strcmp(arg, "local") != 0)
2604 ret_err_free(gen_err, new);
2607 /* local=/xxx.yyy.zzz.in-addr.arpa/ */
2608 domain_rev4(0, NULL, &new->start, msize);
2610 /* local=/<domain>/ */
2611 /* d_raw can't failed to canonicalise here, checked above. */
2612 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL);
2616 else if (inet_pton(AF_INET6, comma, &new->start6))
2618 u64 mask, addrpart = addr6part(&new->start6);
2621 ret_err_free(_("bad prefix length"), new);
2623 mask = (1LLU << (128 - msize)) - 1LLU;
2626 new->prefixlen = msize;
2628 /* prefix==64 overflows the mask calculation above */
2632 new->end6 = new->start6;
2633 setaddr6part(&new->start6, addrpart & ~mask);
2634 setaddr6part(&new->end6, addrpart | mask);
2640 if (!(new->prefix = canonicalise_opt(arg)) ||
2641 strlen(new->prefix) > MAXLABEL - INET6_ADDRSTRLEN)
2642 ret_err_free(_("bad prefix"), new);
2644 else if (strcmp(arg, "local") != 0)
2645 ret_err_free(gen_err, new);
2648 /* generate the equivalent of
2649 local=/xxx.yyy.zzz.ip6.arpa/ */
2650 domain_rev6(0, NULL, &new->start6, msize);
2652 /* local=/<domain>/ */
2653 /* d_raw can't failed to canonicalise here, checked above. */
2654 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL);
2659 ret_err_free(gen_err, new);
2665 prefstr = split(arg);
2667 if (inet_pton(AF_INET, comma, &new->start))
2671 new->end.s_addr = new->start.s_addr;
2672 else if (!inet_pton(AF_INET, arg, &new->end))
2673 ret_err_free(gen_err, new);
2675 else if (inet_pton(AF_INET6, comma, &new->start6))
2679 memcpy(&new->end6, &new->start6, IN6ADDRSZ);
2680 else if (!inet_pton(AF_INET6, arg, &new->end6))
2681 ret_err_free(gen_err, new);
2683 else if (option == 's')
2685 /* subnet from interface. */
2686 new->interface = opt_string_alloc(comma);
2690 ret_err_free(gen_err, new);
2692 if (option != 's' && prefstr)
2694 if (!(new->prefix = canonicalise_opt(prefstr)) ||
2695 strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
2696 ret_err_free(_("bad prefix"), new);
2700 new->domain = canonicalise_opt(d_raw);
2703 new->next = daemon->cond_domain;
2704 daemon->cond_domain = new;
2710 (star = strrchr(new->prefix, '*'))
2715 if (new->is6 && new->prefixlen < 64)
2716 ret_err_free(_("prefix length too small"), new);
2718 new->next = daemon->synth_domains;
2719 daemon->synth_domains = new;
2722 else if (option == 's')
2723 daemon->domain_suffix = canonicalise_opt(d_raw);
2730 case LOPT_CPE_ID: /* --add-dns-client */
2732 daemon->dns_client_id = opt_string_alloc(arg);
2735 case LOPT_UMBRELLA: /* --umbrella */
2736 set_option_bool(OPT_UMBRELLA);
2740 if (strstr(arg, "deviceid:"))
2743 u8 *u = daemon->umbrella_device;
2747 if (strlen(arg) != 16)
2750 for (p = arg; *p; p++)
2751 if (!isxdigit((int)*p))
2754 set_option_bool(OPT_UMBRELLA_DEVID);
2756 for (i = 0; i < (int)sizeof(daemon->umbrella_device); i++, arg+=2)
2758 memcpy(word, &(arg[0]), 2);
2759 *u++ = strtoul(word, NULL, 16);
2762 else if (strstr(arg, "orgid:"))
2764 if (!strtoul_check(arg+6, &daemon->umbrella_org))
2767 else if (strstr(arg, "assetid:"))
2769 if (!strtoul_check(arg+8, &daemon->umbrella_asset))
2779 case LOPT_ADD_MAC: /* --add-mac */
2781 set_option_bool(OPT_ADD_MAC);
2785 if (strcmp(arg, "base64") == 0)
2786 set_option_bool(OPT_MAC_B64);
2787 else if (strcmp(arg, "text") == 0)
2788 set_option_bool(OPT_MAC_HEX);
2794 case 'u': /* --user */
2795 daemon->username = opt_string_alloc(arg);
2798 case 'g': /* --group */
2799 daemon->groupname = opt_string_alloc(arg);
2800 daemon->group_set = 1;
2804 case LOPT_SCRIPTUSR: /* --scriptuser */
2805 daemon->scriptuser = opt_string_alloc(arg);
2809 case 'i': /* --interface */
2811 struct iname *new = opt_malloc(sizeof(struct iname));
2813 new->next = daemon->if_names;
2814 daemon->if_names = new;
2815 /* new->name may be NULL if someone does
2816 "interface=" to disable all interfaces except loop. */
2817 new->name = opt_string_alloc(arg);
2823 case LOPT_TFTP: /* --enable-tftp */
2824 set_option_bool(OPT_TFTP);
2829 case 'I': /* --except-interface */
2830 case '2': /* --no-dhcp-interface */
2832 struct iname *new = opt_malloc(sizeof(struct iname));
2834 new->name = opt_string_alloc(arg);
2837 new->next = daemon->if_except;
2838 daemon->if_except = new;
2840 else if (option == LOPT_TFTP)
2842 new->next = daemon->tftp_interfaces;
2843 daemon->tftp_interfaces = new;
2847 new->next = daemon->dhcp_except;
2848 daemon->dhcp_except = new;
2854 case 'B': /* --bogus-nxdomain */
2855 case LOPT_IGNORE_ADDR: /* --ignore-address */
2857 union all_addr addr;
2858 int prefix, is6 = 0;
2859 struct bogus_addr *baddr;
2864 ((comma = split_chr(arg, '/')) && !atoi_check(comma, &prefix)))
2867 if (inet_pton(AF_INET6, arg, &addr.addr6) == 1)
2869 else if (inet_pton(AF_INET, arg, &addr.addr4) != 1)
2880 if (prefix > 128 || (!is6 && prefix > 32))
2883 baddr = opt_malloc(sizeof(struct bogus_addr));
2886 baddr->next = daemon->bogus_addr;
2887 daemon->bogus_addr = baddr;
2891 baddr->next = daemon->ignore_addr;
2892 daemon->ignore_addr = baddr;
2895 baddr->prefix = prefix;
2901 case 'a': /* --listen-address */
2902 case LOPT_AUTHPEER: /* --auth-peer */
2904 struct iname *new = opt_malloc(sizeof(struct iname));
2907 if (arg && (inet_pton(AF_INET, arg, &new->addr.in.sin_addr) > 0))
2909 new->addr.sa.sa_family = AF_INET;
2910 new->addr.in.sin_port = 0;
2911 #ifdef HAVE_SOCKADDR_SA_LEN
2912 new->addr.in.sin_len = sizeof(new->addr.in);
2915 else if (arg && inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr) > 0)
2917 new->addr.sa.sa_family = AF_INET6;
2918 new->addr.in6.sin6_flowinfo = 0;
2919 new->addr.in6.sin6_scope_id = 0;
2920 new->addr.in6.sin6_port = 0;
2921 #ifdef HAVE_SOCKADDR_SA_LEN
2922 new->addr.in6.sin6_len = sizeof(new->addr.in6);
2926 ret_err_free(gen_err, new);
2931 new->next = daemon->if_addrs;
2932 daemon->if_addrs = new;
2936 new->next = daemon->auth_peers;
2937 daemon->auth_peers = new;
2943 case LOPT_NO_REBIND: /* --rebind-domain-ok */
2945 struct rebind_domain *new;
2953 comma = split_chr(arg, '/');
2954 new = opt_malloc(sizeof(struct rebind_domain));
2955 new->domain = canonicalise_opt(arg);
2956 new->next = daemon->no_rebind;
2957 daemon->no_rebind = new;
2959 } while (arg && *arg);
2964 case 'S': /* --server */
2965 case LOPT_LOCAL: /* --local */
2966 case 'A': /* --address */
2968 char *lastdomain = NULL, *domain = "", *cur_domain;
2971 union all_addr addr;
2972 union mysockaddr serv_addr, source_addr;
2973 char interface[IF_NAMESIZE+1];
2974 struct server_details sdetails;
2976 memset(&sdetails, 0, sizeof(struct server_details));
2977 sdetails.addr = &serv_addr;
2978 sdetails.source_addr = &source_addr;
2979 sdetails.interface = interface;
2980 sdetails.flags = &flags;
2984 /* split the domain args, if any and skip to the end of them. */
2985 if (arg && *arg == '/')
2989 domain = lastdomain = ++arg;
2991 while ((last = split_chr(arg, '/')))
2999 flags = SERV_LITERAL_ADDRESS;
3000 else if (option == 'A')
3002 /* # as literal address means return zero address for 4 and 6 */
3003 if (strcmp(arg, "#") == 0)
3004 flags = SERV_ALL_ZEROS | SERV_LITERAL_ADDRESS;
3005 else if (inet_pton(AF_INET, arg, &addr.addr4) > 0)
3006 flags = SERV_4ADDR | SERV_LITERAL_ADDRESS;
3007 else if (inet_pton(AF_INET6, arg, &addr.addr6) > 0)
3008 flags = SERV_6ADDR | SERV_LITERAL_ADDRESS;
3010 ret_err(_("Bad address in --address"));
3014 if ((err = parse_server(arg, &sdetails)))
3018 if (servers_only && option == 'S')
3019 flags |= SERV_FROM_FILE;
3021 cur_domain = domain;
3022 while ((flags & SERV_LITERAL_ADDRESS) || parse_server_next(&sdetails))
3024 cur_domain = domain;
3026 if (!(flags & SERV_LITERAL_ADDRESS) && (err = parse_server_addr(&sdetails)))
3029 /* When source is set only use DNS records of the same type and skip all others */
3030 if (flags & SERV_HAS_SOURCE && sdetails.addr_type != sdetails.source_addr->sa.sa_family)
3035 /* server=//1.2.3.4 is special. */
3038 if (strlen(cur_domain) == 0)
3039 flags |= SERV_FOR_NODOTS;
3041 flags &= ~SERV_FOR_NODOTS;
3043 /* address=/#/ matches the same as without domain */
3044 if (option == 'A' && cur_domain[0] == '#' && cur_domain[1] == 0)
3048 if (!add_update_server(flags, sdetails.addr, sdetails.source_addr, sdetails.interface, cur_domain, &addr))
3051 if (!lastdomain || cur_domain == lastdomain)
3054 cur_domain += strlen(cur_domain) + 1;
3057 if (flags & SERV_LITERAL_ADDRESS)
3061 if (sdetails.orig_hostinfo)
3062 freeaddrinfo(sdetails.orig_hostinfo);
3067 case LOPT_REV_SERV: /* --rev-server */
3071 struct in_addr addr4;
3072 struct in6_addr addr6;
3080 if (!(string = split_chr(arg, '/')) || !atoi_check(string, &size))
3083 if (inet_pton(AF_INET, arg, &addr4))
3088 if ((string = domain_rev4(servers_only, comma, &addr4, size)))
3091 else if (inet_pton(AF_INET6, arg, &addr6))
3096 if ((string = domain_rev6(servers_only, comma, &addr6, size)))
3105 case LOPT_IPSET: /* --ipset */
3106 case LOPT_NFTSET: /* --nftset */
3108 if (option == LOPT_IPSET)
3110 ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
3115 if (option == LOPT_NFTSET)
3117 ret_err(_("recompile with HAVE_NFTSET defined to enable nftset directives"));
3123 struct ipsets ipsets_head;
3124 struct ipsets *ipsets = &ipsets_head;
3125 struct ipsets **daemon_sets =
3126 (option == LOPT_IPSET) ? &daemon->ipsets : &daemon->nftsets;
3129 char **sets, **sets_pos;
3130 memset(ipsets, 0, sizeof(struct ipsets));
3132 if (arg && *arg == '/')
3135 while ((end = split_chr(arg, '/')))
3137 char *domain = NULL;
3138 /* elide leading dots - they are implied in the search algorithm */
3141 /* # matches everything and becomes a zero length domain string */
3142 if (strcmp(arg, "#") == 0 || !*arg)
3144 else if (strlen(arg) != 0 && !(domain = canonicalise_opt(arg)))
3146 ipsets->next = opt_malloc(sizeof(struct ipsets));
3147 ipsets = ipsets->next;
3148 memset(ipsets, 0, sizeof(struct ipsets));
3149 ipsets->domain = domain;
3155 ipsets->next = opt_malloc(sizeof(struct ipsets));
3156 ipsets = ipsets->next;
3157 memset(ipsets, 0, sizeof(struct ipsets));
3158 ipsets->domain = "";
3164 for (size = 2, end = arg; *end; ++end)
3168 sets = sets_pos = opt_malloc(sizeof(char *) * size);
3173 *sets_pos = opt_string_alloc(arg);
3174 /* Use '#' to delimit table and set */
3175 if (option == LOPT_NFTSET)
3176 while ((p = strchr(*sets_pos, '#')))
3182 for (ipsets = &ipsets_head; ipsets->next; ipsets = ipsets->next)
3183 ipsets->next->sets = sets;
3184 ipsets->next = *daemon_sets;
3185 *daemon_sets = ipsets_head.next;
3190 case LOPT_CMARK_ALST_EN: /* --connmark-allowlist-enable */
3191 #ifndef HAVE_CONNTRACK
3192 ret_err(_("recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"));
3196 u32 mask = UINT32_MAX;
3199 if (!strtoul_check(arg, &mask) || mask < 1)
3202 set_option_bool(OPT_CMARK_ALST_EN);
3203 daemon->allowlist_mask = mask;
3208 case LOPT_CMARK_ALST: /* --connmark-allowlist */
3209 #ifndef HAVE_CONNTRACK
3210 ret_err(_("recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"));
3214 struct allowlist *allowlists;
3215 char **patterns, **patterns_pos;
3216 u32 mark, mask = UINT32_MAX;
3217 size_t num_patterns = 0;
3225 if (*c < '0' || *c > '9')
3227 while (*c && *c != ',')
3236 if (*c < '0' || *c > '9')
3245 char *end = strchr(++c, '/');
3248 if (strcmp(c, "*") && !is_valid_dns_name_pattern(c))
3252 if (num_patterns >= UINT16_MAX - 1)
3259 if (!strtoul_check(arg, &mark) || mark < 1 || mark > UINT32_MAX)
3262 if (!strtoul_check(m, &mask) || mask < 1 || mask > UINT32_MAX || (mark & ~mask))
3266 for (allowlists = daemon->allowlists; allowlists; allowlists = allowlists->next)
3267 if (allowlists->mark == mark && allowlists->mask == mask)
3270 patterns = opt_malloc((num_patterns + 1) * sizeof(char *));
3272 goto fail_cmark_allowlist;
3273 patterns_pos = patterns;
3277 char *end = strchr(++c, '/');
3280 if (!(*patterns_pos++ = opt_string_alloc(c)))
3281 goto fail_cmark_allowlist;
3286 *patterns_pos++ = NULL;
3288 allowlists = opt_malloc(sizeof(struct allowlist));
3290 goto fail_cmark_allowlist;
3291 memset(allowlists, 0, sizeof(struct allowlist));
3292 allowlists->mark = mark;
3293 allowlists->mask = mask;
3294 allowlists->patterns = patterns;
3295 allowlists->next = daemon->allowlists;
3296 daemon->allowlists = allowlists;
3299 fail_cmark_allowlist:
3302 for (patterns_pos = patterns; *patterns_pos; patterns_pos++)
3304 free(*patterns_pos);
3305 *patterns_pos = NULL;
3319 case 'c': /* --cache-size */
3323 if (!atoi_check(arg, &size))
3327 /* zero is OK, and means no caching. */
3332 /* Note that for very large cache sizes, the malloc()
3333 will overflow. For the size of the cache record
3334 at the time this was noted, the value of "very large"
3335 was 46684428. Limit to an order of magnitude less than
3336 that to be safe from changes to the cache record. */
3340 daemon->cachesize = size;
3345 case 'p': /* --port */
3346 if (!atoi_check16(arg, &daemon->port))
3350 case LOPT_MINPORT: /* --min-port */
3351 if (!atoi_check16(arg, &daemon->min_port))
3355 case LOPT_MAXPORT: /* --max-port */
3356 if (!atoi_check16(arg, &daemon->max_port))
3360 case '0': /* --dns-forward-max */
3361 if (!atoi_check(arg, &daemon->ftabsize))
3365 case 'q': /* --log-queries */
3366 set_option_bool(OPT_LOG);
3367 if (arg && strcmp(arg, "extra") == 0)
3368 set_option_bool(OPT_EXTRALOG);
3371 case LOPT_MAX_LOGS: /* --log-async */
3372 daemon->max_logs = LOG_MAX; /* default */
3373 if (arg && !atoi_check(arg, &daemon->max_logs))
3375 else if (daemon->max_logs > 100)
3376 daemon->max_logs = 100;
3379 case 'P': /* --edns-packet-max */
3382 if (!atoi_check(arg, &i))
3384 daemon->edns_pktsz = (unsigned short)i;
3388 case 'Q': /* --query-port */
3389 if (!atoi_check16(arg, &daemon->query_port))
3391 /* if explicitly set to zero, use single OS ephemeral port
3392 and disable random ports */
3393 if (daemon->query_port == 0)
3397 case LOPT_RANDPORT_LIM: /* --port-limit */
3398 if (!atoi_check(arg, &daemon->randport_limit) || (daemon->randport_limit < 1))
3402 case 'T': /* --local-ttl */
3403 case LOPT_NEGTTL: /* --neg-ttl */
3404 case LOPT_MAXTTL: /* --max-ttl */
3405 case LOPT_MINCTTL: /* --min-cache-ttl */
3406 case LOPT_MAXCTTL: /* --max-cache-ttl */
3407 case LOPT_AUTHTTL: /* --auth-ttl */
3408 case LOPT_DHCPTTL: /* --dhcp-ttl */
3411 if (!atoi_check(arg, &ttl))
3413 else if (option == LOPT_NEGTTL)
3414 daemon->neg_ttl = (unsigned long)ttl;
3415 else if (option == LOPT_MAXTTL)
3416 daemon->max_ttl = (unsigned long)ttl;
3417 else if (option == LOPT_MINCTTL)
3419 if (ttl > TTL_FLOOR_LIMIT)
3420 ttl = TTL_FLOOR_LIMIT;
3421 daemon->min_cache_ttl = (unsigned long)ttl;
3423 else if (option == LOPT_MAXCTTL)
3424 daemon->max_cache_ttl = (unsigned long)ttl;
3425 else if (option == LOPT_AUTHTTL)
3426 daemon->auth_ttl = (unsigned long)ttl;
3427 else if (option == LOPT_DHCPTTL)
3429 daemon->dhcp_ttl = (unsigned long)ttl;
3430 daemon->use_dhcp_ttl = 1;
3433 daemon->local_ttl = (unsigned long)ttl;
3437 case LOPT_FAST_RETRY:
3438 daemon->fast_retry_timeout = TIMEOUT;
3441 daemon->fast_retry_time = DEFAULT_FAST_RETRY;
3447 if (!atoi_check(arg, &retry) || retry < 50)
3449 daemon->fast_retry_time = retry;
3453 if (!atoi_check(comma, &retry))
3455 daemon->fast_retry_timeout = retry/1000;
3461 case 'X': /* --dhcp-lease-max */
3462 if (!atoi_check(arg, &daemon->dhcp_max))
3468 case LOPT_TFTP_MAX: /* --tftp-max */
3469 if (!atoi_check(arg, &daemon->tftp_max))
3473 case LOPT_TFTP_MTU: /* --tftp-mtu */
3474 if (!atoi_check(arg, &daemon->tftp_mtu))
3478 case LOPT_PREFIX: /* --tftp-prefix */
3482 struct tftp_prefix *new = opt_malloc(sizeof(struct tftp_prefix));
3483 new->interface = opt_string_alloc(comma);
3484 new->prefix = opt_string_alloc(arg);
3485 new->next = daemon->if_prefix;
3486 daemon->if_prefix = new;
3489 daemon->tftp_prefix = opt_string_alloc(arg);
3492 case LOPT_TFTPPORTS: /* --tftp-port-range */
3493 if (!(comma = split(arg)) ||
3494 !atoi_check16(arg, &daemon->start_tftp_port) ||
3495 !atoi_check16(comma, &daemon->end_tftp_port))
3496 ret_err(_("bad port range"));
3498 if (daemon->start_tftp_port > daemon->end_tftp_port)
3500 int tmp = daemon->start_tftp_port;
3501 daemon->start_tftp_port = daemon->end_tftp_port;
3502 daemon->end_tftp_port = tmp;
3507 case LOPT_APREF: /* --tftp-unique-root */
3508 if (!arg || strcasecmp(arg, "ip") == 0)
3509 set_option_bool(OPT_TFTP_APREF_IP);
3510 else if (strcasecmp(arg, "mac") == 0)
3511 set_option_bool(OPT_TFTP_APREF_MAC);
3517 case LOPT_BRIDGE: /* --bridge-interface */
3519 struct dhcp_bridge *new;
3521 if (!(comma = split(arg)) || strlen(arg) > IF_NAMESIZE - 1 )
3522 ret_err(_("bad bridge-interface"));
3524 for (new = daemon->bridges; new; new = new->next)
3525 if (strcmp(new->iface, arg) == 0)
3530 new = opt_malloc(sizeof(struct dhcp_bridge));
3531 strcpy(new->iface, arg);
3533 new->next = daemon->bridges;
3534 daemon->bridges = new;
3540 if (strlen(arg) != 0 && strlen(arg) <= IF_NAMESIZE - 1)
3542 struct dhcp_bridge *b = opt_malloc(sizeof(struct dhcp_bridge));
3543 b->next = new->alias;
3545 strcpy(b->iface, arg);
3553 case LOPT_SHARED_NET: /* --shared-network */
3555 struct shared_network *new = opt_malloc(sizeof(struct shared_network));
3558 new->shared_addr.s_addr = 0;
3562 if (!(comma = split(arg)))
3566 ret_err(_("bad shared-network"));
3569 if (inet_pton(AF_INET, comma, &new->shared_addr))
3571 if (!inet_pton(AF_INET, arg, &new->match_addr) &&
3572 !(new->if_index = if_nametoindex(arg)))
3576 else if (inet_pton(AF_INET6, comma, &new->shared_addr6))
3578 if (!inet_pton(AF_INET6, arg, &new->match_addr6) &&
3579 !(new->if_index = if_nametoindex(arg)))
3586 new->next = daemon->shared_networks;
3587 daemon->shared_networks = new;
3591 case 'F': /* --dhcp-range */
3593 int k, leasepos = 2;
3594 char *cp, *a[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
3595 struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context));
3597 memset (new, 0, sizeof(*new));
3601 for (cp = arg; *cp; cp++)
3602 if (!(*cp == ' ' || *cp == '.' || *cp == ':' ||
3603 (*cp >= 'a' && *cp <= 'f') || (*cp >= 'A' && *cp <= 'F') ||
3604 (*cp >='0' && *cp <= '9')))
3607 if (*cp != ',' && (comma = split(arg)))
3609 if (is_tag_prefix(arg))
3611 /* ignore empty tag */
3613 new->filter = dhcp_netid_create(arg+4, new->filter);
3619 dhcp_context_free(new);
3620 ret_err(_("only one tag allowed"));
3623 new->netid.net = opt_string_alloc(set_prefix(arg));
3634 for (k = 1; k < 8; k++)
3635 if (!(a[k] = split(a[k-1])))
3640 dhcp_context_free(new);
3641 ret_err(_("bad dhcp-range"));
3644 if (inet_pton(AF_INET, a[0], &new->start))
3646 new->next = daemon->dhcp;
3647 new->lease_time = DEFLEASE;
3649 new->end = new->start;
3650 if (strcmp(a[1], "static") == 0)
3651 new->flags |= CONTEXT_STATIC;
3652 else if (strcmp(a[1], "proxy") == 0)
3653 new->flags |= CONTEXT_PROXY;
3654 else if (!inet_pton(AF_INET, a[1], &new->end))
3656 dhcp_context_free(new);
3657 ret_err(_("bad dhcp-range"));
3660 if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr))
3662 struct in_addr tmp = new->start;
3663 new->start = new->end;
3667 if (k >= 3 && strchr(a[2], '.') &&
3668 (inet_pton(AF_INET, a[2], &new->netmask) > 0))
3670 new->flags |= CONTEXT_NETMASK;
3672 if (!is_same_net(new->start, new->end, new->netmask))
3674 dhcp_context_free(new);
3675 ret_err(_("inconsistent DHCP range"));
3679 if (k >= 4 && strchr(a[3], '.') &&
3680 (inet_pton(AF_INET, a[3], &new->broadcast) > 0))
3682 new->flags |= CONTEXT_BRDCAST;
3688 else if (inet_pton(AF_INET6, a[0], &new->start6))
3690 const char *err = NULL;
3692 new->flags |= CONTEXT_V6;
3693 new->prefix = 64; /* default */
3694 new->end6 = new->start6;
3695 new->lease_time = DEFLEASE6;
3696 new->next = daemon->dhcp6;
3697 daemon->dhcp6 = new;
3699 for (leasepos = 1; leasepos < k; leasepos++)
3701 if (strcmp(a[leasepos], "static") == 0)
3702 new->flags |= CONTEXT_STATIC | CONTEXT_DHCP;
3703 else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 )
3704 new->flags |= CONTEXT_RA;
3705 else if (strcmp(a[leasepos], "ra-names") == 0)
3706 new->flags |= CONTEXT_RA_NAME | CONTEXT_RA;
3707 else if (strcmp(a[leasepos], "ra-advrouter") == 0)
3708 new->flags |= CONTEXT_RA_ROUTER | CONTEXT_RA;
3709 else if (strcmp(a[leasepos], "ra-stateless") == 0)
3710 new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP | CONTEXT_RA;
3711 else if (strcmp(a[leasepos], "off-link") == 0)
3712 new->flags |= CONTEXT_RA_OFF_LINK;
3713 else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6))
3714 new->flags |= CONTEXT_DHCP;
3715 else if (strstr(a[leasepos], "constructor:") == a[leasepos])
3717 new->template_interface = opt_string_alloc(a[leasepos] + 12);
3718 new->flags |= CONTEXT_TEMPLATE;
3724 /* bare integer < 128 is prefix value */
3728 for (cp = a[leasepos]; *cp; cp++)
3729 if (!(*cp >= '0' && *cp <= '9'))
3731 if (!*cp && (pref = atoi(a[leasepos])) <= 128)
3738 if (new->prefix > 64)
3740 if (new->flags & CONTEXT_RA)
3741 err=(_("prefix length must be exactly 64 for RA subnets"));
3742 else if (new->flags & CONTEXT_TEMPLATE)
3743 err=(_("prefix length must be exactly 64 for subnet constructors"));
3745 else if (new->prefix < 64)
3746 err=(_("prefix length must be at least 64"));
3748 if (!err && !is_same_net6(&new->start6, &new->end6, new->prefix))
3749 err=(_("inconsistent DHCPv6 range"));
3753 dhcp_context_free(new);
3757 /* dhcp-range=:: enables DHCP stateless on any interface */
3758 if (IN6_IS_ADDR_UNSPECIFIED(&new->start6) && !(new->flags & CONTEXT_TEMPLATE))
3761 if (new->flags & CONTEXT_TEMPLATE)
3763 struct in6_addr zero;
3764 memset(&zero, 0, sizeof(zero));
3765 if (!is_same_net6(&zero, &new->start6, new->prefix))
3767 dhcp_context_free(new);
3768 ret_err(_("prefix must be zero with \"constructor:\" argument"));
3772 if (addr6part(&new->start6) > addr6part(&new->end6))
3774 struct in6_addr tmp = new->start6;
3775 new->start6 = new->end6;
3782 dhcp_context_free(new);
3783 ret_err(_("bad dhcp-range"));
3788 if (leasepos != k-1)
3790 dhcp_context_free(new);
3791 ret_err(_("bad dhcp-range"));
3794 if (strcmp(a[leasepos], "infinite") == 0)
3796 new->lease_time = 0xffffffff;
3797 new->flags |= CONTEXT_SETLEASE;
3799 else if (strcmp(a[leasepos], "deprecated") == 0)
3800 new->flags |= CONTEXT_DEPRECATE;
3804 if (strlen(a[leasepos]) > 0)
3806 switch (a[leasepos][strlen(a[leasepos]) - 1])
3826 a[leasepos][strlen(a[leasepos]) - 1] = 0;
3829 for (cp = a[leasepos]; *cp; cp++)
3830 if (!(*cp >= '0' && *cp <= '9'))
3833 if (*cp || (leasepos+1 < k))
3834 ret_err_free(_("bad dhcp-range"), new);
3836 new->lease_time = atoi(a[leasepos]) * fac;
3837 new->flags |= CONTEXT_SETLEASE;
3838 /* Leases of a minute or less confuse
3839 some clients, notably Apple's */
3840 if (new->lease_time < 120)
3841 new->lease_time = 120;
3850 case 'G': /* --dhcp-host */
3852 struct dhcp_config *new;
3855 new = opt_malloc(sizeof(struct dhcp_config));
3857 new->next = daemon->dhcp_conf;
3858 new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0;
3870 if (strchr(arg, ':')) /* ethernet address, netid or binary CLID */
3872 if ((arg[0] == 'i' || arg[0] == 'I') &&
3873 (arg[1] == 'd' || arg[1] == 'D') &&
3877 new->flags |= CONFIG_NOCLID;
3881 arg += 3; /* dump id: */
3882 if (strchr(arg, ':'))
3883 len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
3887 len = (int) strlen(arg);
3892 dhcp_config_free(new);
3893 ret_err(_("bad hex constant"));
3895 else if ((new->clid = opt_malloc(len)))
3897 new->flags |= CONFIG_CLID;
3898 new->clid_len = len;
3899 memcpy(new->clid, arg, len);
3903 /* dhcp-host has strange backwards-compat needs. */
3904 else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg)
3906 struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
3907 newlist->next = new->netid;
3908 new->netid = newlist;
3909 newlist->list = dhcp_netid_create(arg+4, NULL);
3911 else if (strstr(arg, "tag:") == arg)
3912 new->filter = dhcp_netid_create(arg+4, new->filter);
3915 else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
3918 struct in6_addr in6;
3919 struct addrlist *new_addr;
3921 arg[strlen(arg)-1] = 0;
3923 pref = split_chr(arg, '/');
3925 if (!inet_pton(AF_INET6, arg, &in6))
3927 dhcp_config_free(new);
3928 ret_err(_("bad IPv6 address"));
3931 new_addr = opt_malloc(sizeof(struct addrlist));
3932 new_addr->next = new->addr6;
3933 new_addr->flags = 0;
3934 new_addr->addr.addr6 = in6;
3935 new->addr6 = new_addr;
3939 u64 addrpart = addr6part(&in6);
3941 if (!atoi_check(pref, &new_addr->prefixlen) ||
3942 new_addr->prefixlen > 128 ||
3943 ((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
3945 dhcp_config_free(new);
3946 ret_err(_("bad IPv6 prefix"));
3949 new_addr->flags |= ADDRLIST_PREFIX;
3952 for (i= 0; i < 8; i++)
3953 if (in6.s6_addr[i] != 0)
3956 /* set WILDCARD if network part all zeros */
3958 new_addr->flags |= ADDRLIST_WILDCARD;
3960 new->flags |= CONFIG_ADDR6;
3965 struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config));
3966 if ((newhw->hwaddr_len = parse_hex(arg, newhw->hwaddr, DHCP_CHADDR_MAX,
3967 &newhw->wildcard_mask, &newhw->hwaddr_type)) == -1)
3970 dhcp_config_free(new);
3971 ret_err(_("bad hex constant"));
3975 newhw->next = new->hwaddr;
3976 new->hwaddr = newhw;
3980 else if (strchr(arg, '.') && (inet_pton(AF_INET, arg, &in) > 0))
3982 struct dhcp_config *configs;
3985 new->flags |= CONFIG_ADDR;
3987 /* If the same IP appears in more than one host config, then DISCOVER
3988 for one of the hosts will get the address, but REQUEST will be NAKed,
3989 since the address is reserved by the other one -> protocol loop. */
3990 for (configs = daemon->dhcp_conf; configs; configs = configs->next)
3991 if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
3993 inet_ntop(AF_INET, &in, daemon->addrbuff, ADDRSTRLEN);
3994 sprintf(errstr, _("duplicate dhcp-host IP address %s"),
3996 dhcp_config_free(new);
4002 char *cp, *lastp = NULL, last = 0;
4003 int fac = 1, isdig = 0;
4005 if (strlen(arg) > 1)
4007 lastp = arg + strlen(arg) - 1;
4033 for (cp = arg; *cp; cp++)
4034 if (isdigit((unsigned char)*cp))
4036 else if (*cp != ' ')
4043 if (strcmp(arg, "infinite") == 0)
4045 new->lease_time = 0xffffffff;
4046 new->flags |= CONFIG_TIME;
4048 else if (strcmp(arg, "ignore") == 0)
4049 new->flags |= CONFIG_DISABLE;
4052 if (!(new->hostname = canonicalise_opt(arg)) ||
4053 !legal_hostname(new->hostname))
4055 dhcp_config_free(new);
4056 ret_err(_("bad DHCP host name"));
4059 new->flags |= CONFIG_NAME;
4060 new->domain = strip_hostname(new->hostname);
4065 new->lease_time = atoi(arg) * fac;
4066 /* Leases of a minute or less confuse
4067 some clients, notably Apple's */
4068 if (new->lease_time < 120)
4069 new->lease_time = 120;
4070 new->flags |= CONFIG_TIME;
4077 daemon->dhcp_conf = new;
4081 case LOPT_TAG_IF: /* --tag-if */
4083 struct tag_if *new = opt_malloc(sizeof(struct tag_if));
4089 /* preserve order */
4090 if (!daemon->tag_if)
4091 daemon->tag_if = new;
4095 for (tmp = daemon->tag_if; tmp->next; tmp = tmp->next);
4113 struct dhcp_netid *newtag = dhcp_netid_create(arg+4, NULL);
4115 if (strstr(arg, "set:") == arg)
4117 struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
4118 newlist->next = new->set;
4120 newlist->list = newtag;
4122 else if (strstr(arg, "tag:") == arg)
4124 newtag->next = new->tag;
4130 dhcp_netid_free(newtag);
4140 dhcp_netid_free(new->tag);
4141 dhcp_netid_list_free(new->set);
4142 ret_err_free(_("bad tag-if"), new);
4149 case 'O': /* --dhcp-option */
4150 case LOPT_FORCE: /* --dhcp-option-force */
4152 case LOPT_MATCH: /* --dhcp-match */
4153 return parse_dhcp_opt(errstr, arg,
4154 option == LOPT_FORCE ? DHOPT_FORCE :
4155 (option == LOPT_MATCH ? DHOPT_MATCH :
4156 (option == LOPT_OPTS ? DHOPT_BANK : 0)));
4158 case LOPT_NAME_MATCH: /* --dhcp-name-match */
4160 struct dhcp_match_name *new;
4163 if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
4166 new = opt_malloc(sizeof(struct dhcp_match_name));
4168 new->netid = opt_malloc(sizeof(struct dhcp_netid));
4169 new->netid->net = opt_string_alloc(set_prefix(arg));
4171 if (comma[len-1] == '*')
4176 new->name = opt_string_alloc(comma);
4178 new->next = daemon->dhcp_name_match;
4179 daemon->dhcp_name_match = new;
4184 case 'M': /* --dhcp-boot */
4186 struct dhcp_netid *id = dhcp_tags(&arg);
4194 char *dhcp_file, *dhcp_sname = NULL, *tftp_sname = NULL;
4195 struct in_addr dhcp_next_server;
4196 struct dhcp_boot *new;
4198 dhcp_file = opt_string_alloc(arg);
4199 dhcp_next_server.s_addr = 0;
4204 dhcp_sname = opt_string_alloc(arg);
4207 unhide_metas(comma);
4208 if (!(inet_pton(AF_INET, comma, &dhcp_next_server) > 0))
4211 * The user may have specified the tftp hostname here.
4212 * save it so that it can be resolved/looked up during
4213 * actual dhcp_reply().
4216 tftp_sname = opt_string_alloc(comma);
4217 dhcp_next_server.s_addr = 0;
4222 new = opt_malloc(sizeof(struct dhcp_boot));
4223 new->file = dhcp_file;
4224 new->sname = dhcp_sname;
4225 new->tftp_sname = tftp_sname;
4226 new->next_server = dhcp_next_server;
4228 new->next = daemon->boot_config;
4229 daemon->boot_config = new;
4235 case LOPT_REPLY_DELAY: /* --dhcp-reply-delay */
4237 struct dhcp_netid *id = dhcp_tags(&arg);
4245 struct delay_config *new;
4247 if (!atoi_check(arg, &delay))
4250 new = opt_malloc(sizeof(struct delay_config));
4253 new->next = daemon->delay_conf;
4254 daemon->delay_conf = new;
4260 case LOPT_PXE_PROMT: /* --pxe-prompt */
4262 struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt));
4266 new->opt = 10; /* PXE_MENU_PROMPT */
4267 new->netid = dhcp_tags(&arg);
4278 new->len = strlen(arg) + 1;
4279 new->val = opt_malloc(new->len);
4280 memcpy(new->val + 1, arg, new->len - 1);
4282 new->u.vendor_class = NULL;
4283 new->flags = DHOPT_VENDOR | DHOPT_VENDOR_PXE;
4285 if (comma && atoi_check(comma, &timeout))
4286 *(new->val) = timeout;
4290 new->next = daemon->dhcp_opts;
4291 daemon->dhcp_opts = new;
4292 daemon->enable_pxe = 1;
4298 case LOPT_PXE_SERV: /* --pxe-service */
4300 struct pxe_service *new = opt_malloc(sizeof(struct pxe_service));
4301 char *CSA[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
4302 "IA32_EFI", "x86-64_EFI", "Xscale_EFI", "BC_EFI",
4303 "ARM32_EFI", "ARM64_EFI", NULL };
4304 static int boottype = 32768;
4308 new->server.s_addr = 0;
4309 new->netid = dhcp_tags(&arg);
4311 if (arg && (comma = split(arg)))
4313 for (i = 0; CSA[i]; i++)
4314 if (strcasecmp(CSA[i], arg) == 0)
4317 if (CSA[i] || atoi_check(arg, &i))
4323 new->menu = opt_string_alloc(arg);
4327 new->type = 0; /* local boot */
4328 new->basename = NULL;
4334 if (atoi_check(arg, &i))
4337 new->basename = NULL;
4341 new->type = boottype++;
4342 new->basename = opt_string_alloc(arg);
4347 if (!inet_pton(AF_INET, comma, &new->server))
4349 new->server.s_addr = 0;
4350 new->sname = opt_string_alloc(comma);
4358 if (!daemon->pxe_services)
4359 daemon->pxe_services = new;
4362 struct pxe_service *s;
4363 for (s = daemon->pxe_services; s->next; s = s->next);
4367 daemon->enable_pxe = 1;
4373 dhcp_netid_free(new->netid);
4378 case '4': /* --dhcp-mac */
4380 if (!(comma = split(arg)))
4384 struct dhcp_mac *new = opt_malloc(sizeof(struct dhcp_mac));
4385 new->netid.net = opt_string_alloc(set_prefix(arg));
4386 unhide_metas(comma);
4387 new->hwaddr_len = parse_hex(comma, new->hwaddr, DHCP_CHADDR_MAX, &new->mask, &new->hwaddr_type);
4388 if (new->hwaddr_len == -1)
4390 free(new->netid.net);
4391 ret_err_free(gen_err, new);
4395 new->next = daemon->dhcp_macs;
4396 daemon->dhcp_macs = new;
4402 case 'U': /* --dhcp-vendorclass */
4403 case 'j': /* --dhcp-userclass */
4404 case LOPT_CIRCUIT: /* --dhcp-circuitid */
4405 case LOPT_REMOTE: /* --dhcp-remoteid */
4406 case LOPT_SUBSCR: /* --dhcp-subscrid */
4410 struct dhcp_vendor *new = opt_malloc(sizeof(struct dhcp_vendor));
4412 if (!(comma = split(arg)))
4413 ret_err_free(gen_err, new);
4415 new->netid.net = opt_string_alloc(set_prefix(arg));
4416 /* check for hex string - must digits may include : must not have nothing else,
4417 only allowed for agent-options. */
4420 if ((comma = split(arg)))
4422 if (option != 'U' || strstr(arg, "enterprise:") != arg)
4424 free(new->netid.net);
4425 ret_err_free(gen_err, new);
4428 new->enterprise = atoi(arg+11);
4433 for (dig = 0, colon = 0, p = (unsigned char *)comma; *p; p++)
4441 unhide_metas(comma);
4442 if (option == 'U' || option == 'j' || *p || !dig || !colon)
4444 new->len = strlen(comma);
4445 new->data = opt_malloc(new->len);
4446 memcpy(new->data, comma, new->len);
4450 new->len = parse_hex(comma, (unsigned char *)comma, strlen(comma), NULL, NULL);
4451 new->data = opt_malloc(new->len);
4452 memcpy(new->data, comma, new->len);
4458 new->match_type = MATCH_USER;
4461 new->match_type = MATCH_VENDOR;
4464 new->match_type = MATCH_CIRCUIT;
4467 new->match_type = MATCH_REMOTE;
4470 new->match_type = MATCH_SUBSCRIBER;
4473 new->next = daemon->dhcp_vendors;
4474 daemon->dhcp_vendors = new;
4479 case LOPT_ALTPORT: /* --dhcp-alternate-port */
4482 daemon->dhcp_server_port = DHCP_SERVER_ALTPORT;
4483 daemon->dhcp_client_port = DHCP_CLIENT_ALTPORT;
4488 if (!atoi_check16(arg, &daemon->dhcp_server_port) ||
4489 (comma && !atoi_check16(comma, &daemon->dhcp_client_port)))
4490 ret_err(_("invalid port number"));
4492 daemon->dhcp_client_port = daemon->dhcp_server_port+1;
4496 case 'J': /* --dhcp-ignore */
4497 case LOPT_NO_NAMES: /* --dhcp-ignore-names */
4498 case LOPT_BROADCAST: /* --dhcp-broadcast */
4499 case '3': /* --bootp-dynamic */
4500 case LOPT_GEN_NAMES: /* --dhcp-generate-names */
4502 struct dhcp_netid_list *new = opt_malloc(sizeof(struct dhcp_netid_list));
4503 struct dhcp_netid *list = NULL;
4506 new->next = daemon->dhcp_ignore;
4507 daemon->dhcp_ignore = new;
4509 else if (option == LOPT_BROADCAST)
4511 new->next = daemon->force_broadcast;
4512 daemon->force_broadcast = new;
4514 else if (option == '3')
4516 new->next = daemon->bootp_dynamic;
4517 daemon->bootp_dynamic = new;
4519 else if (option == LOPT_GEN_NAMES)
4521 new->next = daemon->dhcp_gen_names;
4522 daemon->dhcp_gen_names = new;
4526 new->next = daemon->dhcp_ignore_names;
4527 daemon->dhcp_ignore_names = new;
4532 list = dhcp_netid_create(is_tag_prefix(arg) ? arg+4 :arg, list);
4540 case LOPT_PROXY: /* --dhcp-proxy */
4541 daemon->override = 1;
4543 struct addr_list *new = opt_malloc(sizeof(struct addr_list));
4545 if (!(inet_pton(AF_INET, arg, &new->addr) > 0))
4546 ret_err_free(_("bad dhcp-proxy address"), new);
4547 new->next = daemon->override_relays;
4548 daemon->override_relays = new;
4553 case LOPT_PXE_VENDOR: /* --dhcp-pxe-vendor */
4556 struct dhcp_pxe_vendor *new = opt_malloc(sizeof(struct dhcp_pxe_vendor));
4558 new->data = opt_string_alloc(arg);
4559 new->next = daemon->dhcp_pxe_vendors;
4560 daemon->dhcp_pxe_vendors = new;
4566 case LOPT_RELAY: /* --dhcp-relay */
4568 struct dhcp_relay *new = opt_malloc(sizeof(struct dhcp_relay));
4569 char *two = split(arg);
4570 char *three = split(two);
4572 new->iface_index = 0;
4576 if (inet_pton(AF_INET, arg, &new->local))
4578 char *hash = split_chr(two, '#');
4580 if (!hash || !atoi_check16(hash, &new->port))
4581 new->port = DHCP_SERVER_PORT;
4583 if (!inet_pton(AF_INET, two, &new->server))
4585 new->server.addr4.s_addr = 0;
4587 /* Fail for three arg version where there are not two addresses.
4588 Also fail when broadcasting to wildcard address. */
4589 if (three || strchr(two, '*'))
4595 new->next = daemon->relay4;
4596 daemon->relay4 = new;
4599 else if (inet_pton(AF_INET6, arg, &new->local))
4601 char *hash = split_chr(two, '#');
4603 if (!hash || !atoi_check16(hash, &new->port))
4604 new->port = DHCPV6_SERVER_PORT;
4606 if (!inet_pton(AF_INET6, two, &new->server))
4608 inet_pton(AF_INET6, ALL_SERVERS, &new->server.addr6);
4609 /* Fail for three arg version where there are not two addresses.
4610 Also fail when multicasting to wildcard address. */
4611 if (three || strchr(two, '*'))
4616 new->next = daemon->relay6;
4617 daemon->relay6 = new;
4621 new->interface = opt_string_alloc(three);
4626 free(new->interface);
4627 ret_err_free(_("Bad dhcp-relay"), new);
4636 case LOPT_RA_PARAM: /* --ra-param */
4637 if ((comma = split(arg)))
4639 struct ra_interface *new = opt_malloc(sizeof(struct ra_interface));
4643 new->mtu_name = NULL;
4644 new->name = opt_string_alloc(arg);
4645 if (strcasestr(comma, "mtu:") == comma)
4648 if (!(comma = split(comma)))
4650 if (!strcasecmp(arg, "off"))
4652 else if (!atoi_check(arg, &new->mtu))
4653 new->mtu_name = opt_string_alloc(arg);
4654 else if (new->mtu < 1280)
4657 if (strcasestr(comma, "high") == comma || strcasestr(comma, "low") == comma)
4659 if (*comma == 'l' || *comma == 'L')
4663 comma = split(comma);
4666 if (!atoi_check(comma, &new->interval) ||
4667 (arg && !atoi_check(arg, &new->lifetime)))
4671 ret_err_free(_("bad RA-params"), new);
4674 new->next = daemon->ra_interfaces;
4675 daemon->ra_interfaces = new;
4679 case LOPT_DUID: /* --dhcp-duid */
4680 if (!(comma = split(arg)) || !atoi_check(arg, (int *)&daemon->duid_enterprise))
4681 ret_err(_("bad DUID"));
4684 daemon->duid_config_len = parse_hex(comma,(unsigned char *)comma, strlen(comma), NULL, NULL);
4685 daemon->duid_config = opt_malloc(daemon->duid_config_len);
4686 memcpy(daemon->duid_config, comma, daemon->duid_config_len);
4691 case 'V': /* --alias */
4693 char *dash, *a[3] = { NULL, NULL, NULL };
4695 struct doctor *new = opt_malloc(sizeof(struct doctor));
4696 new->next = daemon->doctors;
4697 daemon->doctors = new;
4698 new->mask.s_addr = 0xffffffff;
4699 new->end.s_addr = 0;
4702 for (k = 1; k < 3; k++)
4704 if (!(a[k] = split(a[k-1])))
4709 dash = split_chr(a[0], '-');
4712 (!(inet_pton(AF_INET, a[0], &new->in) > 0)) ||
4713 (!(inet_pton(AF_INET, a[1], &new->out) > 0)) ||
4714 (k == 3 && !inet_pton(AF_INET, a[2], &new->mask)))
4715 ret_err(_("missing address in alias"));
4718 (!(inet_pton(AF_INET, dash, &new->end) > 0) ||
4719 !is_same_net(new->in, new->end, new->mask) ||
4720 ntohl(new->in.s_addr) > ntohl(new->end.s_addr)))
4721 ret_err_free(_("invalid alias range"), new);
4726 case LOPT_INTNAME: /* --interface-name */
4727 case LOPT_DYNHOST: /* --dynamic-host */
4729 struct interface_name *new, **up;
4734 new = opt_malloc(sizeof(struct interface_name));
4735 memset(new, 0, sizeof(struct interface_name));
4736 new->flags = IN4 | IN6;
4738 /* Add to the end of the list, so that first name
4739 of an interface is used for PTR lookups. */
4740 for (up = &daemon->int_names; *up; up = &((*up)->next));
4743 while ((comma = split(arg)))
4745 if (inet_pton(AF_INET, arg, &new->proto4))
4747 else if (inet_pton(AF_INET6, arg, &new->proto6))
4755 if ((comma = split_chr(arg, '/')))
4757 if (strcmp(comma, "4") == 0)
4759 else if (strcmp(comma, "6") == 0)
4762 ret_err_free(gen_err, new);
4765 new->intr = opt_string_alloc(arg);
4767 if (option == LOPT_DYNHOST)
4769 if (!(new->flags & (INP4 | INP6)))
4770 ret_err(_("missing address in dynamic host"));
4772 if (!(new->flags & IN4) || !(new->flags & IN6))
4773 arg = NULL; /* provoke error below */
4775 new->flags &= ~(IN4 | IN6);
4779 if (new->flags & (INP4 | INP6))
4780 arg = NULL; /* provoke error below */
4783 if (!domain || !arg || !(new->name = canonicalise_opt(domain)))
4784 ret_err(option == LOPT_DYNHOST ?
4785 _("bad dynamic host") : _("bad interface name"));
4790 case LOPT_CNAME: /* --cname */
4793 char *alias, *target=NULL, *last, *pen;
4796 for (last = pen = NULL, comma = arg; comma; comma = split(comma))
4803 ret_err(_("bad CNAME"));
4805 if (pen != arg && atoi_check(last, &ttl))
4810 int arglen = strlen(arg);
4811 alias = canonicalise_opt(arg);
4814 target = canonicalise_opt(last);
4815 if (!alias || !target)
4819 ret_err(_("bad CNAME"));
4822 for (new = daemon->cnames; new; new = new->next)
4823 if (hostname_isequal(new->alias, alias))
4827 ret_err(_("duplicate CNAME"));
4829 new = opt_malloc(sizeof(struct cname));
4830 new->next = daemon->cnames;
4831 daemon->cnames = new;
4833 new->target = target;
4836 for (arg += arglen+1; *arg && isspace(*arg); arg++);
4842 case LOPT_PTR: /* --ptr-record */
4844 struct ptr_record *new;
4845 char *dom, *target = NULL;
4849 if (!(dom = canonicalise_opt(arg)) ||
4850 (comma && !(target = canonicalise_opt(comma))))
4854 ret_err(_("bad PTR record"));
4858 new = opt_malloc(sizeof(struct ptr_record));
4859 new->next = daemon->ptr;
4867 case LOPT_NAPTR: /* --naptr-record */
4869 char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
4873 char *name=NULL, *replace = NULL;
4876 for (k = 1; k < 7; k++)
4877 if (!(a[k] = split(a[k-1])))
4882 !(name = canonicalise_opt(a[0])) ||
4883 !atoi_check16(a[1], &order) ||
4884 !atoi_check16(a[2], &pref) ||
4885 (k == 7 && !(replace = canonicalise_opt(a[6]))))
4889 ret_err(_("bad NAPTR record"));
4893 new = opt_malloc(sizeof(struct naptr));
4894 new->next = daemon->naptr;
4895 daemon->naptr = new;
4897 new->flags = opt_string_alloc(a[3]);
4898 new->services = opt_string_alloc(a[4]);
4899 new->regexp = opt_string_alloc(a[5]);
4900 new->replace = replace;
4907 case LOPT_RR: /* dns-rr */
4909 struct txt_record *new;
4915 data = split(comma);
4917 new = opt_malloc(sizeof(struct txt_record));
4920 if (!atoi_check(comma, &class) ||
4921 !(new->name = canonicalise_opt(arg)) ||
4922 (data && (len = parse_hex(data, (unsigned char *)data, -1, NULL, NULL)) == -1U))
4925 ret_err_free(_("bad RR record"), new);
4930 new->next = daemon->rr;
4935 new->txt = opt_malloc(len);
4937 memcpy(new->txt, data, len);
4943 case LOPT_CAA: /* --caa-record */
4945 struct txt_record *new;
4953 new = opt_malloc(sizeof(struct txt_record));
4954 new->next = daemon->rr;
4957 if (!atoi_check(comma, &flags) || !tag || !value || !(new->name = canonicalise_opt(arg)))
4958 ret_err(_("bad CAA record"));
4961 unhide_metas(value);
4963 new->len = strlen(tag) + strlen(value) + 2;
4964 new->txt = opt_malloc(new->len);
4965 new->txt[0] = flags;
4966 new->txt[1] = strlen(tag);
4967 memcpy(&new->txt[2], tag, strlen(tag));
4968 memcpy(&new->txt[2 + strlen(tag)], value, strlen(value));
4974 case 'Y': /* --txt-record */
4976 struct txt_record *new;
4977 unsigned char *p, *cnt;
4982 new = opt_malloc(sizeof(struct txt_record));
4986 if (!(new->name = canonicalise_opt(arg)))
4987 ret_err_free(_("bad TXT record"), new);
4989 new->next = daemon->txt;
4991 len = comma ? strlen(comma) : 0;
4992 len += (len/255) + 1; /* room for extra counts */
4993 new->txt = p = opt_malloc(len);
4998 while (comma && *comma)
5000 unsigned char c = (unsigned char)*comma++;
5002 if (c == ',' || *cnt == 255)
5011 *p++ = unhide_meta(c);
5016 new->len = p - new->txt;
5021 case 'W': /* --srv-host */
5023 int port = 1, priority = 0, weight = 0;
5024 char *name, *target = NULL;
5025 struct mx_srv_record *new;
5029 if (!(name = canonicalise_opt(arg)))
5030 ret_err(_("bad SRV record"));
5036 if (!(target = canonicalise_opt(arg)))
5037 ret_err_free(_("bad SRV target"), name);
5043 if (!atoi_check16(arg, &port))
5046 ret_err_free(_("invalid port number"), target);
5053 if (!atoi_check16(arg, &priority))
5056 ret_err_free(_("invalid priority"), target);
5058 if (comma && !atoi_check16(comma, &weight))
5061 ret_err_free(_("invalid weight"), target);
5067 new = opt_malloc(sizeof(struct mx_srv_record));
5068 new->next = daemon->mxnames;
5069 daemon->mxnames = new;
5072 new->target = target;
5073 new->srvport = port;
5074 new->priority = priority;
5075 new->weight = weight;
5079 case LOPT_HOST_REC: /* --host-record */
5081 struct host_record *new;
5083 if (!arg || !(comma = split(arg)))
5084 ret_err(_("Bad host-record"));
5086 new = opt_malloc(sizeof(struct host_record));
5087 memset(new, 0, sizeof(struct host_record));
5093 union all_addr addr;
5096 for (dig = arg; *dig != 0; dig++)
5097 if (*dig < '0' || *dig > '9')
5100 new->ttl = atoi(arg);
5101 else if (inet_pton(AF_INET, arg, &addr.addr4))
5103 new->addr = addr.addr4;
5106 else if (inet_pton(AF_INET6, arg, &addr.addr6))
5108 new->addr6 = addr.addr6;
5113 char *canon = canonicalise_opt(arg);
5114 struct name_list *nl;
5117 struct name_list *tmp, *next;
5118 for (tmp = new->names; tmp; tmp = next)
5123 ret_err_free(_("Bad name in host-record"), new);
5126 nl = opt_malloc(sizeof(struct name_list));
5128 /* keep order, so that PTR record goes to first name */
5134 struct name_list *tmp;
5135 for (tmp = new->names; tmp->next; tmp = tmp->next);
5144 /* Keep list order */
5145 if (!daemon->host_records_tail)
5146 daemon->host_records = new;
5148 daemon->host_records_tail->next = new;
5150 daemon->host_records_tail = new;
5154 case LOPT_STALE_CACHE:
5156 int max_expiry = STALE_CACHE_EXPIRY;
5159 /* Don't accept negative TTLs here, they'd have the counter-intuitive
5160 side-effect of evicting cache records before they expire */
5161 if (!atoi_check(arg, &max_expiry) || max_expiry < 0)
5163 /* Store "serve expired forever" as -1 internally, the option isn't
5164 active for daemon->cache_max_expiry == 0 */
5165 if (max_expiry == 0)
5168 daemon->cache_max_expiry = max_expiry;
5173 case LOPT_DNSSEC_STAMP: /* --dnssec-timestamp */
5174 daemon->timestamp_file = opt_string_alloc(arg);
5177 case LOPT_DNSSEC_CHECK: /* --dnssec-check-unsigned */
5180 if (strcmp(arg, "no") == 0)
5181 set_option_bool(OPT_DNSSEC_IGN_NS);
5183 ret_err(_("bad value for dnssec-check-unsigned"));
5187 case LOPT_TRUST_ANCHOR: /* --trust-anchor */
5189 struct ds_config *new = opt_malloc(sizeof(struct ds_config));
5190 char *cp, *cp1, *keyhex, *digest, *algo = NULL;
5196 if ((comma = split(arg)) && (algo = split(comma)))
5199 if (strcmp(comma, "IN") == 0)
5201 else if (strcmp(comma, "CH") == 0)
5203 else if (strcmp(comma, "HS") == 0)
5210 algo = split(comma);
5214 if (!comma || !algo || !(digest = split(algo)) || !(keyhex = split(digest)) ||
5215 !atoi_check16(comma, &new->keytag) ||
5216 !atoi_check8(algo, &new->algo) ||
5217 !atoi_check8(digest, &new->digest_type) ||
5218 !(new->name = canonicalise_opt(arg)))
5219 ret_err_free(_("bad trust anchor"), new);
5221 /* Upper bound on length */
5222 len = (2*strlen(keyhex))+1;
5223 new->digest = opt_malloc(len);
5224 unhide_metas(keyhex);
5225 /* 4034: "Whitespace is allowed within digits" */
5226 for (cp = keyhex; *cp; )
5228 for (cp1 = cp; *cp1; cp1++)
5232 if ((new->digestlen = parse_hex(keyhex, (unsigned char *)new->digest, len, NULL, NULL)) == -1)
5235 ret_err_free(_("bad HEX in trust anchor"), new);
5238 new->next = daemon->ds;
5246 ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"));
5253 static void read_file(char *file, FILE *f, int hard_opt, int from_script)
5255 volatile int lineno = 0;
5256 char *buff = daemon->namebuff;
5258 while (fgets(buff, MAXDNAME, f))
5261 volatile int option;
5262 char *errmess, *p, *arg, *start;
5265 option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt;
5267 /* Memory allocation failure longjmps here if mem_recover == 1 */
5268 if (option != 0 || hard_opt == LOPT_REV_SERV)
5270 if (setjmp(mem_jmp))
5279 /* Implement quotes, inside quotes we allow \\ \" \n and \t
5280 metacharacters get hidden also strip comments */
5281 for (white = 1, p = buff; *p; p++)
5285 memmove(p, p+1, strlen(p+1)+1);
5287 for(; *p && *p != '"'; p++)
5289 if (*p == '\\' && strchr("\"tnebr\\", p[1]))
5293 else if (p[1] == 'n')
5295 else if (p[1] == 'b')
5297 else if (p[1] == 'r')
5299 else if (p[1] == 'e') /* escape */
5301 memmove(p, p+1, strlen(p+1)+1);
5308 errmess = _("missing \"");
5312 memmove(p, p+1, strlen(p+1)+1);
5322 if (white && *p == '#')
5332 /* strip leading spaces */
5333 for (start = buff; *start && *start == ' '; start++);
5335 /* strip trailing spaces */
5336 for (len = strlen(start); (len != 0) && (start[len-1] == ' '); len--);
5345 else if ((p=strchr(start, '=')))
5347 /* allow spaces around "=" */
5348 for (arg = p+1; *arg == ' '; arg++);
5349 for (; p >= start && (*p == ' ' || *p == '='); p--)
5357 for (option = 0, i = 0; opts[i].name; i++)
5358 if (strcmp(opts[i].name, start) == 0)
5360 option = opts[i].val;
5365 errmess = _("bad option");
5366 else if (opts[i].has_arg == 0 && arg)
5367 errmess = _("extraneous parameter");
5368 else if (opts[i].has_arg == 1 && !arg)
5369 errmess = _("missing parameter");
5370 else if (hard_opt == LOPT_REV_SERV && option != 'S' && option != LOPT_REV_SERV)
5371 errmess = _("illegal option");
5376 strcpy(daemon->namebuff, errmess);
5378 if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt == LOPT_REV_SERV))
5381 sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" in output from %s"), file);
5383 sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file);
5386 my_syslog(LOG_ERR, "%s", daemon->namebuff);
5388 die("%s", daemon->namebuff, EC_BADCONF);
5395 #if defined(HAVE_DHCP) && defined(HAVE_INOTIFY)
5396 int option_read_dynfile(char *file, int flags)
5398 my_syslog(MS_DHCP | LOG_INFO, _("read %s"), file);
5400 if (flags & AH_DHCP_HST)
5401 return one_file(file, LOPT_BANK);
5402 else if (flags & AH_DHCP_OPT)
5403 return one_file(file, LOPT_OPTS);
5409 static int one_file(char *file, int hard_opt)
5412 int nofile_ok = 0, do_popen = 0;
5413 static int read_stdin = 0;
5414 static struct fileread {
5417 struct fileread *next;
5418 } *filesread = NULL;
5420 if (hard_opt == LOPT_CONF_OPT)
5422 /* default conf-file reading */
5427 if (hard_opt == LOPT_CONF_SCRIPT)
5433 if (hard_opt == 0 && !do_popen && strcmp(file, "-") == 0)
5435 if (read_stdin == 1)
5443 /* ignore repeated files. */
5444 struct stat statbuf;
5446 if (hard_opt == 0 && stat(file, &statbuf) == 0)
5450 for (r = filesread; r; r = r->next)
5451 if (r->dev == statbuf.st_dev && r->ino == statbuf.st_ino)
5454 r = safe_malloc(sizeof(struct fileread));
5455 r->next = filesread;
5457 r->dev = statbuf.st_dev;
5458 r->ino = statbuf.st_ino;
5463 if (!(f = popen(file, "r")))
5464 die(_("cannot execute %s: %s"), file, EC_FILE);
5466 else if (!(f = fopen(file, "r")))
5468 if (errno == ENOENT && nofile_ok)
5469 return 1; /* No conffile, all done. */
5472 char *str = _("cannot read %s: %s");
5475 my_syslog(LOG_ERR, str, file, strerror(errno));
5479 die(str, file, EC_FILE);
5484 read_file(file, f, hard_opt, do_popen);
5490 if ((rc = pclose(f)) == -1)
5491 die(_("error executing %s: %s"), file, EC_MISC);
5494 die(_("%s returns non-zero error code"), file, rc+10);
5502 static int file_filter(const struct dirent *ent)
5504 size_t lenfile = strlen(ent->d_name);
5506 /* ignore emacs backups and dotfiles */
5509 ent->d_name[lenfile - 1] == '~' ||
5510 (ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
5511 ent->d_name[0] == '.')
5516 /* expand any name which is a directory */
5517 struct hostsfile *expand_filelist(struct hostsfile *list)
5521 struct hostsfile *ah, *last, *next, **up;
5522 struct dirent **namelist;
5524 /* find largest used index */
5525 for (i = SRC_AH, ah = list; ah; ah = ah->next)
5532 if (ah->flags & AH_DIR)
5533 ah->flags |= AH_INACTIVE;
5535 ah->flags &= ~AH_INACTIVE;
5538 for (ah = list; ah; ah = ah->next)
5539 if (!(ah->flags & AH_INACTIVE))
5542 if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
5546 /* don't read this as a file */
5547 ah->flags |= AH_INACTIVE;
5549 entcnt = scandir(ah->fname, &namelist, file_filter, alphasort);
5551 my_syslog(LOG_ERR, _("cannot access directory %s: %s"),
5552 ah->fname, strerror(errno));
5555 for (n = 0; n < entcnt; n++)
5558 size_t lendir = strlen(ah->fname);
5559 size_t lenfile = strlen(ent->d_name);
5560 struct hostsfile *ah1;
5563 /* see if we have an existing record.
5566 path to match is ah1->fname */
5568 for (up = &list, ah1 = list; ah1; ah1 = next)
5572 if (lendir < strlen(ah1->fname) &&
5573 strstr(ah1->fname, ah->fname) == ah1->fname &&
5574 ah1->fname[lendir] == '/' &&
5575 strcmp(ah1->fname + lendir + 1, ent->d_name) == 0)
5577 ah1->flags &= ~AH_INACTIVE;
5578 /* If found, remove from list to re-insert at the end.
5579 Unless it's already at the end. */
5588 /* make new record */
5591 if (!(ah1 = whine_malloc(sizeof(struct hostsfile))))
5594 if (!(path = whine_malloc(lendir + lenfile + 2)))
5600 strcpy(path, ah->fname);
5602 strcat(path, ent->d_name);
5605 ah1->flags = AH_DIR;
5608 /* Edge case, may be the last in the list anyway */
5614 /* inactivate record if not regular file */
5615 if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 && !S_ISREG(buf.st_mode))
5616 ah1->flags |= AH_INACTIVE;
5627 void read_servers_file(void)
5631 if (!(f = fopen(daemon->servers_file, "r")))
5633 my_syslog(LOG_ERR, _("cannot read %s: %s"), daemon->servers_file, strerror(errno));
5637 mark_servers(SERV_FROM_FILE);
5638 read_file(daemon->servers_file, f, LOPT_REV_SERV, 0);
5646 static void clear_dynamic_conf(void)
5648 struct dhcp_config *configs, *cp, **up;
5650 /* remove existing... */
5651 for (up = &daemon->dhcp_conf, configs = daemon->dhcp_conf; configs; configs = cp)
5655 if (configs->flags & CONFIG_BANK)
5658 dhcp_config_free(configs);
5661 up = &configs->next;
5665 static void clear_dynamic_opt(void)
5667 struct dhcp_opt *opts, *cp, **up;
5669 for (up = &daemon->dhcp_opts, opts = daemon->dhcp_opts; opts; opts = cp)
5673 if (opts->flags & DHOPT_BANK)
5676 dhcp_opt_free(opts);
5683 void reread_dhcp(void)
5685 struct hostsfile *hf;
5687 /* Do these even if there is no daemon->dhcp_hosts_file or
5688 daemon->dhcp_opts_file since entries may have been created by the
5689 inotify dynamic file reading system. */
5691 clear_dynamic_conf();
5692 clear_dynamic_opt();
5694 if (daemon->dhcp_hosts_file)
5696 daemon->dhcp_hosts_file = expand_filelist(daemon->dhcp_hosts_file);
5697 for (hf = daemon->dhcp_hosts_file; hf; hf = hf->next)
5698 if (!(hf->flags & AH_INACTIVE))
5700 if (one_file(hf->fname, LOPT_BANK))
5701 my_syslog(MS_DHCP | LOG_INFO, _("read %s"), hf->fname);
5705 if (daemon->dhcp_opts_file)
5707 daemon->dhcp_opts_file = expand_filelist(daemon->dhcp_opts_file);
5708 for (hf = daemon->dhcp_opts_file; hf; hf = hf->next)
5709 if (!(hf->flags & AH_INACTIVE))
5711 if (one_file(hf->fname, LOPT_OPTS))
5712 my_syslog(MS_DHCP | LOG_INFO, _("read %s"), hf->fname);
5716 # ifdef HAVE_INOTIFY
5717 /* Setup notify and read pre-existing files. */
5718 set_dynamic_inotify(AH_DHCP_HST | AH_DHCP_OPT, 0, NULL, 0);
5723 void read_opts(int argc, char **argv, char *compile_opts)
5725 size_t argbuf_size = MAXDNAME;
5726 char *argbuf = opt_malloc(argbuf_size);
5727 char *buff = opt_malloc(MAXDNAME);
5728 int option, testmode = 0;
5729 char *arg, *conffile = NULL;
5733 daemon = opt_malloc(sizeof(struct daemon));
5734 memset(daemon, 0, sizeof(struct daemon));
5735 daemon->namebuff = buff;
5736 daemon->addrbuff = safe_malloc(ADDRSTRLEN);
5738 /* Set defaults - everything else is zero or NULL */
5739 daemon->cachesize = CACHESIZ;
5740 daemon->ftabsize = FTABSIZ;
5741 daemon->port = NAMESERVER_PORT;
5742 daemon->dhcp_client_port = DHCP_CLIENT_PORT;
5743 daemon->dhcp_server_port = DHCP_SERVER_PORT;
5744 daemon->default_resolv.is_default = 1;
5745 daemon->default_resolv.name = RESOLVFILE;
5746 daemon->resolv_files = &daemon->default_resolv;
5747 daemon->username = CHUSER;
5748 daemon->runfile = RUNFILE;
5749 daemon->dhcp_max = MAXLEASES;
5750 daemon->tftp_max = TFTP_MAX_CONNECTIONS;
5751 daemon->edns_pktsz = EDNS_PKTSZ;
5752 daemon->log_fac = -1;
5753 daemon->auth_ttl = AUTH_TTL;
5754 daemon->soa_refresh = SOA_REFRESH;
5755 daemon->soa_retry = SOA_RETRY;
5756 daemon->soa_expiry = SOA_EXPIRY;
5757 daemon->randport_limit = 1;
5758 daemon->host_index = SRC_AH;
5761 add_txt("version.bind", "dnsmasq-" VERSION, 0 );
5762 add_txt("authors.bind", "Simon Kelley", 0);
5763 add_txt("copyright.bind", COPYRIGHT, 0);
5764 add_txt("cachesize.bind", NULL, TXT_STAT_CACHESIZE);
5765 add_txt("insertions.bind", NULL, TXT_STAT_INSERTS);
5766 add_txt("evictions.bind", NULL, TXT_STAT_EVICTIONS);
5767 add_txt("misses.bind", NULL, TXT_STAT_MISSES);
5768 add_txt("hits.bind", NULL, TXT_STAT_HITS);
5770 add_txt("auth.bind", NULL, TXT_STAT_AUTH);
5772 add_txt("servers.bind", NULL, TXT_STAT_SERVERS);
5775 /* See comment above make_servers(). Optimises server-read code. */
5780 #ifdef HAVE_GETOPT_LONG
5781 option = getopt_long(argc, argv, OPTSTRING, opts, NULL);
5783 option = getopt(argc, argv, OPTSTRING);
5788 for (; optind < argc; optind++)
5790 unsigned char *c = (unsigned char *)argv[optind];
5791 for (; *c != 0; c++)
5793 die(_("junk found in command line"), NULL, EC_BADCONF);
5798 /* Copy optarg so that argv doesn't get changed */
5801 if (strlen(optarg) >= argbuf_size)
5804 argbuf_size = strlen(optarg) + 1;
5805 argbuf = opt_malloc(argbuf_size);
5807 safe_strncpy(argbuf, optarg, argbuf_size);
5813 /* command-line only stuff */
5814 if (option == LOPT_TEST)
5816 else if (option == 'w')
5819 if (argc == 3 && strcmp(argv[2], "dhcp") == 0)
5822 else if (argc == 3 && strcmp(argv[2], "dhcp6") == 0)
5831 else if (option == 'v')
5833 printf(_("Dnsmasq version %s %s\n"), VERSION, COPYRIGHT);
5834 printf(_("Compile time options: %s\n\n"), compile_opts);
5835 printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
5836 printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
5837 printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
5840 else if (option == 'C')
5843 conffile = opt_string_alloc(arg);
5846 char *extra = opt_string_alloc(arg);
5853 #ifdef HAVE_GETOPT_LONG
5854 if (!one_opt(option, arg, daemon->namebuff, _("try --help"), 1, 0))
5856 if (!one_opt(option, arg, daemon->namebuff, _("try -w"), 1, 0))
5858 die(_("bad command line options: %s"), daemon->namebuff, EC_BADCONF);
5866 one_file(conffile, 0);
5870 one_file(CONFFILE, LOPT_CONF_OPT);
5872 /* port might not be known when the address is parsed - fill in here */
5873 if (daemon->servers)
5876 for (tmp = daemon->servers; tmp; tmp = tmp->next)
5877 if (!(tmp->flags & SERV_HAS_SOURCE))
5879 if (tmp->source_addr.sa.sa_family == AF_INET)
5880 tmp->source_addr.in.sin_port = htons(daemon->query_port);
5881 else if (tmp->source_addr.sa.sa_family == AF_INET6)
5882 tmp->source_addr.in6.sin6_port = htons(daemon->query_port);
5886 if (daemon->host_records)
5888 struct host_record *hr;
5890 for (hr = daemon->host_records; hr; hr = hr->next)
5892 hr->ttl = daemon->local_ttl;
5897 struct cname *cn, *cn2, *cn3;
5902 /* Fill in TTL for CNAMES now we have local_ttl.
5903 Also prepare to do loop detection. */
5904 for (cn = daemon->cnames; cn; cn = cn->next)
5907 cn->ttl = daemon->local_ttl;
5910 for (cn2 = daemon->cnames; cn2; cn2 = cn2->next)
5911 if (hostname_isequal(cn->target, cn2->alias))
5918 /* Find any CNAME loops.*/
5919 for (cn = daemon->cnames; cn; cn = cn->next)
5921 for (cn2 = cn->targetp; cn2; cn2 = cn2->targetp)
5923 if (cn2->flag == NOLOOP)
5926 if (cn2->flag == TESTLOOP)
5927 die(_("CNAME loop involving %s"), cn->alias, EC_BADCONF);
5929 cn2->flag = TESTLOOP;
5932 for (cn3 = cn->targetp; cn3 != cn2; cn3 = cn3->targetp)
5937 if (daemon->if_addrs)
5940 for(tmp = daemon->if_addrs; tmp; tmp = tmp->next)
5941 if (tmp->addr.sa.sa_family == AF_INET)
5942 tmp->addr.in.sin_port = htons(daemon->port);
5943 else if (tmp->addr.sa.sa_family == AF_INET6)
5944 tmp->addr.in6.sin6_port = htons(daemon->port);
5947 /* create default, if not specified */
5948 if (daemon->authserver && !daemon->hostmaster)
5950 strcpy(buff, "hostmaster.");
5951 strcat(buff, daemon->authserver);
5952 daemon->hostmaster = opt_string_alloc(buff);
5955 if (!daemon->dhcp_pxe_vendors)
5957 daemon->dhcp_pxe_vendors = opt_malloc(sizeof(struct dhcp_pxe_vendor));
5958 daemon->dhcp_pxe_vendors->data = opt_string_alloc(DHCP_PXE_DEF_VENDOR);
5959 daemon->dhcp_pxe_vendors->next = NULL;
5962 /* only one of these need be specified: the other defaults to the host-name */
5963 if (option_bool(OPT_LOCALMX) || daemon->mxnames || daemon->mxtarget)
5965 struct mx_srv_record *mx;
5967 if (gethostname(buff, MAXDNAME) == -1)
5968 die(_("cannot get host-name: %s"), NULL, EC_MISC);
5970 for (mx = daemon->mxnames; mx; mx = mx->next)
5971 if (!mx->issrv && hostname_isequal(mx->name, buff))
5974 if ((daemon->mxtarget || option_bool(OPT_LOCALMX)) && !mx)
5976 mx = opt_malloc(sizeof(struct mx_srv_record));
5977 mx->next = daemon->mxnames;
5980 mx->name = opt_string_alloc(buff);
5981 daemon->mxnames = mx;
5984 if (!daemon->mxtarget)
5985 daemon->mxtarget = opt_string_alloc(buff);
5987 for (mx = daemon->mxnames; mx; mx = mx->next)
5988 if (!mx->issrv && !mx->target)
5989 mx->target = daemon->mxtarget;
5992 if (!option_bool(OPT_NO_RESOLV) &&
5993 daemon->resolv_files &&
5994 daemon->resolv_files->next &&
5995 option_bool(OPT_NO_POLL))
5996 die(_("only one resolv.conf file allowed in no-poll mode."), NULL, EC_BADCONF);
5998 if (option_bool(OPT_RESOLV_DOMAIN))
6003 if (option_bool(OPT_NO_RESOLV) ||
6004 !daemon->resolv_files ||
6005 (daemon->resolv_files)->next)
6006 die(_("must have exactly one resolv.conf to read domain from."), NULL, EC_BADCONF);
6008 if (!(f = fopen((daemon->resolv_files)->name, "r")))
6009 die(_("failed to read %s: %s"), (daemon->resolv_files)->name, EC_FILE);
6011 while ((line = fgets(buff, MAXDNAME, f)))
6013 char *token = strtok(line, " \t\n\r");
6015 if (!token || strcmp(token, "search") != 0)
6018 if ((token = strtok(NULL, " \t\n\r")) &&
6019 (daemon->domain_suffix = canonicalise_opt(token)))
6025 if (!daemon->domain_suffix)
6026 die(_("no search directive found in %s"), (daemon->resolv_files)->name, EC_MISC);
6029 if (daemon->domain_suffix)
6031 /* add domain for any srv record without one. */
6032 struct mx_srv_record *srv;
6034 for (srv = daemon->mxnames; srv; srv = srv->next)
6036 strchr(srv->name, '.') &&
6037 strchr(srv->name, '.') == strrchr(srv->name, '.'))
6039 strcpy(buff, srv->name);
6041 strcat(buff, daemon->domain_suffix);
6043 srv->name = opt_string_alloc(buff);
6046 else if (option_bool(OPT_DHCP_FQDN))
6047 die(_("there must be a default domain when --dhcp-fqdn is set"), NULL, EC_BADCONF);
6049 /* If there's access-control config, then ignore --local-service, it's intended
6050 as a system default to keep otherwise unconfigured installations safe. */
6051 if (daemon->if_names || daemon->if_except || daemon->if_addrs || daemon->authserver)
6052 reset_option_bool(OPT_LOCAL_SERVICE);
6056 fprintf(stderr, "dnsmasq: %s.\n", _("syntax check OK"));