Imported Upstream version 2.88
[platform/upstream/dnsmasq.git] / src / option.c
1 /* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
2
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.
7  
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.
12      
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/>.
15 */
16
17 /* define this to get facilitynames */
18 #define SYSLOG_NAMES
19 #include "dnsmasq.h"
20 #include <setjmp.h>
21
22 static volatile int mem_recover = 0;
23 static jmp_buf mem_jmp;
24 static int one_file(char *file, int hard_opt);
25
26 /* Solaris headers don't have facility names. */
27 #ifdef HAVE_SOLARIS_NETWORK
28 static const struct {
29   char *c_name;
30   unsigned int c_val;
31 }  facilitynames[] = {
32   { "kern",   LOG_KERN },
33   { "user",   LOG_USER },
34   { "mail",   LOG_MAIL },
35   { "daemon", LOG_DAEMON },
36   { "auth",   LOG_AUTH },
37   { "syslog", LOG_SYSLOG },
38   { "lpr",    LOG_LPR },
39   { "news",   LOG_NEWS },
40   { "uucp",   LOG_UUCP },
41   { "audit",  LOG_AUDIT },
42   { "cron",   LOG_CRON },
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 },
51   { NULL, 0 }
52 };
53 #endif
54
55 #ifndef HAVE_GETOPT_LONG
56 struct myoption {
57   const char *name;
58   int has_arg;
59   int *flag;
60   int val;
61 };
62 #endif
63
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:"
65
66 /* options which don't have a one-char version */
67 #define LOPT_RELOAD        256
68 #define LOPT_NO_NAMES      257
69 #define LOPT_TFTP          258
70 #define LOPT_SECURE        259
71 #define LOPT_PREFIX        260
72 #define LOPT_PTR           261
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
83 #define LOPT_BANK          272
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
90 #define LOPT_OPTS          279
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
117 #define LOPT_RA            306
118 #define LOPT_DUID          307
119 #define LOPT_HOST_REC      308
120 #define LOPT_TFTP_LC       309
121 #define LOPT_RR            310
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
165 #define LOPT_CAA           356
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
188
189 #ifdef HAVE_GETOPT_LONG
190 static const struct option opts[] =  
191 #else
192 static const struct myoption opts[] = 
193 #endif
194   { 
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 },
377     { NULL, 0, 0, 0 }
378   };
379
380
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
385
386 static struct {
387   int opt;
388   unsigned int rept;
389   char * const flagdesc;
390   char * const desc;
391   char * const arg;
392 } usage[] = {
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 }
574 }; 
575
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"
586    has six.
587 */
588
589 static const char meta[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
590
591 static char hide_meta(char c)
592 {
593   unsigned int i;
594
595   for (i = 0; i < (sizeof(meta) - 1); i++)
596     if (c == meta[i])
597       return (char)i;
598   
599   return c;
600 }
601
602 static char unhide_meta(char cr)
603
604   unsigned int c = cr;
605   
606   if (c < (sizeof(meta) - 1))
607     cr = meta[c];
608   
609   return cr;
610 }
611
612 static void unhide_metas(char *cp)
613 {
614   if (cp)
615     for(; *cp; cp++)
616       *cp = unhide_meta(*cp);
617 }
618
619 static void *opt_malloc(size_t size)
620 {
621   void *ret;
622
623   if (mem_recover)
624     {
625       ret = whine_malloc(size);
626       if (!ret)
627         longjmp(mem_jmp, 1);
628     }
629   else
630     ret = safe_malloc(size);
631   
632   return ret;
633 }
634
635 static char *opt_string_alloc(const char *cp)
636 {
637   char *ret = NULL;
638   size_t len;
639   
640   if (cp && (len = strlen(cp)) != 0)
641     {
642       ret = opt_malloc(len+1);
643       memcpy(ret, cp, len+1); 
644       
645       /* restore hidden metachars */
646       unhide_metas(ret);
647     }
648     
649   return ret;
650 }
651
652
653 /* find next comma, split string with zero and eliminate spaces.
654    return start of string following comma */
655
656 static char *split_chr(char *s, char c)
657 {
658   char *comma, *p;
659
660   if (!s || !(comma = strchr(s, c)))
661     return NULL;
662   
663   p = comma;
664   *comma = ' ';
665   
666   for (; *comma == ' '; comma++);
667  
668   for (; (p >= s) && *p == ' '; p--)
669     *p = 0;
670     
671   return comma;
672 }
673
674 static char *split(char *s)
675 {
676   return split_chr(s, ',');
677 }
678
679 static char *canonicalise_opt(char *s)
680 {
681   char *ret;
682   int nomem;
683
684   if (!s)
685     return 0;
686
687   if (strlen(s) == 0)
688     return opt_malloc(1); /* Heap-allocated empty string */
689
690   unhide_metas(s);
691   if (!(ret = canonicalise(s, &nomem)) && nomem)
692     {
693       if (mem_recover)
694         longjmp(mem_jmp, 1);
695       else
696         die(_("could not get memory"), NULL, EC_NOMEM);
697     }
698
699   return ret;
700 }
701
702 static int numeric_check(char *a)
703 {
704   char *p;
705
706   if (!a)
707     return 0;
708
709   unhide_metas(a);
710   
711   for (p = a; *p; p++)
712      if (*p < '0' || *p > '9')
713        return 0;
714
715   return 1;
716 }
717
718 static int atoi_check(char *a, int *res)
719 {
720   if (!numeric_check(a))
721     return 0;
722   *res = atoi(a);
723   return 1;
724 }
725
726 static int strtoul_check(char *a, u32 *res)
727 {
728   unsigned long x;
729   
730   if (!numeric_check(a))
731     return 0;
732   x = strtoul(a, NULL, 10);
733   if (errno || x > UINT32_MAX) {
734     errno = 0;
735     return 0;
736   }
737   *res = (u32)x;
738   return 1;
739 }
740
741 static int atoi_check16(char *a, int *res)
742 {
743   if (!(atoi_check(a, res)) ||
744       *res < 0 ||
745       *res > 0xffff)
746     return 0;
747
748   return 1;
749 }
750
751 #ifdef HAVE_DNSSEC
752 static int atoi_check8(char *a, int *res)
753 {
754   if (!(atoi_check(a, res)) ||
755       *res < 0 ||
756       *res > 0xff)
757     return 0;
758
759   return 1;
760 }
761 #endif
762
763 #ifndef NO_ID
764 static void add_txt(char *name, char *txt, int stat)
765 {
766   struct txt_record *r = opt_malloc(sizeof(struct txt_record));
767
768   if (txt)
769     {
770       size_t len = strlen(txt);
771       r->txt = opt_malloc(len+1);
772       r->len = len+1;
773       *(r->txt) = len;
774       memcpy((r->txt)+1, txt, len);
775     }
776
777   r->stat = stat;
778   r->name = opt_string_alloc(name);
779   r->next = daemon->txt;
780   daemon->txt = r;
781   r->class = C_CHAOS;
782 }
783 #endif
784
785 static void do_usage(void)
786 {
787   char buff[100];
788   int i, j;
789
790   struct {
791     char handle;
792     int val;
793   } tab[] = {
794     { '$', CACHESIZ },
795     { '*', EDNS_PKTSZ },
796     { '&', MAXLEASES },
797     { '!', FTABSIZ },
798     { '#', TFTP_MAX_CONNECTIONS },
799     { '\0', 0 }
800   };
801
802   printf(_("Usage: dnsmasq [options]\n\n"));
803 #ifndef HAVE_GETOPT_LONG
804   printf(_("Use short options only on the command line.\n"));
805 #endif
806   printf(_("Valid options are:\n"));
807   
808   for (i = 0; usage[i].opt != 0; i++)
809     {
810       char *desc = usage[i].flagdesc; 
811       char *eq = "=";
812       
813       if (!desc || *desc == '[')
814         eq = "";
815       
816       if (!desc)
817         desc = "";
818
819       for ( j = 0; opts[j].name; j++)
820         if (opts[j].val == usage[i].opt)
821           break;
822       if (usage[i].opt < 256)
823         sprintf(buff, "-%c, ", usage[i].opt);
824       else
825         sprintf(buff, "    ");
826       
827       sprintf(buff+4, "--%s%s%s", opts[j].name, eq, desc);
828       printf("%-55.55s", buff);
829              
830       if (usage[i].arg)
831         {
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);
836         }
837       printf(_(usage[i].desc), buff);
838       printf("\n");
839     }
840 }
841
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)
845
846 static char *parse_mysockaddr(char *arg, union mysockaddr *addr) 
847 {
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;
852   else
853     return _("bad address");
854    
855   return NULL;
856 }
857
858 char *parse_server(char *arg, struct server_details *sdetails)
859 {
860   sdetails->serv_port = NAMESERVER_PORT;
861   char *portno;
862   int ecode = 0;
863   struct addrinfo hints;
864
865   memset(&hints, 0, sizeof(struct addrinfo));
866   
867   *sdetails->interface = 0;
868   sdetails->addr_type = AF_UNSPEC;
869      
870   if (strcmp(arg, "#") == 0)
871     {
872       if (sdetails->flags)
873         *sdetails->flags |= SERV_USE_RESOLV;
874       sdetails->addr_type = AF_LOCAL;
875       sdetails->valid = 1;
876       return NULL;
877     }
878   
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");
883   
884   if ((portno = split_chr(arg, '#')) && /* is there a port no. */
885       !atoi_check16(portno, &sdetails->serv_port))
886     return _("bad port");
887   
888   sdetails->scope_id = split_chr(arg, '%');
889   
890   if (sdetails->source) {
891     sdetails->interface_opt = split_chr(sdetails->source, '@');
892
893     if (sdetails->interface_opt)
894       {
895 #if defined(SO_BINDTODEVICE)
896         safe_strncpy(sdetails->interface, sdetails->source, IF_NAMESIZE);
897         sdetails->source = sdetails->interface_opt;
898 #else
899         return _("interface binding not supported");
900 #endif
901       }
902   }
903
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;
908   else 
909     {
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;
927 #endif
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;
932
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;
937
938       /* Get address associated with this hostname */
939       ecode = getaddrinfo(arg, NULL, &hints, &sdetails->hostinfo);
940       if (ecode == 0)
941         {
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. */
947           sdetails->valid = 1;
948           sdetails->orig_hostinfo = sdetails->hostinfo;
949           return NULL;
950         }
951       else
952         {
953           /* Lookup failed, return human readable error string */
954           if (ecode == EAI_AGAIN)
955             return _("Cannot resolve server name");
956           else
957             return _((char*)gai_strerror(ecode));
958         }
959     }
960   
961   sdetails->valid = 1;
962   return NULL;
963 }
964
965 char *parse_server_addr(struct server_details *sdetails)
966 {
967   if (sdetails->addr_type == AF_INET)
968     {
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);
973 #endif
974       sdetails->source_addr->in.sin_addr.s_addr = INADDR_ANY;
975       sdetails->source_addr->in.sin_port = htons(daemon->query_port);
976       
977       if (sdetails->source)
978         {
979           if (sdetails->flags)
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)
983             {
984               if (inet_pton(AF_INET6, sdetails->source, &sdetails->source_addr->in6.sin6_addr) == 1)
985                 {
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");
992                 }
993               else
994                 {
995 #if defined(SO_BINDTODEVICE)
996                   if (sdetails->interface_opt)
997                     return _("interface can only be specified once");
998
999                   sdetails->source_addr->in.sin_addr.s_addr = INADDR_ANY;
1000                   safe_strncpy(sdetails->interface, sdetails->source, IF_NAMESIZE);
1001 #else
1002                   return _("interface binding not supported");
1003 #endif
1004                 }
1005             }
1006         }
1007     }
1008   else if (sdetails->addr_type == AF_INET6)
1009     {
1010       if (sdetails->scope_id && (sdetails->scope_index = if_nametoindex(sdetails->scope_id)) == 0)
1011         return _("bad interface name");
1012
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);
1022 #endif
1023       if (sdetails->source)
1024         {
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)
1029             {
1030               if (inet_pton(AF_INET, sdetails->source, &sdetails->source_addr->in.sin_addr) == 1)
1031                 {
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");
1038                 }
1039               else
1040                 {
1041 #if defined(SO_BINDTODEVICE)
1042                   if (sdetails->interface_opt)
1043                   return _("interface can only be specified once");
1044
1045                   sdetails->source_addr->in6.sin6_addr = in6addr_any;
1046                   safe_strncpy(sdetails->interface, sdetails->source, IF_NAMESIZE);
1047 #else
1048                   return _("interface binding not supported");
1049 #endif
1050                 }
1051             }
1052         }
1053     }
1054   else if (sdetails->addr_type != AF_LOCAL)
1055     return _("bad address");
1056   
1057   return NULL;
1058 }
1059
1060 int parse_server_next(struct server_details *sdetails)
1061 {
1062   /* Looping over resolved addresses? */
1063   if (sdetails->hostinfo)
1064     {
1065       /* Get address type */
1066       sdetails->addr_type = sdetails->hostinfo->ai_family;
1067
1068       /* Get address */
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));
1077
1078       /* Iterate to the next available address */
1079       sdetails->valid = sdetails->hostinfo->ai_next != NULL;
1080       sdetails->hostinfo = sdetails->hostinfo->ai_next;
1081       return 1;
1082     }
1083   else if (sdetails->valid)
1084     {
1085       /* When using an IP address, we return the address only once */
1086       sdetails->valid = 0;
1087       return 1;
1088     }
1089   /* Stop iterating here, we used all available addresses */
1090   return 0;
1091 }
1092
1093 static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int size)
1094 {
1095   int i, j;
1096   char *string;
1097   int msize;
1098   u16 flags = 0;
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;
1104
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;
1110     
1111   if (!server)
1112     flags = SERV_LITERAL_ADDRESS;
1113   else if ((string = parse_server(server, &sdetails)))
1114     return string;
1115   
1116   if (from_file)
1117     flags |= SERV_FROM_FILE;
1118  
1119   rem = size & 0x7;
1120   addrbytes = (32 - size) >> 3;
1121   addrbits = (32 - size) & 7;
1122   
1123   if (size > 32 || size < 1)
1124     return _("bad IPv4 prefix length");
1125   
1126   /* Zero out last address bits according to CIDR mask */
1127   ((u8 *)addr4)[3-addrbytes] &= ~((1 << addrbits)-1);
1128   
1129   size = size & ~0x7;
1130   
1131   if (rem != 0)
1132     count = 1 << (8 - rem);
1133   
1134   for (i = 0; i < count; i++)
1135     {
1136       *domain = 0;
1137       string = domain;
1138       msize = size/8;
1139       
1140       for (j = (rem == 0) ? msize-1 : msize; j >= 0; j--)
1141         { 
1142           int dig = ((unsigned char *)addr4)[j];
1143           
1144           if (j == msize)
1145             dig += i;
1146           
1147           string += sprintf(string, "%d.", dig);
1148         }
1149       
1150       sprintf(string, "in-addr.arpa");
1151
1152       if (flags & SERV_LITERAL_ADDRESS)
1153         {
1154           if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
1155             return  _("error");
1156         }
1157       else
1158         {
1159           while (parse_server_next(&sdetails))
1160             {
1161               if ((string = parse_server_addr(&sdetails)))
1162                 return string;
1163               
1164               if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
1165                 return  _("error");
1166             }
1167
1168           if (sdetails.orig_hostinfo)
1169             freeaddrinfo(sdetails.orig_hostinfo);
1170         }
1171     }
1172   
1173   return NULL;
1174 }
1175
1176 static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, int size)
1177 {
1178   int i, j;
1179   char *string;
1180   int msize;
1181   u16 flags = 0;
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;
1187   
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;
1193    
1194   if (!server)
1195     flags = SERV_LITERAL_ADDRESS;
1196   else if ((string = parse_server(server, &sdetails)))
1197     return string;
1198
1199   if (from_file)
1200     flags |= SERV_FROM_FILE;
1201   
1202   rem = size & 0x3;
1203   addrbytes = (128 - size) >> 3;
1204   addrbits = (128 - size) & 7;
1205   
1206   if (size > 128 || size < 1)
1207     return _("bad IPv6 prefix length");
1208   
1209   /* Zero out last address bits according to CIDR mask */
1210   addr6->s6_addr[15-addrbytes] &= ~((1 << addrbits) - 1);
1211   
1212   size = size & ~0x3;
1213   
1214   if (rem != 0)
1215     count = 1 << (4 - rem);
1216       
1217   for (i = 0; i < count; i++)
1218     {
1219       *domain = 0;
1220       string = domain;
1221       msize = size/4;
1222   
1223       for (j = (rem == 0) ? msize-1 : msize; j >= 0; j--)
1224         { 
1225           int dig = ((unsigned char *)addr6)[j>>1];
1226           
1227           dig = j & 1 ? dig & 15 : dig >> 4;
1228           
1229           if (j == msize)
1230             dig += i;
1231           
1232           string += sprintf(string, "%.1x.", dig);
1233         }
1234       
1235       sprintf(string, "ip6.arpa");
1236
1237       if (flags & SERV_LITERAL_ADDRESS)
1238         {
1239           if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
1240             return  _("error");
1241         }
1242       else
1243         {
1244           while (parse_server_next(&sdetails))
1245             {
1246               if ((string = parse_server_addr(&sdetails)))
1247                 return string;
1248               
1249               if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
1250                 return  _("error");
1251             }
1252
1253           if (sdetails.orig_hostinfo)
1254             freeaddrinfo(sdetails.orig_hostinfo);
1255         }
1256     }
1257   
1258   return NULL;
1259 }
1260
1261 #ifdef HAVE_DHCP
1262
1263 static int is_tag_prefix(char *arg)
1264 {
1265   if (arg && (strstr(arg, "net:") == arg || strstr(arg, "tag:") == arg))
1266     return 1;
1267   
1268   return 0;
1269 }
1270
1271 static char *set_prefix(char *arg)
1272 {
1273    if (strstr(arg, "set:") == arg)
1274      return arg+4;
1275    
1276    return arg;
1277 }
1278
1279 static struct dhcp_netid *dhcp_netid_create(const char *net, struct dhcp_netid *next)
1280 {
1281   struct dhcp_netid *tt;
1282   tt = opt_malloc(sizeof (struct dhcp_netid));
1283   tt->net = opt_string_alloc(net);
1284   tt->next = next;
1285   return tt;
1286 }
1287
1288 static void dhcp_netid_free(struct dhcp_netid *nid)
1289 {
1290   while (nid)
1291     {
1292       struct dhcp_netid *tmp = nid;
1293       nid = nid->next;
1294       free(tmp->net);
1295       free(tmp);
1296     }
1297 }
1298
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)
1302 {
1303   struct dhcp_netid *id = NULL;
1304
1305   while (is_tag_prefix(*arg))
1306     {
1307       char *comma = split(*arg);
1308       id = dhcp_netid_create((*arg)+4, id);
1309       *arg = comma;
1310     };
1311   if (!*arg)
1312     {
1313       dhcp_netid_free(id);
1314       id = NULL;
1315     }
1316   return id;
1317 }
1318
1319 static void dhcp_netid_list_free(struct dhcp_netid_list *netid)
1320 {
1321   while (netid)
1322     {
1323       struct dhcp_netid_list *tmplist = netid;
1324       netid = netid->next;
1325       dhcp_netid_free(tmplist->list);
1326       free(tmplist);
1327     }
1328 }
1329
1330 static void dhcp_config_free(struct dhcp_config *config)
1331 {
1332   if (config)
1333     {
1334       struct hwaddr_config *hwaddr = config->hwaddr;
1335       
1336       while (hwaddr)
1337         {
1338           struct hwaddr_config *tmp = hwaddr;
1339           hwaddr = hwaddr->next;
1340           free(tmp);
1341         }
1342       
1343       dhcp_netid_list_free(config->netid);
1344       dhcp_netid_free(config->filter);
1345       
1346       if (config->flags & CONFIG_CLID)
1347         free(config->clid);
1348       if (config->flags & CONFIG_NAME)
1349         free(config->hostname);
1350
1351 #ifdef HAVE_DHCP6
1352       if (config->flags & CONFIG_ADDR6)
1353         {
1354           struct addrlist *addr, *tmp;
1355           
1356           for (addr = config->addr6; addr; addr = tmp)
1357             {
1358               tmp = addr->next;
1359               free(addr);
1360             }
1361         }
1362 #endif
1363
1364       free(config);
1365     }
1366 }
1367
1368 static void dhcp_context_free(struct dhcp_context *ctx)
1369 {
1370   if (ctx)
1371     {
1372       dhcp_netid_free(ctx->filter);
1373       free(ctx->netid.net);
1374 #ifdef HAVE_DHCP6
1375       free(ctx->template_interface);
1376 #endif
1377       free(ctx);
1378     }
1379 }
1380
1381 static void dhcp_opt_free(struct dhcp_opt *opt)
1382 {
1383   if (opt->flags & DHOPT_VENDOR)
1384     free(opt->u.vendor_class);
1385   dhcp_netid_free(opt->netid);
1386   free(opt->val);
1387   free(opt);
1388 }
1389
1390
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)
1393 {
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;
1397   char *comma = NULL;
1398   u16 opt_len = 0;
1399   int is6 = 0;
1400   int option_ok = 0;
1401
1402   new->len = 0;
1403   new->flags = flags;
1404   new->netid = NULL;
1405   new->val = NULL;
1406   new->opt = 0;
1407   
1408   while (arg)
1409     {
1410       comma = split(arg);      
1411
1412       for (cp = arg; *cp; cp++)
1413         if (*cp < '0' || *cp > '9')
1414           break;
1415       
1416       if (!*cp)
1417         {
1418           new->opt = atoi(arg);
1419           opt_len = 0;
1420           option_ok = 1;
1421           break;
1422         }
1423       
1424       if (strstr(arg, "option:") == arg)
1425         {
1426           if ((new->opt = lookup_dhcp_opt(AF_INET, arg+7)) != -1)
1427             {
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)
1431                 option_ok = 1;
1432             }
1433           break;
1434         }
1435 #ifdef HAVE_DHCP6
1436       else if (strstr(arg, "option6:") == arg)
1437         {
1438           for (cp = arg+8; *cp; cp++)
1439             if (*cp < '0' || *cp > '9')
1440               break;
1441          
1442           if (!*cp)
1443             {
1444               new->opt = atoi(arg+8);
1445               opt_len = 0;
1446               option_ok = 1;
1447             }
1448           else
1449             {
1450               if ((new->opt = lookup_dhcp_opt(AF_INET6, arg+8)) != -1)
1451                 {
1452                   opt_len = lookup_dhcp_len(AF_INET6, new->opt);
1453                   if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
1454                     option_ok = 1;
1455                 }
1456             }
1457           /* option6:<opt>|<optname> must follow tag and vendor string. */
1458           is6 = 1;
1459           break;
1460         }
1461 #endif
1462       else if (strstr(arg, "vendor:") == arg)
1463         {
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:"));
1468         }
1469       else if (strstr(arg, "encap:") == arg)
1470         {
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:"));
1475         }
1476       else if (strstr(arg, "vi-encap:") == arg)
1477         {
1478           new->u.encap = atoi(arg+9);
1479           new->flags |= DHOPT_RFC3925;
1480           if (flags == DHOPT_MATCH)
1481             {
1482               option_ok = 1;
1483               break;
1484             }
1485         }
1486       else
1487         {
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);
1491         }
1492       
1493       arg = comma; 
1494     }
1495
1496 #ifdef HAVE_DHCP6
1497   if (is6)
1498     {
1499       if (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))
1500         goto_err(_("unsupported encapsulation for IPv6 option"));
1501       
1502       if (opt_len == 0 &&
1503           !(new->flags & DHOPT_RFC3925))
1504         opt_len = lookup_dhcp_len(AF_INET6, new->opt);
1505     }
1506   else
1507 #endif
1508     if (opt_len == 0 &&
1509         !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
1510       opt_len = lookup_dhcp_len(AF_INET, new->opt);
1511   
1512   /* option may be missing with rfc3925 match */
1513   if (!option_ok)
1514     goto_err(_("bad dhcp-option"));
1515   
1516   if (comma)
1517     {
1518       /* characterise the value */
1519       char c;
1520       int found_dig = 0, found_colon = 0;
1521       is_addr = is_addr6 = is_hex = is_dec = is_string = 1;
1522       addrs = digs = 1;
1523       dots = 0;
1524       for (cp = comma; (c = *cp); cp++)
1525         if (c == ',')
1526           {
1527             addrs++;
1528             is_dec = is_hex = 0;
1529           }
1530         else if (c == ':')
1531           {
1532             digs++;
1533             is_dec = is_addr = 0;
1534             found_colon = 1;
1535           }
1536         else if (c == '/') 
1537           {
1538             is_addr6 = is_dec = is_hex = 0;
1539             if (cp == comma) /* leading / means a pathname */
1540               is_addr = 0;
1541           } 
1542         else if (c == '.')      
1543           {
1544             is_dec = is_hex = 0;
1545             dots++;
1546           }
1547         else if (c == '-')
1548           is_hex = is_addr = is_addr6 = 0;
1549         else if (c == ' ')
1550           is_dec = is_hex = 0;
1551         else if (!(c >='0' && c <= '9'))
1552           {
1553             is_addr = 0;
1554             if (cp[1] == 0 && is_dec &&
1555                 (c == 'b' || c == 's' || c == 'i'))
1556               {
1557                 lenchar = c;
1558                 *cp = 0;
1559               }
1560             else
1561               is_dec = 0;
1562             if (!((c >='A' && c <= 'F') ||
1563                   (c >='a' && c <= 'f') || 
1564                   (c == '*' && (flags & DHOPT_MATCH))))
1565               {
1566                 is_hex = 0;
1567                 if (c != '[' && c != ']')
1568                   is_addr6 = 0;
1569               }
1570           }
1571         else
1572           found_dig = 1;
1573      
1574       if (!found_dig)
1575         is_dec = is_addr = 0;
1576
1577       if (!found_colon)
1578         is_addr6 = 0;
1579
1580 #ifdef HAVE_DHCP6
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;
1584 #endif
1585      
1586       /* We know that some options take addresses */
1587       if (opt_len & OT_ADDR_LIST)
1588         {
1589           is_string = is_dec = is_hex = 0;
1590           
1591           if (!is6 && (!is_addr || dots == 0))
1592             goto_err(_("bad IP address"));
1593
1594            if (is6 && !is_addr6)
1595              goto_err(_("bad IPv6 address"));
1596         }
1597       /* or names */
1598       else if (opt_len & (OT_NAME | OT_RFC1035_NAME | OT_CSTRING))
1599         is_addr6 = is_addr = is_dec = is_hex = 0;
1600       
1601       if (found_dig && (opt_len & OT_TIME) && strlen(comma) > 0)
1602         {
1603           int val, fac = 1;
1604
1605           switch (comma[strlen(comma) - 1])
1606             {
1607             case 'w':
1608             case 'W':
1609               fac *= 7;
1610               /* fall through */
1611             case 'd':
1612             case 'D':
1613               fac *= 24;
1614               /* fall through */
1615             case 'h':
1616             case 'H':
1617               fac *= 60;
1618               /* fall through */
1619             case 'm':
1620             case 'M':
1621               fac *= 60;
1622               /* fall through */
1623             case 's':
1624             case 'S':
1625               comma[strlen(comma) - 1] = 0;
1626             }
1627           
1628           new->len = 4;
1629           new->val = opt_malloc(4);
1630           val = atoi(comma);
1631           *((int *)new->val) = htonl(val * fac);          
1632         }  
1633       else if (is_hex && digs > 1)
1634         {
1635           new->len = digs;
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;
1639         }
1640       else if (is_dec)
1641         {
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. */
1646           if (opt_len != 0)
1647             new->len = opt_len;
1648           else if (val & 0xffff0000)
1649             new->len = 4;
1650           else if (val & 0xff00)
1651             new->len = 2;
1652           else
1653             new->len = 1;
1654
1655           if (lenchar == 'b')
1656             new->len = 1;
1657           else if (lenchar == 's')
1658             new->len = 2;
1659           else if (lenchar == 'i')
1660             new->len = 4;
1661           
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);
1665         }
1666       else if (is_addr && !is6) 
1667         {
1668           struct in_addr in;
1669           unsigned char *op;
1670           char *slash;
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;
1675
1676           if (!(new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR | DHOPT_RFC3925)) && 
1677               new->opt == OPTION_SIP_SERVER)
1678             {
1679               *(op++) = 1; /* RFC 3361 "enc byte" */
1680               new->flags &= ~DHOPT_ADDR;
1681             }
1682           while (addrs--) 
1683             {
1684               cp = comma;
1685               comma = split(cp);
1686               slash = split_chr(cp, '/');
1687               if (!inet_pton(AF_INET, cp, &in))
1688                 goto_err(_("bad IPv4 address"));
1689               if (!slash)
1690                 {
1691                   memcpy(op, &in, INADDRSZ);
1692                   op += INADDRSZ;
1693                 }
1694               else
1695                 {
1696                   unsigned char *p = (unsigned char *)&in;
1697                   int netsize = atoi(slash);
1698                   *op++ = netsize;
1699                   if (netsize > 0)
1700                     *op++ = *p++;
1701                   if (netsize > 8)
1702                     *op++ = *p++;
1703                   if (netsize > 16)
1704                     *op++ = *p++;
1705                   if (netsize > 24)
1706                     *op++ = *p++;
1707                   new->flags &= ~DHOPT_ADDR; /* cannot re-write descriptor format */
1708                 } 
1709             }
1710           new->len = op - new->val;
1711         }
1712       else if (is_addr6 && is6)
1713         {
1714           unsigned char *op;
1715           new->val = op = opt_malloc(16 * addrs);
1716           new->flags |= DHOPT_ADDR6;
1717           while (addrs--) 
1718             {
1719               cp = comma;
1720               comma = split(cp);
1721               
1722               /* check for [1234::7] */
1723               if (*cp == '[')
1724                 cp++;
1725               if (strlen(cp) > 1 && cp[strlen(cp)-1] == ']')
1726                 cp[strlen(cp)-1] = 0;
1727               
1728               if (inet_pton(AF_INET6, cp, op))
1729                 {
1730                   op += IN6ADDRSZ;
1731                   continue;
1732                 }
1733
1734               goto_err(_("bad IPv6 address"));
1735             } 
1736           new->len = op - new->val;
1737         }
1738       else if (is_string)
1739         {
1740           /* text arg */
1741           if ((new->opt == OPTION_DOMAIN_SEARCH || new->opt == OPTION_SIP_SERVER) &&
1742               !is6 && !(new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR | DHOPT_RFC3925)))
1743             {
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;
1749               
1750               arg = comma;
1751               comma = split(arg);
1752               
1753               while (arg && *arg)
1754                 {
1755                   char *in, *dom = NULL;
1756                   size_t domlen = 1;
1757                   /* Allow "." as an empty domain */
1758                   if (strcmp (arg, ".") != 0)
1759                     {
1760                       if (!(dom = canonicalise_opt(arg)))
1761                         goto_err(_("bad domain in dhcp-option"));
1762                         
1763                       domlen = strlen(dom) + 2;
1764                     }
1765                       
1766                   newp = opt_malloc(len + domlen + header_size);
1767                   if (m)
1768                     {
1769                       memcpy(newp, m, header_size + len);
1770                       free(m);
1771                     }
1772                   m = newp;
1773                   p = m + header_size;
1774                   q = p + len;
1775                   
1776                   /* add string on the end in RFC1035 format */
1777                   for (in = dom; in && *in;) 
1778                     {
1779                       unsigned char *cp = q++;
1780                       int j;
1781                       for (j = 0; *in && (*in != '.'); in++, j++)
1782                         *q++ = *in;
1783                       *cp = j;
1784                       if (*in)
1785                         in++;
1786                     }
1787                   *q++ = 0;
1788                   free(dom);
1789                   
1790                   /* Now tail-compress using earlier names. */
1791                   newlen = q - p;
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)
1795                         {
1796                           PUTSHORT((r - p) | 0xc000, tail); 
1797                           newlen = tail - p;
1798                           goto end;
1799                         }
1800                 end:
1801                   len = newlen;
1802                   
1803                   arg = comma;
1804                   comma = split(arg);
1805                 }
1806       
1807               /* RFC 3361, enc byte is zero for names */
1808               if (new->opt == OPTION_SIP_SERVER && m)
1809                 m[0] = 0;
1810               new->len = (int) len + header_size;
1811               new->val = m;
1812             }
1813 #ifdef HAVE_DHCP6
1814           else if (comma && (opt_len & OT_CSTRING))
1815             {
1816               /* length fields are two bytes so need 16 bits for each string */
1817               int i, commas = 1;
1818               unsigned char *p, *newp;
1819
1820               for (i = 0; comma[i]; i++)
1821                 if (comma[i] == ',')
1822                   commas++;
1823               
1824               newp = opt_malloc(strlen(comma)+(2*commas));        
1825               p = newp;
1826               arg = comma;
1827               comma = split(arg);
1828               
1829               while (arg && *arg)
1830                 {
1831                   u16 len = strlen(arg);
1832                   unhide_metas(arg);
1833                   PUTSHORT(len, p);
1834                   memcpy(p, arg, len);
1835                   p += len; 
1836
1837                   arg = comma;
1838                   comma = split(arg);
1839                 }
1840
1841               new->val = newp;
1842               new->len = p - newp;
1843             }
1844           else if (comma && (opt_len & OT_RFC1035_NAME))
1845             {
1846               unsigned char *p = NULL, *q, *newp, *end;
1847               int len = 0;
1848               int header_size = (is6 && new->opt == OPTION6_NTP_SERVER) ? 4 : 0;
1849               arg = comma;
1850               comma = split(arg);
1851               
1852               while (arg && *arg)
1853                 {
1854                   char *dom = canonicalise_opt(arg);
1855                   if (!dom)
1856                     goto_err(_("bad domain in dhcp-option"));
1857                                   
1858                   newp = opt_malloc(len + header_size + strlen(dom) + 2);
1859                   
1860                   if (p)
1861                     {
1862                       memcpy(newp, p, len);
1863                       free(p);
1864                     }
1865                   
1866                   p = newp;
1867                   q = p + len;
1868                   end = do_rfc1035_name(q + header_size, dom, NULL);
1869                   *end++ = 0;
1870                   if (is6 && new->opt == OPTION6_NTP_SERVER)
1871                     {
1872                       PUTSHORT(NTP_SUBOPTION_SRV_FQDN, q);
1873                       PUTSHORT(end - q - 2, q);
1874                     }
1875                   len = end - p;
1876                   free(dom);
1877
1878                   arg = comma;
1879                   comma = split(arg);
1880                 }
1881               
1882               new->val = p;
1883               new->len = len;
1884             }
1885 #endif
1886           else
1887             {
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;
1892             }
1893         }
1894     }
1895
1896   if (!is6 && 
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"));
1901   
1902   if (flags == DHOPT_MATCH)
1903     {
1904       if ((new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)) ||
1905           !new->netid ||
1906           new->netid->next)
1907         goto_err(_("illegal dhcp-match"));
1908        
1909       if (is6)
1910         {
1911           new->next = daemon->dhcp_match6;
1912           daemon->dhcp_match6 = new;
1913         }
1914       else
1915         {
1916           new->next = daemon->dhcp_match;
1917           daemon->dhcp_match = new;
1918         }
1919     }
1920   else if (is6)
1921     {
1922       new->next = daemon->dhcp_opts6;
1923       daemon->dhcp_opts6 = new;
1924     }
1925   else
1926     {
1927       new->next = daemon->dhcp_opts;
1928       daemon->dhcp_opts = new;
1929     }
1930     
1931   return 1;
1932 on_error:
1933   dhcp_opt_free(new);
1934   return 0;
1935 }
1936
1937 #endif
1938
1939 void set_option_bool(unsigned int opt)
1940 {
1941   option_var(opt) |= option_val(opt);
1942 }
1943
1944 void reset_option_bool(unsigned int opt)
1945 {
1946   option_var(opt) &= ~(option_val(opt));
1947 }
1948
1949 static int one_opt(int option, char *arg, char *errstr, char *gen_err, int command_line, int servers_only)
1950 {      
1951   int i;
1952   char *comma;
1953
1954   if (option == '?')
1955     ret_err(gen_err);
1956   
1957   for (i=0; usage[i].opt != 0; i++)
1958     if (usage[i].opt == option)
1959       {
1960          int rept = usage[i].rept;
1961          
1962          if (command_line)
1963            {
1964              /* command line */
1965              if (rept == ARG_USED_CL)
1966                ret_err(_("illegal repeated flag"));
1967              if (rept == ARG_ONE)
1968                usage[i].rept = ARG_USED_CL;
1969            }
1970          else
1971            {
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;
1977            }
1978
1979          if (rept != ARG_DUP && rept != ARG_ONE && rept != ARG_USED_CL) 
1980            {
1981              set_option_bool(rept);
1982              return 1;
1983            }
1984        
1985          break;
1986       }
1987   
1988   switch (option)
1989     { 
1990     case 'C': /* --conf-file */
1991       {
1992         char *file = opt_string_alloc(arg);
1993         if (file)
1994           {
1995             one_file(file, 0);
1996             free(file);
1997           }
1998         break;
1999       }
2000
2001     case LOPT_CONF_SCRIPT: /* --conf-script */
2002       {
2003         char *file = opt_string_alloc(arg);
2004         if (file)
2005           {
2006             one_file(file, LOPT_CONF_SCRIPT);
2007             free(file);
2008           }
2009         break;
2010       }
2011
2012     case '7': /* --conf-dir */        
2013       {
2014         DIR *dir_stream;
2015         struct dirent *ent;
2016         char *directory, *path;
2017         struct list {
2018           char *name;
2019           struct list *next;
2020         } *ignore_suffix = NULL, *match_suffix = NULL, *files = NULL, *li;
2021         
2022         comma = split(arg);
2023         if (!(directory = opt_string_alloc(arg)))
2024           break;
2025         
2026         for (arg = comma; arg; arg = comma) 
2027           {
2028             comma = split(arg);
2029             if (strlen(arg) != 0)
2030               {
2031                 li = opt_malloc(sizeof(struct list));
2032                 if (*arg == '*')
2033                   {
2034                     /* "*" with no suffix is a no-op */
2035                     if (arg[1] == 0)
2036                       free(li);
2037                     else
2038                       {
2039                         li->next = match_suffix;
2040                         match_suffix = li;
2041                         /* Have to copy: buffer is overwritten */
2042                         li->name = opt_string_alloc(arg+1);
2043                       }
2044                   }
2045                 else
2046                   {
2047                     li->next = ignore_suffix;
2048                     ignore_suffix = li;
2049                     /* Have to copy: buffer is overwritten */
2050                     li->name = opt_string_alloc(arg);
2051                   }
2052               }
2053           }
2054         
2055         if (!(dir_stream = opendir(directory)))
2056           die(_("cannot access directory %s: %s"), directory, EC_FILE);
2057         
2058         while ((ent = readdir(dir_stream)))
2059           {
2060             size_t len = strlen(ent->d_name);
2061             struct stat buf;
2062             
2063             /* ignore emacs backups and dotfiles */
2064             if (len == 0 ||
2065                 ent->d_name[len - 1] == '~' ||
2066                 (ent->d_name[0] == '#' && ent->d_name[len - 1] == '#') ||
2067                 ent->d_name[0] == '.')
2068               continue;
2069
2070             if (match_suffix)
2071               {
2072                 for (li = match_suffix; li; li = li->next)
2073                   {
2074                     /* check for required suffices */
2075                     size_t ls = strlen(li->name);
2076                     if (len > ls &&
2077                         strcmp(li->name, &ent->d_name[len - ls]) == 0)
2078                       break;
2079                   }
2080                 if (!li)
2081                   continue;
2082               }
2083             
2084             for (li = ignore_suffix; li; li = li->next)
2085               {
2086                 /* check for proscribed suffices */
2087                 size_t ls = strlen(li->name);
2088                 if (len > ls &&
2089                     strcmp(li->name, &ent->d_name[len - ls]) == 0)
2090                   break;
2091               }
2092             if (li)
2093               continue;
2094             
2095             path = opt_malloc(strlen(directory) + len + 2);
2096             strcpy(path, directory);
2097             strcat(path, "/");
2098             strcat(path, ent->d_name);
2099
2100             /* files must be readable */
2101             if (stat(path, &buf) == -1)
2102               die(_("cannot access %s: %s"), path, EC_FILE);
2103             
2104             /* only reg files allowed. */
2105             if (S_ISREG(buf.st_mode))
2106               {
2107                 /* sort files into order. */
2108                 struct list **up, *new = opt_malloc(sizeof(struct list));
2109                 new->name = path;
2110                 
2111                 for (up = &files, li = files; li; up = &li->next, li = li->next)
2112                   if (strcmp(li->name, path) >=0)
2113                     break;
2114
2115                 new->next = li;
2116                 *up = new;
2117               }
2118             else
2119               free(path);
2120
2121           }
2122
2123         for (li = files; li; li = li->next)
2124           one_file(li->name, 0);
2125         
2126         closedir(dir_stream);
2127         free(directory);
2128         for(; ignore_suffix; ignore_suffix = li)
2129           {
2130             li = ignore_suffix->next;
2131             free(ignore_suffix->name);
2132             free(ignore_suffix);
2133           }
2134         for(; match_suffix; match_suffix = li)
2135           {
2136             li = match_suffix->next;
2137             free(match_suffix->name);
2138             free(match_suffix);
2139           }
2140         for(; files; files = li)
2141           {
2142             li = files->next;
2143             free(files->name);
2144             free(files);
2145           }
2146         break;
2147       }
2148
2149     case LOPT_ADD_SBNET: /* --add-subnet */
2150       set_option_bool(OPT_CLIENT_SUBNET);
2151       if (arg)
2152         {
2153           char *err, *end;
2154           comma = split(arg);
2155
2156           struct mysubnet* new = opt_malloc(sizeof(struct mysubnet));
2157           if ((end = split_chr(arg, '/')))
2158             {
2159               /* has subnet+len */
2160               err = parse_mysockaddr(arg, &new->addr);
2161               if (err)
2162                 ret_err_free(err, new);
2163               if (!atoi_check(end, &new->mask))
2164                 ret_err_free(gen_err, new);
2165               new->addr_used = 1;
2166             } 
2167           else if (!atoi_check(arg, &new->mask))
2168             ret_err_free(gen_err, new);
2169             
2170           daemon->add_subnet4 = new;
2171
2172           if (comma)
2173             {
2174               new = opt_malloc(sizeof(struct mysubnet));
2175               if ((end = split_chr(comma, '/')))
2176                 {
2177                   /* has subnet+len */
2178                   err = parse_mysockaddr(comma, &new->addr);
2179                   if (err)
2180                     ret_err_free(err, new);
2181                   if (!atoi_check(end, &new->mask))
2182                     ret_err_free(gen_err, new);
2183                   new->addr_used = 1;
2184                 }
2185               else
2186                 {
2187                   if (!atoi_check(comma, &new->mask))
2188                     ret_err_free(gen_err, new);
2189                 }
2190           
2191               daemon->add_subnet6 = new;
2192             }
2193         }
2194       break;
2195
2196     case '1': /* --enable-dbus */
2197       set_option_bool(OPT_DBUS);
2198       if (arg)
2199         daemon->dbus_name = opt_string_alloc(arg);
2200       else
2201         daemon->dbus_name = DNSMASQ_SERVICE;
2202       break;
2203
2204     case LOPT_UBUS: /* --enable-ubus */
2205       set_option_bool(OPT_UBUS);
2206       if (arg)
2207         daemon->ubus_name = opt_string_alloc(arg);
2208       else
2209         daemon->ubus_name = DNSMASQ_UBUS_NAME;
2210       break;
2211
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);
2216       else
2217         {         
2218 #ifdef __ANDROID__
2219           ret_err(_("setting log facility is not possible under Android"));
2220 #else
2221           for (i = 0; facilitynames[i].c_name; i++)
2222             if (hostname_isequal((char *)facilitynames[i].c_name, arg))
2223               break;
2224           
2225           if (facilitynames[i].c_name)
2226             daemon->log_fac = facilitynames[i].c_val;
2227           else
2228             ret_err(_("bad log facility"));
2229 #endif
2230         }
2231       break;
2232
2233     case 'x': /* --pid-file */
2234       daemon->runfile = opt_string_alloc(arg);
2235       break;
2236
2237     case 'r': /* --resolv-file */
2238       {
2239         char *name = opt_string_alloc(arg);
2240         struct resolvc *new, *list = daemon->resolv_files;
2241         
2242         if (list && list->is_default)
2243           {
2244             /* replace default resolv file - possibly with nothing */
2245             if (name)
2246               {
2247                 list->is_default = 0;
2248                 list->name = name;
2249               }
2250             else
2251               list = NULL;
2252           }
2253         else if (name)
2254           {
2255             new = opt_malloc(sizeof(struct resolvc));
2256             new->next = list;
2257             new->name = name;
2258             new->is_default = 0;
2259             new->mtime = 0;
2260             new->logged = 0;
2261             list = new;
2262           }
2263         daemon->resolv_files = list;
2264         break;
2265       }
2266
2267     case LOPT_SERVERS_FILE:
2268       daemon->servers_file = opt_string_alloc(arg);
2269       break;
2270       
2271     case 'm':  /* --mx-host */
2272       {
2273         int pref = 1;
2274         struct mx_srv_record *new;
2275         char *name, *target = NULL;
2276
2277         if ((comma = split(arg)))
2278           {
2279             char *prefstr;
2280             if ((prefstr = split(comma)) && !atoi_check16(prefstr, &pref))
2281               ret_err(_("bad MX preference"));
2282           }
2283         
2284         if (!(name = canonicalise_opt(arg)) || 
2285             (comma && !(target = canonicalise_opt(comma))))
2286           {
2287             free(name);
2288             free(target);
2289             ret_err(_("bad MX name"));
2290           }
2291         
2292         new = opt_malloc(sizeof(struct mx_srv_record));
2293         new->next = daemon->mxnames;
2294         daemon->mxnames = new;
2295         new->issrv = 0;
2296         new->name = name;
2297         new->target = target; /* may be NULL */
2298         new->weight = pref;
2299         break;
2300       }
2301       
2302     case 't': /*  --mx-target */
2303       if (!(daemon->mxtarget = canonicalise_opt(arg)))
2304         ret_err(_("bad MX target"));
2305       break;
2306
2307     case LOPT_DUMPFILE:  /* --dumpfile */
2308       daemon->dump_file = opt_string_alloc(arg);
2309       break;
2310
2311     case LOPT_DUMPMASK:  /* --dumpmask */
2312       daemon->dump_mask = strtol(arg, NULL, 0);
2313       break;
2314       
2315 #ifdef HAVE_DHCP      
2316     case 'l':  /* --dhcp-leasefile */
2317       daemon->lease_file = opt_string_alloc(arg);
2318       break;
2319       
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"));
2325 #  else
2326       if (option == LOPT_LUASCRIPT)
2327 #    if !defined(HAVE_LUASCRIPT)
2328         ret_err(_("recompile with HAVE_LUASCRIPT defined to enable Lua scripts"));
2329 #    else
2330         daemon->luascript = opt_string_alloc(arg);
2331 #    endif
2332       else
2333         daemon->lease_change_command = opt_string_alloc(arg);
2334 #  endif
2335       break;
2336 #endif /* HAVE_DHCP */
2337
2338     case LOPT_DHCP_HOST:     /* --dhcp-hostsfile */
2339     case LOPT_DHCP_OPTS:     /* --dhcp-optsfile */
2340     case 'H':                /* --addn-hosts */
2341       {
2342         struct hostsfile *new = opt_malloc(sizeof(struct hostsfile));
2343         new->fname = opt_string_alloc(arg);
2344         new->index = daemon->host_index++;
2345         new->flags = 0;
2346         if (option == 'H')
2347           {
2348             new->next = daemon->addn_hosts;
2349             daemon->addn_hosts = new;
2350           }
2351         else if (option == LOPT_DHCP_HOST)
2352           {
2353             new->next = daemon->dhcp_hosts_file;
2354             daemon->dhcp_hosts_file = new;
2355           }
2356         else if (option == LOPT_DHCP_OPTS)
2357           {
2358             new->next = daemon->dhcp_opts_file;
2359             daemon->dhcp_opts_file = new;
2360           }
2361         
2362         break;
2363       }
2364
2365     case LOPT_DHCP_INOTIFY:  /* --dhcp-hostsdir */
2366     case LOPT_DHOPT_INOTIFY: /* --dhcp-optsdir */
2367     case LOPT_HOST_INOTIFY:  /* --hostsdir */
2368       {
2369         struct dyndir *new = opt_malloc(sizeof(struct dyndir));
2370         new->dname = opt_string_alloc(arg);
2371         new->flags = 0;
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;
2380
2381         break;
2382       }
2383       
2384     case LOPT_AUTHSERV: /* --auth-server */
2385       comma = split(arg);
2386       
2387       daemon->authserver = opt_string_alloc(arg);
2388       
2389       while ((arg = comma))
2390         {
2391           struct iname *new = opt_malloc(sizeof(struct iname));
2392           comma = split(arg);
2393           new->name = NULL;
2394           unhide_metas(arg);
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;
2399           else
2400             {
2401               char *fam = split_chr(arg, '/');
2402               new->name = opt_string_alloc(arg);
2403               new->addr.sa.sa_family = 0;
2404               if (fam)
2405                 {
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;
2410                   else
2411                   {
2412                     free(new->name);
2413                     ret_err_free(gen_err, new);
2414                   }
2415                 } 
2416             }
2417           new->next = daemon->authinterface;
2418           daemon->authinterface = new;
2419         };
2420             
2421       break;
2422
2423     case LOPT_AUTHSFS: /* --auth-sec-servers */
2424       {
2425         struct name_list *new;
2426
2427         do {
2428           comma = split(arg);
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;
2433           arg = comma;
2434         } while (arg);
2435         break;
2436       }
2437         
2438     case LOPT_AUTHZONE: /* --auth-zone */
2439       {
2440         struct auth_zone *new;
2441         
2442         comma = split(arg);
2443                 
2444         new = opt_malloc(sizeof(struct auth_zone));
2445         new->domain = canonicalise_opt(arg);
2446         if (!new->domain)
2447           ret_err_free(_("invalid auth-zone"), new);
2448         new->subnet = NULL;
2449         new->exclude = NULL;
2450         new->interface_names = NULL;
2451         new->next = daemon->auth_zones;
2452         daemon->auth_zones = new;
2453
2454         while ((arg = comma))
2455           {
2456             int prefixlen = 0;
2457             int is_exclude = 0;
2458             char *prefix;
2459             struct addrlist *subnet =  NULL;
2460             union all_addr addr;
2461
2462             comma = split(arg);
2463             prefix = split_chr(arg, '/');
2464             
2465             if (prefix && !atoi_check(prefix, &prefixlen))
2466               ret_err(gen_err);
2467             
2468             if (strstr(arg, "exclude:") == arg)
2469               {
2470                     is_exclude = 1;
2471                     arg = arg+8;
2472               }
2473
2474             if (inet_pton(AF_INET, arg, &addr.addr4))
2475               {
2476                 subnet = opt_malloc(sizeof(struct addrlist));
2477                 subnet->prefixlen = (prefixlen == 0) ? 24 : prefixlen;
2478                 subnet->flags = ADDRLIST_LITERAL;
2479               }
2480             else if (inet_pton(AF_INET6, arg, &addr.addr6))
2481               {
2482                 subnet = opt_malloc(sizeof(struct addrlist));
2483                 subnet->prefixlen = (prefixlen == 0) ? 64 : prefixlen;
2484                 subnet->flags = ADDRLIST_LITERAL | ADDRLIST_IPV6;
2485               }
2486             else 
2487               {
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;
2493                 if (prefix)
2494                   {
2495                     if (prefixlen == 4)
2496                       name->flags &= ~AUTH6;
2497                     else if (prefixlen == 6)
2498                       name->flags &= ~AUTH4;
2499                     else
2500                       ret_err(gen_err);
2501                   }
2502               }
2503             
2504             if (subnet)
2505               {
2506                 subnet->addr = addr;
2507
2508                 if (is_exclude)
2509                   {
2510                     subnet->next = new->exclude;
2511                     new->exclude = subnet;
2512                   }
2513                 else
2514                   {
2515                     subnet->next = new->subnet;
2516                     new->subnet = subnet;
2517                   }
2518               }
2519           }
2520         break;
2521       }
2522       
2523     case  LOPT_AUTHSOA: /* --auth-soa */
2524       comma = split(arg);
2525       daemon->soa_sn = (u32)atoi(arg);
2526       if (comma)
2527         {
2528           char *cp;
2529           arg = comma;
2530           comma = split(arg);
2531           daemon->hostmaster = opt_string_alloc(arg);
2532           for (cp = daemon->hostmaster; cp && *cp; cp++)
2533             if (*cp == '@')
2534               *cp = '.';
2535
2536           if (comma)
2537             {
2538               arg = comma;
2539               comma = split(arg); 
2540               daemon->soa_refresh = (u32)atoi(arg);
2541               if (comma)
2542                 {
2543                   arg = comma;
2544                   comma = split(arg); 
2545                   daemon->soa_retry = (u32)atoi(arg);
2546                   if (comma)
2547                     daemon->soa_expiry = (u32)atoi(comma);
2548                 }
2549             }
2550         }
2551
2552       break;
2553
2554     case 's':         /* --domain */
2555     case LOPT_SYNTH:  /* --synth-domain */
2556       if (strcmp (arg, "#") == 0)
2557         set_option_bool(OPT_RESOLV_DOMAIN);
2558       else
2559         {
2560           char *d, *d_raw = arg;
2561           comma = split(arg);
2562           if (!(d = canonicalise_opt(d_raw)))
2563             ret_err(gen_err);
2564           else
2565             {
2566               free(d); /* allocate this again below. */
2567               if (comma)
2568                 {
2569                   struct cond_domain *new = opt_malloc(sizeof(struct cond_domain));
2570                   char *netpart;
2571                   
2572                   new->prefix = NULL;
2573                   new->indexed = 0;
2574                   new->prefixlen = 0;
2575                   
2576                   unhide_metas(comma);
2577                   if ((netpart = split_chr(comma, '/')))
2578                     {
2579                       int msize;
2580
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))
2585                         {
2586                           int mask;
2587
2588                           if (msize > 32)
2589                              ret_err_free(_("bad prefix length"), new);
2590                           
2591                           mask = (1 << (32 - msize)) - 1;
2592                           new->is6 = 0;                           
2593                           new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask);
2594                           new->end.s_addr = new->start.s_addr | htonl(mask);
2595                           if (arg)
2596                             {
2597                               if (option != 's')
2598                                 {
2599                                   if (!(new->prefix = canonicalise_opt(arg)) ||
2600                                       strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
2601                                     ret_err_free(_("bad prefix"), new);
2602                                 }
2603                               else if (strcmp(arg, "local") != 0)
2604                                 ret_err_free(gen_err, new);
2605                               else
2606                                 {
2607                                   /* local=/xxx.yyy.zzz.in-addr.arpa/ */
2608                                   domain_rev4(0, NULL, &new->start, msize);
2609                                                                   
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);
2613                                 }
2614                             }
2615                         }
2616                       else if (inet_pton(AF_INET6, comma, &new->start6))
2617                         {
2618                           u64 mask, addrpart = addr6part(&new->start6);
2619
2620                           if (msize > 128)
2621                             ret_err_free(_("bad prefix length"), new);
2622
2623                           mask = (1LLU << (128 - msize)) - 1LLU;
2624
2625                           new->is6 = 1;
2626                           new->prefixlen = msize;
2627                           
2628                           /* prefix==64 overflows the mask calculation above */
2629                           if (msize <= 64)
2630                             mask = (u64)-1LL;
2631                           
2632                           new->end6 = new->start6;
2633                           setaddr6part(&new->start6, addrpart & ~mask);
2634                           setaddr6part(&new->end6, addrpart | mask);
2635                           
2636                           if (arg)
2637                             {
2638                               if (option != 's')
2639                                 {
2640                                   if (!(new->prefix = canonicalise_opt(arg)) ||
2641                                       strlen(new->prefix) > MAXLABEL - INET6_ADDRSTRLEN)
2642                                     ret_err_free(_("bad prefix"), new);
2643                                 }       
2644                               else if (strcmp(arg, "local") != 0)
2645                                 ret_err_free(gen_err, new);
2646                               else 
2647                                 {
2648                                   /* generate the equivalent of
2649                                      local=/xxx.yyy.zzz.ip6.arpa/ */
2650                                   domain_rev6(0, NULL, &new->start6, msize);
2651                                   
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);
2655                                 }
2656                             }
2657                         }
2658                       else
2659                         ret_err_free(gen_err, new);
2660                     }
2661                   else
2662                     {
2663                       char *prefstr;
2664                       arg = split(comma);
2665                       prefstr = split(arg);
2666
2667                       if (inet_pton(AF_INET, comma, &new->start))
2668                         {
2669                           new->is6 = 0;
2670                           if (!arg)
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);
2674                         }
2675                       else if (inet_pton(AF_INET6, comma, &new->start6))
2676                         {
2677                           new->is6 = 1;
2678                           if (!arg)
2679                             memcpy(&new->end6, &new->start6, IN6ADDRSZ);
2680                           else if (!inet_pton(AF_INET6, arg, &new->end6))
2681                             ret_err_free(gen_err, new);
2682                         }
2683                       else if (option == 's')
2684                         {
2685                           /* subnet from interface. */
2686                           new->interface = opt_string_alloc(comma);
2687                           new->al = NULL;
2688                         }
2689                       else
2690                         ret_err_free(gen_err, new);
2691                       
2692                       if (option != 's' && prefstr)
2693                         {
2694                           if (!(new->prefix = canonicalise_opt(prefstr)) ||
2695                               strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
2696                             ret_err_free(_("bad prefix"), new);
2697                         }
2698                     }
2699
2700                   new->domain = canonicalise_opt(d_raw);
2701                   if (option  == 's')
2702                     {
2703                       new->next = daemon->cond_domain;
2704                       daemon->cond_domain = new;
2705                     }
2706                   else
2707                     {
2708                       char *star;
2709                       if (new->prefix &&
2710                           (star = strrchr(new->prefix, '*'))
2711                           && *(star+1) == 0)
2712                         {
2713                           *star = 0;
2714                           new->indexed = 1;
2715                           if (new->is6 && new->prefixlen < 64)
2716                             ret_err_free(_("prefix length too small"), new);
2717                         }
2718                       new->next = daemon->synth_domains;
2719                       daemon->synth_domains = new;
2720                     }
2721                 }
2722               else if (option == 's')
2723                 daemon->domain_suffix = canonicalise_opt(d_raw);
2724               else 
2725                 ret_err(gen_err);
2726             }
2727         }
2728       break;
2729       
2730     case LOPT_CPE_ID: /* --add-dns-client */
2731       if (arg)
2732         daemon->dns_client_id = opt_string_alloc(arg);
2733       break;
2734
2735     case LOPT_UMBRELLA: /* --umbrella */
2736       set_option_bool(OPT_UMBRELLA);
2737       while (arg)
2738         {
2739           comma = split(arg);
2740           if (strstr(arg, "deviceid:"))
2741             {
2742               char *p;
2743               u8 *u = daemon->umbrella_device;
2744               char word[3];
2745               
2746               arg += 9;
2747               if (strlen(arg) != 16)
2748                 ret_err(gen_err);
2749               
2750               for (p = arg; *p; p++)
2751                 if (!isxdigit((int)*p))
2752                   ret_err(gen_err);
2753               
2754               set_option_bool(OPT_UMBRELLA_DEVID);
2755               
2756               for (i = 0; i < (int)sizeof(daemon->umbrella_device); i++, arg+=2)
2757                 {
2758                   memcpy(word, &(arg[0]), 2);
2759                   *u++ = strtoul(word, NULL, 16);
2760                 }
2761             }
2762           else if (strstr(arg, "orgid:"))
2763             {
2764               if (!strtoul_check(arg+6, &daemon->umbrella_org))
2765                 ret_err(gen_err);
2766             }
2767           else if (strstr(arg, "assetid:"))
2768             {
2769               if (!strtoul_check(arg+8, &daemon->umbrella_asset))
2770                 ret_err(gen_err);
2771             }
2772           else
2773             ret_err(gen_err);
2774           
2775           arg = comma;
2776         }
2777       break;
2778       
2779     case LOPT_ADD_MAC: /* --add-mac */
2780       if (!arg)
2781         set_option_bool(OPT_ADD_MAC);
2782       else
2783         {
2784           unhide_metas(arg);
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);
2789           else
2790             ret_err(gen_err);
2791         }
2792       break;
2793
2794     case 'u':  /* --user */
2795       daemon->username = opt_string_alloc(arg);
2796       break;
2797       
2798     case 'g':  /* --group */
2799       daemon->groupname = opt_string_alloc(arg);
2800       daemon->group_set = 1;
2801       break;
2802
2803 #ifdef HAVE_DHCP
2804     case LOPT_SCRIPTUSR: /* --scriptuser */
2805       daemon->scriptuser = opt_string_alloc(arg);
2806       break;
2807 #endif
2808       
2809     case 'i':  /* --interface */
2810       do {
2811         struct iname *new = opt_malloc(sizeof(struct iname));
2812         comma = split(arg);
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);
2818         new->used = 0;
2819         arg = comma;
2820       } while (arg);
2821       break;
2822       
2823     case LOPT_TFTP: /* --enable-tftp */
2824       set_option_bool(OPT_TFTP);
2825       if (!arg)
2826         break;
2827       /* fall through */
2828
2829     case 'I':  /* --except-interface */
2830     case '2':  /* --no-dhcp-interface */
2831       do {
2832         struct iname *new = opt_malloc(sizeof(struct iname));
2833         comma = split(arg);
2834         new->name = opt_string_alloc(arg);
2835         if (option == 'I')
2836           {
2837             new->next = daemon->if_except;
2838             daemon->if_except = new;
2839           }
2840         else if (option == LOPT_TFTP)
2841            {
2842             new->next = daemon->tftp_interfaces;
2843             daemon->tftp_interfaces = new;
2844           }
2845         else
2846           {
2847             new->next = daemon->dhcp_except;
2848             daemon->dhcp_except = new;
2849           }
2850         arg = comma;
2851       } while (arg);
2852       break;
2853       
2854     case 'B':  /* --bogus-nxdomain */
2855     case LOPT_IGNORE_ADDR: /* --ignore-address */
2856      {
2857         union all_addr addr;
2858         int prefix, is6 = 0;
2859         struct bogus_addr *baddr;
2860         
2861         unhide_metas(arg);
2862
2863         if (!arg ||
2864             ((comma = split_chr(arg, '/')) && !atoi_check(comma, &prefix)))
2865           ret_err(gen_err);
2866
2867         if (inet_pton(AF_INET6, arg, &addr.addr6) == 1)
2868           is6 = 1;
2869         else if (inet_pton(AF_INET, arg, &addr.addr4) != 1)
2870           ret_err(gen_err);
2871
2872         if (!comma)
2873           {
2874             if (is6)
2875               prefix = 128;
2876             else
2877               prefix = 32;
2878           }
2879
2880         if (prefix > 128 || (!is6 && prefix > 32))
2881           ret_err(gen_err);
2882         
2883         baddr = opt_malloc(sizeof(struct bogus_addr));
2884         if (option == 'B')
2885           {
2886             baddr->next = daemon->bogus_addr;
2887             daemon->bogus_addr = baddr;
2888           }
2889         else
2890           {
2891             baddr->next = daemon->ignore_addr;
2892             daemon->ignore_addr = baddr;
2893           }
2894
2895         baddr->prefix = prefix;
2896         baddr->is6 = is6;
2897         baddr->addr = addr;
2898         break;
2899      }
2900       
2901     case 'a':  /* --listen-address */
2902     case LOPT_AUTHPEER: /* --auth-peer */
2903       do {
2904         struct iname *new = opt_malloc(sizeof(struct iname));
2905         comma = split(arg);
2906         unhide_metas(arg);
2907         if (arg && (inet_pton(AF_INET, arg, &new->addr.in.sin_addr) > 0))
2908           {
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);
2913 #endif
2914           }
2915         else if (arg && inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr) > 0)
2916           {
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);
2923 #endif
2924           }
2925         else
2926           ret_err_free(gen_err, new);
2927
2928         new->used = 0;
2929         if (option == 'a')
2930           {
2931             new->next = daemon->if_addrs;
2932             daemon->if_addrs = new;
2933           }
2934         else
2935           {
2936             new->next = daemon->auth_peers;
2937             daemon->auth_peers = new;
2938           } 
2939         arg = comma;
2940       } while (arg);
2941       break;
2942       
2943     case LOPT_NO_REBIND: /*  --rebind-domain-ok */
2944       {
2945         struct rebind_domain *new;
2946
2947         unhide_metas(arg);
2948
2949         if (*arg == '/')
2950           arg++;
2951         
2952         do {
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;
2958           arg = comma;
2959         } while (arg && *arg);
2960
2961         break;
2962       }
2963       
2964     case 'S':            /*  --server */
2965     case LOPT_LOCAL:     /*  --local */
2966     case 'A':            /*  --address */
2967       {
2968         char *lastdomain = NULL, *domain = "", *cur_domain;
2969         u16 flags = 0;
2970         char *err;
2971         union all_addr addr;
2972         union mysockaddr serv_addr, source_addr;
2973         char interface[IF_NAMESIZE+1];
2974         struct server_details sdetails;
2975
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;
2981                         
2982         unhide_metas(arg);
2983         
2984         /* split the domain args, if any and skip to the end of them. */
2985         if (arg && *arg == '/')
2986           {
2987             char *last;
2988
2989             domain = lastdomain = ++arg;
2990             
2991             while ((last = split_chr(arg, '/')))
2992               {
2993                 lastdomain = arg;
2994                 arg = last;
2995               }
2996           }
2997         
2998         if (!arg || !*arg)
2999           flags = SERV_LITERAL_ADDRESS;
3000         else if (option == 'A')
3001           {
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;
3009             else
3010               ret_err(_("Bad address in --address"));
3011           }
3012         else
3013           {
3014             if ((err = parse_server(arg, &sdetails)))
3015               ret_err(err);
3016           }
3017
3018         if (servers_only && option == 'S')
3019           flags |= SERV_FROM_FILE;
3020
3021         cur_domain = domain;
3022         while ((flags & SERV_LITERAL_ADDRESS) || parse_server_next(&sdetails))
3023           {
3024             cur_domain = domain;
3025
3026             if (!(flags & SERV_LITERAL_ADDRESS) && (err = parse_server_addr(&sdetails)))
3027               ret_err(err);
3028
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)
3031               continue;
3032
3033             while (1)
3034               {
3035                 /* server=//1.2.3.4 is special. */
3036                 if (lastdomain)
3037                   {
3038                     if (strlen(cur_domain) == 0)
3039                       flags |= SERV_FOR_NODOTS;
3040                     else
3041                       flags &= ~SERV_FOR_NODOTS;
3042                     
3043                     /* address=/#/ matches the same as without domain */
3044                     if (option == 'A' && cur_domain[0] == '#' && cur_domain[1] == 0)
3045                       cur_domain[0] = 0;
3046                   }
3047                 
3048                 if (!add_update_server(flags, sdetails.addr, sdetails.source_addr, sdetails.interface, cur_domain, &addr))
3049                   ret_err(gen_err);
3050                 
3051                 if (!lastdomain || cur_domain == lastdomain)
3052                   break;
3053
3054                 cur_domain += strlen(cur_domain) + 1;
3055               }
3056
3057             if (flags & SERV_LITERAL_ADDRESS)
3058               break;
3059           }
3060
3061         if (sdetails.orig_hostinfo)
3062           freeaddrinfo(sdetails.orig_hostinfo);
3063         
3064         break;
3065       }
3066
3067     case LOPT_REV_SERV: /* --rev-server */
3068       {
3069         char *string;
3070         int size;
3071         struct in_addr addr4;
3072         struct in6_addr addr6;
3073         
3074         unhide_metas(arg);
3075         if (!arg)
3076           ret_err(gen_err);
3077         
3078         comma=split(arg);
3079         
3080         if (!(string = split_chr(arg, '/')) || !atoi_check(string, &size))
3081           size = -1;
3082
3083         if (inet_pton(AF_INET, arg, &addr4))
3084           {
3085            if (size == -1)
3086              size = 32;
3087
3088            if ((string = domain_rev4(servers_only, comma, &addr4, size)))
3089               ret_err(string);
3090           }
3091         else if (inet_pton(AF_INET6, arg, &addr6))
3092           {
3093              if (size == -1)
3094                size = 128;
3095
3096              if ((string = domain_rev6(servers_only, comma, &addr6, size)))
3097               ret_err(string);
3098           }
3099         else
3100           ret_err(gen_err);
3101         
3102         break;
3103       }
3104
3105     case LOPT_IPSET: /* --ipset */
3106     case LOPT_NFTSET: /* --nftset */
3107 #ifndef HAVE_IPSET
3108       if (option == LOPT_IPSET)
3109         {
3110           ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
3111           break;
3112         }
3113 #endif
3114 #ifndef HAVE_NFTSET
3115       if (option == LOPT_NFTSET)
3116         {
3117           ret_err(_("recompile with HAVE_NFTSET defined to enable nftset directives"));
3118           break;
3119         }
3120 #endif
3121
3122       {
3123          struct ipsets ipsets_head;
3124          struct ipsets *ipsets = &ipsets_head;
3125          struct ipsets **daemon_sets =
3126            (option == LOPT_IPSET) ? &daemon->ipsets : &daemon->nftsets;
3127          int size;
3128          char *end;
3129          char **sets, **sets_pos;
3130          memset(ipsets, 0, sizeof(struct ipsets));
3131          unhide_metas(arg);
3132          if (arg && *arg == '/') 
3133            {
3134              arg++;
3135              while ((end = split_chr(arg, '/'))) 
3136                {
3137                  char *domain = NULL;
3138                  /* elide leading dots - they are implied in the search algorithm */
3139                  while (*arg == '.')
3140                    arg++;
3141                  /* # matches everything and becomes a zero length domain string */
3142                  if (strcmp(arg, "#") == 0 || !*arg)
3143                    domain = "";
3144                  else if (strlen(arg) != 0 && !(domain = canonicalise_opt(arg)))
3145                    ret_err(gen_err);
3146                  ipsets->next = opt_malloc(sizeof(struct ipsets));
3147                  ipsets = ipsets->next;
3148                  memset(ipsets, 0, sizeof(struct ipsets));
3149                  ipsets->domain = domain;
3150                  arg = end;
3151                }
3152            } 
3153          else 
3154            {
3155              ipsets->next = opt_malloc(sizeof(struct ipsets));
3156              ipsets = ipsets->next;
3157              memset(ipsets, 0, sizeof(struct ipsets));
3158              ipsets->domain = "";
3159            }
3160          
3161          if (!arg || !*arg)
3162            ret_err(gen_err);
3163          
3164          for (size = 2, end = arg; *end; ++end) 
3165            if (*end == ',')
3166                ++size;
3167      
3168          sets = sets_pos = opt_malloc(sizeof(char *) * size);
3169          
3170          do {
3171            char *p;
3172            end = split(arg);
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, '#')))
3177                *p = ' ';
3178            sets_pos++;
3179            arg = end;
3180          } while (end);
3181          *sets_pos = 0;
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;
3186          
3187          break;
3188       }
3189       
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"));
3193       break;
3194 #else
3195       {
3196         u32 mask = UINT32_MAX;
3197         
3198         if (arg)
3199           if (!strtoul_check(arg, &mask) || mask < 1)
3200             ret_err(gen_err);
3201         
3202         set_option_bool(OPT_CMARK_ALST_EN);
3203         daemon->allowlist_mask = mask;
3204         break;
3205       }
3206 #endif
3207       
3208     case LOPT_CMARK_ALST: /* --connmark-allowlist */
3209 #ifndef HAVE_CONNTRACK
3210         ret_err(_("recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"));
3211         break;
3212 #else
3213       {
3214         struct allowlist *allowlists;
3215         char **patterns, **patterns_pos;
3216         u32 mark, mask = UINT32_MAX;
3217         size_t num_patterns = 0;
3218         
3219         char *c, *m = NULL;
3220         char *separator;
3221         unhide_metas(arg);
3222         if (!arg)
3223           ret_err(gen_err);
3224         c = arg;
3225         if (*c < '0' || *c > '9')
3226           ret_err(gen_err);
3227         while (*c && *c != ',')
3228           {
3229             if (*c == '/')
3230               {
3231                 if (m)
3232                   ret_err(gen_err);
3233                 *c = '\0';
3234                 m = ++c;
3235               }
3236             if (*c < '0' || *c > '9')
3237               ret_err(gen_err);
3238             c++;
3239           }
3240         separator = c;
3241         if (!*separator)
3242           break;
3243         while (c && *c)
3244           {
3245             char *end = strchr(++c, '/');
3246             if (end)
3247               *end = '\0';
3248             if (strcmp(c, "*") && !is_valid_dns_name_pattern(c))
3249               ret_err(gen_err);
3250             if (end)
3251               *end = '/';
3252             if (num_patterns >= UINT16_MAX - 1)
3253               ret_err(gen_err);
3254             num_patterns++;
3255             c = end;
3256           }
3257         
3258         *separator = '\0';
3259         if (!strtoul_check(arg, &mark) || mark < 1 || mark > UINT32_MAX)
3260           ret_err(gen_err);
3261         if (m)
3262           if (!strtoul_check(m, &mask) || mask < 1 || mask > UINT32_MAX || (mark & ~mask))
3263             ret_err(gen_err);
3264         if (num_patterns)
3265           *separator = ',';
3266         for (allowlists = daemon->allowlists; allowlists; allowlists = allowlists->next)
3267           if (allowlists->mark == mark && allowlists->mask == mask)
3268             ret_err(gen_err);
3269         
3270         patterns = opt_malloc((num_patterns + 1) * sizeof(char *));
3271         if (!patterns)
3272           goto fail_cmark_allowlist;
3273         patterns_pos = patterns;
3274         c = separator;
3275         while (c && *c)
3276         {
3277           char *end = strchr(++c, '/');
3278           if (end)
3279             *end = '\0';
3280           if (!(*patterns_pos++ = opt_string_alloc(c)))
3281             goto fail_cmark_allowlist;
3282           if (end)
3283             *end = '/';
3284           c = end;
3285         }
3286         *patterns_pos++ = NULL;
3287         
3288         allowlists = opt_malloc(sizeof(struct allowlist));
3289         if (!allowlists)
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;
3297         break;
3298         
3299       fail_cmark_allowlist:
3300         if (patterns)
3301           {
3302             for (patterns_pos = patterns; *patterns_pos; patterns_pos++)
3303               {
3304                 free(*patterns_pos);
3305                 *patterns_pos = NULL;
3306               }
3307             free(patterns);
3308             patterns = NULL;
3309           }
3310         if (allowlists)
3311           {
3312             free(allowlists);
3313             allowlists = NULL;
3314           }
3315         ret_err(gen_err);
3316       }
3317 #endif
3318       
3319     case 'c':  /* --cache-size */
3320       {
3321         int size;
3322         
3323         if (!atoi_check(arg, &size))
3324           ret_err(gen_err);
3325         else
3326           {
3327             /* zero is OK, and means no caching. */
3328             
3329             if (size < 0)
3330               size = 0;
3331
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. */
3337             if (size > 5000000)
3338               size = 5000000;
3339             
3340             daemon->cachesize = size;
3341           }
3342         break;
3343       }
3344       
3345     case 'p':  /* --port */
3346       if (!atoi_check16(arg, &daemon->port))
3347         ret_err(gen_err);
3348       break;
3349     
3350     case LOPT_MINPORT:  /* --min-port */
3351       if (!atoi_check16(arg, &daemon->min_port))
3352         ret_err(gen_err);
3353       break;
3354
3355     case LOPT_MAXPORT:  /* --max-port */
3356       if (!atoi_check16(arg, &daemon->max_port))
3357         ret_err(gen_err);
3358       break;
3359
3360     case '0':  /* --dns-forward-max */
3361       if (!atoi_check(arg, &daemon->ftabsize))
3362         ret_err(gen_err);
3363       break;  
3364     
3365     case 'q': /* --log-queries */
3366       set_option_bool(OPT_LOG);
3367       if (arg && strcmp(arg, "extra") == 0)
3368         set_option_bool(OPT_EXTRALOG);
3369       break;
3370
3371     case LOPT_MAX_LOGS:  /* --log-async */
3372       daemon->max_logs = LOG_MAX; /* default */
3373       if (arg && !atoi_check(arg, &daemon->max_logs))
3374         ret_err(gen_err);
3375       else if (daemon->max_logs > 100)
3376         daemon->max_logs = 100;
3377       break;  
3378
3379     case 'P': /* --edns-packet-max */
3380       {
3381         int i;
3382         if (!atoi_check(arg, &i))
3383           ret_err(gen_err);
3384         daemon->edns_pktsz = (unsigned short)i; 
3385         break;
3386       }
3387       
3388     case 'Q':  /* --query-port */
3389       if (!atoi_check16(arg, &daemon->query_port))
3390         ret_err(gen_err);
3391       /* if explicitly set to zero, use single OS ephemeral port
3392          and disable random ports */
3393       if (daemon->query_port == 0)
3394         daemon->osport = 1;
3395       break;
3396
3397     case LOPT_RANDPORT_LIM: /* --port-limit */
3398       if (!atoi_check(arg, &daemon->randport_limit) || (daemon->randport_limit < 1))
3399         ret_err(gen_err);
3400       break;
3401       
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 */
3409       {
3410         int ttl;
3411         if (!atoi_check(arg, &ttl))
3412           ret_err(gen_err);
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)
3418           {
3419             if (ttl > TTL_FLOOR_LIMIT)
3420               ttl = TTL_FLOOR_LIMIT;
3421             daemon->min_cache_ttl = (unsigned long)ttl;
3422           }
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)
3428           {
3429             daemon->dhcp_ttl = (unsigned long)ttl;
3430             daemon->use_dhcp_ttl = 1;
3431           }
3432         else
3433           daemon->local_ttl = (unsigned long)ttl;
3434         break;
3435       }
3436
3437     case LOPT_FAST_RETRY:
3438       daemon->fast_retry_timeout = TIMEOUT;
3439       
3440       if (!arg)
3441         daemon->fast_retry_time = DEFAULT_FAST_RETRY;
3442       else
3443         {
3444           int retry;
3445           
3446           comma = split(arg);
3447           if (!atoi_check(arg, &retry) || retry < 50)
3448             ret_err(gen_err);
3449           daemon->fast_retry_time = retry;
3450           
3451           if (comma)
3452             {
3453               if (!atoi_check(comma, &retry))
3454                 ret_err(gen_err);
3455               daemon->fast_retry_timeout = retry/1000;
3456             }
3457         }
3458       break;
3459             
3460 #ifdef HAVE_DHCP
3461     case 'X': /* --dhcp-lease-max */
3462       if (!atoi_check(arg, &daemon->dhcp_max))
3463         ret_err(gen_err);
3464       break;
3465 #endif
3466       
3467 #ifdef HAVE_TFTP
3468     case LOPT_TFTP_MAX:  /*  --tftp-max */
3469       if (!atoi_check(arg, &daemon->tftp_max))
3470         ret_err(gen_err);
3471       break;  
3472
3473     case LOPT_TFTP_MTU:  /*  --tftp-mtu */
3474       if (!atoi_check(arg, &daemon->tftp_mtu))
3475         ret_err(gen_err);
3476       break;
3477
3478     case LOPT_PREFIX: /* --tftp-prefix */
3479       comma = split(arg);
3480       if (comma)
3481         {
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;
3487         }
3488       else
3489         daemon->tftp_prefix = opt_string_alloc(arg);
3490       break;
3491
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"));
3497       
3498       if (daemon->start_tftp_port > daemon->end_tftp_port)
3499         {
3500           int tmp = daemon->start_tftp_port;
3501           daemon->start_tftp_port = daemon->end_tftp_port;
3502           daemon->end_tftp_port = tmp;
3503         } 
3504       
3505       break;
3506
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);
3512       else
3513         ret_err(gen_err);
3514       break;
3515 #endif
3516               
3517     case LOPT_BRIDGE:   /* --bridge-interface */
3518       {
3519         struct dhcp_bridge *new;
3520
3521         if (!(comma = split(arg)) || strlen(arg) > IF_NAMESIZE - 1 )
3522           ret_err(_("bad bridge-interface"));
3523
3524         for (new = daemon->bridges; new; new = new->next)
3525           if (strcmp(new->iface, arg) == 0)
3526             break;
3527
3528         if (!new)
3529           {
3530              new = opt_malloc(sizeof(struct dhcp_bridge));
3531              strcpy(new->iface, arg);
3532              new->alias = NULL;
3533              new->next = daemon->bridges;
3534              daemon->bridges = new;
3535           }
3536         
3537         do {
3538           arg = comma;
3539           comma = split(arg);
3540           if (strlen(arg) != 0 && strlen(arg) <= IF_NAMESIZE - 1)
3541             {
3542               struct dhcp_bridge *b = opt_malloc(sizeof(struct dhcp_bridge)); 
3543               b->next = new->alias;
3544               new->alias = b;
3545               strcpy(b->iface, arg);
3546             }
3547         } while (comma);
3548         
3549         break;
3550       }
3551
3552 #ifdef HAVE_DHCP
3553     case LOPT_SHARED_NET: /* --shared-network */
3554       {
3555         struct shared_network *new = opt_malloc(sizeof(struct shared_network));
3556
3557 #ifdef HAVE_DHCP6
3558         new->shared_addr.s_addr = 0;
3559 #endif
3560         new->if_index = 0;
3561         
3562         if (!(comma = split(arg)))
3563           {
3564           snerr:
3565             free(new);
3566             ret_err(_("bad shared-network"));
3567           }
3568         
3569         if (inet_pton(AF_INET, comma, &new->shared_addr))
3570           {
3571             if (!inet_pton(AF_INET, arg, &new->match_addr) &&
3572                 !(new->if_index = if_nametoindex(arg)))
3573               goto snerr;
3574           }
3575 #ifdef HAVE_DHCP6
3576         else if (inet_pton(AF_INET6, comma, &new->shared_addr6))
3577           {
3578             if (!inet_pton(AF_INET6, arg, &new->match_addr6) &&
3579                 !(new->if_index = if_nametoindex(arg)))
3580               goto snerr;
3581           }
3582 #endif
3583         else
3584           goto snerr;
3585
3586         new->next = daemon->shared_networks;
3587         daemon->shared_networks = new;
3588         break;
3589       }
3590           
3591     case 'F':  /* --dhcp-range */
3592       {
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));
3596         
3597         memset (new, 0, sizeof(*new));
3598         
3599         while(1)
3600           {
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')))
3605                 break;
3606             
3607             if (*cp != ',' && (comma = split(arg)))
3608               {
3609                 if (is_tag_prefix(arg))
3610                   {
3611                     /* ignore empty tag */
3612                     if (arg[4])
3613                       new->filter = dhcp_netid_create(arg+4, new->filter);
3614                   }
3615                 else
3616                   {
3617                     if (new->netid.net)
3618                       {
3619                         dhcp_context_free(new);
3620                         ret_err(_("only one tag allowed"));
3621                       }
3622                     else
3623                       new->netid.net = opt_string_alloc(set_prefix(arg));
3624                   }
3625                 arg = comma;
3626               }
3627             else
3628               {
3629                 a[0] = arg;
3630                 break;
3631               }
3632           }
3633         
3634         for (k = 1; k < 8; k++)
3635           if (!(a[k] = split(a[k-1])))
3636             break;
3637         
3638         if (k < 2)
3639           {
3640             dhcp_context_free(new);
3641             ret_err(_("bad dhcp-range"));
3642           }
3643         
3644         if (inet_pton(AF_INET, a[0], &new->start))
3645           {
3646             new->next = daemon->dhcp;
3647             new->lease_time = DEFLEASE;
3648             daemon->dhcp = new;
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))
3655               {
3656                 dhcp_context_free(new);
3657                 ret_err(_("bad dhcp-range"));
3658               }
3659             
3660             if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr))
3661               {
3662                 struct in_addr tmp = new->start;
3663                 new->start = new->end;
3664                 new->end = tmp;
3665               }
3666             
3667             if (k >= 3 && strchr(a[2], '.') &&  
3668                 (inet_pton(AF_INET, a[2], &new->netmask) > 0))
3669               {
3670                 new->flags |= CONTEXT_NETMASK;
3671                 leasepos = 3;
3672                 if (!is_same_net(new->start, new->end, new->netmask))
3673                   {
3674                     dhcp_context_free(new);
3675                     ret_err(_("inconsistent DHCP range"));
3676                   }
3677                 
3678             
3679                 if (k >= 4 && strchr(a[3], '.') &&  
3680                     (inet_pton(AF_INET, a[3], &new->broadcast) > 0))
3681                   {
3682                     new->flags |= CONTEXT_BRDCAST;
3683                     leasepos = 4;
3684                   }
3685               }
3686           }
3687 #ifdef HAVE_DHCP6
3688         else if (inet_pton(AF_INET6, a[0], &new->start6))
3689           {
3690             const char *err = NULL;
3691
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;
3698
3699             for (leasepos = 1; leasepos < k; leasepos++)
3700               {
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])
3716                   {
3717                     new->template_interface = opt_string_alloc(a[leasepos] + 12);
3718                     new->flags |= CONTEXT_TEMPLATE;
3719                   }
3720                 else  
3721                   break;
3722               }
3723                              
3724             /* bare integer < 128 is prefix value */
3725             if (leasepos < k)
3726               {
3727                 int pref;
3728                 for (cp = a[leasepos]; *cp; cp++)
3729                   if (!(*cp >= '0' && *cp <= '9'))
3730                     break;
3731                 if (!*cp && (pref = atoi(a[leasepos])) <= 128)
3732                   {
3733                     new->prefix = pref;
3734                     leasepos++;
3735                   }
3736               }
3737             
3738             if (new->prefix > 64)
3739               {
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"));
3744               }
3745             else if (new->prefix < 64)
3746               err=(_("prefix length must be at least 64"));
3747             
3748             if (!err && !is_same_net6(&new->start6, &new->end6, new->prefix))
3749               err=(_("inconsistent DHCPv6 range"));
3750
3751             if (err)
3752               {
3753                 dhcp_context_free(new);
3754                 ret_err(err);
3755               }
3756
3757             /* dhcp-range=:: enables DHCP stateless on any interface */
3758             if (IN6_IS_ADDR_UNSPECIFIED(&new->start6) && !(new->flags & CONTEXT_TEMPLATE))
3759               new->prefix = 0;
3760             
3761             if (new->flags & CONTEXT_TEMPLATE)
3762               {
3763                 struct in6_addr zero;
3764                 memset(&zero, 0, sizeof(zero));
3765                 if (!is_same_net6(&zero, &new->start6, new->prefix))
3766                   {
3767                     dhcp_context_free(new);
3768                     ret_err(_("prefix must be zero with \"constructor:\" argument"));
3769                   }
3770               }
3771             
3772             if (addr6part(&new->start6) > addr6part(&new->end6))
3773               {
3774                 struct in6_addr tmp = new->start6;
3775                 new->start6 = new->end6;
3776                 new->end6 = tmp;
3777               }
3778           }
3779 #endif
3780         else
3781           {
3782             dhcp_context_free(new);
3783             ret_err(_("bad dhcp-range"));
3784           }
3785         
3786         if (leasepos < k)
3787           {
3788             if (leasepos != k-1)
3789               {
3790                 dhcp_context_free(new);
3791                 ret_err(_("bad dhcp-range"));
3792               }
3793             
3794             if (strcmp(a[leasepos], "infinite") == 0)
3795               {
3796                 new->lease_time = 0xffffffff;
3797                 new->flags |= CONTEXT_SETLEASE;
3798               }
3799             else if (strcmp(a[leasepos], "deprecated") == 0)
3800               new->flags |= CONTEXT_DEPRECATE;
3801             else
3802               {
3803                 int fac = 1;
3804                 if (strlen(a[leasepos]) > 0)
3805                   {
3806                     switch (a[leasepos][strlen(a[leasepos]) - 1])
3807                       {
3808                       case 'w':
3809                       case 'W':
3810                         fac *= 7;
3811                         /* fall through */
3812                       case 'd':
3813                       case 'D':
3814                         fac *= 24;
3815                         /* fall through */
3816                       case 'h':
3817                       case 'H':
3818                         fac *= 60;
3819                         /* fall through */
3820                       case 'm':
3821                       case 'M':
3822                         fac *= 60;
3823                         /* fall through */
3824                       case 's':
3825                       case 'S':
3826                         a[leasepos][strlen(a[leasepos]) - 1] = 0;
3827                       }
3828                     
3829                     for (cp = a[leasepos]; *cp; cp++)
3830                       if (!(*cp >= '0' && *cp <= '9'))
3831                         break;
3832
3833                     if (*cp || (leasepos+1 < k))
3834                       ret_err_free(_("bad dhcp-range"), new);
3835                     
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;
3842                   }
3843               }
3844           }
3845
3846         break;
3847       }
3848
3849     case LOPT_BANK:
3850     case 'G':  /* --dhcp-host */
3851       {
3852         struct dhcp_config *new;
3853         struct in_addr in;
3854         
3855         new = opt_malloc(sizeof(struct dhcp_config));
3856         
3857         new->next = daemon->dhcp_conf;
3858         new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0;
3859         new->hwaddr = NULL;
3860         new->netid = NULL;
3861         new->filter = NULL;
3862         new->clid = NULL;
3863 #ifdef HAVE_DHCP6
3864         new->addr6 = NULL;
3865 #endif
3866
3867         while (arg)
3868           {
3869             comma = split(arg);
3870             if (strchr(arg, ':')) /* ethernet address, netid or binary CLID */
3871               {
3872                 if ((arg[0] == 'i' || arg[0] == 'I') &&
3873                     (arg[1] == 'd' || arg[1] == 'D') &&
3874                     arg[2] == ':')
3875                   {
3876                     if (arg[3] == '*')
3877                       new->flags |= CONFIG_NOCLID;
3878                     else
3879                       {
3880                         int len;
3881                         arg += 3; /* dump id: */
3882                         if (strchr(arg, ':'))
3883                           len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
3884                         else
3885                           {
3886                             unhide_metas(arg);
3887                             len = (int) strlen(arg);
3888                           }
3889                         
3890                         if (len == -1)
3891                           {
3892                             dhcp_config_free(new);
3893                             ret_err(_("bad hex constant"));
3894                           }
3895                         else if ((new->clid = opt_malloc(len)))
3896                           {
3897                             new->flags |= CONFIG_CLID;
3898                             new->clid_len = len;
3899                             memcpy(new->clid, arg, len);
3900                           }
3901                       }
3902                   }
3903                 /* dhcp-host has strange backwards-compat needs. */
3904                 else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg)
3905                   {
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);
3910                   }
3911                 else if (strstr(arg, "tag:") == arg)
3912                   new->filter = dhcp_netid_create(arg+4, new->filter);
3913                   
3914 #ifdef HAVE_DHCP6
3915                 else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
3916                   {
3917                     char *pref;
3918                     struct in6_addr in6;
3919                     struct addrlist *new_addr;
3920                     
3921                     arg[strlen(arg)-1] = 0;
3922                     arg++;
3923                     pref = split_chr(arg, '/');
3924                     
3925                     if (!inet_pton(AF_INET6, arg, &in6))
3926                       {
3927                         dhcp_config_free(new);
3928                         ret_err(_("bad IPv6 address"));
3929                       }
3930
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;
3936                     
3937                     if (pref)
3938                       {
3939                         u64 addrpart = addr6part(&in6);
3940                         
3941                         if (!atoi_check(pref, &new_addr->prefixlen) ||
3942                             new_addr->prefixlen > 128 ||
3943                             ((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
3944                           {
3945                             dhcp_config_free(new);
3946                             ret_err(_("bad IPv6 prefix"));
3947                           }
3948                         
3949                         new_addr->flags |= ADDRLIST_PREFIX;
3950                       }
3951                   
3952                     for (i= 0; i < 8; i++)
3953                       if (in6.s6_addr[i] != 0)
3954                         break;
3955                     
3956                     /* set WILDCARD if network part all zeros */
3957                     if (i == 8)
3958                       new_addr->flags |= ADDRLIST_WILDCARD;
3959                     
3960                     new->flags |= CONFIG_ADDR6;
3961                   }
3962 #endif
3963                 else
3964                   {
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)
3968                       {
3969                         free(newhw);
3970                         dhcp_config_free(new);
3971                         ret_err(_("bad hex constant"));
3972                       }
3973                     else
3974                       {
3975                         newhw->next = new->hwaddr;
3976                         new->hwaddr = newhw;
3977                       }             
3978                   }
3979               }
3980             else if (strchr(arg, '.') && (inet_pton(AF_INET, arg, &in) > 0))
3981               {
3982                 struct dhcp_config *configs;
3983                 
3984                 new->addr = in;
3985                 new->flags |= CONFIG_ADDR;
3986                 
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)
3992                     {
3993                       inet_ntop(AF_INET, &in, daemon->addrbuff, ADDRSTRLEN);
3994                       sprintf(errstr, _("duplicate dhcp-host IP address %s"),
3995                               daemon->addrbuff);
3996                       dhcp_config_free(new);
3997                       return 0;
3998                     }         
3999               }
4000             else
4001               {
4002                 char *cp, *lastp = NULL, last = 0;
4003                 int fac = 1, isdig = 0;
4004                 
4005                 if (strlen(arg) > 1)
4006                   {
4007                     lastp = arg + strlen(arg) - 1;
4008                     last = *lastp;
4009                     switch (last)
4010                       {
4011                       case 'w':
4012                       case 'W':
4013                         fac *= 7;
4014                         /* fall through */
4015                       case 'd':
4016                       case 'D':
4017                         fac *= 24;
4018                         /* fall through */
4019                       case 'h':
4020                       case 'H':
4021                         fac *= 60;
4022                         /* fall through */
4023                       case 'm':
4024                       case 'M':
4025                         fac *= 60;
4026                         /* fall through */
4027                       case 's':
4028                       case 'S':
4029                         *lastp = 0;
4030                       }
4031                   }
4032                 
4033                 for (cp = arg; *cp; cp++)
4034                   if (isdigit((unsigned char)*cp))
4035                     isdig = 1;
4036                   else if (*cp != ' ')
4037                     break;
4038
4039                 if (*cp)
4040                   {
4041                     if (lastp)
4042                       *lastp = last;
4043                     if (strcmp(arg, "infinite") == 0)
4044                       {
4045                         new->lease_time = 0xffffffff;
4046                         new->flags |= CONFIG_TIME;
4047                       }
4048                     else if (strcmp(arg, "ignore") == 0)
4049                       new->flags |= CONFIG_DISABLE;
4050                     else
4051                       {
4052                         if (!(new->hostname = canonicalise_opt(arg)) ||
4053                             !legal_hostname(new->hostname))
4054                           {
4055                             dhcp_config_free(new);
4056                             ret_err(_("bad DHCP host name"));
4057                           }
4058                         
4059                         new->flags |= CONFIG_NAME;
4060                         new->domain = strip_hostname(new->hostname);                    
4061                       }
4062                   }
4063                 else if (isdig)
4064                   {
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;
4071                   }
4072               }
4073
4074             arg = comma;
4075           }
4076
4077         daemon->dhcp_conf = new;
4078         break;
4079       }
4080       
4081     case LOPT_TAG_IF:  /* --tag-if */
4082       {
4083         struct tag_if *new = opt_malloc(sizeof(struct tag_if));
4084                 
4085         new->tag = NULL;
4086         new->set = NULL;
4087         new->next = NULL;
4088         
4089         /* preserve order */
4090         if (!daemon->tag_if)
4091           daemon->tag_if = new;
4092         else
4093           {
4094             struct tag_if *tmp;
4095             for (tmp = daemon->tag_if; tmp->next; tmp = tmp->next);
4096             tmp->next = new;
4097           }
4098
4099         while (arg)
4100           {
4101             size_t len;
4102
4103             comma = split(arg);
4104             len = strlen(arg);
4105
4106             if (len < 5)
4107               {
4108                 new->set = NULL;
4109                 break;
4110               }
4111             else
4112               {
4113                 struct dhcp_netid *newtag = dhcp_netid_create(arg+4, NULL);
4114
4115                 if (strstr(arg, "set:") == arg)
4116                   {
4117                     struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
4118                     newlist->next = new->set;
4119                     new->set = newlist;
4120                     newlist->list = newtag;
4121                   }
4122                 else if (strstr(arg, "tag:") == arg)
4123                   {
4124                     newtag->next = new->tag;
4125                     new->tag = newtag;
4126                   }
4127                 else 
4128                   {
4129                     new->set = NULL;
4130                     dhcp_netid_free(newtag);
4131                     break;
4132                   }
4133               }
4134             
4135             arg = comma;
4136           }
4137
4138         if (!new->set)
4139           {
4140             dhcp_netid_free(new->tag);
4141             dhcp_netid_list_free(new->set);
4142             ret_err_free(_("bad tag-if"), new);
4143           }
4144           
4145         break;
4146       }
4147
4148       
4149     case 'O':           /* --dhcp-option */
4150     case LOPT_FORCE:    /* --dhcp-option-force */
4151     case LOPT_OPTS:
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)));
4157
4158     case LOPT_NAME_MATCH: /* --dhcp-name-match */
4159       {
4160         struct dhcp_match_name *new;
4161         ssize_t len;
4162         
4163         if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
4164           ret_err(gen_err);
4165
4166         new = opt_malloc(sizeof(struct dhcp_match_name));
4167         new->wildcard = 0;
4168         new->netid = opt_malloc(sizeof(struct dhcp_netid));
4169         new->netid->net = opt_string_alloc(set_prefix(arg));
4170
4171         if (comma[len-1] == '*')
4172           {
4173             comma[len-1] = 0;
4174             new->wildcard = 1;
4175           }
4176         new->name = opt_string_alloc(comma);
4177
4178         new->next = daemon->dhcp_name_match;
4179         daemon->dhcp_name_match = new;
4180
4181         break;
4182       }
4183       
4184     case 'M': /* --dhcp-boot */
4185       {
4186         struct dhcp_netid *id = dhcp_tags(&arg);
4187         
4188         if (!arg)
4189           {
4190             ret_err(gen_err);
4191           }
4192         else 
4193           {
4194             char *dhcp_file, *dhcp_sname = NULL, *tftp_sname = NULL;
4195             struct in_addr dhcp_next_server;
4196             struct dhcp_boot *new;
4197             comma = split(arg);
4198             dhcp_file = opt_string_alloc(arg);
4199             dhcp_next_server.s_addr = 0;
4200             if (comma)
4201               {
4202                 arg = comma;
4203                 comma = split(arg);
4204                 dhcp_sname = opt_string_alloc(arg);
4205                 if (comma)
4206                   {
4207                     unhide_metas(comma);
4208                     if (!(inet_pton(AF_INET, comma, &dhcp_next_server) > 0))
4209                       {
4210                         /*
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().
4214                          */     
4215                         
4216                         tftp_sname = opt_string_alloc(comma);
4217                         dhcp_next_server.s_addr = 0;
4218                       }
4219                   }
4220               }
4221             
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;
4227             new->netid = id;
4228             new->next = daemon->boot_config;
4229             daemon->boot_config = new;
4230           }
4231       
4232         break;
4233       }
4234
4235     case LOPT_REPLY_DELAY: /* --dhcp-reply-delay */
4236       {
4237         struct dhcp_netid *id = dhcp_tags(&arg);
4238         
4239         if (!arg)
4240           {
4241             ret_err(gen_err);
4242           }
4243         else
4244           {
4245             struct delay_config *new;
4246             int delay;
4247             if (!atoi_check(arg, &delay))
4248               ret_err(gen_err);
4249             
4250             new = opt_malloc(sizeof(struct delay_config));
4251             new->delay = delay;
4252             new->netid = id;
4253             new->next = daemon->delay_conf;
4254             daemon->delay_conf = new;
4255           }
4256         
4257         break;
4258       }
4259       
4260     case LOPT_PXE_PROMT:  /* --pxe-prompt */
4261        {
4262          struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt));
4263          int timeout;
4264          
4265          new->netid = NULL;
4266          new->opt = 10; /* PXE_MENU_PROMPT */
4267          new->netid = dhcp_tags(&arg);
4268          
4269          if (!arg)
4270            {
4271              dhcp_opt_free(new);
4272              ret_err(gen_err);
4273            }
4274          else
4275            {
4276              comma = split(arg);
4277              unhide_metas(arg);
4278              new->len = strlen(arg) + 1;
4279              new->val = opt_malloc(new->len);
4280              memcpy(new->val + 1, arg, new->len - 1);
4281              
4282              new->u.vendor_class = NULL;
4283              new->flags = DHOPT_VENDOR | DHOPT_VENDOR_PXE;
4284              
4285              if (comma && atoi_check(comma, &timeout))
4286                *(new->val) = timeout;
4287              else
4288                *(new->val) = 255;
4289
4290              new->next = daemon->dhcp_opts;
4291              daemon->dhcp_opts = new;
4292              daemon->enable_pxe = 1;
4293            }
4294          
4295          break;
4296        }
4297        
4298     case LOPT_PXE_SERV:  /* --pxe-service */
4299        {
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;
4305          
4306          new->netid = NULL;
4307          new->sname = NULL;
4308          new->server.s_addr = 0;
4309          new->netid = dhcp_tags(&arg);
4310
4311          if (arg && (comma = split(arg)))
4312            {
4313              for (i = 0; CSA[i]; i++)
4314                if (strcasecmp(CSA[i], arg) == 0)
4315                  break;
4316              
4317              if (CSA[i] || atoi_check(arg, &i))
4318                {
4319                  arg = comma;
4320                  comma = split(arg);
4321                  
4322                  new->CSA = i;
4323                  new->menu = opt_string_alloc(arg);
4324                  
4325                  if (!comma)
4326                    {
4327                      new->type = 0; /* local boot */
4328                      new->basename = NULL;
4329                    }
4330                  else
4331                    {
4332                      arg = comma;
4333                      comma = split(arg);
4334                      if (atoi_check(arg, &i))
4335                        {
4336                          new->type = i;
4337                          new->basename = NULL;
4338                        }
4339                      else
4340                        {
4341                          new->type = boottype++;
4342                          new->basename = opt_string_alloc(arg);
4343                        }
4344                      
4345                      if (comma)
4346                        {
4347                          if (!inet_pton(AF_INET, comma, &new->server))
4348                            {
4349                              new->server.s_addr = 0;
4350                              new->sname = opt_string_alloc(comma);
4351                            }
4352                        
4353                        }
4354                    }
4355                  
4356                  /* Order matters */
4357                  new->next = NULL;
4358                  if (!daemon->pxe_services)
4359                    daemon->pxe_services = new; 
4360                  else
4361                    {
4362                      struct pxe_service *s;
4363                      for (s = daemon->pxe_services; s->next; s = s->next);
4364                      s->next = new;
4365                    }
4366                  
4367                  daemon->enable_pxe = 1;
4368                  break;
4369                 
4370                }
4371            }
4372          
4373          dhcp_netid_free(new->netid);
4374          free(new);
4375          ret_err(gen_err);
4376        }
4377          
4378     case '4':  /* --dhcp-mac */
4379       {
4380         if (!(comma = split(arg)))
4381           ret_err(gen_err);
4382         else
4383           {
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)
4389               {
4390                 free(new->netid.net);
4391                 ret_err_free(gen_err, new);
4392               }
4393             else
4394               {
4395                 new->next = daemon->dhcp_macs;
4396                 daemon->dhcp_macs = new;
4397               }
4398           }
4399       }
4400       break;
4401
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 */
4407       {
4408          unsigned char *p;
4409          int dig, colon;
4410          struct dhcp_vendor *new = opt_malloc(sizeof(struct dhcp_vendor));
4411          
4412          if (!(comma = split(arg)))
4413            ret_err_free(gen_err, new);
4414         
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. */
4418          
4419          arg = comma;
4420          if ((comma = split(arg)))
4421            {
4422              if (option  != 'U' || strstr(arg, "enterprise:") != arg)
4423                {
4424                  free(new->netid.net);
4425                  ret_err_free(gen_err, new);
4426                }
4427              else
4428                new->enterprise = atoi(arg+11);
4429            }
4430          else
4431            comma = arg;
4432          
4433          for (dig = 0, colon = 0, p = (unsigned char *)comma; *p; p++)
4434            if (isxdigit(*p))
4435              dig = 1;
4436            else if (*p == ':')
4437              colon = 1;
4438            else
4439              break;
4440          
4441          unhide_metas(comma);
4442          if (option == 'U' || option == 'j' || *p || !dig || !colon)
4443            {
4444              new->len = strlen(comma);  
4445              new->data = opt_malloc(new->len);
4446              memcpy(new->data, comma, new->len);
4447            }
4448          else
4449            {
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);
4453            }
4454          
4455          switch (option)
4456            {
4457            case 'j':
4458              new->match_type = MATCH_USER;
4459              break;
4460            case 'U':
4461              new->match_type = MATCH_VENDOR;
4462              break; 
4463            case LOPT_CIRCUIT:
4464              new->match_type = MATCH_CIRCUIT;
4465              break;
4466            case LOPT_REMOTE:
4467              new->match_type = MATCH_REMOTE;
4468              break;
4469            case LOPT_SUBSCR:
4470              new->match_type = MATCH_SUBSCRIBER;
4471              break;
4472            }
4473          new->next = daemon->dhcp_vendors;
4474          daemon->dhcp_vendors = new;
4475
4476          break;
4477       }
4478       
4479     case LOPT_ALTPORT:   /* --dhcp-alternate-port */
4480       if (!arg)
4481         {
4482           daemon->dhcp_server_port = DHCP_SERVER_ALTPORT;
4483           daemon->dhcp_client_port = DHCP_CLIENT_ALTPORT;
4484         }
4485       else
4486         {
4487           comma = split(arg);
4488           if (!atoi_check16(arg, &daemon->dhcp_server_port) || 
4489               (comma && !atoi_check16(comma, &daemon->dhcp_client_port)))
4490             ret_err(_("invalid port number"));
4491           if (!comma)
4492             daemon->dhcp_client_port = daemon->dhcp_server_port+1; 
4493         }
4494       break;
4495
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 */
4501       {
4502         struct dhcp_netid_list *new = opt_malloc(sizeof(struct dhcp_netid_list));
4503         struct dhcp_netid *list = NULL;
4504         if (option == 'J')
4505           {
4506             new->next = daemon->dhcp_ignore;
4507             daemon->dhcp_ignore = new;
4508           }
4509         else if (option == LOPT_BROADCAST)
4510           {
4511             new->next = daemon->force_broadcast;
4512             daemon->force_broadcast = new;
4513           }
4514         else if (option == '3')
4515           {
4516             new->next = daemon->bootp_dynamic;
4517             daemon->bootp_dynamic = new;
4518           }
4519         else if (option == LOPT_GEN_NAMES)
4520           {
4521             new->next = daemon->dhcp_gen_names;
4522             daemon->dhcp_gen_names = new;
4523           }
4524         else
4525           {
4526             new->next = daemon->dhcp_ignore_names;
4527             daemon->dhcp_ignore_names = new;
4528           }
4529         
4530         while (arg) {
4531           comma = split(arg);
4532           list = dhcp_netid_create(is_tag_prefix(arg) ? arg+4 :arg, list);
4533           arg = comma;
4534         }
4535         
4536         new->list = list;
4537         break;
4538       }
4539
4540     case LOPT_PROXY: /* --dhcp-proxy */
4541       daemon->override = 1;
4542       while (arg) {
4543         struct addr_list *new = opt_malloc(sizeof(struct addr_list));
4544         comma = split(arg);
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;
4549         arg = comma;
4550         }
4551           break;
4552
4553     case LOPT_PXE_VENDOR: /* --dhcp-pxe-vendor */
4554       {
4555         while (arg) {
4556           struct dhcp_pxe_vendor *new = opt_malloc(sizeof(struct dhcp_pxe_vendor));
4557           comma = split(arg);
4558           new->data = opt_string_alloc(arg);
4559           new->next = daemon->dhcp_pxe_vendors;
4560           daemon->dhcp_pxe_vendors = new;
4561           arg = comma;
4562         }
4563       }
4564       break;
4565       
4566     case LOPT_RELAY: /* --dhcp-relay */
4567       {
4568         struct dhcp_relay *new = opt_malloc(sizeof(struct dhcp_relay));
4569         char *two = split(arg);
4570         char *three = split(two);
4571         
4572         new->iface_index = 0;
4573
4574         if (two)
4575           {
4576             if (inet_pton(AF_INET, arg, &new->local))
4577               {
4578                 char *hash = split_chr(two, '#');
4579
4580                 if (!hash || !atoi_check16(hash, &new->port))
4581                   new->port = DHCP_SERVER_PORT;
4582                 
4583                 if (!inet_pton(AF_INET, two, &new->server))
4584                   {
4585                     new->server.addr4.s_addr = 0;
4586                                     
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, '*'))
4590                       two = NULL;
4591                     else
4592                       three = two;
4593                   }
4594                 
4595                 new->next = daemon->relay4;
4596                 daemon->relay4 = new;
4597               }
4598 #ifdef HAVE_DHCP6
4599             else if (inet_pton(AF_INET6, arg, &new->local))
4600               {
4601                 char *hash = split_chr(two, '#');
4602
4603                 if (!hash || !atoi_check16(hash, &new->port))
4604                   new->port = DHCPV6_SERVER_PORT;
4605
4606                 if (!inet_pton(AF_INET6, two, &new->server))
4607                   {
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, '*'))
4612                       two = NULL;
4613                     else
4614                       three = two;
4615                   }
4616                 new->next = daemon->relay6;
4617                 daemon->relay6 = new;
4618               }
4619 #endif
4620
4621             new->interface = opt_string_alloc(three);
4622           }
4623         
4624         if (!two)
4625           {
4626             free(new->interface);
4627             ret_err_free(_("Bad dhcp-relay"), new);
4628           }
4629         
4630         break;
4631       }
4632
4633 #endif
4634       
4635 #ifdef HAVE_DHCP6
4636     case LOPT_RA_PARAM: /* --ra-param */
4637       if ((comma = split(arg)))
4638         {
4639           struct ra_interface *new = opt_malloc(sizeof(struct ra_interface));
4640           new->lifetime = -1;
4641           new->prio = 0;
4642           new->mtu = 0;
4643           new->mtu_name = NULL;
4644           new->name = opt_string_alloc(arg);
4645           if (strcasestr(comma, "mtu:") == comma)
4646             {
4647               arg = comma + 4;
4648               if (!(comma = split(comma)))
4649                 goto err;
4650               if (!strcasecmp(arg, "off"))
4651                 new->mtu = -1;
4652               else if (!atoi_check(arg, &new->mtu))
4653                 new->mtu_name = opt_string_alloc(arg);
4654               else if (new->mtu < 1280)
4655                 goto err;
4656             }
4657           if (strcasestr(comma, "high") == comma || strcasestr(comma, "low") == comma)
4658             {
4659               if (*comma == 'l' || *comma == 'L')
4660                 new->prio = 0x18;
4661               else
4662                 new->prio = 0x08;
4663               comma = split(comma);
4664             }
4665            arg = split(comma);
4666            if (!atoi_check(comma, &new->interval) || 
4667               (arg && !atoi_check(arg, &new->lifetime)))
4668              {
4669 err:
4670                free(new->name);
4671                ret_err_free(_("bad RA-params"), new);
4672              }
4673           
4674           new->next = daemon->ra_interfaces;
4675           daemon->ra_interfaces = new;
4676         }
4677       break;
4678       
4679     case LOPT_DUID: /* --dhcp-duid */
4680       if (!(comma = split(arg)) || !atoi_check(arg, (int *)&daemon->duid_enterprise))
4681         ret_err(_("bad DUID"));
4682       else
4683         {
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);
4687         }
4688       break;
4689 #endif
4690
4691     case 'V':  /* --alias */
4692       {
4693         char *dash, *a[3] = { NULL, NULL, NULL };
4694         int k = 0;
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;
4700
4701         if ((a[0] = arg))
4702           for (k = 1; k < 3; k++)
4703             {
4704               if (!(a[k] = split(a[k-1])))
4705                 break;
4706               unhide_metas(a[k]);
4707             }
4708         
4709         dash = split_chr(a[0], '-');
4710
4711         if ((k < 2) || 
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"));
4716         
4717         if (dash && 
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);
4722         
4723         break;
4724       }
4725       
4726     case LOPT_INTNAME:  /* --interface-name */
4727     case LOPT_DYNHOST:  /* --dynamic-host */
4728       {
4729         struct interface_name *new, **up;
4730         char *domain = arg;
4731         
4732         arg = split(arg);
4733         
4734         new = opt_malloc(sizeof(struct interface_name));
4735         memset(new, 0, sizeof(struct interface_name));
4736         new->flags = IN4 | IN6;
4737         
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));
4741         *up = new;
4742         
4743         while ((comma = split(arg)))
4744           {
4745             if (inet_pton(AF_INET, arg, &new->proto4))
4746               new->flags |= INP4;
4747             else if (inet_pton(AF_INET6, arg, &new->proto6))
4748               new->flags |= INP6;
4749             else
4750               break;
4751             
4752             arg = comma;
4753           }
4754
4755         if ((comma = split_chr(arg, '/')))
4756           {
4757             if (strcmp(comma, "4") == 0)
4758               new->flags &= ~IN6;
4759             else if (strcmp(comma, "6") == 0)
4760               new->flags &= ~IN4;
4761             else
4762               ret_err_free(gen_err, new);
4763           }
4764
4765         new->intr = opt_string_alloc(arg);
4766
4767         if (option == LOPT_DYNHOST)
4768           {
4769             if (!(new->flags & (INP4 | INP6)))
4770               ret_err(_("missing address in dynamic host"));
4771
4772             if (!(new->flags & IN4) || !(new->flags & IN6))
4773               arg = NULL; /* provoke error below */
4774
4775             new->flags &= ~(IN4 | IN6);
4776           }
4777         else
4778           {
4779             if (new->flags & (INP4 | INP6))
4780               arg = NULL; /* provoke error below */
4781           }
4782         
4783         if (!domain || !arg || !(new->name = canonicalise_opt(domain)))
4784           ret_err(option == LOPT_DYNHOST ?
4785                   _("bad dynamic host") : _("bad interface name"));
4786         
4787         break;
4788       }
4789       
4790     case LOPT_CNAME: /* --cname */
4791       {
4792         struct cname *new;
4793         char *alias, *target=NULL, *last, *pen;
4794         int ttl = -1;
4795
4796         for (last = pen = NULL, comma = arg; comma; comma = split(comma))
4797           {
4798             pen = last;
4799             last = comma;
4800           }
4801
4802         if (!pen)
4803           ret_err(_("bad CNAME"));
4804         
4805         if (pen != arg && atoi_check(last, &ttl))
4806           last = pen;
4807                 
4808         while (arg != last)
4809           {
4810             int arglen = strlen(arg);
4811             alias = canonicalise_opt(arg);
4812
4813             if (!target)
4814               target = canonicalise_opt(last);
4815             if (!alias || !target)
4816               {
4817                 free(target);
4818                 free(alias);
4819                 ret_err(_("bad CNAME"));
4820               }
4821             
4822             for (new = daemon->cnames; new; new = new->next)
4823               if (hostname_isequal(new->alias, alias))
4824                 {
4825                   free(target);
4826                   free(alias);
4827                   ret_err(_("duplicate CNAME"));
4828                 }
4829             new = opt_malloc(sizeof(struct cname));
4830             new->next = daemon->cnames;
4831             daemon->cnames = new;
4832             new->alias = alias;
4833             new->target = target;
4834             new->ttl = ttl;
4835
4836             for (arg += arglen+1; *arg && isspace(*arg); arg++);
4837           }
4838       
4839         break;
4840       }
4841
4842     case LOPT_PTR:  /* --ptr-record */
4843       {
4844         struct ptr_record *new;
4845         char *dom, *target = NULL;
4846
4847         comma = split(arg);
4848         
4849         if (!(dom = canonicalise_opt(arg)) ||
4850             (comma && !(target = canonicalise_opt(comma))))
4851           {
4852             free(dom);
4853             free(target);
4854             ret_err(_("bad PTR record"));
4855           }
4856         else
4857           {
4858             new = opt_malloc(sizeof(struct ptr_record));
4859             new->next = daemon->ptr;
4860             daemon->ptr = new;
4861             new->name = dom;
4862             new->ptr = target;
4863           }
4864         break;
4865       }
4866
4867     case LOPT_NAPTR: /* --naptr-record */
4868       {
4869         char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
4870         int k = 0;
4871         struct naptr *new;
4872         int order, pref;
4873         char *name=NULL, *replace = NULL;
4874
4875         if ((a[0] = arg))
4876           for (k = 1; k < 7; k++)
4877             if (!(a[k] = split(a[k-1])))
4878               break;
4879         
4880         
4881         if (k < 6 || 
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]))))
4886           {
4887             free(name);
4888             free(replace);
4889             ret_err(_("bad NAPTR record"));
4890           }
4891         else
4892           {
4893             new = opt_malloc(sizeof(struct naptr));
4894             new->next = daemon->naptr;
4895             daemon->naptr = new;
4896             new->name = name;
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;
4901             new->order = order;
4902             new->pref = pref;
4903           }
4904         break;
4905       }
4906
4907     case LOPT_RR: /* dns-rr */
4908       {
4909         struct txt_record *new;
4910         size_t len = 0;
4911         char *data;
4912         int class;
4913
4914         comma = split(arg);
4915         data = split(comma);
4916                 
4917         new = opt_malloc(sizeof(struct txt_record));
4918         new->name = NULL;
4919         
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))
4923           {
4924             free(new->name);
4925             ret_err_free(_("bad RR record"), new);
4926           }
4927
4928         new->len = 0;
4929         new->class = class;
4930         new->next = daemon->rr;
4931         daemon->rr = new;
4932         
4933         if (data)
4934           {
4935             new->txt = opt_malloc(len);
4936             new->len = len;
4937             memcpy(new->txt, data, len);
4938           }
4939         
4940         break;
4941       }
4942
4943     case LOPT_CAA: /* --caa-record */
4944       {
4945         struct txt_record *new;
4946         char *tag, *value;
4947         int flags;
4948         
4949         comma = split(arg);
4950         tag = split(comma);
4951         value = split(tag);
4952         
4953         new = opt_malloc(sizeof(struct txt_record));
4954         new->next = daemon->rr;
4955         daemon->rr = new;
4956
4957         if (!atoi_check(comma, &flags) || !tag || !value || !(new->name = canonicalise_opt(arg)))
4958           ret_err(_("bad CAA record"));
4959         
4960         unhide_metas(tag);
4961         unhide_metas(value);
4962
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));
4969         new->class = T_CAA;
4970         
4971         break;
4972       }
4973         
4974     case 'Y':  /* --txt-record */
4975       {
4976         struct txt_record *new;
4977         unsigned char *p, *cnt;
4978         size_t len;
4979
4980         comma = split(arg);
4981                 
4982         new = opt_malloc(sizeof(struct txt_record));
4983         new->class = C_IN;
4984         new->stat = 0;
4985
4986         if (!(new->name = canonicalise_opt(arg)))
4987           ret_err_free(_("bad TXT record"), new);
4988         
4989         new->next = daemon->txt;
4990         daemon->txt = new;
4991         len = comma ? strlen(comma) : 0;
4992         len += (len/255) + 1; /* room for extra counts */
4993         new->txt = p = opt_malloc(len);
4994
4995         cnt = p++;
4996         *cnt = 0;
4997         
4998         while (comma && *comma)
4999           {
5000             unsigned char c = (unsigned char)*comma++;
5001
5002             if (c == ',' || *cnt == 255)
5003               {
5004                 if (c != ',')
5005                   comma--;
5006                 cnt = p++;
5007                 *cnt = 0;
5008               }
5009             else
5010               {
5011                 *p++ = unhide_meta(c);
5012                 (*cnt)++;
5013               }
5014           }
5015
5016         new->len = p - new->txt;
5017
5018         break;
5019       }
5020       
5021     case 'W':  /* --srv-host */
5022       {
5023         int port = 1, priority = 0, weight = 0;
5024         char *name, *target = NULL;
5025         struct mx_srv_record *new;
5026         
5027         comma = split(arg);
5028         
5029         if (!(name = canonicalise_opt(arg)))
5030           ret_err(_("bad SRV record"));
5031         
5032         if (comma)
5033           {
5034             arg = comma;
5035             comma = split(arg);
5036             if (!(target = canonicalise_opt(arg)))
5037               ret_err_free(_("bad SRV target"), name);
5038                 
5039             if (comma)
5040               {
5041                 arg = comma;
5042                 comma = split(arg);
5043                 if (!atoi_check16(arg, &port))
5044                   {
5045                     free(name);
5046                     ret_err_free(_("invalid port number"), target);
5047                   }
5048                 
5049                 if (comma)
5050                   {
5051                     arg = comma;
5052                     comma = split(arg);
5053                     if (!atoi_check16(arg, &priority))
5054                       {
5055                         free(name);
5056                         ret_err_free(_("invalid priority"), target);
5057                       }
5058                     if (comma && !atoi_check16(comma, &weight))
5059                       {
5060                         free(name);
5061                         ret_err_free(_("invalid weight"), target);
5062                       }
5063                   }
5064               }
5065           }
5066         
5067         new = opt_malloc(sizeof(struct mx_srv_record));
5068         new->next = daemon->mxnames;
5069         daemon->mxnames = new;
5070         new->issrv = 1;
5071         new->name = name;
5072         new->target = target;
5073         new->srvport = port;
5074         new->priority = priority;
5075         new->weight = weight;
5076         break;
5077       }
5078       
5079     case LOPT_HOST_REC: /* --host-record */
5080       {
5081         struct host_record *new;
5082
5083         if (!arg || !(comma = split(arg)))
5084           ret_err(_("Bad host-record"));
5085         
5086         new = opt_malloc(sizeof(struct host_record));
5087         memset(new, 0, sizeof(struct host_record));
5088         new->ttl = -1;
5089         new->flags = 0;
5090
5091         while (arg)
5092           {
5093             union all_addr addr;
5094             char *dig;
5095
5096             for (dig = arg; *dig != 0; dig++)
5097               if (*dig < '0' || *dig > '9')
5098                 break;
5099             if (*dig == 0)
5100               new->ttl = atoi(arg);
5101             else if (inet_pton(AF_INET, arg, &addr.addr4))
5102               {
5103                 new->addr = addr.addr4;
5104                 new->flags |= HR_4;
5105               }
5106             else if (inet_pton(AF_INET6, arg, &addr.addr6))
5107               {
5108                 new->addr6 = addr.addr6;
5109                 new->flags |= HR_6;
5110               }
5111             else
5112               {
5113                 char *canon = canonicalise_opt(arg);
5114                 struct name_list *nl;
5115                 if (!canon)
5116                   {
5117                     struct name_list *tmp, *next;
5118                     for (tmp = new->names; tmp; tmp = next)
5119                       {
5120                         next = tmp->next;
5121                         free(tmp);
5122                       }
5123                     ret_err_free(_("Bad name in host-record"), new);
5124                   }
5125
5126                 nl = opt_malloc(sizeof(struct name_list));
5127                 nl->name = canon;
5128                 /* keep order, so that PTR record goes to first name */
5129                 nl->next = NULL;
5130                 if (!new->names)
5131                   new->names = nl;
5132                 else
5133                   { 
5134                     struct name_list *tmp;
5135                     for (tmp = new->names; tmp->next; tmp = tmp->next);
5136                     tmp->next = nl;
5137                   }
5138               }
5139             
5140             arg = comma;
5141             comma = split(arg);
5142           }
5143
5144         /* Keep list order */
5145         if (!daemon->host_records_tail)
5146           daemon->host_records = new;
5147         else
5148           daemon->host_records_tail->next = new;
5149         new->next = NULL;
5150         daemon->host_records_tail = new;
5151         break;
5152       }
5153
5154     case LOPT_STALE_CACHE:
5155       {
5156         int max_expiry = STALE_CACHE_EXPIRY;
5157         if (arg)
5158           {
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)
5162               ret_err(gen_err);
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)
5166               max_expiry = -1;
5167           }
5168         daemon->cache_max_expiry = max_expiry;
5169         break;
5170       }
5171
5172 #ifdef HAVE_DNSSEC
5173     case LOPT_DNSSEC_STAMP: /* --dnssec-timestamp */
5174       daemon->timestamp_file = opt_string_alloc(arg); 
5175       break;
5176
5177     case LOPT_DNSSEC_CHECK: /* --dnssec-check-unsigned */
5178       if (arg)
5179         {
5180           if (strcmp(arg, "no") == 0)
5181             set_option_bool(OPT_DNSSEC_IGN_NS);
5182           else
5183             ret_err(_("bad value for dnssec-check-unsigned"));
5184         }
5185       break;
5186       
5187     case LOPT_TRUST_ANCHOR: /* --trust-anchor */
5188       {
5189         struct ds_config *new = opt_malloc(sizeof(struct ds_config));
5190         char *cp, *cp1, *keyhex, *digest, *algo = NULL;
5191         int len;
5192         
5193         new->class = C_IN;
5194         new->name = NULL;
5195
5196         if ((comma = split(arg)) && (algo = split(comma)))
5197           {
5198             int class = 0;
5199             if (strcmp(comma, "IN") == 0)
5200               class = C_IN;
5201             else if (strcmp(comma, "CH") == 0)
5202               class = C_CHAOS;
5203             else if (strcmp(comma, "HS") == 0)
5204               class = C_HESIOD;
5205             
5206             if (class != 0)
5207               {
5208                 new->class = class;
5209                 comma = algo;
5210                 algo = split(comma);
5211               }
5212           }
5213                   
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);
5220             
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; )
5227           if (isspace(*cp))
5228             for (cp1 = cp; *cp1; cp1++)
5229               *cp1 = *(cp1+1);
5230           else
5231             cp++;
5232         if ((new->digestlen = parse_hex(keyhex, (unsigned char *)new->digest, len, NULL, NULL)) == -1)
5233           {
5234             free(new->name);
5235             ret_err_free(_("bad HEX in trust anchor"), new);
5236           }
5237         
5238         new->next = daemon->ds;
5239         daemon->ds = new;
5240         
5241         break;
5242       }
5243 #endif
5244                 
5245     default:
5246       ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"));
5247       
5248     }
5249   
5250   return 1;
5251 }
5252
5253 static void read_file(char *file, FILE *f, int hard_opt, int from_script)       
5254 {
5255   volatile int lineno = 0;
5256   char *buff = daemon->namebuff;
5257   
5258   while (fgets(buff, MAXDNAME, f))
5259     {
5260       int white, i;
5261       volatile int option;
5262       char *errmess, *p, *arg, *start;
5263       size_t len;
5264
5265       option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt;
5266
5267       /* Memory allocation failure longjmps here if mem_recover == 1 */ 
5268       if (option != 0 || hard_opt == LOPT_REV_SERV)
5269         {
5270           if (setjmp(mem_jmp))
5271             continue;
5272           mem_recover = 1;
5273         }
5274
5275       arg = NULL;
5276       lineno++;
5277       errmess = NULL;
5278       
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++)
5282         {
5283           if (*p == '"')
5284             {
5285               memmove(p, p+1, strlen(p+1)+1);
5286
5287               for(; *p && *p != '"'; p++)
5288                 {
5289                   if (*p == '\\' && strchr("\"tnebr\\", p[1]))
5290                     {
5291                       if (p[1] == 't')
5292                         p[1] = '\t';
5293                       else if (p[1] == 'n')
5294                         p[1] = '\n';
5295                       else if (p[1] == 'b')
5296                         p[1] = '\b';
5297                       else if (p[1] == 'r')
5298                         p[1] = '\r';
5299                       else if (p[1] == 'e') /* escape */
5300                         p[1] = '\033';
5301                       memmove(p, p+1, strlen(p+1)+1);
5302                     }
5303                   *p = hide_meta(*p);
5304                 }
5305
5306               if (*p == 0) 
5307                 {
5308                   errmess = _("missing \"");
5309                   goto oops; 
5310                 }
5311
5312               memmove(p, p+1, strlen(p+1)+1);
5313             }
5314
5315           if (isspace(*p))
5316             {
5317               *p = ' ';
5318               white = 1;
5319             }
5320           else 
5321             {
5322               if (white && *p == '#')
5323                 { 
5324                   *p = 0;
5325                   break;
5326                 }
5327               white = 0;
5328             } 
5329         }
5330
5331       
5332       /* strip leading spaces */
5333       for (start = buff; *start && *start == ' '; start++);
5334       
5335       /* strip trailing spaces */
5336       for (len = strlen(start); (len != 0) && (start[len-1] == ' '); len--);
5337       
5338       if (len == 0)
5339         continue; 
5340       else
5341         start[len] = 0;
5342       
5343       if (option != 0)
5344         arg = start;
5345       else if ((p=strchr(start, '=')))
5346         {
5347           /* allow spaces around "=" */
5348           for (arg = p+1; *arg == ' '; arg++);
5349           for (; p >= start && (*p == ' ' || *p == '='); p--)
5350             *p = 0;
5351         }
5352       else
5353         arg = NULL;
5354
5355       if (option == 0)
5356         {
5357           for (option = 0, i = 0; opts[i].name; i++) 
5358             if (strcmp(opts[i].name, start) == 0)
5359               {
5360                 option = opts[i].val;
5361                 break;
5362               }
5363           
5364           if (!option)
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");
5372         }
5373
5374     oops:
5375       if (errmess)
5376         strcpy(daemon->namebuff, errmess);
5377           
5378       if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt == LOPT_REV_SERV))
5379         {
5380           if (from_script)
5381             sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" in output from %s"), file);
5382           else
5383             sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file);
5384           
5385           if (hard_opt != 0)
5386             my_syslog(LOG_ERR, "%s", daemon->namebuff);
5387           else
5388             die("%s", daemon->namebuff, EC_BADCONF);
5389         }
5390     }
5391
5392   mem_recover = 0;
5393 }
5394
5395 #if defined(HAVE_DHCP) && defined(HAVE_INOTIFY)
5396 int option_read_dynfile(char *file, int flags)
5397 {
5398   my_syslog(MS_DHCP | LOG_INFO, _("read %s"), file);
5399   
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);
5404   
5405   return 0;
5406 }
5407 #endif
5408
5409 static int one_file(char *file, int hard_opt)
5410 {
5411   FILE *f;
5412   int nofile_ok = 0, do_popen = 0;
5413   static int read_stdin = 0;
5414   static struct fileread {
5415     dev_t dev;
5416     ino_t ino;
5417     struct fileread *next;
5418   } *filesread = NULL;
5419   
5420   if (hard_opt == LOPT_CONF_OPT)
5421     {
5422       /* default conf-file reading */
5423       hard_opt = 0;
5424       nofile_ok = 1;
5425     }
5426
5427    if (hard_opt == LOPT_CONF_SCRIPT)
5428      {
5429        hard_opt = 0;
5430        do_popen = 1;
5431      }
5432    
5433    if (hard_opt == 0 && !do_popen && strcmp(file, "-") == 0)
5434     {
5435       if (read_stdin == 1)
5436         return 1;
5437       read_stdin = 1;
5438       file = "stdin";
5439       f = stdin;
5440     }
5441   else
5442     {
5443       /* ignore repeated files. */
5444       struct stat statbuf;
5445     
5446       if (hard_opt == 0 && stat(file, &statbuf) == 0)
5447         {
5448           struct fileread *r;
5449           
5450           for (r = filesread; r; r = r->next)
5451             if (r->dev == statbuf.st_dev && r->ino == statbuf.st_ino)
5452               return 1;
5453           
5454           r = safe_malloc(sizeof(struct fileread));
5455           r->next = filesread;
5456           filesread = r;
5457           r->dev = statbuf.st_dev;
5458           r->ino = statbuf.st_ino;
5459         }
5460
5461       if (do_popen)
5462         {
5463           if (!(f = popen(file, "r")))
5464             die(_("cannot execute %s: %s"), file, EC_FILE);
5465         }
5466       else if (!(f = fopen(file, "r")))
5467         {   
5468           if (errno == ENOENT && nofile_ok)
5469             return 1; /* No conffile, all done. */
5470           else
5471             {
5472               char *str = _("cannot read %s: %s");
5473               if (hard_opt != 0)
5474                 {
5475                   my_syslog(LOG_ERR, str, file, strerror(errno));
5476                   return 0;
5477                 }
5478               else
5479                 die(str, file, EC_FILE);
5480             }
5481         } 
5482     }
5483   
5484    read_file(file, f, hard_opt, do_popen);
5485
5486   if (do_popen)
5487     {
5488       int rc;
5489
5490       if ((rc = pclose(f)) == -1)
5491         die(_("error executing %s: %s"), file, EC_MISC);
5492
5493       if (rc != 0)
5494         die(_("%s returns non-zero error code"), file, rc+10);
5495     }
5496   else
5497     fclose(f);
5498         
5499   return 1;
5500 }
5501
5502 static int file_filter(const struct dirent *ent)
5503 {
5504   size_t lenfile = strlen(ent->d_name);
5505
5506   /* ignore emacs backups and dotfiles */
5507
5508   if (lenfile == 0 || 
5509       ent->d_name[lenfile - 1] == '~' ||
5510       (ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
5511       ent->d_name[0] == '.')
5512     return 0;
5513
5514   return 1;
5515 }
5516 /* expand any name which is a directory */
5517 struct hostsfile *expand_filelist(struct hostsfile *list)
5518 {
5519   unsigned int i;
5520   int entcnt, n;
5521   struct hostsfile *ah, *last, *next, **up;
5522   struct dirent **namelist;
5523
5524   /* find largest used index */
5525   for (i = SRC_AH, ah = list; ah; ah = ah->next)
5526     {
5527       last = ah;
5528       
5529       if (i <= ah->index)
5530         i = ah->index + 1;
5531
5532       if (ah->flags & AH_DIR)
5533         ah->flags |= AH_INACTIVE;
5534       else
5535         ah->flags &= ~AH_INACTIVE;
5536     }
5537
5538   for (ah = list; ah; ah = ah->next)
5539     if (!(ah->flags & AH_INACTIVE))
5540       {
5541         struct stat buf;
5542         if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
5543           {
5544             struct dirent *ent;
5545             
5546             /* don't read this as a file */
5547             ah->flags |= AH_INACTIVE;
5548             
5549             entcnt = scandir(ah->fname, &namelist, file_filter, alphasort);
5550             if (entcnt < 0)
5551               my_syslog(LOG_ERR, _("cannot access directory %s: %s"), 
5552                         ah->fname, strerror(errno));
5553             else
5554               {
5555                 for (n = 0; n < entcnt; n++)
5556                   {
5557                     ent = namelist[n];
5558                     size_t lendir = strlen(ah->fname);
5559                     size_t lenfile = strlen(ent->d_name);
5560                     struct hostsfile *ah1;
5561                     char *path;
5562                     
5563                     /* see if we have an existing record.
5564                        dir is ah->fname 
5565                        file is ent->d_name
5566                        path to match is ah1->fname */
5567                     
5568                     for (up = &list, ah1 = list; ah1; ah1 = next)
5569                       {
5570                         next = ah1->next;
5571
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)
5576                           {
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. */
5580                             if (last != ah1)
5581                               *up = next;
5582                             break;
5583                           }
5584
5585                         up = &ah1->next;
5586                       }
5587                     
5588                     /* make new record */
5589                     if (!ah1)
5590                       {
5591                         if (!(ah1 = whine_malloc(sizeof(struct hostsfile))))
5592                           continue;
5593                         
5594                         if (!(path = whine_malloc(lendir + lenfile + 2)))
5595                           {
5596                             free(ah1);
5597                             continue;
5598                           }
5599                         
5600                         strcpy(path, ah->fname);
5601                         strcat(path, "/");
5602                         strcat(path, ent->d_name);
5603                         ah1->fname = path;
5604                         ah1->index = i++;
5605                         ah1->flags = AH_DIR;
5606                       }
5607
5608                     /* Edge case, may be the last in the list anyway */
5609                     if (last != ah1)
5610                       last->next = ah1;
5611                     ah1->next = NULL;
5612                     last = ah1;
5613                     
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; 
5617                     
5618                   }
5619               }
5620             free(namelist);
5621           }
5622       }
5623   
5624   return list;
5625 }
5626
5627 void read_servers_file(void)
5628 {
5629   FILE *f;
5630
5631   if (!(f = fopen(daemon->servers_file, "r")))
5632     {
5633        my_syslog(LOG_ERR, _("cannot read %s: %s"), daemon->servers_file, strerror(errno));
5634        return;
5635     }
5636   
5637   mark_servers(SERV_FROM_FILE);
5638   read_file(daemon->servers_file, f, LOPT_REV_SERV, 0);
5639   fclose(f);
5640   cleanup_servers();
5641   check_servers(0);
5642 }
5643  
5644
5645 #ifdef HAVE_DHCP
5646 static void clear_dynamic_conf(void)
5647 {
5648   struct dhcp_config *configs, *cp, **up;
5649   
5650   /* remove existing... */
5651   for (up = &daemon->dhcp_conf, configs = daemon->dhcp_conf; configs; configs = cp)
5652     {
5653       cp = configs->next;
5654       
5655       if (configs->flags & CONFIG_BANK)
5656         {
5657           *up = cp;
5658           dhcp_config_free(configs);
5659         }
5660       else
5661         up = &configs->next;
5662     }
5663 }
5664
5665 static void clear_dynamic_opt(void)
5666 {
5667   struct dhcp_opt *opts, *cp, **up;
5668
5669   for (up = &daemon->dhcp_opts, opts = daemon->dhcp_opts; opts; opts = cp)
5670     {
5671       cp = opts->next;
5672       
5673       if (opts->flags & DHOPT_BANK)
5674         {
5675           *up = cp;
5676           dhcp_opt_free(opts);
5677         }
5678       else
5679         up = &opts->next;
5680     }
5681 }
5682
5683 void reread_dhcp(void)
5684 {
5685    struct hostsfile *hf;
5686
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. */
5690    
5691    clear_dynamic_conf();
5692    clear_dynamic_opt();
5693
5694    if (daemon->dhcp_hosts_file)
5695     {
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))
5699           {
5700             if (one_file(hf->fname, LOPT_BANK))  
5701               my_syslog(MS_DHCP | LOG_INFO, _("read %s"), hf->fname);
5702           }
5703     }
5704
5705   if (daemon->dhcp_opts_file)
5706     {
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))
5710           {
5711             if (one_file(hf->fname, LOPT_OPTS))  
5712               my_syslog(MS_DHCP | LOG_INFO, _("read %s"), hf->fname);
5713           }
5714     }
5715
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);
5719 #  endif
5720 }
5721 #endif
5722
5723 void read_opts(int argc, char **argv, char *compile_opts)
5724 {
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;
5730       
5731   opterr = 0;
5732
5733   daemon = opt_malloc(sizeof(struct daemon));
5734   memset(daemon, 0, sizeof(struct daemon));
5735   daemon->namebuff = buff;
5736   daemon->addrbuff = safe_malloc(ADDRSTRLEN);
5737   
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;
5759   
5760 #ifndef NO_ID
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);
5769 #ifdef HAVE_AUTH
5770   add_txt("auth.bind", NULL, TXT_STAT_AUTH);
5771 #endif
5772   add_txt("servers.bind", NULL, TXT_STAT_SERVERS);
5773 #endif
5774   
5775   /* See comment above make_servers(). Optimises server-read code. */
5776   mark_servers(0);
5777   
5778   while (1) 
5779     {
5780 #ifdef HAVE_GETOPT_LONG
5781       option = getopt_long(argc, argv, OPTSTRING, opts, NULL);
5782 #else
5783       option = getopt(argc, argv, OPTSTRING);
5784 #endif
5785       
5786       if (option == -1)
5787         {
5788           for (; optind < argc; optind++)
5789             {
5790               unsigned char *c = (unsigned char *)argv[optind];
5791               for (; *c != 0; c++)
5792                 if (!isspace(*c))
5793                   die(_("junk found in command line"), NULL, EC_BADCONF);
5794             }
5795           break;
5796         }
5797
5798       /* Copy optarg so that argv doesn't get changed */
5799       if (optarg)
5800         {
5801           if (strlen(optarg) >= argbuf_size)
5802             {
5803               free(argbuf);
5804               argbuf_size = strlen(optarg) + 1;
5805               argbuf = opt_malloc(argbuf_size);
5806             }
5807           safe_strncpy(argbuf, optarg, argbuf_size);
5808           arg = argbuf;
5809         }
5810       else
5811         arg = NULL;
5812       
5813       /* command-line only stuff */
5814       if (option == LOPT_TEST)
5815         testmode = 1;
5816       else if (option == 'w')
5817         {
5818 #ifdef HAVE_DHCP
5819           if (argc == 3 && strcmp(argv[2], "dhcp") == 0)
5820             display_opts();
5821 #ifdef HAVE_DHCP6
5822           else if (argc == 3 && strcmp(argv[2], "dhcp6") == 0)
5823             display_opts6();
5824 #endif
5825           else
5826 #endif
5827             do_usage();
5828
5829           exit(0);
5830         }
5831       else if (option == 'v')
5832         {
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"));
5838           exit(0);
5839         }
5840       else if (option == 'C')
5841         {
5842           if (!conffile)
5843             conffile = opt_string_alloc(arg);
5844           else
5845             {
5846               char *extra = opt_string_alloc(arg);
5847               one_file(extra, 0);
5848               free(extra);
5849             }
5850         }
5851       else
5852         {
5853 #ifdef HAVE_GETOPT_LONG
5854           if (!one_opt(option, arg, daemon->namebuff, _("try --help"), 1, 0))
5855 #else 
5856             if (!one_opt(option, arg, daemon->namebuff, _("try -w"), 1, 0)) 
5857 #endif  
5858             die(_("bad command line options: %s"), daemon->namebuff, EC_BADCONF);
5859         }
5860     }
5861
5862   free(argbuf);
5863
5864   if (conffile)
5865     {
5866       one_file(conffile, 0);
5867       free(conffile);
5868     }
5869   else
5870     one_file(CONFFILE, LOPT_CONF_OPT);
5871
5872   /* port might not be known when the address is parsed - fill in here */
5873   if (daemon->servers)
5874     {
5875       struct server *tmp;
5876       for (tmp = daemon->servers; tmp; tmp = tmp->next)
5877         if (!(tmp->flags & SERV_HAS_SOURCE))
5878           {
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);
5883           }
5884     } 
5885   
5886   if (daemon->host_records)
5887     {
5888       struct host_record *hr;
5889       
5890       for (hr = daemon->host_records; hr; hr = hr->next)
5891         if (hr->ttl == -1)
5892           hr->ttl = daemon->local_ttl;
5893     }
5894
5895   if (daemon->cnames)
5896     {
5897       struct cname *cn, *cn2, *cn3;
5898
5899 #define NOLOOP 1
5900 #define TESTLOOP 2      
5901
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)
5905         {
5906           if (cn->ttl == -1)
5907             cn->ttl = daemon->local_ttl;
5908           cn->flag = 0;
5909           cn->targetp = NULL;
5910           for (cn2 = daemon->cnames; cn2; cn2 = cn2->next)
5911             if (hostname_isequal(cn->target, cn2->alias))
5912               {
5913                 cn->targetp = cn2;
5914                 break;
5915               }
5916         }
5917       
5918       /* Find any CNAME loops.*/
5919       for (cn = daemon->cnames; cn; cn = cn->next)
5920         {
5921           for (cn2 = cn->targetp; cn2; cn2 = cn2->targetp)
5922             {
5923               if (cn2->flag == NOLOOP)
5924                 break;
5925               
5926               if (cn2->flag == TESTLOOP)
5927                 die(_("CNAME loop involving %s"), cn->alias, EC_BADCONF);
5928               
5929               cn2->flag = TESTLOOP;
5930             }
5931           
5932           for (cn3 = cn->targetp; cn3 != cn2; cn3 = cn3->targetp)
5933             cn3->flag = NOLOOP;
5934         }
5935     }
5936
5937   if (daemon->if_addrs)
5938     {  
5939       struct iname *tmp;
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);
5945     }
5946         
5947   /* create default, if not specified */
5948   if (daemon->authserver && !daemon->hostmaster)
5949     {
5950       strcpy(buff, "hostmaster.");
5951       strcat(buff, daemon->authserver);
5952       daemon->hostmaster = opt_string_alloc(buff);
5953     }
5954
5955   if (!daemon->dhcp_pxe_vendors)
5956     {
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;
5960     }
5961   
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)
5964     {
5965       struct mx_srv_record *mx;
5966       
5967       if (gethostname(buff, MAXDNAME) == -1)
5968         die(_("cannot get host-name: %s"), NULL, EC_MISC);
5969       
5970       for (mx = daemon->mxnames; mx; mx = mx->next)
5971         if (!mx->issrv && hostname_isequal(mx->name, buff))
5972           break;
5973       
5974       if ((daemon->mxtarget || option_bool(OPT_LOCALMX)) && !mx)
5975         {
5976           mx = opt_malloc(sizeof(struct mx_srv_record));
5977           mx->next = daemon->mxnames;
5978           mx->issrv = 0;
5979           mx->target = NULL;
5980           mx->name = opt_string_alloc(buff);
5981           daemon->mxnames = mx;
5982         }
5983       
5984       if (!daemon->mxtarget)
5985         daemon->mxtarget = opt_string_alloc(buff);
5986
5987       for (mx = daemon->mxnames; mx; mx = mx->next)
5988         if (!mx->issrv && !mx->target)
5989           mx->target = daemon->mxtarget;
5990     }
5991
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);
5997   
5998   if (option_bool(OPT_RESOLV_DOMAIN))
5999     {
6000       char *line;
6001       FILE *f;
6002
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);
6007       
6008       if (!(f = fopen((daemon->resolv_files)->name, "r")))
6009         die(_("failed to read %s: %s"), (daemon->resolv_files)->name, EC_FILE);
6010       
6011       while ((line = fgets(buff, MAXDNAME, f)))
6012         {
6013           char *token = strtok(line, " \t\n\r");
6014           
6015           if (!token || strcmp(token, "search") != 0)
6016             continue;
6017           
6018           if ((token = strtok(NULL, " \t\n\r")) &&  
6019               (daemon->domain_suffix = canonicalise_opt(token)))
6020             break;
6021         }
6022
6023       fclose(f);
6024
6025       if (!daemon->domain_suffix)
6026         die(_("no search directive found in %s"), (daemon->resolv_files)->name, EC_MISC);
6027     }
6028
6029   if (daemon->domain_suffix)
6030     {
6031        /* add domain for any srv record without one. */
6032       struct mx_srv_record *srv;
6033       
6034       for (srv = daemon->mxnames; srv; srv = srv->next)
6035         if (srv->issrv &&
6036             strchr(srv->name, '.') && 
6037             strchr(srv->name, '.') == strrchr(srv->name, '.'))
6038           {
6039             strcpy(buff, srv->name);
6040             strcat(buff, ".");
6041             strcat(buff, daemon->domain_suffix);
6042             free(srv->name);
6043             srv->name = opt_string_alloc(buff);
6044           }
6045     }
6046   else if (option_bool(OPT_DHCP_FQDN))
6047     die(_("there must be a default domain when --dhcp-fqdn is set"), NULL, EC_BADCONF);
6048
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); 
6053
6054   if (testmode)
6055     {
6056       fprintf(stderr, "dnsmasq: %s.\n", _("syntax check OK"));
6057       exit(0);
6058     }
6059 }