blob: f657a08d04d9ab4f45a2024483a69490f8033072 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* dnsmasq is Copyright (c) 2000-2021 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
22static volatile int mem_recover = 0;
23static jmp_buf mem_jmp;
24static int one_file(char *file, int hard_opt);
25
26/* Solaris headers don't have facility names. */
27#ifdef HAVE_SOLARIS_NETWORK
28static 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
56struct 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
178#ifdef HAVE_GETOPT_LONG
179static const struct option opts[] =
180#else
181static const struct myoption opts[] =
182#endif
183 {
184 { "version", 0, 0, 'v' },
185 { "no-hosts", 0, 0, 'h' },
186 { "no-poll", 0, 0, 'n' },
187 { "help", 0, 0, 'w' },
188 { "no-daemon", 0, 0, 'd' },
189 { "log-queries", 2, 0, 'q' },
190 { "user", 2, 0, 'u' },
191 { "group", 2, 0, 'g' },
192 { "resolv-file", 2, 0, 'r' },
193 { "servers-file", 1, 0, LOPT_SERVERS_FILE },
194 { "mx-host", 1, 0, 'm' },
195 { "mx-target", 1, 0, 't' },
196 { "cache-size", 2, 0, 'c' },
197 { "port", 1, 0, 'p' },
198 { "dhcp-leasefile", 2, 0, 'l' },
199 { "dhcp-lease", 1, 0, 'l' },
200 { "dhcp-host", 1, 0, 'G' },
201 { "dhcp-range", 1, 0, 'F' },
202 { "dhcp-option", 1, 0, 'O' },
203 { "dhcp-boot", 1, 0, 'M' },
204 { "domain", 1, 0, 's' },
205 { "domain-suffix", 1, 0, 's' },
206 { "interface", 1, 0, 'i' },
207 { "listen-address", 1, 0, 'a' },
208 { "local-service", 0, 0, LOPT_LOCAL_SERVICE },
209 { "bogus-priv", 0, 0, 'b' },
210 { "bogus-nxdomain", 1, 0, 'B' },
211 { "ignore-address", 1, 0, LOPT_IGNORE_ADDR },
212 { "selfmx", 0, 0, 'e' },
213 { "filterwin2k", 0, 0, 'f' },
214 { "pid-file", 2, 0, 'x' },
215 { "strict-order", 0, 0, 'o' },
216 { "server", 1, 0, 'S' },
217 { "rev-server", 1, 0, LOPT_REV_SERV },
218 { "local", 1, 0, LOPT_LOCAL },
219 { "address", 1, 0, 'A' },
220 { "conf-file", 2, 0, 'C' },
221 { "no-resolv", 0, 0, 'R' },
222 { "expand-hosts", 0, 0, 'E' },
223 { "localmx", 0, 0, 'L' },
224 { "local-ttl", 1, 0, 'T' },
225 { "no-negcache", 0, 0, 'N' },
226 { "addn-hosts", 1, 0, 'H' },
227 { "hostsdir", 1, 0, LOPT_HOST_INOTIFY },
228 { "query-port", 1, 0, 'Q' },
229 { "except-interface", 1, 0, 'I' },
230 { "no-dhcp-interface", 1, 0, '2' },
231 { "domain-needed", 0, 0, 'D' },
232 { "dhcp-lease-max", 1, 0, 'X' },
233 { "bind-interfaces", 0, 0, 'z' },
234 { "read-ethers", 0, 0, 'Z' },
235 { "alias", 1, 0, 'V' },
236 { "dhcp-vendorclass", 1, 0, 'U' },
237 { "dhcp-userclass", 1, 0, 'j' },
238 { "dhcp-ignore", 1, 0, 'J' },
239 { "edns-packet-max", 1, 0, 'P' },
240 { "keep-in-foreground", 0, 0, 'k' },
241 { "dhcp-authoritative", 0, 0, 'K' },
242 { "srv-host", 1, 0, 'W' },
243 { "localise-queries", 0, 0, 'y' },
244 { "txt-record", 1, 0, 'Y' },
245 { "caa-record", 1, 0 , LOPT_CAA },
246 { "dns-rr", 1, 0, LOPT_RR },
247 { "enable-dbus", 2, 0, '1' },
248 { "enable-ubus", 2, 0, LOPT_UBUS },
249 { "bootp-dynamic", 2, 0, '3' },
250 { "dhcp-mac", 1, 0, '4' },
251 { "no-ping", 0, 0, '5' },
252 { "dhcp-script", 1, 0, '6' },
253 { "conf-dir", 1, 0, '7' },
254 { "log-facility", 1, 0 ,'8' },
255 { "leasefile-ro", 0, 0, '9' },
256 { "script-on-renewal", 0, 0, LOPT_SCRIPT_TIME},
257 { "dns-forward-max", 1, 0, '0' },
258 { "clear-on-reload", 0, 0, LOPT_RELOAD },
259 { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES },
260 { "enable-tftp", 2, 0, LOPT_TFTP },
261 { "tftp-secure", 0, 0, LOPT_SECURE },
262 { "tftp-no-fail", 0, 0, LOPT_TFTP_NO_FAIL },
263 { "tftp-unique-root", 2, 0, LOPT_APREF },
264 { "tftp-root", 1, 0, LOPT_PREFIX },
265 { "tftp-max", 1, 0, LOPT_TFTP_MAX },
266 { "tftp-mtu", 1, 0, LOPT_TFTP_MTU },
267 { "tftp-lowercase", 0, 0, LOPT_TFTP_LC },
268 { "tftp-single-port", 0, 0, LOPT_SINGLE_PORT },
269 { "ptr-record", 1, 0, LOPT_PTR },
270 { "naptr-record", 1, 0, LOPT_NAPTR },
271 { "bridge-interface", 1, 0 , LOPT_BRIDGE },
272 { "shared-network", 1, 0, LOPT_SHARED_NET },
273 { "dhcp-option-force", 1, 0, LOPT_FORCE },
274 { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK },
275 { "log-dhcp", 0, 0, LOPT_LOG_OPTS },
276 { "log-async", 2, 0, LOPT_MAX_LOGS },
277 { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT },
278 { "dhcp-remoteid", 1, 0, LOPT_REMOTE },
279 { "dhcp-subscrid", 1, 0, LOPT_SUBSCR },
280 { "dhcp-pxe-vendor", 1, 0, LOPT_PXE_VENDOR },
281 { "interface-name", 1, 0, LOPT_INTNAME },
282 { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST },
283 { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS },
284 { "dhcp-hostsdir", 1, 0, LOPT_DHCP_INOTIFY },
285 { "dhcp-optsdir", 1, 0, LOPT_DHOPT_INOTIFY },
286 { "dhcp-no-override", 0, 0, LOPT_OVERRIDE },
287 { "tftp-port-range", 1, 0, LOPT_TFTPPORTS },
288 { "stop-dns-rebind", 0, 0, LOPT_REBIND },
289 { "rebind-domain-ok", 1, 0, LOPT_NO_REBIND },
290 { "all-servers", 0, 0, LOPT_NOLAST },
291 { "dhcp-match", 1, 0, LOPT_MATCH },
292 { "dhcp-name-match", 1, 0, LOPT_NAME_MATCH },
293 { "dhcp-broadcast", 2, 0, LOPT_BROADCAST },
294 { "neg-ttl", 1, 0, LOPT_NEGTTL },
295 { "max-ttl", 1, 0, LOPT_MAXTTL },
296 { "min-cache-ttl", 1, 0, LOPT_MINCTTL },
297 { "max-cache-ttl", 1, 0, LOPT_MAXCTTL },
298 { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT },
299 { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR },
300 { "min-port", 1, 0, LOPT_MINPORT },
301 { "max-port", 1, 0, LOPT_MAXPORT },
302 { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN },
303 { "cname", 1, 0, LOPT_CNAME },
304 { "pxe-prompt", 1, 0, LOPT_PXE_PROMT },
305 { "pxe-service", 1, 0, LOPT_PXE_SERV },
306 { "test", 0, 0, LOPT_TEST },
307 { "tag-if", 1, 0, LOPT_TAG_IF },
308 { "dhcp-proxy", 2, 0, LOPT_PROXY },
309 { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES },
310 { "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND },
311 { "add-mac", 2, 0, LOPT_ADD_MAC },
312 { "add-subnet", 2, 0, LOPT_ADD_SBNET },
313 { "add-cpe-id", 1, 0 , LOPT_CPE_ID },
314 { "proxy-dnssec", 0, 0, LOPT_DNSSEC },
315 { "dhcp-sequential-ip", 0, 0, LOPT_INCR_ADDR },
316 { "conntrack", 0, 0, LOPT_CONNTRACK },
317 { "dhcp-client-update", 0, 0, LOPT_FQDN },
318 { "dhcp-luascript", 1, 0, LOPT_LUASCRIPT },
319 { "enable-ra", 0, 0, LOPT_RA },
320 { "dhcp-duid", 1, 0, LOPT_DUID },
321 { "host-record", 1, 0, LOPT_HOST_REC },
322 { "bind-dynamic", 0, 0, LOPT_CLVERBIND },
323 { "auth-zone", 1, 0, LOPT_AUTHZONE },
324 { "auth-server", 1, 0, LOPT_AUTHSERV },
325 { "auth-ttl", 1, 0, LOPT_AUTHTTL },
326 { "auth-soa", 1, 0, LOPT_AUTHSOA },
327 { "auth-sec-servers", 1, 0, LOPT_AUTHSFS },
328 { "auth-peer", 1, 0, LOPT_AUTHPEER },
329 { "ipset", 1, 0, LOPT_IPSET },
330 { "connmark-allowlist-enable", 2, 0, LOPT_CMARK_ALST_EN },
331 { "connmark-allowlist", 1, 0, LOPT_CMARK_ALST },
332 { "synth-domain", 1, 0, LOPT_SYNTH },
333 { "dnssec", 0, 0, LOPT_SEC_VALID },
334 { "trust-anchor", 1, 0, LOPT_TRUST_ANCHOR },
335 { "dnssec-debug", 0, 0, LOPT_DNSSEC_DEBUG },
336 { "dnssec-check-unsigned", 2, 0, LOPT_DNSSEC_CHECK },
337 { "dnssec-no-timecheck", 0, 0, LOPT_DNSSEC_TIME },
338 { "dnssec-timestamp", 1, 0, LOPT_DNSSEC_STAMP },
339 { "dhcp-relay", 1, 0, LOPT_RELAY },
340 { "ra-param", 1, 0, LOPT_RA_PARAM },
341 { "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP },
342 { "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6 },
343 { "quiet-ra", 0, 0, LOPT_QUIET_RA },
344 { "dns-loop-detect", 0, 0, LOPT_LOOP_DETECT },
345 { "script-arp", 0, 0, LOPT_SCRIPT_ARP },
346 { "dhcp-ttl", 1, 0 , LOPT_DHCPTTL },
347 { "dhcp-reply-delay", 1, 0, LOPT_REPLY_DELAY },
348 { "dhcp-rapid-commit", 0, 0, LOPT_RAPID_COMMIT },
349 { "dumpfile", 1, 0, LOPT_DUMPFILE },
350 { "dumpmask", 1, 0, LOPT_DUMPMASK },
351 { "dhcp-ignore-clid", 0, 0, LOPT_IGNORE_CLID },
352 { "dynamic-host", 1, 0, LOPT_DYNHOST },
353 { "log-debug", 0, 0, LOPT_LOG_DEBUG },
354 { "umbrella", 2, 0, LOPT_UMBRELLA },
355 { "quiet-tftp", 0, 0, LOPT_QUIET_TFTP },
356 { NULL, 0, 0, 0 }
357 };
358
359
360#define ARG_DUP OPT_LAST
361#define ARG_ONE OPT_LAST + 1
362#define ARG_USED_CL OPT_LAST + 2
363#define ARG_USED_FILE OPT_LAST + 3
364
365static struct {
366 int opt;
367 unsigned int rept;
368 char * const flagdesc;
369 char * const desc;
370 char * const arg;
371} usage[] = {
372 { 'a', ARG_DUP, "<ipaddr>", gettext_noop("Specify local address(es) to listen on."), NULL },
373 { 'A', ARG_DUP, "/<domain>/<ipaddr>", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL },
374 { 'b', OPT_BOGUSPRIV, NULL, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL },
375 { 'B', ARG_DUP, "<ipaddr>", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL },
376 { 'c', ARG_ONE, "<integer>", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
377 { 'C', ARG_DUP, "<path>", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE },
378 { 'd', OPT_DEBUG, NULL, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL },
379 { 'D', OPT_NODOTS_LOCAL, NULL, gettext_noop("Do NOT forward queries with no domain part."), NULL },
380 { 'e', OPT_SELFMX, NULL, gettext_noop("Return self-pointing MX records for local hosts."), NULL },
381 { 'E', OPT_EXPAND, NULL, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL },
382 { 'f', OPT_FILTER, NULL, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL },
383 { 'F', ARG_DUP, "<ipaddr>,...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL },
384 { 'g', ARG_ONE, "<groupname>", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP },
385 { 'G', ARG_DUP, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL },
386 { LOPT_DHCP_HOST, ARG_DUP, "<path>", gettext_noop("Read DHCP host specs from file."), NULL },
387 { LOPT_DHCP_OPTS, ARG_DUP, "<path>", gettext_noop("Read DHCP option specs from file."), NULL },
388 { LOPT_DHCP_INOTIFY, ARG_DUP, "<path>", gettext_noop("Read DHCP host specs from a directory."), NULL },
389 { LOPT_DHOPT_INOTIFY, ARG_DUP, "<path>", gettext_noop("Read DHCP options from a directory."), NULL },
390 { LOPT_TAG_IF, ARG_DUP, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL },
391 { 'h', OPT_NO_HOSTS, NULL, gettext_noop("Do NOT load %s file."), HOSTSFILE },
392 { 'H', ARG_DUP, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE },
393 { LOPT_HOST_INOTIFY, ARG_DUP, "<path>", gettext_noop("Read hosts files from a directory."), NULL },
394 { 'i', ARG_DUP, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL },
395 { 'I', ARG_DUP, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL },
396 { 'j', ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL },
397 { LOPT_CIRCUIT, ARG_DUP, "set:<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL },
398 { LOPT_REMOTE, ARG_DUP, "set:<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL },
399 { LOPT_SUBSCR, ARG_DUP, "set:<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL },
400 { LOPT_PXE_VENDOR, ARG_DUP, "<vendor>[,...]", gettext_noop("Specify vendor class to match for PXE requests."), NULL },
401 { 'J', ARG_DUP, "tag:<tag>...", gettext_noop("Don't do DHCP for hosts with tag set."), NULL },
402 { LOPT_BROADCAST, ARG_DUP, "[=tag:<tag>...]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL },
403 { 'k', OPT_NO_FORK, NULL, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL },
404 { 'K', OPT_AUTHORITATIVE, NULL, gettext_noop("Assume we are the only DHCP server on the local network."), NULL },
405 { 'l', ARG_ONE, "<path>", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE },
406 { 'L', OPT_LOCALMX, NULL, gettext_noop("Return MX records for local hosts."), NULL },
407 { 'm', ARG_DUP, "<host_name>,<target>,<pref>", gettext_noop("Specify an MX record."), NULL },
408 { 'M', ARG_DUP, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL },
409 { 'n', OPT_NO_POLL, NULL, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE },
410 { 'N', OPT_NO_NEG, NULL, gettext_noop("Do NOT cache failed search results."), NULL },
411 { 'o', OPT_ORDER, NULL, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE },
412 { 'O', ARG_DUP, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL },
413 { LOPT_FORCE, ARG_DUP, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL},
414 { 'p', ARG_ONE, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL },
415 { 'P', ARG_ONE, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
416 { 'q', ARG_DUP, NULL, gettext_noop("Log DNS queries."), NULL },
417 { 'Q', ARG_ONE, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL },
418 { 'R', OPT_NO_RESOLV, NULL, gettext_noop("Do NOT read resolv.conf."), NULL },
419 { 'r', ARG_DUP, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE },
420 { LOPT_SERVERS_FILE, ARG_ONE, "<path>", gettext_noop("Specify path to file with server= options"), NULL },
421 { 'S', ARG_DUP, "/<domain>/<ipaddr>", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL },
422 { LOPT_REV_SERV, ARG_DUP, "<addr>/<prefix>,<ipaddr>", gettext_noop("Specify address of upstream servers for reverse address queries"), NULL },
423 { LOPT_LOCAL, ARG_DUP, "/<domain>/", gettext_noop("Never forward queries to specified domains."), NULL },
424 { 's', ARG_DUP, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL },
425 { 't', ARG_ONE, "<host_name>", gettext_noop("Specify default target in an MX record."), NULL },
426 { 'T', ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL },
427 { LOPT_NEGTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL },
428 { LOPT_MAXTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL },
429 { LOPT_MAXCTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live ceiling for cache."), NULL },
430 { LOPT_MINCTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live floor for cache."), NULL },
431 { 'u', ARG_ONE, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER },
432 { 'U', ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL },
433 { 'v', 0, NULL, gettext_noop("Display dnsmasq version and copyright information."), NULL },
434 { 'V', ARG_DUP, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL },
435 { 'W', ARG_DUP, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL },
436 { 'w', 0, NULL, gettext_noop("Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."), NULL },
437 { 'x', ARG_ONE, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE },
438 { 'X', ARG_ONE, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
439 { 'y', OPT_LOCALISE, NULL, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL },
440 { 'Y', ARG_DUP, "<name>,<txt>[,<txt]", gettext_noop("Specify TXT DNS record."), NULL },
441 { LOPT_PTR, ARG_DUP, "<name>,<target>", gettext_noop("Specify PTR DNS record."), NULL },
442 { LOPT_INTNAME, ARG_DUP, "<name>,<interface>", gettext_noop("Give DNS name to IPv4 address of interface."), NULL },
443 { 'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL },
444 { 'Z', OPT_ETHERS, NULL, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE },
445 { '1', ARG_ONE, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL },
446 { LOPT_UBUS, ARG_ONE, "[=<busname>]", gettext_noop("Enable the UBus interface."), NULL },
447 { '2', ARG_DUP, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL },
448 { '3', ARG_DUP, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL },
449 { '4', ARG_DUP, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL },
450 { LOPT_BRIDGE, ARG_DUP, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL },
451 { LOPT_SHARED_NET, ARG_DUP, "<iface>|<addr>,<addr>", gettext_noop("Specify extra networks sharing a broadcast domain for DHCP"), NULL},
452 { '5', OPT_NO_PING, NULL, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL },
453 { '6', ARG_ONE, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL },
454 { LOPT_LUASCRIPT, ARG_DUP, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL },
455 { LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL },
456 { LOPT_SCRIPT_ARP, OPT_SCRIPT_ARP, NULL, gettext_noop("Call dhcp-script with changes to local ARP table."), NULL },
457 { '7', ARG_DUP, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL },
458 { '8', ARG_ONE, "<facility>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL },
459 { '9', OPT_LEASE_RO, NULL, gettext_noop("Do not use leasefile."), NULL },
460 { '0', ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
461 { LOPT_RELOAD, OPT_RELOAD, NULL, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE },
462 { LOPT_NO_NAMES, ARG_DUP, "[=tag:<tag>]...", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL },
463 { LOPT_OVERRIDE, OPT_NO_OVERRIDE, NULL, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL },
464 { LOPT_TFTP, ARG_DUP, "[=<intr>[,<intr>]]", gettext_noop("Enable integrated read-only TFTP server."), NULL },
465 { LOPT_PREFIX, ARG_DUP, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL },
466 { LOPT_APREF, ARG_DUP, "[=ip|mac]", gettext_noop("Add client IP or hardware address to tftp-root."), NULL },
467 { LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },
468 { LOPT_TFTP_NO_FAIL, OPT_TFTP_NO_FAIL, NULL, gettext_noop("Do not terminate the service if TFTP directories are inaccessible."), NULL },
469 { LOPT_TFTP_MAX, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent TFTP transfers (defaults to %s)."), "#" },
470 { LOPT_TFTP_MTU, ARG_ONE, "<integer>", gettext_noop("Maximum MTU to use for TFTP transfers."), NULL },
471 { LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL },
472 { LOPT_TFTP_LC, OPT_TFTP_LC, NULL, gettext_noop("Convert TFTP filenames to lowercase"), NULL },
473 { LOPT_TFTPPORTS, ARG_ONE, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL },
474 { LOPT_SINGLE_PORT, OPT_SINGLE_PORT, NULL, gettext_noop("Use only one port for TFTP server."), NULL },
475 { LOPT_LOG_OPTS, OPT_LOG_OPTS, NULL, gettext_noop("Extra logging for DHCP."), NULL },
476 { LOPT_MAX_LOGS, ARG_ONE, "[=<integer>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL },
477 { LOPT_REBIND, OPT_NO_REBIND, NULL, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL },
478 { LOPT_LOC_REBND, OPT_LOCAL_REBIND, NULL, gettext_noop("Allow rebinding of 127.0.0.0/8, for RBL servers."), NULL },
479 { LOPT_NO_REBIND, ARG_DUP, "/<domain>/", gettext_noop("Inhibit DNS-rebind protection on this domain."), NULL },
480 { LOPT_NOLAST, OPT_ALL_SERVERS, NULL, gettext_noop("Always perform DNS queries to all servers."), NULL },
481 { LOPT_MATCH, ARG_DUP, "set:<tag>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL },
482 { LOPT_NAME_MATCH, ARG_DUP, "set:<tag>,<string>[*]", gettext_noop("Set tag if client provides given name."), NULL },
483 { LOPT_ALTPORT, ARG_ONE, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL },
484 { LOPT_NAPTR, ARG_DUP, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL },
485 { LOPT_MINPORT, ARG_ONE, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL },
486 { LOPT_MAXPORT, ARG_ONE, "<port>", gettext_noop("Specify highest port available for DNS query transmission."), NULL },
487 { LOPT_DHCP_FQDN, OPT_DHCP_FQDN, NULL, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL },
488 { LOPT_GEN_NAMES, ARG_DUP, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL},
489 { LOPT_PROXY, ARG_DUP, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL },
490 { LOPT_RELAY, ARG_DUP, "<local-addr>,<server>[,<iface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL},
491 { LOPT_CNAME, ARG_DUP, "<alias>,<target>[,<ttl>]", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
492 { LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL },
493 { LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
494 { LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },
495 { LOPT_ADD_MAC, ARG_DUP, "[=base64|text]", gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL },
496 { LOPT_ADD_SBNET, ARG_ONE, "<v4 pref>[,<v6 pref>]", gettext_noop("Add specified IP subnet to forwarded DNS queries."), NULL },
497 { LOPT_CPE_ID, ARG_ONE, "<text>", gettext_noop("Add client identification to forwarded DNS queries."), NULL },
498 { LOPT_DNSSEC, OPT_DNSSEC_PROXY, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },
499 { LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },
500 { LOPT_IGNORE_CLID, OPT_IGNORE_CLID, NULL, gettext_noop("Ignore client identifier option sent by DHCP clients."), NULL },
501 { LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
502 { LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
503 { LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
504 { LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
505 { LOPT_HOST_REC, ARG_DUP, "<name>,<address>[,<ttl>]", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
506 { LOPT_DYNHOST, ARG_DUP, "<name>,[<IPv4>][,<IPv6>],<interface-name>", gettext_noop("Specify host record in interface subnet"), NULL },
507 { LOPT_CAA, ARG_DUP, "<name>,<flags>,<tag>,<value>", gettext_noop("Specify certification authority authorization record"), NULL },
508 { LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
509 { LOPT_CLVERBIND, OPT_CLEVERBIND, NULL, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL },
510 { LOPT_AUTHSERV, ARG_ONE, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL },
511 { LOPT_AUTHZONE, ARG_DUP, "<domain>,[<subnet>...]", gettext_noop("Domain to export to global DNS"), NULL },
512 { LOPT_AUTHTTL, ARG_ONE, "<integer>", gettext_noop("Set TTL for authoritative replies"), NULL },
513 { LOPT_AUTHSOA, ARG_ONE, "<serial>[,...]", gettext_noop("Set authoritative zone information"), NULL },
514 { LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
515 { LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
516 { LOPT_IPSET, ARG_DUP, "/<domain>[/<domain>...]/<ipset>...", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
517 { LOPT_CMARK_ALST_EN, ARG_ONE, "[=<mask>]", gettext_noop("Enable filtering of DNS queries with connection-track marks."), NULL },
518 { LOPT_CMARK_ALST, ARG_DUP, "<connmark>[/<mask>][,<pattern>[/<pattern>...]]", gettext_noop("Set allowed DNS patterns for a connection-track mark."), NULL },
519 { LOPT_SYNTH, ARG_DUP, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL },
520 { LOPT_SEC_VALID, OPT_DNSSEC_VALID, NULL, gettext_noop("Activate DNSSEC validation"), NULL },
521 { LOPT_TRUST_ANCHOR, ARG_DUP, "<domain>,[<class>],...", gettext_noop("Specify trust anchor key digest."), NULL },
522 { LOPT_DNSSEC_DEBUG, OPT_DNSSEC_DEBUG, NULL, gettext_noop("Disable upstream checking for DNSSEC debugging."), NULL },
523 { LOPT_DNSSEC_CHECK, ARG_DUP, NULL, gettext_noop("Ensure answers without DNSSEC are in unsigned zones."), NULL },
524 { LOPT_DNSSEC_TIME, OPT_DNSSEC_TIME, NULL, gettext_noop("Don't check DNSSEC signature timestamps until first cache-reload"), NULL },
525 { LOPT_DNSSEC_STAMP, ARG_ONE, "<path>", gettext_noop("Timestamp file to verify system clock for DNSSEC"), NULL },
526 { LOPT_RA_PARAM, ARG_DUP, "<iface>,[mtu:<value>|<interface>|off,][<prio>,]<intval>[,<lifetime>]", gettext_noop("Set MTU, priority, resend-interval and router-lifetime"), NULL },
527 { LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
528 { LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
529 { LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
530 { LOPT_LOG_DEBUG, OPT_LOG_DEBUG, NULL, gettext_noop("Log debugging information."), NULL },
531 { LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks."), NULL },
532 { LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops."), NULL },
533 { LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL },
534 { LOPT_DHCPTTL, ARG_ONE, "<ttl>", gettext_noop("Set TTL in DNS responses with DHCP-derived addresses."), NULL },
535 { LOPT_REPLY_DELAY, ARG_ONE, "<integer>", gettext_noop("Delay DHCP replies for at least number of seconds."), NULL },
536 { LOPT_RAPID_COMMIT, OPT_RAPID_COMMIT, NULL, gettext_noop("Enables DHCPv4 Rapid Commit option."), NULL },
537 { LOPT_DUMPFILE, ARG_ONE, "<path>", gettext_noop("Path to debug packet dump file"), NULL },
538 { LOPT_DUMPMASK, ARG_ONE, "<hex>", gettext_noop("Mask which packets to dump"), NULL },
539 { LOPT_SCRIPT_TIME, OPT_LEASE_RENEW, NULL, gettext_noop("Call dhcp-script when lease expiry changes."), NULL },
540 { LOPT_UMBRELLA, ARG_ONE, "[=<optspec>]", gettext_noop("Send Cisco Umbrella identifiers including remote IP."), NULL },
541 { LOPT_QUIET_TFTP, OPT_QUIET_TFTP, NULL, gettext_noop("Do not log routine TFTP."), NULL },
542 { 0, 0, NULL, NULL, NULL }
543};
544
545/* We hide metacharacters in quoted strings by mapping them into the ASCII control
546 character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the
547 following sequence so that they map to themselves: it is therefore possible to call
548 unhide_metas repeatedly on string without breaking things.
549 The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a
550 couple of other places.
551 Note that space is included here so that
552 --dhcp-option=3, string
553 has five characters, whilst
554 --dhcp-option=3," string"
555 has six.
556*/
557
558static const char meta[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
559
560static char hide_meta(char c)
561{
562 unsigned int i;
563
564 for (i = 0; i < (sizeof(meta) - 1); i++)
565 if (c == meta[i])
566 return (char)i;
567
568 return c;
569}
570
571static char unhide_meta(char cr)
572{
573 unsigned int c = cr;
574
575 if (c < (sizeof(meta) - 1))
576 cr = meta[c];
577
578 return cr;
579}
580
581static void unhide_metas(char *cp)
582{
583 if (cp)
584 for(; *cp; cp++)
585 *cp = unhide_meta(*cp);
586}
587
588static void *opt_malloc(size_t size)
589{
590 void *ret;
591
592 if (mem_recover)
593 {
594 ret = whine_malloc(size);
595 if (!ret)
596 longjmp(mem_jmp, 1);
597 }
598 else
599 ret = safe_malloc(size);
600
601 return ret;
602}
603
604static char *opt_string_alloc(const char *cp)
605{
606 char *ret = NULL;
607 size_t len;
608
609 if (cp && (len = strlen(cp)) != 0)
610 {
611 ret = opt_malloc(len+1);
612 memcpy(ret, cp, len+1);
613
614 /* restore hidden metachars */
615 unhide_metas(ret);
616 }
617
618 return ret;
619}
620
621
622/* find next comma, split string with zero and eliminate spaces.
623 return start of string following comma */
624
625static char *split_chr(char *s, char c)
626{
627 char *comma, *p;
628
629 if (!s || !(comma = strchr(s, c)))
630 return NULL;
631
632 p = comma;
633 *comma = ' ';
634
635 for (; *comma == ' '; comma++);
636
637 for (; (p >= s) && *p == ' '; p--)
638 *p = 0;
639
640 return comma;
641}
642
643static char *split(char *s)
644{
645 return split_chr(s, ',');
646}
647
648static char *canonicalise_opt(char *s)
649{
650 char *ret;
651 int nomem;
652
653 if (!s)
654 return 0;
655
656 if (strlen(s) == 0)
657 return opt_string_alloc("");
658
659 unhide_metas(s);
660 if (!(ret = canonicalise(s, &nomem)) && nomem)
661 {
662 if (mem_recover)
663 longjmp(mem_jmp, 1);
664 else
665 die(_("could not get memory"), NULL, EC_NOMEM);
666 }
667
668 return ret;
669}
670
671static int numeric_check(char *a)
672{
673 char *p;
674
675 if (!a)
676 return 0;
677
678 unhide_metas(a);
679
680 for (p = a; *p; p++)
681 if (*p < '0' || *p > '9')
682 return 0;
683
684 return 1;
685}
686
687static int atoi_check(char *a, int *res)
688{
689 if (!numeric_check(a))
690 return 0;
691 *res = atoi(a);
692 return 1;
693}
694
695static int strtoul_check(char *a, u32 *res)
696{
697 unsigned long x;
698
699 if (!numeric_check(a))
700 return 0;
701 x = strtoul(a, NULL, 10);
702 if (errno || x > UINT32_MAX) {
703 errno = 0;
704 return 0;
705 }
706 *res = (u32)x;
707 return 1;
708}
709
710static int atoi_check16(char *a, int *res)
711{
712 if (!(atoi_check(a, res)) ||
713 *res < 0 ||
714 *res > 0xffff)
715 return 0;
716
717 return 1;
718}
719
720#ifdef HAVE_DNSSEC
721static int atoi_check8(char *a, int *res)
722{
723 if (!(atoi_check(a, res)) ||
724 *res < 0 ||
725 *res > 0xff)
726 return 0;
727
728 return 1;
729}
730#endif
731
732#ifndef NO_ID
733static void add_txt(char *name, char *txt, int stat)
734{
735 struct txt_record *r = opt_malloc(sizeof(struct txt_record));
736
737 if (txt)
738 {
739 size_t len = strlen(txt);
740 r->txt = opt_malloc(len+1);
741 r->len = len+1;
742 *(r->txt) = len;
743 memcpy((r->txt)+1, txt, len);
744 }
745
746 r->stat = stat;
747 r->name = opt_string_alloc(name);
748 r->next = daemon->txt;
749 daemon->txt = r;
750 r->class = C_CHAOS;
751}
752#endif
753
754static void do_usage(void)
755{
756 char buff[100];
757 int i, j;
758
759 struct {
760 char handle;
761 int val;
762 } tab[] = {
763 { '$', CACHESIZ },
764 { '*', EDNS_PKTSZ },
765 { '&', MAXLEASES },
766 { '!', FTABSIZ },
767 { '#', TFTP_MAX_CONNECTIONS },
768 { '\0', 0 }
769 };
770
771 printf(_("Usage: dnsmasq [options]\n\n"));
772#ifndef HAVE_GETOPT_LONG
773 printf(_("Use short options only on the command line.\n"));
774#endif
775 printf(_("Valid options are:\n"));
776
777 for (i = 0; usage[i].opt != 0; i++)
778 {
779 char *desc = usage[i].flagdesc;
780 char *eq = "=";
781
782 if (!desc || *desc == '[')
783 eq = "";
784
785 if (!desc)
786 desc = "";
787
788 for ( j = 0; opts[j].name; j++)
789 if (opts[j].val == usage[i].opt)
790 break;
791 if (usage[i].opt < 256)
792 sprintf(buff, "-%c, ", usage[i].opt);
793 else
794 sprintf(buff, " ");
795
796 sprintf(buff+4, "--%s%s%s", opts[j].name, eq, desc);
797 printf("%-55.55s", buff);
798
799 if (usage[i].arg)
800 {
801 strcpy(buff, usage[i].arg);
802 for (j = 0; tab[j].handle; j++)
803 if (tab[j].handle == *(usage[i].arg))
804 sprintf(buff, "%d", tab[j].val);
805 }
806 printf(_(usage[i].desc), buff);
807 printf("\n");
808 }
809}
810
811#define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
812#define ret_err_free(x,m) do { strcpy(errstr, (x)); free((m)); return 0; } while (0)
813#define goto_err(x) do { strcpy(errstr, (x)); goto on_error; } while (0)
814
815static char *parse_mysockaddr(char *arg, union mysockaddr *addr)
816{
817 if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
818 addr->sa.sa_family = AF_INET;
819 else if (inet_pton(AF_INET6, arg, &addr->in6.sin6_addr) > 0)
820 addr->sa.sa_family = AF_INET6;
821 else
822 return _("bad address");
823
824 return NULL;
825}
826
827char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, u16 *flags)
828{
829 int source_port = 0, serv_port = NAMESERVER_PORT;
830 char *portno, *source;
831 char *interface_opt = NULL;
832 int scope_index = 0;
833 char *scope_id;
834
835 *interface = 0;
836
837 if (strcmp(arg, "#") == 0)
838 {
839 if (flags)
840 *flags |= SERV_USE_RESOLV;
841 return NULL;
842 }
843
844 if ((source = split_chr(arg, '@')) && /* is there a source. */
845 (portno = split_chr(source, '#')) &&
846 !atoi_check16(portno, &source_port))
847 return _("bad port");
848
849 if ((portno = split_chr(arg, '#')) && /* is there a port no. */
850 !atoi_check16(portno, &serv_port))
851 return _("bad port");
852
853 scope_id = split_chr(arg, '%');
854
855 if (source) {
856 interface_opt = split_chr(source, '@');
857
858 if (interface_opt)
859 {
860#if defined(SO_BINDTODEVICE)
861 safe_strncpy(interface, source, IF_NAMESIZE);
862 source = interface_opt;
863#else
864 return _("interface binding not supported");
865#endif
866 }
867 }
868
869 if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
870 {
871 addr->in.sin_port = htons(serv_port);
872 addr->sa.sa_family = source_addr->sa.sa_family = AF_INET;
873#ifdef HAVE_SOCKADDR_SA_LEN
874 source_addr->in.sin_len = addr->in.sin_len = sizeof(struct sockaddr_in);
875#endif
876 source_addr->in.sin_addr.s_addr = INADDR_ANY;
877 source_addr->in.sin_port = htons(daemon->query_port);
878
879 if (source)
880 {
881 if (flags)
882 *flags |= SERV_HAS_SOURCE;
883 source_addr->in.sin_port = htons(source_port);
884 if (!(inet_pton(AF_INET, source, &source_addr->in.sin_addr) > 0))
885 {
886#if defined(SO_BINDTODEVICE)
887 if (interface_opt)
888 return _("interface can only be specified once");
889
890 source_addr->in.sin_addr.s_addr = INADDR_ANY;
891 safe_strncpy(interface, source, IF_NAMESIZE);
892#else
893 return _("interface binding not supported");
894#endif
895 }
896 }
897 }
898 else if (inet_pton(AF_INET6, arg, &addr->in6.sin6_addr) > 0)
899 {
900 if (scope_id && (scope_index = if_nametoindex(scope_id)) == 0)
901 return _("bad interface name");
902
903 addr->in6.sin6_port = htons(serv_port);
904 addr->in6.sin6_scope_id = scope_index;
905 source_addr->in6.sin6_addr = in6addr_any;
906 source_addr->in6.sin6_port = htons(daemon->query_port);
907 source_addr->in6.sin6_scope_id = 0;
908 addr->sa.sa_family = source_addr->sa.sa_family = AF_INET6;
909 addr->in6.sin6_flowinfo = source_addr->in6.sin6_flowinfo = 0;
910#ifdef HAVE_SOCKADDR_SA_LEN
911 addr->in6.sin6_len = source_addr->in6.sin6_len = sizeof(addr->in6);
912#endif
913 if (source)
914 {
915 if (flags)
916 *flags |= SERV_HAS_SOURCE;
917 source_addr->in6.sin6_port = htons(source_port);
918 if (inet_pton(AF_INET6, source, &source_addr->in6.sin6_addr) == 0)
919 {
920#if defined(SO_BINDTODEVICE)
921 if (interface_opt)
922 return _("interface can only be specified once");
923
924 source_addr->in6.sin6_addr = in6addr_any;
925 safe_strncpy(interface, source, IF_NAMESIZE);
926#else
927 return _("interface binding not supported");
928#endif
929 }
930 }
931 }
932 else
933 return _("bad address");
934
935 return NULL;
936}
937
938static int domain_rev4(char *domain, struct in_addr addr, int msize)
939{
940 in_addr_t a = ntohl(addr.s_addr);
941
942 *domain = 0;
943
944 switch (msize)
945 {
946 case 32:
947 domain += sprintf(domain, "%u.", a & 0xff);
948 /* fall through */
949 case 24:
950 domain += sprintf(domain, "%d.", (a >> 8) & 0xff);
951 /* fall through */
952 case 16:
953 domain += sprintf(domain, "%d.", (a >> 16) & 0xff);
954 /* fall through */
955 case 8:
956 domain += sprintf(domain, "%d.", (a >> 24) & 0xff);
957 break;
958 default:
959 return 0;
960 }
961
962 domain += sprintf(domain, "in-addr.arpa");
963
964 return 1;
965}
966
967static int domain_rev6(char *domain, struct in6_addr *addr, int msize)
968{
969 int i;
970
971 if (msize > 128 || msize%4)
972 return 0;
973
974 *domain = 0;
975
976 for (i = msize-1; i >= 0; i -= 4)
977 {
978 int dig = ((unsigned char *)addr)[i>>3];
979 domain += sprintf(domain, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
980 }
981 domain += sprintf(domain, "ip6.arpa");
982
983 return 1;
984}
985
986#ifdef HAVE_DHCP
987
988static int is_tag_prefix(char *arg)
989{
990 if (arg && (strstr(arg, "net:") == arg || strstr(arg, "tag:") == arg))
991 return 1;
992
993 return 0;
994}
995
996static char *set_prefix(char *arg)
997{
998 if (strstr(arg, "set:") == arg)
999 return arg+4;
1000
1001 return arg;
1002}
1003
1004static struct dhcp_netid *dhcp_netid_create(const char *net, struct dhcp_netid *next)
1005{
1006 struct dhcp_netid *tt;
1007 tt = opt_malloc(sizeof (struct dhcp_netid));
1008 tt->net = opt_string_alloc(net);
1009 tt->next = next;
1010 return tt;
1011}
1012
1013static void dhcp_netid_free(struct dhcp_netid *nid)
1014{
1015 while (nid)
1016 {
1017 struct dhcp_netid *tmp = nid;
1018 nid = nid->next;
1019 free(tmp->net);
1020 free(tmp);
1021 }
1022}
1023
1024/* Parse one or more tag:s before parameters.
1025 * Moves arg to the end of tags. */
1026static struct dhcp_netid * dhcp_tags(char **arg)
1027{
1028 struct dhcp_netid *id = NULL;
1029
1030 while (is_tag_prefix(*arg))
1031 {
1032 char *comma = split(*arg);
1033 id = dhcp_netid_create((*arg)+4, id);
1034 *arg = comma;
1035 };
1036 if (!*arg)
1037 {
1038 dhcp_netid_free(id);
1039 id = NULL;
1040 }
1041 return id;
1042}
1043
1044static void dhcp_netid_list_free(struct dhcp_netid_list *netid)
1045{
1046 while (netid)
1047 {
1048 struct dhcp_netid_list *tmplist = netid;
1049 netid = netid->next;
1050 dhcp_netid_free(tmplist->list);
1051 free(tmplist);
1052 }
1053}
1054
1055static void dhcp_config_free(struct dhcp_config *config)
1056{
1057 if (config)
1058 {
1059 struct hwaddr_config *hwaddr = config->hwaddr;
1060
1061 while (hwaddr)
1062 {
1063 struct hwaddr_config *tmp = hwaddr;
1064 hwaddr = hwaddr->next;
1065 free(tmp);
1066 }
1067
1068 dhcp_netid_list_free(config->netid);
1069 dhcp_netid_free(config->filter);
1070
1071 if (config->flags & CONFIG_CLID)
1072 free(config->clid);
1073 if (config->flags & CONFIG_NAME)
1074 free(config->hostname);
1075
1076#ifdef HAVE_DHCP6
1077 if (config->flags & CONFIG_ADDR6)
1078 {
1079 struct addrlist *addr, *tmp;
1080
1081 for (addr = config->addr6; addr; addr = tmp)
1082 {
1083 tmp = addr->next;
1084 free(addr);
1085 }
1086 }
1087#endif
1088
1089 free(config);
1090 }
1091}
1092
1093static void dhcp_context_free(struct dhcp_context *ctx)
1094{
1095 if (ctx)
1096 {
1097 dhcp_netid_free(ctx->filter);
1098 free(ctx->netid.net);
1099#ifdef HAVE_DHCP6
1100 free(ctx->template_interface);
1101#endif
1102 free(ctx);
1103 }
1104}
1105
1106static void dhcp_opt_free(struct dhcp_opt *opt)
1107{
1108 if (opt->flags & DHOPT_VENDOR)
1109 free(opt->u.vendor_class);
1110 dhcp_netid_free(opt->netid);
1111 free(opt->val);
1112 free(opt);
1113}
1114
1115
1116/* This is too insanely large to keep in-line in the switch */
1117static int parse_dhcp_opt(char *errstr, char *arg, int flags)
1118{
1119 struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt));
1120 char lenchar = 0, *cp;
1121 int addrs, digs, is_addr, is_addr6, is_hex, is_dec, is_string, dots;
1122 char *comma = NULL;
1123 u16 opt_len = 0;
1124 int is6 = 0;
1125 int option_ok = 0;
1126
1127 new->len = 0;
1128 new->flags = flags;
1129 new->netid = NULL;
1130 new->val = NULL;
1131 new->opt = 0;
1132
1133 while (arg)
1134 {
1135 comma = split(arg);
1136
1137 for (cp = arg; *cp; cp++)
1138 if (*cp < '0' || *cp > '9')
1139 break;
1140
1141 if (!*cp)
1142 {
1143 new->opt = atoi(arg);
1144 opt_len = 0;
1145 option_ok = 1;
1146 break;
1147 }
1148
1149 if (strstr(arg, "option:") == arg)
1150 {
1151 if ((new->opt = lookup_dhcp_opt(AF_INET, arg+7)) != -1)
1152 {
1153 opt_len = lookup_dhcp_len(AF_INET, new->opt);
1154 /* option:<optname> must follow tag and vendor string. */
1155 if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
1156 option_ok = 1;
1157 }
1158 break;
1159 }
1160#ifdef HAVE_DHCP6
1161 else if (strstr(arg, "option6:") == arg)
1162 {
1163 for (cp = arg+8; *cp; cp++)
1164 if (*cp < '0' || *cp > '9')
1165 break;
1166
1167 if (!*cp)
1168 {
1169 new->opt = atoi(arg+8);
1170 opt_len = 0;
1171 option_ok = 1;
1172 }
1173 else
1174 {
1175 if ((new->opt = lookup_dhcp_opt(AF_INET6, arg+8)) != -1)
1176 {
1177 opt_len = lookup_dhcp_len(AF_INET6, new->opt);
1178 if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
1179 option_ok = 1;
1180 }
1181 }
1182 /* option6:<opt>|<optname> must follow tag and vendor string. */
1183 is6 = 1;
1184 break;
1185 }
1186#endif
1187 else if (strstr(arg, "vendor:") == arg)
1188 {
1189 new->u.vendor_class = (unsigned char *)opt_string_alloc(arg+7);
1190 new->flags |= DHOPT_VENDOR;
1191 if ((new->flags & DHOPT_ENCAPSULATE) || flags == DHOPT_MATCH)
1192 goto_err(_("inappropriate vendor:"));
1193 }
1194 else if (strstr(arg, "encap:") == arg)
1195 {
1196 new->u.encap = atoi(arg+6);
1197 new->flags |= DHOPT_ENCAPSULATE;
1198 if ((new->flags & DHOPT_VENDOR) || flags == DHOPT_MATCH)
1199 goto_err(_("inappropriate encap:"));
1200 }
1201 else if (strstr(arg, "vi-encap:") == arg)
1202 {
1203 new->u.encap = atoi(arg+9);
1204 new->flags |= DHOPT_RFC3925;
1205 if (flags == DHOPT_MATCH)
1206 {
1207 option_ok = 1;
1208 break;
1209 }
1210 }
1211 else
1212 {
1213 /* allow optional "net:" or "tag:" for consistency */
1214 const char *name = (is_tag_prefix(arg)) ? arg+4 : set_prefix(arg);
1215 new->netid = dhcp_netid_create(name, new->netid);
1216 }
1217
1218 arg = comma;
1219 }
1220
1221#ifdef HAVE_DHCP6
1222 if (is6)
1223 {
1224 if (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))
1225 goto_err(_("unsupported encapsulation for IPv6 option"));
1226
1227 if (opt_len == 0 &&
1228 !(new->flags & DHOPT_RFC3925))
1229 opt_len = lookup_dhcp_len(AF_INET6, new->opt);
1230 }
1231 else
1232#endif
1233 if (opt_len == 0 &&
1234 !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
1235 opt_len = lookup_dhcp_len(AF_INET, new->opt);
1236
1237 /* option may be missing with rfc3925 match */
1238 if (!option_ok)
1239 goto_err(_("bad dhcp-option"));
1240
1241 if (comma)
1242 {
1243 /* characterise the value */
1244 char c;
1245 int found_dig = 0, found_colon = 0;
1246 is_addr = is_addr6 = is_hex = is_dec = is_string = 1;
1247 addrs = digs = 1;
1248 dots = 0;
1249 for (cp = comma; (c = *cp); cp++)
1250 if (c == ',')
1251 {
1252 addrs++;
1253 is_dec = is_hex = 0;
1254 }
1255 else if (c == ':')
1256 {
1257 digs++;
1258 is_dec = is_addr = 0;
1259 found_colon = 1;
1260 }
1261 else if (c == '/')
1262 {
1263 is_addr6 = is_dec = is_hex = 0;
1264 if (cp == comma) /* leading / means a pathname */
1265 is_addr = 0;
1266 }
1267 else if (c == '.')
1268 {
1269 is_dec = is_hex = 0;
1270 dots++;
1271 }
1272 else if (c == '-')
1273 is_hex = is_addr = is_addr6 = 0;
1274 else if (c == ' ')
1275 is_dec = is_hex = 0;
1276 else if (!(c >='0' && c <= '9'))
1277 {
1278 is_addr = 0;
1279 if (cp[1] == 0 && is_dec &&
1280 (c == 'b' || c == 's' || c == 'i'))
1281 {
1282 lenchar = c;
1283 *cp = 0;
1284 }
1285 else
1286 is_dec = 0;
1287 if (!((c >='A' && c <= 'F') ||
1288 (c >='a' && c <= 'f') ||
1289 (c == '*' && (flags & DHOPT_MATCH))))
1290 {
1291 is_hex = 0;
1292 if (c != '[' && c != ']')
1293 is_addr6 = 0;
1294 }
1295 }
1296 else
1297 found_dig = 1;
1298
1299 if (!found_dig)
1300 is_dec = is_addr = 0;
1301
1302 if (!found_colon)
1303 is_addr6 = 0;
1304
1305#ifdef HAVE_DHCP6
1306 /* NTP server option takes hex, addresses or FQDN */
1307 if (is6 && new->opt == OPTION6_NTP_SERVER && !is_hex)
1308 opt_len |= is_addr6 ? OT_ADDR_LIST : OT_RFC1035_NAME;
1309#endif
1310
1311 /* We know that some options take addresses */
1312 if (opt_len & OT_ADDR_LIST)
1313 {
1314 is_string = is_dec = is_hex = 0;
1315
1316 if (!is6 && (!is_addr || dots == 0))
1317 goto_err(_("bad IP address"));
1318
1319 if (is6 && !is_addr6)
1320 goto_err(_("bad IPv6 address"));
1321 }
1322 /* or names */
1323 else if (opt_len & (OT_NAME | OT_RFC1035_NAME | OT_CSTRING))
1324 is_addr6 = is_addr = is_dec = is_hex = 0;
1325
1326 if (found_dig && (opt_len & OT_TIME) && strlen(comma) > 0)
1327 {
1328 int val, fac = 1;
1329
1330 switch (comma[strlen(comma) - 1])
1331 {
1332 case 'w':
1333 case 'W':
1334 fac *= 7;
1335 /* fall through */
1336 case 'd':
1337 case 'D':
1338 fac *= 24;
1339 /* fall through */
1340 case 'h':
1341 case 'H':
1342 fac *= 60;
1343 /* fall through */
1344 case 'm':
1345 case 'M':
1346 fac *= 60;
1347 /* fall through */
1348 case 's':
1349 case 'S':
1350 comma[strlen(comma) - 1] = 0;
1351 }
1352
1353 new->len = 4;
1354 new->val = opt_malloc(4);
1355 val = atoi(comma);
1356 *((int *)new->val) = htonl(val * fac);
1357 }
1358 else if (is_hex && digs > 1)
1359 {
1360 new->len = digs;
1361 new->val = opt_malloc(new->len);
1362 parse_hex(comma, new->val, digs, (flags & DHOPT_MATCH) ? &new->u.wildcard_mask : NULL, NULL);
1363 new->flags |= DHOPT_HEX;
1364 }
1365 else if (is_dec)
1366 {
1367 int i, val = atoi(comma);
1368 /* assume numeric arg is 1 byte except for
1369 options where it is known otherwise.
1370 For vendor class option, we have to hack. */
1371 if (opt_len != 0)
1372 new->len = opt_len;
1373 else if (val & 0xffff0000)
1374 new->len = 4;
1375 else if (val & 0xff00)
1376 new->len = 2;
1377 else
1378 new->len = 1;
1379
1380 if (lenchar == 'b')
1381 new->len = 1;
1382 else if (lenchar == 's')
1383 new->len = 2;
1384 else if (lenchar == 'i')
1385 new->len = 4;
1386
1387 new->val = opt_malloc(new->len);
1388 for (i=0; i<new->len; i++)
1389 new->val[i] = val>>((new->len - i - 1)*8);
1390 }
1391 else if (is_addr && !is6)
1392 {
1393 struct in_addr in;
1394 unsigned char *op;
1395 char *slash;
1396 /* max length of address/subnet descriptor is five bytes,
1397 add one for the option 120 enc byte too */
1398 new->val = op = opt_malloc((5 * addrs) + 1);
1399 new->flags |= DHOPT_ADDR;
1400
1401 if (!(new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR | DHOPT_RFC3925)) &&
1402 new->opt == OPTION_SIP_SERVER)
1403 {
1404 *(op++) = 1; /* RFC 3361 "enc byte" */
1405 new->flags &= ~DHOPT_ADDR;
1406 }
1407 while (addrs--)
1408 {
1409 cp = comma;
1410 comma = split(cp);
1411 slash = split_chr(cp, '/');
1412 if (!inet_pton(AF_INET, cp, &in))
1413 goto_err(_("bad IPv4 address"));
1414 if (!slash)
1415 {
1416 memcpy(op, &in, INADDRSZ);
1417 op += INADDRSZ;
1418 }
1419 else
1420 {
1421 unsigned char *p = (unsigned char *)&in;
1422 int netsize = atoi(slash);
1423 *op++ = netsize;
1424 if (netsize > 0)
1425 *op++ = *p++;
1426 if (netsize > 8)
1427 *op++ = *p++;
1428 if (netsize > 16)
1429 *op++ = *p++;
1430 if (netsize > 24)
1431 *op++ = *p++;
1432 new->flags &= ~DHOPT_ADDR; /* cannot re-write descriptor format */
1433 }
1434 }
1435 new->len = op - new->val;
1436 }
1437 else if (is_addr6 && is6)
1438 {
1439 unsigned char *op;
1440 new->val = op = opt_malloc(16 * addrs);
1441 new->flags |= DHOPT_ADDR6;
1442 while (addrs--)
1443 {
1444 cp = comma;
1445 comma = split(cp);
1446
1447 /* check for [1234::7] */
1448 if (*cp == '[')
1449 cp++;
1450 if (strlen(cp) > 1 && cp[strlen(cp)-1] == ']')
1451 cp[strlen(cp)-1] = 0;
1452
1453 if (inet_pton(AF_INET6, cp, op))
1454 {
1455 op += IN6ADDRSZ;
1456 continue;
1457 }
1458
1459 goto_err(_("bad IPv6 address"));
1460 }
1461 new->len = op - new->val;
1462 }
1463 else if (is_string)
1464 {
1465 /* text arg */
1466 if ((new->opt == OPTION_DOMAIN_SEARCH || new->opt == OPTION_SIP_SERVER) &&
1467 !is6 && !(new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR | DHOPT_RFC3925)))
1468 {
1469 /* dns search, RFC 3397, or SIP, RFC 3361 */
1470 unsigned char *q, *r, *tail;
1471 unsigned char *p, *m = NULL, *newp;
1472 size_t newlen, len = 0;
1473 int header_size = (new->opt == OPTION_DOMAIN_SEARCH) ? 0 : 1;
1474
1475 arg = comma;
1476 comma = split(arg);
1477
1478 while (arg && *arg)
1479 {
1480 char *in, *dom = NULL;
1481 size_t domlen = 1;
1482 /* Allow "." as an empty domain */
1483 if (strcmp (arg, ".") != 0)
1484 {
1485 if (!(dom = canonicalise_opt(arg)))
1486 goto_err(_("bad domain in dhcp-option"));
1487
1488 domlen = strlen(dom) + 2;
1489 }
1490
1491 newp = opt_malloc(len + domlen + header_size);
1492 if (m)
1493 {
1494 memcpy(newp, m, header_size + len);
1495 free(m);
1496 }
1497 m = newp;
1498 p = m + header_size;
1499 q = p + len;
1500
1501 /* add string on the end in RFC1035 format */
1502 for (in = dom; in && *in;)
1503 {
1504 unsigned char *cp = q++;
1505 int j;
1506 for (j = 0; *in && (*in != '.'); in++, j++)
1507 *q++ = *in;
1508 *cp = j;
1509 if (*in)
1510 in++;
1511 }
1512 *q++ = 0;
1513 free(dom);
1514
1515 /* Now tail-compress using earlier names. */
1516 newlen = q - p;
1517 for (tail = p + len; *tail; tail += (*tail) + 1)
1518 for (r = p; r - p < (int)len; r += (*r) + 1)
1519 if (strcmp((char *)r, (char *)tail) == 0)
1520 {
1521 PUTSHORT((r - p) | 0xc000, tail);
1522 newlen = tail - p;
1523 goto end;
1524 }
1525 end:
1526 len = newlen;
1527
1528 arg = comma;
1529 comma = split(arg);
1530 }
1531
1532 /* RFC 3361, enc byte is zero for names */
1533 if (new->opt == OPTION_SIP_SERVER && m)
1534 m[0] = 0;
1535 new->len = (int) len + header_size;
1536 new->val = m;
1537 }
1538#ifdef HAVE_DHCP6
1539 else if (comma && (opt_len & OT_CSTRING))
1540 {
1541 /* length fields are two bytes so need 16 bits for each string */
1542 int i, commas = 1;
1543 unsigned char *p, *newp;
1544
1545 for (i = 0; comma[i]; i++)
1546 if (comma[i] == ',')
1547 commas++;
1548
1549 newp = opt_malloc(strlen(comma)+(2*commas));
1550 p = newp;
1551 arg = comma;
1552 comma = split(arg);
1553
1554 while (arg && *arg)
1555 {
1556 u16 len = strlen(arg);
1557 unhide_metas(arg);
1558 PUTSHORT(len, p);
1559 memcpy(p, arg, len);
1560 p += len;
1561
1562 arg = comma;
1563 comma = split(arg);
1564 }
1565
1566 new->val = newp;
1567 new->len = p - newp;
1568 }
1569 else if (comma && (opt_len & OT_RFC1035_NAME))
1570 {
1571 unsigned char *p = NULL, *q, *newp, *end;
1572 int len = 0;
1573 int header_size = (is6 && new->opt == OPTION6_NTP_SERVER) ? 4 : 0;
1574 arg = comma;
1575 comma = split(arg);
1576
1577 while (arg && *arg)
1578 {
1579 char *dom = canonicalise_opt(arg);
1580 if (!dom)
1581 goto_err(_("bad domain in dhcp-option"));
1582
1583 newp = opt_malloc(len + header_size + strlen(dom) + 2);
1584
1585 if (p)
1586 {
1587 memcpy(newp, p, len);
1588 free(p);
1589 }
1590
1591 p = newp;
1592 q = p + len;
1593 end = do_rfc1035_name(q + header_size, dom, NULL);
1594 *end++ = 0;
1595 if (is6 && new->opt == OPTION6_NTP_SERVER)
1596 {
1597 PUTSHORT(NTP_SUBOPTION_SRV_FQDN, q);
1598 PUTSHORT(end - q - 2, q);
1599 }
1600 len = end - p;
1601 free(dom);
1602
1603 arg = comma;
1604 comma = split(arg);
1605 }
1606
1607 new->val = p;
1608 new->len = len;
1609 }
1610#endif
1611 else
1612 {
1613 new->len = strlen(comma);
1614 /* keep terminating zero on string */
1615 new->val = (unsigned char *)opt_string_alloc(comma);
1616 new->flags |= DHOPT_STRING;
1617 }
1618 }
1619 }
1620
1621 if (!is6 &&
1622 ((new->len > 255) ||
1623 (new->len > 253 && (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))) ||
1624 (new->len > 250 && (new->flags & DHOPT_RFC3925))))
1625 goto_err(_("dhcp-option too long"));
1626
1627 if (flags == DHOPT_MATCH)
1628 {
1629 if ((new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)) ||
1630 !new->netid ||
1631 new->netid->next)
1632 goto_err(_("illegal dhcp-match"));
1633
1634 if (is6)
1635 {
1636 new->next = daemon->dhcp_match6;
1637 daemon->dhcp_match6 = new;
1638 }
1639 else
1640 {
1641 new->next = daemon->dhcp_match;
1642 daemon->dhcp_match = new;
1643 }
1644 }
1645 else if (is6)
1646 {
1647 new->next = daemon->dhcp_opts6;
1648 daemon->dhcp_opts6 = new;
1649 }
1650 else
1651 {
1652 new->next = daemon->dhcp_opts;
1653 daemon->dhcp_opts = new;
1654 }
1655
1656 return 1;
1657on_error:
1658 dhcp_opt_free(new);
1659 return 0;
1660}
1661
1662#endif
1663
1664void set_option_bool(unsigned int opt)
1665{
1666 option_var(opt) |= option_val(opt);
1667}
1668
1669void reset_option_bool(unsigned int opt)
1670{
1671 option_var(opt) &= ~(option_val(opt));
1672}
1673
1674static int one_opt(int option, char *arg, char *errstr, char *gen_err, int command_line, int servers_only)
1675{
1676 int i;
1677 char *comma;
1678
1679 if (option == '?')
1680 ret_err(gen_err);
1681
1682 for (i=0; usage[i].opt != 0; i++)
1683 if (usage[i].opt == option)
1684 {
1685 int rept = usage[i].rept;
1686
1687 if (command_line)
1688 {
1689 /* command line */
1690 if (rept == ARG_USED_CL)
1691 ret_err(_("illegal repeated flag"));
1692 if (rept == ARG_ONE)
1693 usage[i].rept = ARG_USED_CL;
1694 }
1695 else
1696 {
1697 /* allow file to override command line */
1698 if (rept == ARG_USED_FILE)
1699 ret_err(_("illegal repeated keyword"));
1700 if (rept == ARG_USED_CL || rept == ARG_ONE)
1701 usage[i].rept = ARG_USED_FILE;
1702 }
1703
1704 if (rept != ARG_DUP && rept != ARG_ONE && rept != ARG_USED_CL)
1705 {
1706 set_option_bool(rept);
1707 return 1;
1708 }
1709
1710 break;
1711 }
1712
1713 switch (option)
1714 {
1715 case 'C': /* --conf-file */
1716 {
1717 char *file = opt_string_alloc(arg);
1718 if (file)
1719 {
1720 one_file(file, 0);
1721 free(file);
1722 }
1723 break;
1724 }
1725
1726 case '7': /* --conf-dir */
1727 {
1728 DIR *dir_stream;
1729 struct dirent *ent;
1730 char *directory, *path;
1731 struct list {
1732 char *name;
1733 struct list *next;
1734 } *ignore_suffix = NULL, *match_suffix = NULL, *files = NULL, *li;
1735
1736 comma = split(arg);
1737 if (!(directory = opt_string_alloc(arg)))
1738 break;
1739
1740 for (arg = comma; arg; arg = comma)
1741 {
1742 comma = split(arg);
1743 if (strlen(arg) != 0)
1744 {
1745 li = opt_malloc(sizeof(struct list));
1746 if (*arg == '*')
1747 {
1748 /* "*" with no suffix is a no-op */
1749 if (arg[1] == 0)
1750 free(li);
1751 else
1752 {
1753 li->next = match_suffix;
1754 match_suffix = li;
1755 /* Have to copy: buffer is overwritten */
1756 li->name = opt_string_alloc(arg+1);
1757 }
1758 }
1759 else
1760 {
1761 li->next = ignore_suffix;
1762 ignore_suffix = li;
1763 /* Have to copy: buffer is overwritten */
1764 li->name = opt_string_alloc(arg);
1765 }
1766 }
1767 }
1768
1769 if (!(dir_stream = opendir(directory)))
1770 die(_("cannot access directory %s: %s"), directory, EC_FILE);
1771
1772 while ((ent = readdir(dir_stream)))
1773 {
1774 size_t len = strlen(ent->d_name);
1775 struct stat buf;
1776
1777 /* ignore emacs backups and dotfiles */
1778 if (len == 0 ||
1779 ent->d_name[len - 1] == '~' ||
1780 (ent->d_name[0] == '#' && ent->d_name[len - 1] == '#') ||
1781 ent->d_name[0] == '.')
1782 continue;
1783
1784 if (match_suffix)
1785 {
1786 for (li = match_suffix; li; li = li->next)
1787 {
1788 /* check for required suffices */
1789 size_t ls = strlen(li->name);
1790 if (len > ls &&
1791 strcmp(li->name, &ent->d_name[len - ls]) == 0)
1792 break;
1793 }
1794 if (!li)
1795 continue;
1796 }
1797
1798 for (li = ignore_suffix; li; li = li->next)
1799 {
1800 /* check for proscribed suffices */
1801 size_t ls = strlen(li->name);
1802 if (len > ls &&
1803 strcmp(li->name, &ent->d_name[len - ls]) == 0)
1804 break;
1805 }
1806 if (li)
1807 continue;
1808
1809 path = opt_malloc(strlen(directory) + len + 2);
1810 strcpy(path, directory);
1811 strcat(path, "/");
1812 strcat(path, ent->d_name);
1813
1814 /* files must be readable */
1815 if (stat(path, &buf) == -1)
1816 die(_("cannot access %s: %s"), path, EC_FILE);
1817
1818 /* only reg files allowed. */
1819 if (S_ISREG(buf.st_mode))
1820 {
1821 /* sort files into order. */
1822 struct list **up, *new = opt_malloc(sizeof(struct list));
1823 new->name = path;
1824
1825 for (up = &files, li = files; li; up = &li->next, li = li->next)
1826 if (strcmp(li->name, path) >=0)
1827 break;
1828
1829 new->next = li;
1830 *up = new;
1831 }
1832
1833 }
1834
1835 for (li = files; li; li = li->next)
1836 one_file(li->name, 0);
1837
1838 closedir(dir_stream);
1839 free(directory);
1840 for(; ignore_suffix; ignore_suffix = li)
1841 {
1842 li = ignore_suffix->next;
1843 free(ignore_suffix->name);
1844 free(ignore_suffix);
1845 }
1846 for(; match_suffix; match_suffix = li)
1847 {
1848 li = match_suffix->next;
1849 free(match_suffix->name);
1850 free(match_suffix);
1851 }
1852 for(; files; files = li)
1853 {
1854 li = files->next;
1855 free(files->name);
1856 free(files);
1857 }
1858 break;
1859 }
1860
1861 case LOPT_ADD_SBNET: /* --add-subnet */
1862 set_option_bool(OPT_CLIENT_SUBNET);
1863 if (arg)
1864 {
1865 char *err, *end;
1866 comma = split(arg);
1867
1868 struct mysubnet* new = opt_malloc(sizeof(struct mysubnet));
1869 if ((end = split_chr(arg, '/')))
1870 {
1871 /* has subnet+len */
1872 err = parse_mysockaddr(arg, &new->addr);
1873 if (err)
1874 ret_err_free(err, new);
1875 if (!atoi_check(end, &new->mask))
1876 ret_err_free(gen_err, new);
1877 new->addr_used = 1;
1878 }
1879 else if (!atoi_check(arg, &new->mask))
1880 ret_err_free(gen_err, new);
1881
1882 daemon->add_subnet4 = new;
1883
1884 if (comma)
1885 {
1886 new = opt_malloc(sizeof(struct mysubnet));
1887 if ((end = split_chr(comma, '/')))
1888 {
1889 /* has subnet+len */
1890 err = parse_mysockaddr(comma, &new->addr);
1891 if (err)
1892 ret_err_free(err, new);
1893 if (!atoi_check(end, &new->mask))
1894 ret_err_free(gen_err, new);
1895 new->addr_used = 1;
1896 }
1897 else
1898 {
1899 if (!atoi_check(comma, &new->mask))
1900 ret_err_free(gen_err, new);
1901 }
1902
1903 daemon->add_subnet6 = new;
1904 }
1905 }
1906 break;
1907
1908 case '1': /* --enable-dbus */
1909 set_option_bool(OPT_DBUS);
1910 if (arg)
1911 daemon->dbus_name = opt_string_alloc(arg);
1912 else
1913 daemon->dbus_name = DNSMASQ_SERVICE;
1914 break;
1915
1916 case LOPT_UBUS: /* --enable-ubus */
1917 set_option_bool(OPT_UBUS);
1918 if (arg)
1919 daemon->ubus_name = opt_string_alloc(arg);
1920 else
1921 daemon->ubus_name = DNSMASQ_UBUS_NAME;
1922 break;
1923
1924 case '8': /* --log-facility */
1925 /* may be a filename */
1926 if (strchr(arg, '/') || strcmp (arg, "-") == 0)
1927 daemon->log_file = opt_string_alloc(arg);
1928 else
1929 {
1930#ifdef __ANDROID__
1931 ret_err(_("setting log facility is not possible under Android"));
1932#else
1933 for (i = 0; facilitynames[i].c_name; i++)
1934 if (hostname_isequal((char *)facilitynames[i].c_name, arg))
1935 break;
1936
1937 if (facilitynames[i].c_name)
1938 daemon->log_fac = facilitynames[i].c_val;
1939 else
1940 ret_err(_("bad log facility"));
1941#endif
1942 }
1943 break;
1944
1945 case 'x': /* --pid-file */
1946 daemon->runfile = opt_string_alloc(arg);
1947 break;
1948
1949 case 'r': /* --resolv-file */
1950 {
1951 char *name = opt_string_alloc(arg);
1952 struct resolvc *new, *list = daemon->resolv_files;
1953
1954 if (list && list->is_default)
1955 {
1956 /* replace default resolv file - possibly with nothing */
1957 if (name)
1958 {
1959 list->is_default = 0;
1960 list->name = name;
1961 }
1962 else
1963 list = NULL;
1964 }
1965 else if (name)
1966 {
1967 new = opt_malloc(sizeof(struct resolvc));
1968 new->next = list;
1969 new->name = name;
1970 new->is_default = 0;
1971 new->mtime = 0;
1972 new->logged = 0;
1973 list = new;
1974 }
1975 daemon->resolv_files = list;
1976 break;
1977 }
1978
1979 case LOPT_SERVERS_FILE:
1980 daemon->servers_file = opt_string_alloc(arg);
1981 break;
1982
1983 case 'm': /* --mx-host */
1984 {
1985 int pref = 1;
1986 struct mx_srv_record *new;
1987 char *name, *target = NULL;
1988
1989 if ((comma = split(arg)))
1990 {
1991 char *prefstr;
1992 if ((prefstr = split(comma)) && !atoi_check16(prefstr, &pref))
1993 ret_err(_("bad MX preference"));
1994 }
1995
1996 if (!(name = canonicalise_opt(arg)) ||
1997 (comma && !(target = canonicalise_opt(comma))))
1998 ret_err(_("bad MX name"));
1999
2000 new = opt_malloc(sizeof(struct mx_srv_record));
2001 new->next = daemon->mxnames;
2002 daemon->mxnames = new;
2003 new->issrv = 0;
2004 new->name = name;
2005 new->target = target; /* may be NULL */
2006 new->weight = pref;
2007 break;
2008 }
2009
2010 case 't': /* --mx-target */
2011 if (!(daemon->mxtarget = canonicalise_opt(arg)))
2012 ret_err(_("bad MX target"));
2013 break;
2014
2015 case LOPT_DUMPFILE: /* --dumpfile */
2016 daemon->dump_file = opt_string_alloc(arg);
2017 break;
2018
2019 case LOPT_DUMPMASK: /* --dumpmask */
2020 daemon->dump_mask = strtol(arg, NULL, 0);
2021 break;
2022
2023#ifdef HAVE_DHCP
2024 case 'l': /* --dhcp-leasefile */
2025 daemon->lease_file = opt_string_alloc(arg);
2026 break;
2027
2028 /* Sorry about the gross pre-processor abuse */
2029 case '6': /* --dhcp-script */
2030 case LOPT_LUASCRIPT: /* --dhcp-luascript */
2031# if !defined(HAVE_SCRIPT)
2032 ret_err(_("recompile with HAVE_SCRIPT defined to enable lease-change scripts"));
2033# else
2034 if (option == LOPT_LUASCRIPT)
2035# if !defined(HAVE_LUASCRIPT)
2036 ret_err(_("recompile with HAVE_LUASCRIPT defined to enable Lua scripts"));
2037# else
2038 daemon->luascript = opt_string_alloc(arg);
2039# endif
2040 else
2041 daemon->lease_change_command = opt_string_alloc(arg);
2042# endif
2043 break;
2044#endif /* HAVE_DHCP */
2045
2046 case LOPT_DHCP_HOST: /* --dhcp-hostsfile */
2047 case LOPT_DHCP_OPTS: /* --dhcp-optsfile */
2048 case LOPT_DHCP_INOTIFY: /* --dhcp-hostsdir */
2049 case LOPT_DHOPT_INOTIFY: /* --dhcp-optsdir */
2050 case LOPT_HOST_INOTIFY: /* --hostsdir */
2051 case 'H': /* --addn-hosts */
2052 {
2053 struct hostsfile *new = opt_malloc(sizeof(struct hostsfile));
2054 static unsigned int hosts_index = SRC_AH;
2055 new->fname = opt_string_alloc(arg);
2056 new->index = hosts_index++;
2057 new->flags = 0;
2058 if (option == 'H')
2059 {
2060 new->next = daemon->addn_hosts;
2061 daemon->addn_hosts = new;
2062 }
2063 else if (option == LOPT_DHCP_HOST)
2064 {
2065 new->next = daemon->dhcp_hosts_file;
2066 daemon->dhcp_hosts_file = new;
2067 }
2068 else if (option == LOPT_DHCP_OPTS)
2069 {
2070 new->next = daemon->dhcp_opts_file;
2071 daemon->dhcp_opts_file = new;
2072 }
2073 else
2074 {
2075 new->next = daemon->dynamic_dirs;
2076 daemon->dynamic_dirs = new;
2077 if (option == LOPT_DHCP_INOTIFY)
2078 new->flags |= AH_DHCP_HST;
2079 else if (option == LOPT_DHOPT_INOTIFY)
2080 new->flags |= AH_DHCP_OPT;
2081 else if (option == LOPT_HOST_INOTIFY)
2082 new->flags |= AH_HOSTS;
2083 }
2084
2085 break;
2086 }
2087
2088 case LOPT_AUTHSERV: /* --auth-server */
2089 comma = split(arg);
2090
2091 daemon->authserver = opt_string_alloc(arg);
2092
2093 while ((arg = comma))
2094 {
2095 struct iname *new = opt_malloc(sizeof(struct iname));
2096 comma = split(arg);
2097 new->name = NULL;
2098 unhide_metas(arg);
2099 if (inet_pton(AF_INET, arg, &new->addr.in.sin_addr) > 0)
2100 new->addr.sa.sa_family = AF_INET;
2101 else if (inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr) > 0)
2102 new->addr.sa.sa_family = AF_INET6;
2103 else
2104 {
2105 char *fam = split_chr(arg, '/');
2106 new->name = opt_string_alloc(arg);
2107 new->addr.sa.sa_family = 0;
2108 if (fam)
2109 {
2110 if (strcmp(fam, "4") == 0)
2111 new->addr.sa.sa_family = AF_INET;
2112 else if (strcmp(fam, "6") == 0)
2113 new->addr.sa.sa_family = AF_INET6;
2114 else
2115 {
2116 free(new->name);
2117 ret_err_free(gen_err, new);
2118 }
2119 }
2120 }
2121 new->next = daemon->authinterface;
2122 daemon->authinterface = new;
2123 };
2124
2125 break;
2126
2127 case LOPT_AUTHSFS: /* --auth-sec-servers */
2128 {
2129 struct name_list *new;
2130
2131 do {
2132 comma = split(arg);
2133 new = opt_malloc(sizeof(struct name_list));
2134 new->name = opt_string_alloc(arg);
2135 new->next = daemon->secondary_forward_server;
2136 daemon->secondary_forward_server = new;
2137 arg = comma;
2138 } while (arg);
2139 break;
2140 }
2141
2142 case LOPT_AUTHZONE: /* --auth-zone */
2143 {
2144 struct auth_zone *new;
2145
2146 comma = split(arg);
2147
2148 new = opt_malloc(sizeof(struct auth_zone));
2149 new->domain = opt_string_alloc(arg);
2150 new->subnet = NULL;
2151 new->exclude = NULL;
2152 new->interface_names = NULL;
2153 new->next = daemon->auth_zones;
2154 daemon->auth_zones = new;
2155
2156 while ((arg = comma))
2157 {
2158 int prefixlen = 0;
2159 int is_exclude = 0;
2160 char *prefix;
2161 struct addrlist *subnet = NULL;
2162 union all_addr addr;
2163
2164 comma = split(arg);
2165 prefix = split_chr(arg, '/');
2166
2167 if (prefix && !atoi_check(prefix, &prefixlen))
2168 ret_err(gen_err);
2169
2170 if (strstr(arg, "exclude:") == arg)
2171 {
2172 is_exclude = 1;
2173 arg = arg+8;
2174 }
2175
2176 if (inet_pton(AF_INET, arg, &addr.addr4))
2177 {
2178 subnet = opt_malloc(sizeof(struct addrlist));
2179 subnet->prefixlen = (prefixlen == 0) ? 24 : prefixlen;
2180 subnet->flags = ADDRLIST_LITERAL;
2181 }
2182 else if (inet_pton(AF_INET6, arg, &addr.addr6))
2183 {
2184 subnet = opt_malloc(sizeof(struct addrlist));
2185 subnet->prefixlen = (prefixlen == 0) ? 64 : prefixlen;
2186 subnet->flags = ADDRLIST_LITERAL | ADDRLIST_IPV6;
2187 }
2188 else
2189 {
2190 struct auth_name_list *name = opt_malloc(sizeof(struct auth_name_list));
2191 name->name = opt_string_alloc(arg);
2192 name->flags = AUTH4 | AUTH6;
2193 name->next = new->interface_names;
2194 new->interface_names = name;
2195 if (prefix)
2196 {
2197 if (prefixlen == 4)
2198 name->flags &= ~AUTH6;
2199 else if (prefixlen == 6)
2200 name->flags &= ~AUTH4;
2201 else
2202 ret_err(gen_err);
2203 }
2204 }
2205
2206 if (subnet)
2207 {
2208 subnet->addr = addr;
2209
2210 if (is_exclude)
2211 {
2212 subnet->next = new->exclude;
2213 new->exclude = subnet;
2214 }
2215 else
2216 {
2217 subnet->next = new->subnet;
2218 new->subnet = subnet;
2219 }
2220 }
2221 }
2222 break;
2223 }
2224
2225 case LOPT_AUTHSOA: /* --auth-soa */
2226 comma = split(arg);
2227 daemon->soa_sn = (u32)atoi(arg);
2228 if (comma)
2229 {
2230 char *cp;
2231 arg = comma;
2232 comma = split(arg);
2233 daemon->hostmaster = opt_string_alloc(arg);
2234 for (cp = daemon->hostmaster; cp && *cp; cp++)
2235 if (*cp == '@')
2236 *cp = '.';
2237
2238 if (comma)
2239 {
2240 arg = comma;
2241 comma = split(arg);
2242 daemon->soa_refresh = (u32)atoi(arg);
2243 if (comma)
2244 {
2245 arg = comma;
2246 comma = split(arg);
2247 daemon->soa_retry = (u32)atoi(arg);
2248 if (comma)
2249 daemon->soa_expiry = (u32)atoi(comma);
2250 }
2251 }
2252 }
2253
2254 break;
2255
2256 case 's': /* --domain */
2257 case LOPT_SYNTH: /* --synth-domain */
2258 if (strcmp (arg, "#") == 0)
2259 set_option_bool(OPT_RESOLV_DOMAIN);
2260 else
2261 {
2262 char *d, *d_raw = arg;
2263 comma = split(arg);
2264 if (!(d = canonicalise_opt(d_raw)))
2265 ret_err(gen_err);
2266 else
2267 {
2268 free(d); /* allocate this again below. */
2269 if (comma)
2270 {
2271 struct cond_domain *new = opt_malloc(sizeof(struct cond_domain));
2272 char *netpart;
2273
2274 new->prefix = NULL;
2275 new->indexed = 0;
2276 new->prefixlen = 0;
2277
2278 unhide_metas(comma);
2279 if ((netpart = split_chr(comma, '/')))
2280 {
2281 int msize;
2282
2283 arg = split(netpart);
2284 if (!atoi_check(netpart, &msize))
2285 ret_err_free(gen_err, new);
2286 else if (inet_pton(AF_INET, comma, &new->start))
2287 {
2288 int mask;
2289
2290 if (msize > 32)
2291 ret_err_free(_("bad prefix length"), new);
2292
2293 mask = (1 << (32 - msize)) - 1;
2294 new->is6 = 0;
2295 new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask);
2296 new->end.s_addr = new->start.s_addr | htonl(mask);
2297 if (arg)
2298 {
2299 if (option != 's')
2300 {
2301 if (!(new->prefix = canonicalise_opt(arg)) ||
2302 strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
2303 ret_err_free(_("bad prefix"), new);
2304 }
2305 else if (strcmp(arg, "local") != 0 ||
2306 (msize != 8 && msize != 16 && msize != 24))
2307 ret_err_free(gen_err, new);
2308 else
2309 {
2310 char domain[29]; /* strlen("xxx.yyy.zzz.ttt.in-addr.arpa")+1 */
2311 /* local=/xxx.yyy.zzz.in-addr.arpa/ */
2312 /* domain_rev4 can't fail here, msize checked above. */
2313 domain_rev4(domain, new->start, msize);
2314 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, domain, NULL);
2315
2316 /* local=/<domain>/ */
2317 /* d_raw can't failed to canonicalise here, checked above. */
2318 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL);
2319 }
2320 }
2321 }
2322 else if (inet_pton(AF_INET6, comma, &new->start6))
2323 {
2324 u64 mask, addrpart = addr6part(&new->start6);
2325
2326 if (msize > 128)
2327 ret_err_free(_("bad prefix length"), new);
2328
2329 mask = (1LLU << (128 - msize)) - 1LLU;
2330
2331 new->is6 = 1;
2332 new->prefixlen = msize;
2333
2334 /* prefix==64 overflows the mask calculation above */
2335 if (msize <= 64)
2336 mask = (u64)-1LL;
2337
2338 new->end6 = new->start6;
2339 setaddr6part(&new->start6, addrpart & ~mask);
2340 setaddr6part(&new->end6, addrpart | mask);
2341
2342 if (arg)
2343 {
2344 if (option != 's')
2345 {
2346 if (!(new->prefix = canonicalise_opt(arg)) ||
2347 strlen(new->prefix) > MAXLABEL - INET6_ADDRSTRLEN)
2348 ret_err_free(_("bad prefix"), new);
2349 }
2350 else if (strcmp(arg, "local") != 0 || ((msize & 4) != 0))
2351 ret_err_free(gen_err, new);
2352 else
2353 {
2354 char domain[73]; /* strlen("32*<n.>ip6.arpa")+1 */
2355 /* generate the equivalent of
2356 local=/xxx.yyy.zzz.ip6.arpa/ */
2357 domain_rev6(domain, &new->start6, msize);
2358 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, domain, NULL);
2359
2360 /* local=/<domain>/ */
2361 /* d_raw can't failed to canonicalise here, checked above. */
2362 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL);
2363 }
2364 }
2365 }
2366 else
2367 ret_err_free(gen_err, new);
2368 }
2369 else
2370 {
2371 char *prefstr;
2372 arg = split(comma);
2373 prefstr = split(arg);
2374
2375 if (inet_pton(AF_INET, comma, &new->start))
2376 {
2377 new->is6 = 0;
2378 if (!arg)
2379 new->end.s_addr = new->start.s_addr;
2380 else if (!inet_pton(AF_INET, arg, &new->end))
2381 ret_err_free(gen_err, new);
2382 }
2383 else if (inet_pton(AF_INET6, comma, &new->start6))
2384 {
2385 new->is6 = 1;
2386 if (!arg)
2387 memcpy(&new->end6, &new->start6, IN6ADDRSZ);
2388 else if (!inet_pton(AF_INET6, arg, &new->end6))
2389 ret_err_free(gen_err, new);
2390 }
2391 else
2392 ret_err_free(gen_err, new);
2393
2394 if (option != 's' && prefstr)
2395 {
2396 if (!(new->prefix = canonicalise_opt(prefstr)) ||
2397 strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
2398 ret_err_free(_("bad prefix"), new);
2399 }
2400 }
2401
2402 new->domain = canonicalise_opt(d_raw);
2403 if (option == 's')
2404 {
2405 new->next = daemon->cond_domain;
2406 daemon->cond_domain = new;
2407 }
2408 else
2409 {
2410 char *star;
2411 if (new->prefix &&
2412 (star = strrchr(new->prefix, '*'))
2413 && *(star+1) == 0)
2414 {
2415 *star = 0;
2416 new->indexed = 1;
2417 if (new->is6 && new->prefixlen < 64)
2418 ret_err_free(_("prefix length too small"), new);
2419 }
2420 new->next = daemon->synth_domains;
2421 daemon->synth_domains = new;
2422 }
2423 }
2424 else if (option == 's')
2425 daemon->domain_suffix = canonicalise_opt(d_raw);
2426 else
2427 ret_err(gen_err);
2428 }
2429 }
2430 break;
2431
2432 case LOPT_CPE_ID: /* --add-dns-client */
2433 if (arg)
2434 daemon->dns_client_id = opt_string_alloc(arg);
2435 break;
2436
2437 case LOPT_UMBRELLA: /* --umbrella */
2438 set_option_bool(OPT_UMBRELLA);
2439 while (arg) {
2440 comma = split(arg);
2441 if (strstr(arg, "deviceid:")) {
2442 arg += 9;
2443 if (strlen(arg) != 16)
2444 ret_err(gen_err);
2445 char *p;
2446 for (p = arg; *p; p++) {
2447 if (!isxdigit((int)*p))
2448 ret_err(gen_err);
2449 }
2450 set_option_bool(OPT_UMBRELLA_DEVID);
2451
2452 u8 *u = daemon->umbrella_device;
2453 char word[3];
2454 u8 i;
2455 for (i = 0; i < sizeof(daemon->umbrella_device); i++, arg+=2) {
2456 memcpy(word, &(arg[0]), 2);
2457 *u++ = strtoul(word, NULL, 16);
2458 }
2459 }
2460 else if (strstr(arg, "orgid:")) {
2461 if (!strtoul_check(arg+6, &daemon->umbrella_org)) {
2462 ret_err(gen_err);
2463 }
2464 }
2465 else if (strstr(arg, "assetid:")) {
2466 if (!strtoul_check(arg+8, &daemon->umbrella_asset)) {
2467 ret_err(gen_err);
2468 }
2469 }
2470 arg = comma;
2471 }
2472 break;
2473
2474 case LOPT_ADD_MAC: /* --add-mac */
2475 if (!arg)
2476 set_option_bool(OPT_ADD_MAC);
2477 else
2478 {
2479 unhide_metas(arg);
2480 if (strcmp(arg, "base64") == 0)
2481 set_option_bool(OPT_MAC_B64);
2482 else if (strcmp(arg, "text") == 0)
2483 set_option_bool(OPT_MAC_HEX);
2484 else
2485 ret_err(gen_err);
2486 }
2487 break;
2488
2489 case 'u': /* --user */
2490 daemon->username = opt_string_alloc(arg);
2491 break;
2492
2493 case 'g': /* --group */
2494 daemon->groupname = opt_string_alloc(arg);
2495 daemon->group_set = 1;
2496 break;
2497
2498#ifdef HAVE_DHCP
2499 case LOPT_SCRIPTUSR: /* --scriptuser */
2500 daemon->scriptuser = opt_string_alloc(arg);
2501 break;
2502#endif
2503
2504 case 'i': /* --interface */
2505 do {
2506 struct iname *new = opt_malloc(sizeof(struct iname));
2507 comma = split(arg);
2508 new->next = daemon->if_names;
2509 daemon->if_names = new;
2510 /* new->name may be NULL if someone does
2511 "interface=" to disable all interfaces except loop. */
2512 new->name = opt_string_alloc(arg);
2513 new->used = 0;
2514 arg = comma;
2515 } while (arg);
2516 break;
2517
2518 case LOPT_TFTP: /* --enable-tftp */
2519 set_option_bool(OPT_TFTP);
2520 if (!arg)
2521 break;
2522 /* fall through */
2523
2524 case 'I': /* --except-interface */
2525 case '2': /* --no-dhcp-interface */
2526 do {
2527 struct iname *new = opt_malloc(sizeof(struct iname));
2528 comma = split(arg);
2529 new->name = opt_string_alloc(arg);
2530 if (option == 'I')
2531 {
2532 new->next = daemon->if_except;
2533 daemon->if_except = new;
2534 }
2535 else if (option == LOPT_TFTP)
2536 {
2537 new->next = daemon->tftp_interfaces;
2538 daemon->tftp_interfaces = new;
2539 }
2540 else
2541 {
2542 new->next = daemon->dhcp_except;
2543 daemon->dhcp_except = new;
2544 }
2545 arg = comma;
2546 } while (arg);
2547 break;
2548
2549 case 'B': /* --bogus-nxdomain */
2550 case LOPT_IGNORE_ADDR: /* --ignore-address */
2551 {
2552 union all_addr addr;
2553 int prefix, is6 = 0;
2554 struct bogus_addr *baddr;
2555
2556 unhide_metas(arg);
2557
2558 if (!arg ||
2559 ((comma = split_chr(arg, '/')) && !atoi_check(comma, &prefix)))
2560 ret_err(gen_err);
2561
2562 if (inet_pton(AF_INET6, arg, &addr.addr6) == 1)
2563 is6 = 1;
2564 else if (inet_pton(AF_INET, arg, &addr.addr4) != 1)
2565 ret_err(gen_err);
2566
2567 if (!comma)
2568 {
2569 if (is6)
2570 prefix = 128;
2571 else
2572 prefix = 32;
2573 }
2574
2575 if (prefix > 128 || (!is6 && prefix > 32))
2576 ret_err(gen_err);
2577
2578 baddr = opt_malloc(sizeof(struct bogus_addr));
2579 if (option == 'B')
2580 {
2581 baddr->next = daemon->bogus_addr;
2582 daemon->bogus_addr = baddr;
2583 }
2584 else
2585 {
2586 baddr->next = daemon->ignore_addr;
2587 daemon->ignore_addr = baddr;
2588 }
2589
2590 baddr->prefix = prefix;
2591 baddr->is6 = is6;
2592 baddr->addr = addr;
2593 break;
2594 }
2595
2596 case 'a': /* --listen-address */
2597 case LOPT_AUTHPEER: /* --auth-peer */
2598 do {
2599 struct iname *new = opt_malloc(sizeof(struct iname));
2600 comma = split(arg);
2601 unhide_metas(arg);
2602 if (arg && (inet_pton(AF_INET, arg, &new->addr.in.sin_addr) > 0))
2603 {
2604 new->addr.sa.sa_family = AF_INET;
2605 new->addr.in.sin_port = 0;
2606#ifdef HAVE_SOCKADDR_SA_LEN
2607 new->addr.in.sin_len = sizeof(new->addr.in);
2608#endif
2609 }
2610 else if (arg && inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr) > 0)
2611 {
2612 new->addr.sa.sa_family = AF_INET6;
2613 new->addr.in6.sin6_flowinfo = 0;
2614 new->addr.in6.sin6_scope_id = 0;
2615 new->addr.in6.sin6_port = 0;
2616#ifdef HAVE_SOCKADDR_SA_LEN
2617 new->addr.in6.sin6_len = sizeof(new->addr.in6);
2618#endif
2619 }
2620 else
2621 ret_err_free(gen_err, new);
2622
2623 new->used = 0;
2624 if (option == 'a')
2625 {
2626 new->next = daemon->if_addrs;
2627 daemon->if_addrs = new;
2628 }
2629 else
2630 {
2631 new->next = daemon->auth_peers;
2632 daemon->auth_peers = new;
2633 }
2634 arg = comma;
2635 } while (arg);
2636 break;
2637
2638 case LOPT_NO_REBIND: /* --rebind-domain-ok */
2639 {
2640 struct server *new;
2641
2642 unhide_metas(arg);
2643
2644 if (*arg == '/')
2645 arg++;
2646
2647 do {
2648 comma = split_chr(arg, '/');
2649 new = opt_malloc(sizeof(struct serv_local));
2650 new->domain = opt_string_alloc(arg);
2651 new->domain_len = strlen(arg);
2652 new->next = daemon->no_rebind;
2653 daemon->no_rebind = new;
2654 arg = comma;
2655 } while (arg && *arg);
2656
2657 break;
2658 }
2659
2660 case 'S': /* --server */
2661 case LOPT_LOCAL: /* --local */
2662 case 'A': /* --address */
2663 {
2664 char *lastdomain = NULL, *domain = "";
2665 u16 flags = 0;
2666 char *err;
2667 union all_addr addr;
2668 union mysockaddr serv_addr, source_addr;
2669 char interface[IF_NAMESIZE+1];
2670
2671 unhide_metas(arg);
2672
2673 /* split the domain args, if any and skip to the end of them. */
2674 if (arg && *arg == '/')
2675 {
2676 char *last;
2677
2678 domain = lastdomain = ++arg;
2679
2680 while ((last = split_chr(arg, '/')))
2681 {
2682 lastdomain = arg;
2683 arg = last;
2684 }
2685 }
2686
2687 if (!arg || !*arg)
2688 flags = SERV_LITERAL_ADDRESS;
2689 else if (option == 'A')
2690 {
2691 /* # as literal address means return zero address for 4 and 6 */
2692 if (strcmp(arg, "#") == 0)
2693 flags = SERV_ALL_ZEROS | SERV_LITERAL_ADDRESS;
2694 else if (inet_pton(AF_INET, arg, &addr.addr4) > 0)
2695 flags = SERV_4ADDR | SERV_LITERAL_ADDRESS;
2696 else if (inet_pton(AF_INET6, arg, &addr.addr6) > 0)
2697 flags = SERV_6ADDR | SERV_LITERAL_ADDRESS;
2698 else
2699 ret_err(_("Bad address in --address"));
2700 }
2701 else
2702 {
2703 if ((err = parse_server(arg, &serv_addr, &source_addr, interface, &flags)))
2704 ret_err(err);
2705 }
2706
2707 if (servers_only && option == 'S')
2708 flags |= SERV_FROM_FILE;
2709
2710 while (1)
2711 {
2712 /* server=//1.2.3.4 is special. */
2713 if (strlen(domain) == 0 && lastdomain)
2714 flags |= SERV_FOR_NODOTS;
2715 else
2716 flags &= ~SERV_FOR_NODOTS;
2717
2718 if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, &addr))
2719 ret_err(gen_err);
2720
2721 if (!lastdomain || domain == lastdomain)
2722 break;
2723
2724 domain += strlen(domain) + 1;
2725 }
2726
2727 break;
2728 }
2729
2730 case LOPT_REV_SERV: /* --rev-server */
2731 {
2732 char *string;
2733 int size;
2734 u16 flags = 0;
2735 char domain[73]; /* strlen("32*<n.>ip6.arpa")+1 */
2736 struct in_addr addr4;
2737 struct in6_addr addr6;
2738 union mysockaddr serv_addr, source_addr;
2739 char interface[IF_NAMESIZE+1];
2740
2741 unhide_metas(arg);
2742 if (!arg)
2743 ret_err(gen_err);
2744
2745 comma=split(arg);
2746
2747 if (!(string = split_chr(arg, '/')) || !atoi_check(string, &size))
2748 ret_err(gen_err);
2749
2750 if (inet_pton(AF_INET, arg, &addr4))
2751 {
2752 if (!domain_rev4(domain, addr4, size))
2753 ret_err(_("bad IPv4 prefix"));
2754 }
2755 else if (inet_pton(AF_INET6, arg, &addr6))
2756 {
2757 if (!domain_rev6(domain, &addr6, size))
2758 ret_err(_("bad IPv6 prefix"));
2759 }
2760 else
2761 ret_err(gen_err);
2762
2763 if (!comma)
2764 flags |= SERV_LITERAL_ADDRESS;
2765 else if ((string = parse_server(comma, &serv_addr, &source_addr, interface, &flags)))
2766 ret_err(string);
2767
2768 if (servers_only)
2769 flags |= SERV_FROM_FILE;
2770
2771 if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
2772 ret_err(gen_err);
2773
2774 break;
2775 }
2776
2777 case LOPT_IPSET: /* --ipset */
2778#ifndef HAVE_IPSET
2779 ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
2780 break;
2781#else
2782 {
2783 struct ipsets ipsets_head;
2784 struct ipsets *ipsets = &ipsets_head;
2785 int size;
2786 char *end;
2787 char **sets, **sets_pos;
2788 memset(ipsets, 0, sizeof(struct ipsets));
2789 unhide_metas(arg);
2790 if (arg && *arg == '/')
2791 {
2792 arg++;
2793 while ((end = split_chr(arg, '/')))
2794 {
2795 char *domain = NULL;
2796 /* elide leading dots - they are implied in the search algorithm */
2797 while (*arg == '.')
2798 arg++;
2799 /* # matches everything and becomes a zero length domain string */
2800 if (strcmp(arg, "#") == 0 || !*arg)
2801 domain = "";
2802 else if (strlen(arg) != 0 && !(domain = canonicalise_opt(arg)))
2803 ret_err(gen_err);
2804 ipsets->next = opt_malloc(sizeof(struct ipsets));
2805 ipsets = ipsets->next;
2806 memset(ipsets, 0, sizeof(struct ipsets));
2807 ipsets->domain = domain;
2808 arg = end;
2809 }
2810 }
2811 else
2812 {
2813 ipsets->next = opt_malloc(sizeof(struct ipsets));
2814 ipsets = ipsets->next;
2815 memset(ipsets, 0, sizeof(struct ipsets));
2816 ipsets->domain = "";
2817 }
2818
2819 if (!arg || !*arg)
2820 ret_err(gen_err);
2821
2822 for (size = 2, end = arg; *end; ++end)
2823 if (*end == ',')
2824 ++size;
2825
2826 sets = sets_pos = opt_malloc(sizeof(char *) * size);
2827
2828 do {
2829 end = split(arg);
2830 *sets_pos++ = opt_string_alloc(arg);
2831 arg = end;
2832 } while (end);
2833 *sets_pos = 0;
2834 for (ipsets = &ipsets_head; ipsets->next; ipsets = ipsets->next)
2835 ipsets->next->sets = sets;
2836 ipsets->next = daemon->ipsets;
2837 daemon->ipsets = ipsets_head.next;
2838
2839 break;
2840 }
2841#endif
2842
2843 case LOPT_CMARK_ALST_EN: /* --connmark-allowlist-enable */
2844#ifndef HAVE_CONNTRACK
2845 ret_err(_("recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"));
2846 break;
2847#else
2848 {
2849 u32 mask = UINT32_MAX;
2850
2851 if (arg)
2852 if (!strtoul_check(arg, &mask) || mask < 1)
2853 ret_err(gen_err);
2854
2855 set_option_bool(OPT_CMARK_ALST_EN);
2856 daemon->allowlist_mask = mask;
2857 break;
2858 }
2859#endif
2860
2861 case LOPT_CMARK_ALST: /* --connmark-allowlist */
2862#ifndef HAVE_CONNTRACK
2863 ret_err(_("recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"));
2864 break;
2865#else
2866 {
2867 struct allowlist *allowlists;
2868 char **patterns, **patterns_pos;
2869 u32 mark, mask = UINT32_MAX;
2870 size_t num_patterns = 0;
2871
2872 char *c, *m = NULL;
2873 char *separator;
2874 unhide_metas(arg);
2875 if (!arg)
2876 ret_err(gen_err);
2877 c = arg;
2878 if (*c < '0' || *c > '9')
2879 ret_err(gen_err);
2880 while (*c && *c != ',')
2881 {
2882 if (*c == '/')
2883 {
2884 if (m)
2885 ret_err(gen_err);
2886 *c = '\0';
2887 m = ++c;
2888 }
2889 if (*c < '0' || *c > '9')
2890 ret_err(gen_err);
2891 c++;
2892 }
2893 separator = c;
2894 if (!*separator)
2895 break;
2896 while (c && *c)
2897 {
2898 char *end = strchr(++c, '/');
2899 if (end)
2900 *end = '\0';
2901 if (strcmp(c, "*") && !is_valid_dns_name_pattern(c))
2902 ret_err(gen_err);
2903 if (end)
2904 *end = '/';
2905 if (num_patterns >= UINT16_MAX - 1)
2906 ret_err(gen_err);
2907 num_patterns++;
2908 c = end;
2909 }
2910
2911 *separator = '\0';
2912 if (!strtoul_check(arg, &mark) || mark < 1 || mark > UINT32_MAX)
2913 ret_err(gen_err);
2914 if (m)
2915 if (!strtoul_check(m, &mask) || mask < 1 || mask > UINT32_MAX || (mark & ~mask))
2916 ret_err(gen_err);
2917 if (num_patterns)
2918 *separator = ',';
2919 for (allowlists = daemon->allowlists; allowlists; allowlists = allowlists->next)
2920 if (allowlists->mark == mark && allowlists->mask == mask)
2921 ret_err(gen_err);
2922
2923 patterns = opt_malloc((num_patterns + 1) * sizeof(char *));
2924 if (!patterns)
2925 goto fail_cmark_allowlist;
2926 patterns_pos = patterns;
2927 c = separator;
2928 while (c && *c)
2929 {
2930 char *end = strchr(++c, '/');
2931 if (end)
2932 *end = '\0';
2933 if (!(*patterns_pos++ = opt_string_alloc(c)))
2934 goto fail_cmark_allowlist;
2935 if (end)
2936 *end = '/';
2937 c = end;
2938 }
2939 *patterns_pos++ = NULL;
2940
2941 allowlists = opt_malloc(sizeof(struct allowlist));
2942 if (!allowlists)
2943 goto fail_cmark_allowlist;
2944 memset(allowlists, 0, sizeof(struct allowlist));
2945 allowlists->mark = mark;
2946 allowlists->mask = mask;
2947 allowlists->patterns = patterns;
2948 allowlists->next = daemon->allowlists;
2949 daemon->allowlists = allowlists;
2950 break;
2951
2952 fail_cmark_allowlist:
2953 if (patterns)
2954 {
2955 for (patterns_pos = patterns; *patterns_pos; patterns_pos++)
2956 {
2957 free(*patterns_pos);
2958 *patterns_pos = NULL;
2959 }
2960 free(patterns);
2961 patterns = NULL;
2962 }
2963 if (allowlists)
2964 {
2965 free(allowlists);
2966 allowlists = NULL;
2967 }
2968 ret_err(gen_err);
2969 }
2970#endif
2971
2972 case 'c': /* --cache-size */
2973 {
2974 int size;
2975
2976 if (!atoi_check(arg, &size))
2977 ret_err(gen_err);
2978 else
2979 {
2980 /* zero is OK, and means no caching. */
2981
2982 if (size < 0)
2983 size = 0;
2984
2985 /* Note that for very large cache sizes, the malloc()
2986 will overflow. For the size of the cache record
2987 at the time this was noted, the value of "very large"
2988 was 46684428. Limit to an order of magnitude less than
2989 that to be safe from changes to the cache record. */
2990 if (size > 5000000)
2991 size = 5000000;
2992
2993 daemon->cachesize = size;
2994 }
2995 break;
2996 }
2997
2998 case 'p': /* --port */
2999 if (!atoi_check16(arg, &daemon->port))
3000 ret_err(gen_err);
3001 break;
3002
3003 case LOPT_MINPORT: /* --min-port */
3004 if (!atoi_check16(arg, &daemon->min_port))
3005 ret_err(gen_err);
3006 break;
3007
3008 case LOPT_MAXPORT: /* --max-port */
3009 if (!atoi_check16(arg, &daemon->max_port))
3010 ret_err(gen_err);
3011 break;
3012
3013 case '0': /* --dns-forward-max */
3014 if (!atoi_check(arg, &daemon->ftabsize))
3015 ret_err(gen_err);
3016 break;
3017
3018 case 'q': /* --log-queries */
3019 set_option_bool(OPT_LOG);
3020 if (arg && strcmp(arg, "extra") == 0)
3021 set_option_bool(OPT_EXTRALOG);
3022 break;
3023
3024 case LOPT_MAX_LOGS: /* --log-async */
3025 daemon->max_logs = LOG_MAX; /* default */
3026 if (arg && !atoi_check(arg, &daemon->max_logs))
3027 ret_err(gen_err);
3028 else if (daemon->max_logs > 100)
3029 daemon->max_logs = 100;
3030 break;
3031
3032 case 'P': /* --edns-packet-max */
3033 {
3034 int i;
3035 if (!atoi_check(arg, &i))
3036 ret_err(gen_err);
3037 daemon->edns_pktsz = (unsigned short)i;
3038 break;
3039 }
3040
3041 case 'Q': /* --query-port */
3042 if (!atoi_check16(arg, &daemon->query_port))
3043 ret_err(gen_err);
3044 /* if explicitly set to zero, use single OS ephemeral port
3045 and disable random ports */
3046 if (daemon->query_port == 0)
3047 daemon->osport = 1;
3048 break;
3049
3050 case 'T': /* --local-ttl */
3051 case LOPT_NEGTTL: /* --neg-ttl */
3052 case LOPT_MAXTTL: /* --max-ttl */
3053 case LOPT_MINCTTL: /* --min-cache-ttl */
3054 case LOPT_MAXCTTL: /* --max-cache-ttl */
3055 case LOPT_AUTHTTL: /* --auth-ttl */
3056 case LOPT_DHCPTTL: /* --dhcp-ttl */
3057 {
3058 int ttl;
3059 if (!atoi_check(arg, &ttl))
3060 ret_err(gen_err);
3061 else if (option == LOPT_NEGTTL)
3062 daemon->neg_ttl = (unsigned long)ttl;
3063 else if (option == LOPT_MAXTTL)
3064 daemon->max_ttl = (unsigned long)ttl;
3065 else if (option == LOPT_MINCTTL)
3066 {
3067 if (ttl > TTL_FLOOR_LIMIT)
3068 ttl = TTL_FLOOR_LIMIT;
3069 daemon->min_cache_ttl = (unsigned long)ttl;
3070 }
3071 else if (option == LOPT_MAXCTTL)
3072 daemon->max_cache_ttl = (unsigned long)ttl;
3073 else if (option == LOPT_AUTHTTL)
3074 daemon->auth_ttl = (unsigned long)ttl;
3075 else if (option == LOPT_DHCPTTL)
3076 {
3077 daemon->dhcp_ttl = (unsigned long)ttl;
3078 daemon->use_dhcp_ttl = 1;
3079 }
3080 else
3081 daemon->local_ttl = (unsigned long)ttl;
3082 break;
3083 }
3084
3085#ifdef HAVE_DHCP
3086 case 'X': /* --dhcp-lease-max */
3087 if (!atoi_check(arg, &daemon->dhcp_max))
3088 ret_err(gen_err);
3089 break;
3090#endif
3091
3092#ifdef HAVE_TFTP
3093 case LOPT_TFTP_MAX: /* --tftp-max */
3094 if (!atoi_check(arg, &daemon->tftp_max))
3095 ret_err(gen_err);
3096 break;
3097
3098 case LOPT_TFTP_MTU: /* --tftp-mtu */
3099 if (!atoi_check(arg, &daemon->tftp_mtu))
3100 ret_err(gen_err);
3101 break;
3102
3103 case LOPT_PREFIX: /* --tftp-prefix */
3104 comma = split(arg);
3105 if (comma)
3106 {
3107 struct tftp_prefix *new = opt_malloc(sizeof(struct tftp_prefix));
3108 new->interface = opt_string_alloc(comma);
3109 new->prefix = opt_string_alloc(arg);
3110 new->next = daemon->if_prefix;
3111 daemon->if_prefix = new;
3112 }
3113 else
3114 daemon->tftp_prefix = opt_string_alloc(arg);
3115 break;
3116
3117 case LOPT_TFTPPORTS: /* --tftp-port-range */
3118 if (!(comma = split(arg)) ||
3119 !atoi_check16(arg, &daemon->start_tftp_port) ||
3120 !atoi_check16(comma, &daemon->end_tftp_port))
3121 ret_err(_("bad port range"));
3122
3123 if (daemon->start_tftp_port > daemon->end_tftp_port)
3124 {
3125 int tmp = daemon->start_tftp_port;
3126 daemon->start_tftp_port = daemon->end_tftp_port;
3127 daemon->end_tftp_port = tmp;
3128 }
3129
3130 break;
3131
3132 case LOPT_APREF: /* --tftp-unique-root */
3133 if (!arg || strcasecmp(arg, "ip") == 0)
3134 set_option_bool(OPT_TFTP_APREF_IP);
3135 else if (strcasecmp(arg, "mac") == 0)
3136 set_option_bool(OPT_TFTP_APREF_MAC);
3137 else
3138 ret_err(gen_err);
3139 break;
3140#endif
3141
3142 case LOPT_BRIDGE: /* --bridge-interface */
3143 {
3144 struct dhcp_bridge *new;
3145
3146 if (!(comma = split(arg)) || strlen(arg) > IF_NAMESIZE - 1 )
3147 ret_err(_("bad bridge-interface"));
3148
3149 for (new = daemon->bridges; new; new = new->next)
3150 if (strcmp(new->iface, arg) == 0)
3151 break;
3152
3153 if (!new)
3154 {
3155 new = opt_malloc(sizeof(struct dhcp_bridge));
3156 strcpy(new->iface, arg);
3157 new->alias = NULL;
3158 new->next = daemon->bridges;
3159 daemon->bridges = new;
3160 }
3161
3162 do {
3163 arg = comma;
3164 comma = split(arg);
3165 if (strlen(arg) != 0 && strlen(arg) <= IF_NAMESIZE - 1)
3166 {
3167 struct dhcp_bridge *b = opt_malloc(sizeof(struct dhcp_bridge));
3168 b->next = new->alias;
3169 new->alias = b;
3170 strcpy(b->iface, arg);
3171 }
3172 } while (comma);
3173
3174 break;
3175 }
3176
3177#ifdef HAVE_DHCP
3178 case LOPT_SHARED_NET: /* --shared-network */
3179 {
3180 struct shared_network *new = opt_malloc(sizeof(struct shared_network));
3181
3182#ifdef HAVE_DHCP6
3183 new->shared_addr.s_addr = 0;
3184#endif
3185 new->if_index = 0;
3186
3187 if (!(comma = split(arg)))
3188 {
3189 snerr:
3190 free(new);
3191 ret_err(_("bad shared-network"));
3192 }
3193
3194 if (inet_pton(AF_INET, comma, &new->shared_addr))
3195 {
3196 if (!inet_pton(AF_INET, arg, &new->match_addr) &&
3197 !(new->if_index = if_nametoindex(arg)))
3198 goto snerr;
3199 }
3200#ifdef HAVE_DHCP6
3201 else if (inet_pton(AF_INET6, comma, &new->shared_addr6))
3202 {
3203 if (!inet_pton(AF_INET6, arg, &new->match_addr6) &&
3204 !(new->if_index = if_nametoindex(arg)))
3205 goto snerr;
3206 }
3207#endif
3208 else
3209 goto snerr;
3210
3211 new->next = daemon->shared_networks;
3212 daemon->shared_networks = new;
3213 break;
3214 }
3215
3216 case 'F': /* --dhcp-range */
3217 {
3218 int k, leasepos = 2;
3219 char *cp, *a[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
3220 struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context));
3221
3222 memset (new, 0, sizeof(*new));
3223
3224 while(1)
3225 {
3226 for (cp = arg; *cp; cp++)
3227 if (!(*cp == ' ' || *cp == '.' || *cp == ':' ||
3228 (*cp >= 'a' && *cp <= 'f') || (*cp >= 'A' && *cp <= 'F') ||
3229 (*cp >='0' && *cp <= '9')))
3230 break;
3231
3232 if (*cp != ',' && (comma = split(arg)))
3233 {
3234 if (is_tag_prefix(arg))
3235 {
3236 /* ignore empty tag */
3237 if (arg[4])
3238 new->filter = dhcp_netid_create(arg+4, new->filter);
3239 }
3240 else
3241 {
3242 if (new->netid.net)
3243 {
3244 dhcp_context_free(new);
3245 ret_err(_("only one tag allowed"));
3246 }
3247 else
3248 new->netid.net = opt_string_alloc(set_prefix(arg));
3249 }
3250 arg = comma;
3251 }
3252 else
3253 {
3254 a[0] = arg;
3255 break;
3256 }
3257 }
3258
3259 for (k = 1; k < 8; k++)
3260 if (!(a[k] = split(a[k-1])))
3261 break;
3262
3263 if (k < 2)
3264 {
3265 dhcp_context_free(new);
3266 ret_err(_("bad dhcp-range"));
3267 }
3268
3269 if (inet_pton(AF_INET, a[0], &new->start))
3270 {
3271 new->next = daemon->dhcp;
3272 new->lease_time = DEFLEASE;
3273 daemon->dhcp = new;
3274 new->end = new->start;
3275 if (strcmp(a[1], "static") == 0)
3276 new->flags |= CONTEXT_STATIC;
3277 else if (strcmp(a[1], "proxy") == 0)
3278 new->flags |= CONTEXT_PROXY;
3279 else if (!inet_pton(AF_INET, a[1], &new->end))
3280 {
3281 dhcp_context_free(new);
3282 ret_err(_("bad dhcp-range"));
3283 }
3284
3285 if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr))
3286 {
3287 struct in_addr tmp = new->start;
3288 new->start = new->end;
3289 new->end = tmp;
3290 }
3291
3292 if (k >= 3 && strchr(a[2], '.') &&
3293 (inet_pton(AF_INET, a[2], &new->netmask) > 0))
3294 {
3295 new->flags |= CONTEXT_NETMASK;
3296 leasepos = 3;
3297 if (!is_same_net(new->start, new->end, new->netmask))
3298 {
3299 dhcp_context_free(new);
3300 ret_err(_("inconsistent DHCP range"));
3301 }
3302
3303
3304 if (k >= 4 && strchr(a[3], '.') &&
3305 (inet_pton(AF_INET, a[3], &new->broadcast) > 0))
3306 {
3307 new->flags |= CONTEXT_BRDCAST;
3308 leasepos = 4;
3309 }
3310 }
3311 }
3312#ifdef HAVE_DHCP6
3313 else if (inet_pton(AF_INET6, a[0], &new->start6))
3314 {
3315 const char *err = NULL;
3316
3317 new->flags |= CONTEXT_V6;
3318 new->prefix = 64; /* default */
3319 new->end6 = new->start6;
3320 new->lease_time = DEFLEASE6;
3321 new->next = daemon->dhcp6;
3322 daemon->dhcp6 = new;
3323
3324 for (leasepos = 1; leasepos < k; leasepos++)
3325 {
3326 if (strcmp(a[leasepos], "static") == 0)
3327 new->flags |= CONTEXT_STATIC | CONTEXT_DHCP;
3328 else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 )
3329 new->flags |= CONTEXT_RA;
3330 else if (strcmp(a[leasepos], "ra-names") == 0)
3331 new->flags |= CONTEXT_RA_NAME | CONTEXT_RA;
3332 else if (strcmp(a[leasepos], "ra-advrouter") == 0)
3333 new->flags |= CONTEXT_RA_ROUTER | CONTEXT_RA;
3334 else if (strcmp(a[leasepos], "ra-stateless") == 0)
3335 new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP | CONTEXT_RA;
3336 else if (strcmp(a[leasepos], "off-link") == 0)
3337 new->flags |= CONTEXT_RA_OFF_LINK;
3338 else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6))
3339 new->flags |= CONTEXT_DHCP;
3340 else if (strstr(a[leasepos], "constructor:") == a[leasepos])
3341 {
3342 new->template_interface = opt_string_alloc(a[leasepos] + 12);
3343 new->flags |= CONTEXT_TEMPLATE;
3344 }
3345 else
3346 break;
3347 }
3348
3349 /* bare integer < 128 is prefix value */
3350 if (leasepos < k)
3351 {
3352 int pref;
3353 for (cp = a[leasepos]; *cp; cp++)
3354 if (!(*cp >= '0' && *cp <= '9'))
3355 break;
3356 if (!*cp && (pref = atoi(a[leasepos])) <= 128)
3357 {
3358 new->prefix = pref;
3359 leasepos++;
3360 }
3361 }
3362
3363 if (new->prefix > 64)
3364 {
3365 if (new->flags & CONTEXT_RA)
3366 err=(_("prefix length must be exactly 64 for RA subnets"));
3367 else if (new->flags & CONTEXT_TEMPLATE)
3368 err=(_("prefix length must be exactly 64 for subnet constructors"));
3369 }
3370 else if (new->prefix < 64)
3371 err=(_("prefix length must be at least 64"));
3372
3373 if (!err && !is_same_net6(&new->start6, &new->end6, new->prefix))
3374 err=(_("inconsistent DHCPv6 range"));
3375
3376 if (err)
3377 {
3378 dhcp_context_free(new);
3379 ret_err(err);
3380 }
3381
3382 /* dhcp-range=:: enables DHCP stateless on any interface */
3383 if (IN6_IS_ADDR_UNSPECIFIED(&new->start6) && !(new->flags & CONTEXT_TEMPLATE))
3384 new->prefix = 0;
3385
3386 if (new->flags & CONTEXT_TEMPLATE)
3387 {
3388 struct in6_addr zero;
3389 memset(&zero, 0, sizeof(zero));
3390 if (!is_same_net6(&zero, &new->start6, new->prefix))
3391 {
3392 dhcp_context_free(new);
3393 ret_err(_("prefix must be zero with \"constructor:\" argument"));
3394 }
3395 }
3396
3397 if (addr6part(&new->start6) > addr6part(&new->end6))
3398 {
3399 struct in6_addr tmp = new->start6;
3400 new->start6 = new->end6;
3401 new->end6 = tmp;
3402 }
3403 }
3404#endif
3405 else
3406 {
3407 dhcp_context_free(new);
3408 ret_err(_("bad dhcp-range"));
3409 }
3410
3411 if (leasepos < k)
3412 {
3413 if (leasepos != k-1)
3414 {
3415 dhcp_context_free(new);
3416 ret_err(_("bad dhcp-range"));
3417 }
3418
3419 if (strcmp(a[leasepos], "infinite") == 0)
3420 {
3421 new->lease_time = 0xffffffff;
3422 new->flags |= CONTEXT_SETLEASE;
3423 }
3424 else if (strcmp(a[leasepos], "deprecated") == 0)
3425 new->flags |= CONTEXT_DEPRECATE;
3426 else
3427 {
3428 int fac = 1;
3429 if (strlen(a[leasepos]) > 0)
3430 {
3431 switch (a[leasepos][strlen(a[leasepos]) - 1])
3432 {
3433 case 'w':
3434 case 'W':
3435 fac *= 7;
3436 /* fall through */
3437 case 'd':
3438 case 'D':
3439 fac *= 24;
3440 /* fall through */
3441 case 'h':
3442 case 'H':
3443 fac *= 60;
3444 /* fall through */
3445 case 'm':
3446 case 'M':
3447 fac *= 60;
3448 /* fall through */
3449 case 's':
3450 case 'S':
3451 a[leasepos][strlen(a[leasepos]) - 1] = 0;
3452 }
3453
3454 for (cp = a[leasepos]; *cp; cp++)
3455 if (!(*cp >= '0' && *cp <= '9'))
3456 break;
3457
3458 if (*cp || (leasepos+1 < k))
3459 ret_err_free(_("bad dhcp-range"), new);
3460
3461 new->lease_time = atoi(a[leasepos]) * fac;
3462 new->flags |= CONTEXT_SETLEASE;
3463 /* Leases of a minute or less confuse
3464 some clients, notably Apple's */
3465 if (new->lease_time < 120)
3466 new->lease_time = 120;
3467 }
3468 }
3469 }
3470
3471 break;
3472 }
3473
3474 case LOPT_BANK:
3475 case 'G': /* --dhcp-host */
3476 {
3477 struct dhcp_config *new;
3478 struct in_addr in;
3479
3480 new = opt_malloc(sizeof(struct dhcp_config));
3481
3482 new->next = daemon->dhcp_conf;
3483 new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0;
3484 new->hwaddr = NULL;
3485 new->netid = NULL;
3486 new->filter = NULL;
3487 new->clid = NULL;
3488#ifdef HAVE_DHCP6
3489 new->addr6 = NULL;
3490#endif
3491
3492 while (arg)
3493 {
3494 comma = split(arg);
3495 if (strchr(arg, ':')) /* ethernet address, netid or binary CLID */
3496 {
3497 if ((arg[0] == 'i' || arg[0] == 'I') &&
3498 (arg[1] == 'd' || arg[1] == 'D') &&
3499 arg[2] == ':')
3500 {
3501 if (arg[3] == '*')
3502 new->flags |= CONFIG_NOCLID;
3503 else
3504 {
3505 int len;
3506 arg += 3; /* dump id: */
3507 if (strchr(arg, ':'))
3508 len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
3509 else
3510 {
3511 unhide_metas(arg);
3512 len = (int) strlen(arg);
3513 }
3514
3515 if (len == -1)
3516 {
3517 dhcp_config_free(new);
3518 ret_err(_("bad hex constant"));
3519 }
3520 else if ((new->clid = opt_malloc(len)))
3521 {
3522 new->flags |= CONFIG_CLID;
3523 new->clid_len = len;
3524 memcpy(new->clid, arg, len);
3525 }
3526 }
3527 }
3528 /* dhcp-host has strange backwards-compat needs. */
3529 else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg)
3530 {
3531 struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
3532 newlist->next = new->netid;
3533 new->netid = newlist;
3534 newlist->list = dhcp_netid_create(arg+4, NULL);
3535 }
3536 else if (strstr(arg, "tag:") == arg)
3537 new->filter = dhcp_netid_create(arg+4, new->filter);
3538
3539#ifdef HAVE_DHCP6
3540 else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
3541 {
3542 char *pref;
3543 struct in6_addr in6;
3544 struct addrlist *new_addr;
3545
3546 arg[strlen(arg)-1] = 0;
3547 arg++;
3548 pref = split_chr(arg, '/');
3549
3550 if (!inet_pton(AF_INET6, arg, &in6))
3551 {
3552 dhcp_config_free(new);
3553 ret_err(_("bad IPv6 address"));
3554 }
3555
3556 new_addr = opt_malloc(sizeof(struct addrlist));
3557 new_addr->next = new->addr6;
3558 new_addr->flags = 0;
3559 new_addr->addr.addr6 = in6;
3560 new->addr6 = new_addr;
3561
3562 if (pref)
3563 {
3564 u64 addrpart = addr6part(&in6);
3565
3566 if (!atoi_check(pref, &new_addr->prefixlen) ||
3567 new_addr->prefixlen > 128 ||
3568 ((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
3569 {
3570 dhcp_config_free(new);
3571 ret_err(_("bad IPv6 prefix"));
3572 }
3573
3574 new_addr->flags |= ADDRLIST_PREFIX;
3575 }
3576
3577 for (i= 0; i < 8; i++)
3578 if (in6.s6_addr[i] != 0)
3579 break;
3580
3581 /* set WILDCARD if network part all zeros */
3582 if (i == 8)
3583 new_addr->flags |= ADDRLIST_WILDCARD;
3584
3585 new->flags |= CONFIG_ADDR6;
3586 }
3587#endif
3588 else
3589 {
3590 struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config));
3591 if ((newhw->hwaddr_len = parse_hex(arg, newhw->hwaddr, DHCP_CHADDR_MAX,
3592 &newhw->wildcard_mask, &newhw->hwaddr_type)) == -1)
3593 {
3594 free(newhw);
3595 dhcp_config_free(new);
3596 ret_err(_("bad hex constant"));
3597 }
3598 else
3599 {
3600 newhw->next = new->hwaddr;
3601 new->hwaddr = newhw;
3602 }
3603 }
3604 }
3605 else if (strchr(arg, '.') && (inet_pton(AF_INET, arg, &in) > 0))
3606 {
3607 struct dhcp_config *configs;
3608
3609 new->addr = in;
3610 new->flags |= CONFIG_ADDR;
3611
3612 /* If the same IP appears in more than one host config, then DISCOVER
3613 for one of the hosts will get the address, but REQUEST will be NAKed,
3614 since the address is reserved by the other one -> protocol loop. */
3615 for (configs = daemon->dhcp_conf; configs; configs = configs->next)
3616 if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
3617 {
3618 inet_ntop(AF_INET, &in, daemon->addrbuff, ADDRSTRLEN);
3619 sprintf(errstr, _("duplicate dhcp-host IP address %s"),
3620 daemon->addrbuff);
3621 return 0;
3622 }
3623 }
3624 else
3625 {
3626 char *cp, *lastp = NULL, last = 0;
3627 int fac = 1, isdig = 0;
3628
3629 if (strlen(arg) > 1)
3630 {
3631 lastp = arg + strlen(arg) - 1;
3632 last = *lastp;
3633 switch (last)
3634 {
3635 case 'w':
3636 case 'W':
3637 fac *= 7;
3638 /* fall through */
3639 case 'd':
3640 case 'D':
3641 fac *= 24;
3642 /* fall through */
3643 case 'h':
3644 case 'H':
3645 fac *= 60;
3646 /* fall through */
3647 case 'm':
3648 case 'M':
3649 fac *= 60;
3650 /* fall through */
3651 case 's':
3652 case 'S':
3653 *lastp = 0;
3654 }
3655 }
3656
3657 for (cp = arg; *cp; cp++)
3658 if (isdigit((unsigned char)*cp))
3659 isdig = 1;
3660 else if (*cp != ' ')
3661 break;
3662
3663 if (*cp)
3664 {
3665 if (lastp)
3666 *lastp = last;
3667 if (strcmp(arg, "infinite") == 0)
3668 {
3669 new->lease_time = 0xffffffff;
3670 new->flags |= CONFIG_TIME;
3671 }
3672 else if (strcmp(arg, "ignore") == 0)
3673 new->flags |= CONFIG_DISABLE;
3674 else
3675 {
3676 if (!(new->hostname = canonicalise_opt(arg)) ||
3677 !legal_hostname(new->hostname))
3678 {
3679 dhcp_config_free(new);
3680 ret_err(_("bad DHCP host name"));
3681 }
3682
3683 new->flags |= CONFIG_NAME;
3684 new->domain = strip_hostname(new->hostname);
3685 }
3686 }
3687 else if (isdig)
3688 {
3689 new->lease_time = atoi(arg) * fac;
3690 /* Leases of a minute or less confuse
3691 some clients, notably Apple's */
3692 if (new->lease_time < 120)
3693 new->lease_time = 120;
3694 new->flags |= CONFIG_TIME;
3695 }
3696 }
3697
3698 arg = comma;
3699 }
3700
3701 daemon->dhcp_conf = new;
3702 break;
3703 }
3704
3705 case LOPT_TAG_IF: /* --tag-if */
3706 {
3707 struct tag_if *new = opt_malloc(sizeof(struct tag_if));
3708
3709 new->tag = NULL;
3710 new->set = NULL;
3711 new->next = NULL;
3712
3713 /* preserve order */
3714 if (!daemon->tag_if)
3715 daemon->tag_if = new;
3716 else
3717 {
3718 struct tag_if *tmp;
3719 for (tmp = daemon->tag_if; tmp->next; tmp = tmp->next);
3720 tmp->next = new;
3721 }
3722
3723 while (arg)
3724 {
3725 size_t len;
3726
3727 comma = split(arg);
3728 len = strlen(arg);
3729
3730 if (len < 5)
3731 {
3732 new->set = NULL;
3733 break;
3734 }
3735 else
3736 {
3737 struct dhcp_netid *newtag = dhcp_netid_create(arg+4, NULL);
3738
3739 if (strstr(arg, "set:") == arg)
3740 {
3741 struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
3742 newlist->next = new->set;
3743 new->set = newlist;
3744 newlist->list = newtag;
3745 }
3746 else if (strstr(arg, "tag:") == arg)
3747 {
3748 newtag->next = new->tag;
3749 new->tag = newtag;
3750 }
3751 else
3752 {
3753 new->set = NULL;
3754 dhcp_netid_free(newtag);
3755 break;
3756 }
3757 }
3758
3759 arg = comma;
3760 }
3761
3762 if (!new->set)
3763 {
3764 dhcp_netid_free(new->tag);
3765 dhcp_netid_list_free(new->set);
3766 ret_err_free(_("bad tag-if"), new);
3767 }
3768
3769 break;
3770 }
3771
3772
3773 case 'O': /* --dhcp-option */
3774 case LOPT_FORCE: /* --dhcp-option-force */
3775 case LOPT_OPTS:
3776 case LOPT_MATCH: /* --dhcp-match */
3777 return parse_dhcp_opt(errstr, arg,
3778 option == LOPT_FORCE ? DHOPT_FORCE :
3779 (option == LOPT_MATCH ? DHOPT_MATCH :
3780 (option == LOPT_OPTS ? DHOPT_BANK : 0)));
3781
3782 case LOPT_NAME_MATCH: /* --dhcp-name-match */
3783 {
3784 struct dhcp_match_name *new = opt_malloc(sizeof(struct dhcp_match_name));
3785 struct dhcp_netid *id = opt_malloc(sizeof(struct dhcp_netid));
3786 ssize_t len;
3787
3788 if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
3789 ret_err(gen_err);
3790
3791 new->wildcard = 0;
3792 new->netid = id;
3793 id->net = opt_string_alloc(set_prefix(arg));
3794
3795 if (comma[len-1] == '*')
3796 {
3797 comma[len-1] = 0;
3798 new->wildcard = 1;
3799 }
3800 new->name = opt_string_alloc(comma);
3801
3802 new->next = daemon->dhcp_name_match;
3803 daemon->dhcp_name_match = new;
3804
3805 break;
3806 }
3807
3808 case 'M': /* --dhcp-boot */
3809 {
3810 struct dhcp_netid *id = dhcp_tags(&arg);
3811
3812 if (!arg)
3813 {
3814 ret_err(gen_err);
3815 }
3816 else
3817 {
3818 char *dhcp_file, *dhcp_sname = NULL, *tftp_sname = NULL;
3819 struct in_addr dhcp_next_server;
3820 struct dhcp_boot *new;
3821 comma = split(arg);
3822 dhcp_file = opt_string_alloc(arg);
3823 dhcp_next_server.s_addr = 0;
3824 if (comma)
3825 {
3826 arg = comma;
3827 comma = split(arg);
3828 dhcp_sname = opt_string_alloc(arg);
3829 if (comma)
3830 {
3831 unhide_metas(comma);
3832 if (!(inet_pton(AF_INET, comma, &dhcp_next_server) > 0))
3833 {
3834 /*
3835 * The user may have specified the tftp hostname here.
3836 * save it so that it can be resolved/looked up during
3837 * actual dhcp_reply().
3838 */
3839
3840 tftp_sname = opt_string_alloc(comma);
3841 dhcp_next_server.s_addr = 0;
3842 }
3843 }
3844 }
3845
3846 new = opt_malloc(sizeof(struct dhcp_boot));
3847 new->file = dhcp_file;
3848 new->sname = dhcp_sname;
3849 new->tftp_sname = tftp_sname;
3850 new->next_server = dhcp_next_server;
3851 new->netid = id;
3852 new->next = daemon->boot_config;
3853 daemon->boot_config = new;
3854 }
3855
3856 break;
3857 }
3858
3859 case LOPT_REPLY_DELAY: /* --dhcp-reply-delay */
3860 {
3861 struct dhcp_netid *id = dhcp_tags(&arg);
3862
3863 if (!arg)
3864 {
3865 ret_err(gen_err);
3866 }
3867 else
3868 {
3869 struct delay_config *new;
3870 int delay;
3871 if (!atoi_check(arg, &delay))
3872 ret_err(gen_err);
3873
3874 new = opt_malloc(sizeof(struct delay_config));
3875 new->delay = delay;
3876 new->netid = id;
3877 new->next = daemon->delay_conf;
3878 daemon->delay_conf = new;
3879 }
3880
3881 break;
3882 }
3883
3884 case LOPT_PXE_PROMT: /* --pxe-prompt */
3885 {
3886 struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt));
3887 int timeout;
3888
3889 new->netid = NULL;
3890 new->opt = 10; /* PXE_MENU_PROMPT */
3891 new->netid = dhcp_tags(&arg);
3892
3893 if (!arg)
3894 {
3895 dhcp_opt_free(new);
3896 ret_err(gen_err);
3897 }
3898 else
3899 {
3900 comma = split(arg);
3901 unhide_metas(arg);
3902 new->len = strlen(arg) + 1;
3903 new->val = opt_malloc(new->len);
3904 memcpy(new->val + 1, arg, new->len - 1);
3905
3906 new->u.vendor_class = NULL;
3907 new->flags = DHOPT_VENDOR | DHOPT_VENDOR_PXE;
3908
3909 if (comma && atoi_check(comma, &timeout))
3910 *(new->val) = timeout;
3911 else
3912 *(new->val) = 255;
3913
3914 new->next = daemon->dhcp_opts;
3915 daemon->dhcp_opts = new;
3916 daemon->enable_pxe = 1;
3917 }
3918
3919 break;
3920 }
3921
3922 case LOPT_PXE_SERV: /* --pxe-service */
3923 {
3924 struct pxe_service *new = opt_malloc(sizeof(struct pxe_service));
3925 char *CSA[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
3926 "IA32_EFI", "x86-64_EFI", "Xscale_EFI", "BC_EFI",
3927 "ARM32_EFI", "ARM64_EFI", NULL };
3928 static int boottype = 32768;
3929
3930 new->netid = NULL;
3931 new->sname = NULL;
3932 new->server.s_addr = 0;
3933 new->netid = dhcp_tags(&arg);
3934
3935 if (arg && (comma = split(arg)))
3936 {
3937 for (i = 0; CSA[i]; i++)
3938 if (strcasecmp(CSA[i], arg) == 0)
3939 break;
3940
3941 if (CSA[i] || atoi_check(arg, &i))
3942 {
3943 arg = comma;
3944 comma = split(arg);
3945
3946 new->CSA = i;
3947 new->menu = opt_string_alloc(arg);
3948
3949 if (!comma)
3950 {
3951 new->type = 0; /* local boot */
3952 new->basename = NULL;
3953 }
3954 else
3955 {
3956 arg = comma;
3957 comma = split(arg);
3958 if (atoi_check(arg, &i))
3959 {
3960 new->type = i;
3961 new->basename = NULL;
3962 }
3963 else
3964 {
3965 new->type = boottype++;
3966 new->basename = opt_string_alloc(arg);
3967 }
3968
3969 if (comma)
3970 {
3971 if (!inet_pton(AF_INET, comma, &new->server))
3972 {
3973 new->server.s_addr = 0;
3974 new->sname = opt_string_alloc(comma);
3975 }
3976
3977 }
3978 }
3979
3980 /* Order matters */
3981 new->next = NULL;
3982 if (!daemon->pxe_services)
3983 daemon->pxe_services = new;
3984 else
3985 {
3986 struct pxe_service *s;
3987 for (s = daemon->pxe_services; s->next; s = s->next);
3988 s->next = new;
3989 }
3990
3991 daemon->enable_pxe = 1;
3992 break;
3993
3994 }
3995 }
3996
3997 ret_err(gen_err);
3998 }
3999
4000 case '4': /* --dhcp-mac */
4001 {
4002 if (!(comma = split(arg)))
4003 ret_err(gen_err);
4004 else
4005 {
4006 struct dhcp_mac *new = opt_malloc(sizeof(struct dhcp_mac));
4007 new->netid.net = opt_string_alloc(set_prefix(arg));
4008 unhide_metas(comma);
4009 new->hwaddr_len = parse_hex(comma, new->hwaddr, DHCP_CHADDR_MAX, &new->mask, &new->hwaddr_type);
4010 if (new->hwaddr_len == -1)
4011 {
4012 free(new->netid.net);
4013 ret_err_free(gen_err, new);
4014 }
4015 else
4016 {
4017 new->next = daemon->dhcp_macs;
4018 daemon->dhcp_macs = new;
4019 }
4020 }
4021 }
4022 break;
4023
4024 case 'U': /* --dhcp-vendorclass */
4025 case 'j': /* --dhcp-userclass */
4026 case LOPT_CIRCUIT: /* --dhcp-circuitid */
4027 case LOPT_REMOTE: /* --dhcp-remoteid */
4028 case LOPT_SUBSCR: /* --dhcp-subscrid */
4029 {
4030 unsigned char *p;
4031 int dig = 0;
4032 struct dhcp_vendor *new = opt_malloc(sizeof(struct dhcp_vendor));
4033
4034 if (!(comma = split(arg)))
4035 ret_err_free(gen_err, new);
4036
4037 new->netid.net = opt_string_alloc(set_prefix(arg));
4038 /* check for hex string - must digits may include : must not have nothing else,
4039 only allowed for agent-options. */
4040
4041 arg = comma;
4042 if ((comma = split(arg)))
4043 {
4044 if (option != 'U' || strstr(arg, "enterprise:") != arg)
4045 {
4046 free(new->netid.net);
4047 ret_err_free(gen_err, new);
4048 }
4049 else
4050 new->enterprise = atoi(arg+11);
4051 }
4052 else
4053 comma = arg;
4054
4055 for (p = (unsigned char *)comma; *p; p++)
4056 if (isxdigit(*p))
4057 dig = 1;
4058 else if (*p != ':')
4059 break;
4060 unhide_metas(comma);
4061 if (option == 'U' || option == 'j' || *p || !dig)
4062 {
4063 new->len = strlen(comma);
4064 new->data = opt_malloc(new->len);
4065 memcpy(new->data, comma, new->len);
4066 }
4067 else
4068 {
4069 new->len = parse_hex(comma, (unsigned char *)comma, strlen(comma), NULL, NULL);
4070 new->data = opt_malloc(new->len);
4071 memcpy(new->data, comma, new->len);
4072 }
4073
4074 switch (option)
4075 {
4076 case 'j':
4077 new->match_type = MATCH_USER;
4078 break;
4079 case 'U':
4080 new->match_type = MATCH_VENDOR;
4081 break;
4082 case LOPT_CIRCUIT:
4083 new->match_type = MATCH_CIRCUIT;
4084 break;
4085 case LOPT_REMOTE:
4086 new->match_type = MATCH_REMOTE;
4087 break;
4088 case LOPT_SUBSCR:
4089 new->match_type = MATCH_SUBSCRIBER;
4090 break;
4091 }
4092 new->next = daemon->dhcp_vendors;
4093 daemon->dhcp_vendors = new;
4094
4095 break;
4096 }
4097
4098 case LOPT_ALTPORT: /* --dhcp-alternate-port */
4099 if (!arg)
4100 {
4101 daemon->dhcp_server_port = DHCP_SERVER_ALTPORT;
4102 daemon->dhcp_client_port = DHCP_CLIENT_ALTPORT;
4103 }
4104 else
4105 {
4106 comma = split(arg);
4107 if (!atoi_check16(arg, &daemon->dhcp_server_port) ||
4108 (comma && !atoi_check16(comma, &daemon->dhcp_client_port)))
4109 ret_err(_("invalid port number"));
4110 if (!comma)
4111 daemon->dhcp_client_port = daemon->dhcp_server_port+1;
4112 }
4113 break;
4114
4115 case 'J': /* --dhcp-ignore */
4116 case LOPT_NO_NAMES: /* --dhcp-ignore-names */
4117 case LOPT_BROADCAST: /* --dhcp-broadcast */
4118 case '3': /* --bootp-dynamic */
4119 case LOPT_GEN_NAMES: /* --dhcp-generate-names */
4120 {
4121 struct dhcp_netid_list *new = opt_malloc(sizeof(struct dhcp_netid_list));
4122 struct dhcp_netid *list = NULL;
4123 if (option == 'J')
4124 {
4125 new->next = daemon->dhcp_ignore;
4126 daemon->dhcp_ignore = new;
4127 }
4128 else if (option == LOPT_BROADCAST)
4129 {
4130 new->next = daemon->force_broadcast;
4131 daemon->force_broadcast = new;
4132 }
4133 else if (option == '3')
4134 {
4135 new->next = daemon->bootp_dynamic;
4136 daemon->bootp_dynamic = new;
4137 }
4138 else if (option == LOPT_GEN_NAMES)
4139 {
4140 new->next = daemon->dhcp_gen_names;
4141 daemon->dhcp_gen_names = new;
4142 }
4143 else
4144 {
4145 new->next = daemon->dhcp_ignore_names;
4146 daemon->dhcp_ignore_names = new;
4147 }
4148
4149 while (arg) {
4150 comma = split(arg);
4151 list = dhcp_netid_create(is_tag_prefix(arg) ? arg+4 :arg, list);
4152 arg = comma;
4153 }
4154
4155 new->list = list;
4156 break;
4157 }
4158
4159 case LOPT_PROXY: /* --dhcp-proxy */
4160 daemon->override = 1;
4161 while (arg) {
4162 struct addr_list *new = opt_malloc(sizeof(struct addr_list));
4163 comma = split(arg);
4164 if (!(inet_pton(AF_INET, arg, &new->addr) > 0))
4165 ret_err_free(_("bad dhcp-proxy address"), new);
4166 new->next = daemon->override_relays;
4167 daemon->override_relays = new;
4168 arg = comma;
4169 }
4170 break;
4171
4172 case LOPT_PXE_VENDOR: /* --dhcp-pxe-vendor */
4173 {
4174 while (arg) {
4175 struct dhcp_pxe_vendor *new = opt_malloc(sizeof(struct dhcp_pxe_vendor));
4176 comma = split(arg);
4177 new->data = opt_string_alloc(arg);
4178 new->next = daemon->dhcp_pxe_vendors;
4179 daemon->dhcp_pxe_vendors = new;
4180 arg = comma;
4181 }
4182 }
4183 break;
4184
4185 case LOPT_RELAY: /* --dhcp-relay */
4186 {
4187 struct dhcp_relay *new = opt_malloc(sizeof(struct dhcp_relay));
4188 comma = split(arg);
4189 new->interface = opt_string_alloc(split(comma));
4190 new->iface_index = 0;
4191 if (comma && inet_pton(AF_INET, arg, &new->local) && inet_pton(AF_INET, comma, &new->server))
4192 {
4193 new->next = daemon->relay4;
4194 daemon->relay4 = new;
4195 }
4196#ifdef HAVE_DHCP6
4197 else if (comma && inet_pton(AF_INET6, arg, &new->local) && inet_pton(AF_INET6, comma, &new->server))
4198 {
4199 new->next = daemon->relay6;
4200 daemon->relay6 = new;
4201 }
4202#endif
4203 else
4204 {
4205 free(new->interface);
4206 ret_err_free(_("Bad dhcp-relay"), new);
4207 }
4208
4209 break;
4210 }
4211
4212#endif
4213
4214#ifdef HAVE_DHCP6
4215 case LOPT_RA_PARAM: /* --ra-param */
4216 if ((comma = split(arg)))
4217 {
4218 struct ra_interface *new = opt_malloc(sizeof(struct ra_interface));
4219 new->lifetime = -1;
4220 new->prio = 0;
4221 new->mtu = 0;
4222 new->mtu_name = NULL;
4223 new->name = opt_string_alloc(arg);
4224 if (strcasestr(comma, "mtu:") == comma)
4225 {
4226 arg = comma + 4;
4227 if (!(comma = split(comma)))
4228 goto err;
4229 if (!strcasecmp(arg, "off"))
4230 new->mtu = -1;
4231 else if (!atoi_check(arg, &new->mtu))
4232 new->mtu_name = opt_string_alloc(arg);
4233 else if (new->mtu < 1280)
4234 goto err;
4235 }
4236 if (strcasestr(comma, "high") == comma || strcasestr(comma, "low") == comma)
4237 {
4238 if (*comma == 'l' || *comma == 'L')
4239 new->prio = 0x18;
4240 else
4241 new->prio = 0x08;
4242 comma = split(comma);
4243 }
4244 arg = split(comma);
4245 if (!atoi_check(comma, &new->interval) ||
4246 (arg && !atoi_check(arg, &new->lifetime)))
4247 {
4248err:
4249 free(new->name);
4250 ret_err_free(_("bad RA-params"), new);
4251 }
4252
4253 new->next = daemon->ra_interfaces;
4254 daemon->ra_interfaces = new;
4255 }
4256 break;
4257
4258 case LOPT_DUID: /* --dhcp-duid */
4259 if (!(comma = split(arg)) || !atoi_check(arg, (int *)&daemon->duid_enterprise))
4260 ret_err(_("bad DUID"));
4261 else
4262 {
4263 daemon->duid_config_len = parse_hex(comma,(unsigned char *)comma, strlen(comma), NULL, NULL);
4264 daemon->duid_config = opt_malloc(daemon->duid_config_len);
4265 memcpy(daemon->duid_config, comma, daemon->duid_config_len);
4266 }
4267 break;
4268#endif
4269
4270 case 'V': /* --alias */
4271 {
4272 char *dash, *a[3] = { NULL, NULL, NULL };
4273 int k = 0;
4274 struct doctor *new = opt_malloc(sizeof(struct doctor));
4275 new->next = daemon->doctors;
4276 daemon->doctors = new;
4277 new->mask.s_addr = 0xffffffff;
4278 new->end.s_addr = 0;
4279
4280 if ((a[0] = arg))
4281 for (k = 1; k < 3; k++)
4282 {
4283 if (!(a[k] = split(a[k-1])))
4284 break;
4285 unhide_metas(a[k]);
4286 }
4287
4288 dash = split_chr(a[0], '-');
4289
4290 if ((k < 2) ||
4291 (!(inet_pton(AF_INET, a[0], &new->in) > 0)) ||
4292 (!(inet_pton(AF_INET, a[1], &new->out) > 0)) ||
4293 (k == 3 && !inet_pton(AF_INET, a[2], &new->mask)))
4294 ret_err(_("missing address in alias"));
4295
4296 if (dash &&
4297 (!(inet_pton(AF_INET, dash, &new->end) > 0) ||
4298 !is_same_net(new->in, new->end, new->mask) ||
4299 ntohl(new->in.s_addr) > ntohl(new->end.s_addr)))
4300 ret_err_free(_("invalid alias range"), new);
4301
4302 break;
4303 }
4304
4305 case LOPT_INTNAME: /* --interface-name */
4306 case LOPT_DYNHOST: /* --dynamic-host */
4307 {
4308 struct interface_name *new, **up;
4309 char *domain = arg;
4310
4311 arg = split(arg);
4312
4313 new = opt_malloc(sizeof(struct interface_name));
4314 memset(new, 0, sizeof(struct interface_name));
4315 new->flags = IN4 | IN6;
4316
4317 /* Add to the end of the list, so that first name
4318 of an interface is used for PTR lookups. */
4319 for (up = &daemon->int_names; *up; up = &((*up)->next));
4320 *up = new;
4321
4322 while ((comma = split(arg)))
4323 {
4324 if (inet_pton(AF_INET, arg, &new->proto4))
4325 new->flags |= INP4;
4326 else if (inet_pton(AF_INET6, arg, &new->proto6))
4327 new->flags |= INP6;
4328 else
4329 break;
4330
4331 arg = comma;
4332 }
4333
4334 if ((comma = split_chr(arg, '/')))
4335 {
4336 if (strcmp(comma, "4") == 0)
4337 new->flags &= ~IN6;
4338 else if (strcmp(comma, "6") == 0)
4339 new->flags &= ~IN4;
4340 else
4341 ret_err_free(gen_err, new);
4342 }
4343
4344 new->intr = opt_string_alloc(arg);
4345
4346 if (option == LOPT_DYNHOST)
4347 {
4348 if (!(new->flags & (INP4 | INP6)))
4349 ret_err(_("missing address in dynamic host"));
4350
4351 if (!(new->flags & IN4) || !(new->flags & IN6))
4352 arg = NULL; /* provoke error below */
4353
4354 new->flags &= ~(IN4 | IN6);
4355 }
4356 else
4357 {
4358 if (new->flags & (INP4 | INP6))
4359 arg = NULL; /* provoke error below */
4360 }
4361
4362 if (!domain || !arg || !(new->name = canonicalise_opt(domain)))
4363 ret_err(option == LOPT_DYNHOST ?
4364 _("bad dynamic host") : _("bad interface name"));
4365
4366 break;
4367 }
4368
4369 case LOPT_CNAME: /* --cname */
4370 {
4371 struct cname *new;
4372 char *alias, *target, *last, *pen;
4373 int ttl = -1;
4374
4375 for (last = pen = NULL, comma = arg; comma; comma = split(comma))
4376 {
4377 pen = last;
4378 last = comma;
4379 }
4380
4381 if (!pen)
4382 ret_err(_("bad CNAME"));
4383
4384 if (pen != arg && atoi_check(last, &ttl))
4385 last = pen;
4386
4387 target = canonicalise_opt(last);
4388
4389 while (arg != last)
4390 {
4391 int arglen = strlen(arg);
4392 alias = canonicalise_opt(arg);
4393
4394 if (!alias || !target)
4395 {
4396 free(target);
4397 free(alias);
4398 ret_err(_("bad CNAME"));
4399 }
4400
4401 for (new = daemon->cnames; new; new = new->next)
4402 if (hostname_isequal(new->alias, alias))
4403 {
4404 free(target);
4405 free(alias);
4406 ret_err(_("duplicate CNAME"));
4407 }
4408 new = opt_malloc(sizeof(struct cname));
4409 new->next = daemon->cnames;
4410 daemon->cnames = new;
4411 new->alias = alias;
4412 new->target = target;
4413 new->ttl = ttl;
4414
4415 for (arg += arglen+1; *arg && isspace(*arg); arg++);
4416 }
4417
4418 break;
4419 }
4420
4421 case LOPT_PTR: /* --ptr-record */
4422 {
4423 struct ptr_record *new;
4424 char *dom, *target = NULL;
4425
4426 comma = split(arg);
4427
4428 if (!(dom = canonicalise_opt(arg)) ||
4429 (comma && !(target = canonicalise_opt(comma))))
4430 {
4431 free(dom);
4432 free(target);
4433 ret_err(_("bad PTR record"));
4434 }
4435 else
4436 {
4437 new = opt_malloc(sizeof(struct ptr_record));
4438 new->next = daemon->ptr;
4439 daemon->ptr = new;
4440 new->name = dom;
4441 new->ptr = target;
4442 }
4443 break;
4444 }
4445
4446 case LOPT_NAPTR: /* --naptr-record */
4447 {
4448 char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
4449 int k = 0;
4450 struct naptr *new;
4451 int order, pref;
4452 char *name=NULL, *replace = NULL;
4453
4454 if ((a[0] = arg))
4455 for (k = 1; k < 7; k++)
4456 if (!(a[k] = split(a[k-1])))
4457 break;
4458
4459
4460 if (k < 6 ||
4461 !(name = canonicalise_opt(a[0])) ||
4462 !atoi_check16(a[1], &order) ||
4463 !atoi_check16(a[2], &pref) ||
4464 (k == 7 && !(replace = canonicalise_opt(a[6]))))
4465 {
4466 free(name);
4467 free(replace);
4468 ret_err(_("bad NAPTR record"));
4469 }
4470 else
4471 {
4472 new = opt_malloc(sizeof(struct naptr));
4473 new->next = daemon->naptr;
4474 daemon->naptr = new;
4475 new->name = name;
4476 new->flags = opt_string_alloc(a[3]);
4477 new->services = opt_string_alloc(a[4]);
4478 new->regexp = opt_string_alloc(a[5]);
4479 new->replace = replace;
4480 new->order = order;
4481 new->pref = pref;
4482 }
4483 break;
4484 }
4485
4486 case LOPT_RR: /* dns-rr */
4487 {
4488 struct txt_record *new;
4489 size_t len = 0;
4490 char *data;
4491 int class;
4492
4493 comma = split(arg);
4494 data = split(comma);
4495
4496 new = opt_malloc(sizeof(struct txt_record));
4497 new->name = NULL;
4498
4499 if (!atoi_check(comma, &class) ||
4500 !(new->name = canonicalise_opt(arg)) ||
4501 (data && (len = parse_hex(data, (unsigned char *)data, -1, NULL, NULL)) == -1U))
4502 {
4503 free(new->name);
4504 ret_err_free(_("bad RR record"), new);
4505 }
4506
4507 new->len = 0;
4508 new->class = class;
4509 new->next = daemon->rr;
4510 daemon->rr = new;
4511
4512 if (data)
4513 {
4514 new->txt = opt_malloc(len);
4515 new->len = len;
4516 memcpy(new->txt, data, len);
4517 }
4518
4519 break;
4520 }
4521
4522 case LOPT_CAA: /* --caa-record */
4523 {
4524 struct txt_record *new;
4525 char *tag, *value;
4526 int flags;
4527
4528 comma = split(arg);
4529 tag = split(comma);
4530 value = split(tag);
4531
4532 new = opt_malloc(sizeof(struct txt_record));
4533 new->next = daemon->rr;
4534 daemon->rr = new;
4535
4536 if (!atoi_check(comma, &flags) || !tag || !value || !(new->name = canonicalise_opt(arg)))
4537 ret_err(_("bad CAA record"));
4538
4539 unhide_metas(tag);
4540 unhide_metas(value);
4541
4542 new->len = strlen(tag) + strlen(value) + 2;
4543 new->txt = opt_malloc(new->len);
4544 new->txt[0] = flags;
4545 new->txt[1] = strlen(tag);
4546 memcpy(&new->txt[2], tag, strlen(tag));
4547 memcpy(&new->txt[2 + strlen(tag)], value, strlen(value));
4548 new->class = T_CAA;
4549
4550 break;
4551 }
4552
4553 case 'Y': /* --txt-record */
4554 {
4555 struct txt_record *new;
4556 unsigned char *p, *cnt;
4557 size_t len;
4558
4559 comma = split(arg);
4560
4561 new = opt_malloc(sizeof(struct txt_record));
4562 new->class = C_IN;
4563 new->stat = 0;
4564
4565 if (!(new->name = canonicalise_opt(arg)))
4566 ret_err_free(_("bad TXT record"), new);
4567
4568 new->next = daemon->txt;
4569 daemon->txt = new;
4570 len = comma ? strlen(comma) : 0;
4571 len += (len/255) + 1; /* room for extra counts */
4572 new->txt = p = opt_malloc(len);
4573
4574 cnt = p++;
4575 *cnt = 0;
4576
4577 while (comma && *comma)
4578 {
4579 unsigned char c = (unsigned char)*comma++;
4580
4581 if (c == ',' || *cnt == 255)
4582 {
4583 if (c != ',')
4584 comma--;
4585 cnt = p++;
4586 *cnt = 0;
4587 }
4588 else
4589 {
4590 *p++ = unhide_meta(c);
4591 (*cnt)++;
4592 }
4593 }
4594
4595 new->len = p - new->txt;
4596
4597 break;
4598 }
4599
4600 case 'W': /* --srv-host */
4601 {
4602 int port = 1, priority = 0, weight = 0;
4603 char *name, *target = NULL;
4604 struct mx_srv_record *new;
4605
4606 comma = split(arg);
4607
4608 if (!(name = canonicalise_opt(arg)))
4609 ret_err(_("bad SRV record"));
4610
4611 if (comma)
4612 {
4613 arg = comma;
4614 comma = split(arg);
4615 if (!(target = canonicalise_opt(arg)))
4616 ret_err_free(_("bad SRV target"), name);
4617
4618 if (comma)
4619 {
4620 arg = comma;
4621 comma = split(arg);
4622 if (!atoi_check16(arg, &port))
4623 {
4624 free(name);
4625 ret_err_free(_("invalid port number"), target);
4626 }
4627
4628 if (comma)
4629 {
4630 arg = comma;
4631 comma = split(arg);
4632 if (!atoi_check16(arg, &priority))
4633 {
4634 free(name);
4635 ret_err_free(_("invalid priority"), target);
4636 }
4637 if (comma && !atoi_check16(comma, &weight))
4638 {
4639 free(name);
4640 ret_err_free(_("invalid weight"), target);
4641 }
4642 }
4643 }
4644 }
4645
4646 new = opt_malloc(sizeof(struct mx_srv_record));
4647 new->next = daemon->mxnames;
4648 daemon->mxnames = new;
4649 new->issrv = 1;
4650 new->name = name;
4651 new->target = target;
4652 new->srvport = port;
4653 new->priority = priority;
4654 new->weight = weight;
4655 break;
4656 }
4657
4658 case LOPT_HOST_REC: /* --host-record */
4659 {
4660 struct host_record *new;
4661
4662 if (!arg || !(comma = split(arg)))
4663 ret_err(_("Bad host-record"));
4664
4665 new = opt_malloc(sizeof(struct host_record));
4666 memset(new, 0, sizeof(struct host_record));
4667 new->ttl = -1;
4668 new->flags = 0;
4669
4670 while (arg)
4671 {
4672 union all_addr addr;
4673 char *dig;
4674
4675 for (dig = arg; *dig != 0; dig++)
4676 if (*dig < '0' || *dig > '9')
4677 break;
4678 if (*dig == 0)
4679 new->ttl = atoi(arg);
4680 else if (inet_pton(AF_INET, arg, &addr.addr4))
4681 {
4682 new->addr = addr.addr4;
4683 new->flags |= HR_4;
4684 }
4685 else if (inet_pton(AF_INET6, arg, &addr.addr6))
4686 {
4687 new->addr6 = addr.addr6;
4688 new->flags |= HR_6;
4689 }
4690 else
4691 {
4692 char *canon = canonicalise_opt(arg);
4693 struct name_list *nl;
4694 if (!canon)
4695 {
4696 struct name_list *tmp = new->names, *next;
4697 for (tmp = new->names; tmp; tmp = next)
4698 {
4699 next = tmp->next;
4700 free(tmp);
4701 }
4702 ret_err_free(_("Bad name in host-record"), new);
4703 }
4704
4705 nl = opt_malloc(sizeof(struct name_list));
4706 nl->name = canon;
4707 /* keep order, so that PTR record goes to first name */
4708 nl->next = NULL;
4709 if (!new->names)
4710 new->names = nl;
4711 else
4712 {
4713 struct name_list *tmp;
4714 for (tmp = new->names; tmp->next; tmp = tmp->next);
4715 tmp->next = nl;
4716 }
4717 }
4718
4719 arg = comma;
4720 comma = split(arg);
4721 }
4722
4723 /* Keep list order */
4724 if (!daemon->host_records_tail)
4725 daemon->host_records = new;
4726 else
4727 daemon->host_records_tail->next = new;
4728 new->next = NULL;
4729 daemon->host_records_tail = new;
4730 break;
4731 }
4732
4733#ifdef HAVE_DNSSEC
4734 case LOPT_DNSSEC_STAMP: /* --dnssec-timestamp */
4735 daemon->timestamp_file = opt_string_alloc(arg);
4736 break;
4737
4738 case LOPT_DNSSEC_CHECK: /* --dnssec-check-unsigned */
4739 if (arg)
4740 {
4741 if (strcmp(arg, "no") == 0)
4742 set_option_bool(OPT_DNSSEC_IGN_NS);
4743 else
4744 ret_err(_("bad value for dnssec-check-unsigned"));
4745 }
4746 break;
4747
4748 case LOPT_TRUST_ANCHOR: /* --trust-anchor */
4749 {
4750 struct ds_config *new = opt_malloc(sizeof(struct ds_config));
4751 char *cp, *cp1, *keyhex, *digest, *algo = NULL;
4752 int len;
4753
4754 new->class = C_IN;
4755 new->name = NULL;
4756
4757 if ((comma = split(arg)) && (algo = split(comma)))
4758 {
4759 int class = 0;
4760 if (strcmp(comma, "IN") == 0)
4761 class = C_IN;
4762 else if (strcmp(comma, "CH") == 0)
4763 class = C_CHAOS;
4764 else if (strcmp(comma, "HS") == 0)
4765 class = C_HESIOD;
4766
4767 if (class != 0)
4768 {
4769 new->class = class;
4770 comma = algo;
4771 algo = split(comma);
4772 }
4773 }
4774
4775 if (!comma || !algo || !(digest = split(algo)) || !(keyhex = split(digest)) ||
4776 !atoi_check16(comma, &new->keytag) ||
4777 !atoi_check8(algo, &new->algo) ||
4778 !atoi_check8(digest, &new->digest_type) ||
4779 !(new->name = canonicalise_opt(arg)))
4780 ret_err_free(_("bad trust anchor"), new);
4781
4782 /* Upper bound on length */
4783 len = (2*strlen(keyhex))+1;
4784 new->digest = opt_malloc(len);
4785 unhide_metas(keyhex);
4786 /* 4034: "Whitespace is allowed within digits" */
4787 for (cp = keyhex; *cp; )
4788 if (isspace(*cp))
4789 for (cp1 = cp; *cp1; cp1++)
4790 *cp1 = *(cp1+1);
4791 else
4792 cp++;
4793 if ((new->digestlen = parse_hex(keyhex, (unsigned char *)new->digest, len, NULL, NULL)) == -1)
4794 {
4795 free(new->name);
4796 ret_err_free(_("bad HEX in trust anchor"), new);
4797 }
4798
4799 new->next = daemon->ds;
4800 daemon->ds = new;
4801
4802 break;
4803 }
4804#endif
4805
4806 default:
4807 ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"));
4808
4809 }
4810
4811 return 1;
4812}
4813
4814static void read_file(char *file, FILE *f, int hard_opt)
4815{
4816 volatile int lineno = 0;
4817 char *buff = daemon->namebuff;
4818
4819 while (fgets(buff, MAXDNAME, f))
4820 {
4821 int white, i;
4822 volatile int option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt;
4823 char *errmess, *p, *arg, *start;
4824 size_t len;
4825
4826 /* Memory allocation failure longjmps here if mem_recover == 1 */
4827 if (option != 0 || hard_opt == LOPT_REV_SERV)
4828 {
4829 if (setjmp(mem_jmp))
4830 continue;
4831 mem_recover = 1;
4832 }
4833
4834 arg = NULL;
4835 lineno++;
4836 errmess = NULL;
4837
4838 /* Implement quotes, inside quotes we allow \\ \" \n and \t
4839 metacharacters get hidden also strip comments */
4840 for (white = 1, p = buff; *p; p++)
4841 {
4842 if (*p == '"')
4843 {
4844 memmove(p, p+1, strlen(p+1)+1);
4845
4846 for(; *p && *p != '"'; p++)
4847 {
4848 if (*p == '\\' && strchr("\"tnebr\\", p[1]))
4849 {
4850 if (p[1] == 't')
4851 p[1] = '\t';
4852 else if (p[1] == 'n')
4853 p[1] = '\n';
4854 else if (p[1] == 'b')
4855 p[1] = '\b';
4856 else if (p[1] == 'r')
4857 p[1] = '\r';
4858 else if (p[1] == 'e') /* escape */
4859 p[1] = '\033';
4860 memmove(p, p+1, strlen(p+1)+1);
4861 }
4862 *p = hide_meta(*p);
4863 }
4864
4865 if (*p == 0)
4866 {
4867 errmess = _("missing \"");
4868 goto oops;
4869 }
4870
4871 memmove(p, p+1, strlen(p+1)+1);
4872 }
4873
4874 if (isspace(*p))
4875 {
4876 *p = ' ';
4877 white = 1;
4878 }
4879 else
4880 {
4881 if (white && *p == '#')
4882 {
4883 *p = 0;
4884 break;
4885 }
4886 white = 0;
4887 }
4888 }
4889
4890
4891 /* strip leading spaces */
4892 for (start = buff; *start && *start == ' '; start++);
4893
4894 /* strip trailing spaces */
4895 for (len = strlen(start); (len != 0) && (start[len-1] == ' '); len--);
4896
4897 if (len == 0)
4898 continue;
4899 else
4900 start[len] = 0;
4901
4902 if (option != 0)
4903 arg = start;
4904 else if ((p=strchr(start, '=')))
4905 {
4906 /* allow spaces around "=" */
4907 for (arg = p+1; *arg == ' '; arg++);
4908 for (; p >= start && (*p == ' ' || *p == '='); p--)
4909 *p = 0;
4910 }
4911 else
4912 arg = NULL;
4913
4914 if (option == 0)
4915 {
4916 for (option = 0, i = 0; opts[i].name; i++)
4917 if (strcmp(opts[i].name, start) == 0)
4918 {
4919 option = opts[i].val;
4920 break;
4921 }
4922
4923 if (!option)
4924 errmess = _("bad option");
4925 else if (opts[i].has_arg == 0 && arg)
4926 errmess = _("extraneous parameter");
4927 else if (opts[i].has_arg == 1 && !arg)
4928 errmess = _("missing parameter");
4929 else if (hard_opt == LOPT_REV_SERV && option != 'S' && option != LOPT_REV_SERV)
4930 errmess = _("illegal option");
4931 }
4932
4933 oops:
4934 if (errmess)
4935 strcpy(daemon->namebuff, errmess);
4936
4937 if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt == LOPT_REV_SERV))
4938 {
4939 sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file);
4940 if (hard_opt != 0)
4941 my_syslog(LOG_ERR, "%s", daemon->namebuff);
4942 else
4943 die("%s", daemon->namebuff, EC_BADCONF);
4944 }
4945 }
4946
4947 mem_recover = 0;
4948 fclose(f);
4949}
4950
4951#if defined(HAVE_DHCP) && defined(HAVE_INOTIFY)
4952int option_read_dynfile(char *file, int flags)
4953{
4954 my_syslog(MS_DHCP | LOG_INFO, _("read %s"), file);
4955
4956 if (flags & AH_DHCP_HST)
4957 return one_file(file, LOPT_BANK);
4958 else if (flags & AH_DHCP_OPT)
4959 return one_file(file, LOPT_OPTS);
4960
4961 return 0;
4962}
4963#endif
4964
4965static int one_file(char *file, int hard_opt)
4966{
4967 FILE *f;
4968 int nofile_ok = 0;
4969 static int read_stdin = 0;
4970 static struct fileread {
4971 dev_t dev;
4972 ino_t ino;
4973 struct fileread *next;
4974 } *filesread = NULL;
4975
4976 if (hard_opt == '7')
4977 {
4978 /* default conf-file reading */
4979 hard_opt = 0;
4980 nofile_ok = 1;
4981 }
4982
4983 if (hard_opt == 0 && strcmp(file, "-") == 0)
4984 {
4985 if (read_stdin == 1)
4986 return 1;
4987 read_stdin = 1;
4988 file = "stdin";
4989 f = stdin;
4990 }
4991 else
4992 {
4993 /* ignore repeated files. */
4994 struct stat statbuf;
4995
4996 if (hard_opt == 0 && stat(file, &statbuf) == 0)
4997 {
4998 struct fileread *r;
4999
5000 for (r = filesread; r; r = r->next)
5001 if (r->dev == statbuf.st_dev && r->ino == statbuf.st_ino)
5002 return 1;
5003
5004 r = safe_malloc(sizeof(struct fileread));
5005 r->next = filesread;
5006 filesread = r;
5007 r->dev = statbuf.st_dev;
5008 r->ino = statbuf.st_ino;
5009 }
5010
5011 if (!(f = fopen(file, "r")))
5012 {
5013 if (errno == ENOENT && nofile_ok)
5014 return 1; /* No conffile, all done. */
5015 else
5016 {
5017 char *str = _("cannot read %s: %s");
5018 if (hard_opt != 0)
5019 {
5020 my_syslog(LOG_ERR, str, file, strerror(errno));
5021 return 0;
5022 }
5023 else
5024 die(str, file, EC_FILE);
5025 }
5026 }
5027 }
5028
5029 read_file(file, f, hard_opt);
5030 return 1;
5031}
5032
5033static int file_filter(const struct dirent *ent)
5034{
5035 size_t lenfile = strlen(ent->d_name);
5036
5037 /* ignore emacs backups and dotfiles */
5038
5039 if (lenfile == 0 ||
5040 ent->d_name[lenfile - 1] == '~' ||
5041 (ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
5042 ent->d_name[0] == '.')
5043 return 0;
5044
5045 return 1;
5046}
5047/* expand any name which is a directory */
5048struct hostsfile *expand_filelist(struct hostsfile *list)
5049{
5050 unsigned int i;
5051 int entcnt, n;
5052 struct hostsfile *ah, *last, *next, **up;
5053 struct dirent **namelist;
5054
5055 /* find largest used index */
5056 for (i = SRC_AH, ah = list; ah; ah = ah->next)
5057 {
5058 last = ah;
5059
5060 if (i <= ah->index)
5061 i = ah->index + 1;
5062
5063 if (ah->flags & AH_DIR)
5064 ah->flags |= AH_INACTIVE;
5065 else
5066 ah->flags &= ~AH_INACTIVE;
5067 }
5068
5069 for (ah = list; ah; ah = ah->next)
5070 if (!(ah->flags & AH_INACTIVE))
5071 {
5072 struct stat buf;
5073 if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
5074 {
5075 struct dirent *ent;
5076
5077 /* don't read this as a file */
5078 ah->flags |= AH_INACTIVE;
5079
5080 entcnt = scandir(ah->fname, &namelist, file_filter, alphasort);
5081 if (entcnt < 0)
5082 my_syslog(LOG_ERR, _("cannot access directory %s: %s"),
5083 ah->fname, strerror(errno));
5084 else
5085 {
5086 for (n = 0; n < entcnt; n++)
5087 {
5088 ent = namelist[n];
5089 size_t lendir = strlen(ah->fname);
5090 size_t lenfile = strlen(ent->d_name);
5091 struct hostsfile *ah1;
5092 char *path;
5093
5094 /* see if we have an existing record.
5095 dir is ah->fname
5096 file is ent->d_name
5097 path to match is ah1->fname */
5098
5099 for (up = &list, ah1 = list; ah1; ah1 = next)
5100 {
5101 next = ah1->next;
5102
5103 if (lendir < strlen(ah1->fname) &&
5104 strstr(ah1->fname, ah->fname) == ah1->fname &&
5105 ah1->fname[lendir] == '/' &&
5106 strcmp(ah1->fname + lendir + 1, ent->d_name) == 0)
5107 {
5108 ah1->flags &= ~AH_INACTIVE;
5109 /* If found, remove from list to re-insert at the end.
5110 Unless it's already at the end. */
5111 if (last != ah1)
5112 *up = next;
5113 break;
5114 }
5115
5116 up = &ah1->next;
5117 }
5118
5119 /* make new record */
5120 if (!ah1)
5121 {
5122 if (!(ah1 = whine_malloc(sizeof(struct hostsfile))))
5123 continue;
5124
5125 if (!(path = whine_malloc(lendir + lenfile + 2)))
5126 {
5127 free(ah1);
5128 continue;
5129 }
5130
5131 strcpy(path, ah->fname);
5132 strcat(path, "/");
5133 strcat(path, ent->d_name);
5134 ah1->fname = path;
5135 ah1->index = i++;
5136 ah1->flags = AH_DIR;
5137 }
5138
5139 /* Edge case, may be the last in the list anyway */
5140 if (last != ah1)
5141 last->next = ah1;
5142 ah1->next = NULL;
5143 last = ah1;
5144
5145 /* inactivate record if not regular file */
5146 if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 && !S_ISREG(buf.st_mode))
5147 ah1->flags |= AH_INACTIVE;
5148
5149 }
5150 }
5151 free(namelist);
5152 }
5153 }
5154
5155 return list;
5156}
5157
5158void read_servers_file(void)
5159{
5160 FILE *f;
5161
5162 if (!(f = fopen(daemon->servers_file, "r")))
5163 {
5164 my_syslog(LOG_ERR, _("cannot read %s: %s"), daemon->servers_file, strerror(errno));
5165 return;
5166 }
5167
5168 mark_servers(SERV_FROM_FILE);
5169 read_file(daemon->servers_file, f, LOPT_REV_SERV);
5170 cleanup_servers();
5171 check_servers(0);
5172}
5173
5174
5175#ifdef HAVE_DHCP
5176static void clear_dynamic_conf(void)
5177{
5178 struct dhcp_config *configs, *cp, **up;
5179
5180 /* remove existing... */
5181 for (up = &daemon->dhcp_conf, configs = daemon->dhcp_conf; configs; configs = cp)
5182 {
5183 cp = configs->next;
5184
5185 if (configs->flags & CONFIG_BANK)
5186 {
5187 *up = cp;
5188 dhcp_config_free(configs);
5189 }
5190 else
5191 up = &configs->next;
5192 }
5193}
5194
5195static void clear_dynamic_opt(void)
5196{
5197 struct dhcp_opt *opts, *cp, **up;
5198
5199 for (up = &daemon->dhcp_opts, opts = daemon->dhcp_opts; opts; opts = cp)
5200 {
5201 cp = opts->next;
5202
5203 if (opts->flags & DHOPT_BANK)
5204 {
5205 *up = cp;
5206 dhcp_opt_free(opts);
5207 }
5208 else
5209 up = &opts->next;
5210 }
5211}
5212
5213void reread_dhcp(void)
5214{
5215 struct hostsfile *hf;
5216
5217 /* Do these even if there is no daemon->dhcp_hosts_file or
5218 daemon->dhcp_opts_file since entries may have been created by the
5219 inotify dynamic file reading system. */
5220
5221 clear_dynamic_conf();
5222 clear_dynamic_opt();
5223
5224 if (daemon->dhcp_hosts_file)
5225 {
5226 daemon->dhcp_hosts_file = expand_filelist(daemon->dhcp_hosts_file);
5227 for (hf = daemon->dhcp_hosts_file; hf; hf = hf->next)
5228 if (!(hf->flags & AH_INACTIVE))
5229 {
5230 if (one_file(hf->fname, LOPT_BANK))
5231 my_syslog(MS_DHCP | LOG_INFO, _("read %s"), hf->fname);
5232 }
5233 }
5234
5235 if (daemon->dhcp_opts_file)
5236 {
5237 daemon->dhcp_opts_file = expand_filelist(daemon->dhcp_opts_file);
5238 for (hf = daemon->dhcp_opts_file; hf; hf = hf->next)
5239 if (!(hf->flags & AH_INACTIVE))
5240 {
5241 if (one_file(hf->fname, LOPT_OPTS))
5242 my_syslog(MS_DHCP | LOG_INFO, _("read %s"), hf->fname);
5243 }
5244 }
5245
5246# ifdef HAVE_INOTIFY
5247 /* Setup notify and read pre-existing files. */
5248 set_dynamic_inotify(AH_DHCP_HST | AH_DHCP_OPT, 0, NULL, 0);
5249# endif
5250}
5251#endif
5252
5253void read_opts(int argc, char **argv, char *compile_opts)
5254{
5255 size_t argbuf_size = MAXDNAME;
5256 char *argbuf = opt_malloc(argbuf_size);
5257 char *buff = opt_malloc(MAXDNAME);
5258 int option, testmode = 0;
5259 char *arg, *conffile = NULL;
5260
5261 opterr = 0;
5262
5263 daemon = opt_malloc(sizeof(struct daemon));
5264 memset(daemon, 0, sizeof(struct daemon));
5265 daemon->namebuff = buff;
5266 daemon->addrbuff = safe_malloc(ADDRSTRLEN);
5267
5268 /* Set defaults - everything else is zero or NULL */
5269 daemon->cachesize = CACHESIZ;
5270 daemon->ftabsize = FTABSIZ;
5271 daemon->port = NAMESERVER_PORT;
5272 daemon->dhcp_client_port = DHCP_CLIENT_PORT;
5273 daemon->dhcp_server_port = DHCP_SERVER_PORT;
5274 daemon->default_resolv.is_default = 1;
5275 daemon->default_resolv.name = RESOLVFILE;
5276 daemon->resolv_files = &daemon->default_resolv;
5277 daemon->username = CHUSER;
5278 daemon->runfile = RUNFILE;
5279 daemon->dhcp_max = MAXLEASES;
5280 daemon->tftp_max = TFTP_MAX_CONNECTIONS;
5281 daemon->edns_pktsz = EDNS_PKTSZ;
5282 daemon->log_fac = -1;
5283 daemon->auth_ttl = AUTH_TTL;
5284 daemon->soa_refresh = SOA_REFRESH;
5285 daemon->soa_retry = SOA_RETRY;
5286 daemon->soa_expiry = SOA_EXPIRY;
5287
5288#ifndef NO_ID
5289 add_txt("version.bind", "dnsmasq-" VERSION, 0 );
5290 add_txt("authors.bind", "Simon Kelley", 0);
5291 add_txt("copyright.bind", COPYRIGHT, 0);
5292 add_txt("cachesize.bind", NULL, TXT_STAT_CACHESIZE);
5293 add_txt("insertions.bind", NULL, TXT_STAT_INSERTS);
5294 add_txt("evictions.bind", NULL, TXT_STAT_EVICTIONS);
5295 add_txt("misses.bind", NULL, TXT_STAT_MISSES);
5296 add_txt("hits.bind", NULL, TXT_STAT_HITS);
5297#ifdef HAVE_AUTH
5298 add_txt("auth.bind", NULL, TXT_STAT_AUTH);
5299#endif
5300 add_txt("servers.bind", NULL, TXT_STAT_SERVERS);
5301#endif
5302
5303 while (1)
5304 {
5305#ifdef HAVE_GETOPT_LONG
5306 option = getopt_long(argc, argv, OPTSTRING, opts, NULL);
5307#else
5308 option = getopt(argc, argv, OPTSTRING);
5309#endif
5310
5311 if (option == -1)
5312 {
5313 for (; optind < argc; optind++)
5314 {
5315 unsigned char *c = (unsigned char *)argv[optind];
5316 for (; *c != 0; c++)
5317 if (!isspace(*c))
5318 die(_("junk found in command line"), NULL, EC_BADCONF);
5319 }
5320 break;
5321 }
5322
5323 /* Copy optarg so that argv doesn't get changed */
5324 if (optarg)
5325 {
5326 if (strlen(optarg) >= argbuf_size)
5327 {
5328 free(argbuf);
5329 argbuf_size = strlen(optarg) + 1;
5330 argbuf = opt_malloc(argbuf_size);
5331 }
5332 safe_strncpy(argbuf, optarg, argbuf_size);
5333 arg = argbuf;
5334 }
5335 else
5336 arg = NULL;
5337
5338 /* command-line only stuff */
5339 if (option == LOPT_TEST)
5340 testmode = 1;
5341 else if (option == 'w')
5342 {
5343#ifdef HAVE_DHCP
5344 if (argc == 3 && strcmp(argv[2], "dhcp") == 0)
5345 display_opts();
5346#ifdef HAVE_DHCP6
5347 else if (argc == 3 && strcmp(argv[2], "dhcp6") == 0)
5348 display_opts6();
5349#endif
5350 else
5351#endif
5352 do_usage();
5353
5354 exit(0);
5355 }
5356 else if (option == 'v')
5357 {
5358 printf(_("Dnsmasq version %s %s\n"), VERSION, COPYRIGHT);
5359 printf(_("Compile time options: %s\n\n"), compile_opts);
5360 printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
5361 printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
5362 printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
5363 exit(0);
5364 }
5365 else if (option == 'C')
5366 {
5367 if (!conffile)
5368 conffile = opt_string_alloc(arg);
5369 else
5370 {
5371 char *extra = opt_string_alloc(arg);
5372 one_file(extra, 0);
5373 free(extra);
5374 }
5375 }
5376 else
5377 {
5378#ifdef HAVE_GETOPT_LONG
5379 if (!one_opt(option, arg, daemon->namebuff, _("try --help"), 1, 0))
5380#else
5381 if (!one_opt(option, arg, daemon->namebuff, _("try -w"), 1, 0))
5382#endif
5383 die(_("bad command line options: %s"), daemon->namebuff, EC_BADCONF);
5384 }
5385 }
5386
5387 free(argbuf);
5388
5389 if (conffile)
5390 {
5391 one_file(conffile, 0);
5392 free(conffile);
5393 }
5394 else
5395 one_file(CONFFILE, '7');
5396
5397 /* port might not be known when the address is parsed - fill in here */
5398 if (daemon->servers)
5399 {
5400 struct server *tmp;
5401 for (tmp = daemon->servers; tmp; tmp = tmp->next)
5402 if (!(tmp->flags & SERV_HAS_SOURCE))
5403 {
5404 if (tmp->source_addr.sa.sa_family == AF_INET)
5405 tmp->source_addr.in.sin_port = htons(daemon->query_port);
5406 else if (tmp->source_addr.sa.sa_family == AF_INET6)
5407 tmp->source_addr.in6.sin6_port = htons(daemon->query_port);
5408 }
5409 }
5410
5411 if (daemon->host_records)
5412 {
5413 struct host_record *hr;
5414
5415 for (hr = daemon->host_records; hr; hr = hr->next)
5416 if (hr->ttl == -1)
5417 hr->ttl = daemon->local_ttl;
5418 }
5419
5420 if (daemon->cnames)
5421 {
5422 struct cname *cn, *cn2, *cn3;
5423
5424#define NOLOOP 1
5425#define TESTLOOP 2
5426
5427 /* Fill in TTL for CNAMES now we have local_ttl.
5428 Also prepare to do loop detection. */
5429 for (cn = daemon->cnames; cn; cn = cn->next)
5430 {
5431 if (cn->ttl == -1)
5432 cn->ttl = daemon->local_ttl;
5433 cn->flag = 0;
5434 cn->targetp = NULL;
5435 for (cn2 = daemon->cnames; cn2; cn2 = cn2->next)
5436 if (hostname_isequal(cn->target, cn2->alias))
5437 {
5438 cn->targetp = cn2;
5439 break;
5440 }
5441 }
5442
5443 /* Find any CNAME loops.*/
5444 for (cn = daemon->cnames; cn; cn = cn->next)
5445 {
5446 for (cn2 = cn->targetp; cn2; cn2 = cn2->targetp)
5447 {
5448 if (cn2->flag == NOLOOP)
5449 break;
5450
5451 if (cn2->flag == TESTLOOP)
5452 die(_("CNAME loop involving %s"), cn->alias, EC_BADCONF);
5453
5454 cn2->flag = TESTLOOP;
5455 }
5456
5457 for (cn3 = cn->targetp; cn3 != cn2; cn3 = cn3->targetp)
5458 cn3->flag = NOLOOP;
5459 }
5460 }
5461
5462 if (daemon->if_addrs)
5463 {
5464 struct iname *tmp;
5465 for(tmp = daemon->if_addrs; tmp; tmp = tmp->next)
5466 if (tmp->addr.sa.sa_family == AF_INET)
5467 tmp->addr.in.sin_port = htons(daemon->port);
5468 else if (tmp->addr.sa.sa_family == AF_INET6)
5469 tmp->addr.in6.sin6_port = htons(daemon->port);
5470 }
5471
5472 /* create default, if not specified */
5473 if (daemon->authserver && !daemon->hostmaster)
5474 {
5475 strcpy(buff, "hostmaster.");
5476 strcat(buff, daemon->authserver);
5477 daemon->hostmaster = opt_string_alloc(buff);
5478 }
5479
5480 if (!daemon->dhcp_pxe_vendors)
5481 {
5482 daemon->dhcp_pxe_vendors = opt_malloc(sizeof(struct dhcp_pxe_vendor));
5483 daemon->dhcp_pxe_vendors->data = opt_string_alloc(DHCP_PXE_DEF_VENDOR);
5484 daemon->dhcp_pxe_vendors->next = NULL;
5485 }
5486
5487 /* only one of these need be specified: the other defaults to the host-name */
5488 if (option_bool(OPT_LOCALMX) || daemon->mxnames || daemon->mxtarget)
5489 {
5490 struct mx_srv_record *mx;
5491
5492 if (gethostname(buff, MAXDNAME) == -1)
5493 die(_("cannot get host-name: %s"), NULL, EC_MISC);
5494
5495 for (mx = daemon->mxnames; mx; mx = mx->next)
5496 if (!mx->issrv && hostname_isequal(mx->name, buff))
5497 break;
5498
5499 if ((daemon->mxtarget || option_bool(OPT_LOCALMX)) && !mx)
5500 {
5501 mx = opt_malloc(sizeof(struct mx_srv_record));
5502 mx->next = daemon->mxnames;
5503 mx->issrv = 0;
5504 mx->target = NULL;
5505 mx->name = opt_string_alloc(buff);
5506 daemon->mxnames = mx;
5507 }
5508
5509 if (!daemon->mxtarget)
5510 daemon->mxtarget = opt_string_alloc(buff);
5511
5512 for (mx = daemon->mxnames; mx; mx = mx->next)
5513 if (!mx->issrv && !mx->target)
5514 mx->target = daemon->mxtarget;
5515 }
5516
5517 if (!option_bool(OPT_NO_RESOLV) &&
5518 daemon->resolv_files &&
5519 daemon->resolv_files->next &&
5520 option_bool(OPT_NO_POLL))
5521 die(_("only one resolv.conf file allowed in no-poll mode."), NULL, EC_BADCONF);
5522
5523 if (option_bool(OPT_RESOLV_DOMAIN))
5524 {
5525 char *line;
5526 FILE *f;
5527
5528 if (option_bool(OPT_NO_RESOLV) ||
5529 !daemon->resolv_files ||
5530 (daemon->resolv_files)->next)
5531 die(_("must have exactly one resolv.conf to read domain from."), NULL, EC_BADCONF);
5532
5533 if (!(f = fopen((daemon->resolv_files)->name, "r")))
5534 die(_("failed to read %s: %s"), (daemon->resolv_files)->name, EC_FILE);
5535
5536 while ((line = fgets(buff, MAXDNAME, f)))
5537 {
5538 char *token = strtok(line, " \t\n\r");
5539
5540 if (!token || strcmp(token, "search") != 0)
5541 continue;
5542
5543 if ((token = strtok(NULL, " \t\n\r")) &&
5544 (daemon->domain_suffix = canonicalise_opt(token)))
5545 break;
5546 }
5547
5548 fclose(f);
5549
5550 if (!daemon->domain_suffix)
5551 die(_("no search directive found in %s"), (daemon->resolv_files)->name, EC_MISC);
5552 }
5553
5554 if (daemon->domain_suffix)
5555 {
5556 /* add domain for any srv record without one. */
5557 struct mx_srv_record *srv;
5558
5559 for (srv = daemon->mxnames; srv; srv = srv->next)
5560 if (srv->issrv &&
5561 strchr(srv->name, '.') &&
5562 strchr(srv->name, '.') == strrchr(srv->name, '.'))
5563 {
5564 strcpy(buff, srv->name);
5565 strcat(buff, ".");
5566 strcat(buff, daemon->domain_suffix);
5567 free(srv->name);
5568 srv->name = opt_string_alloc(buff);
5569 }
5570 }
5571 else if (option_bool(OPT_DHCP_FQDN))
5572 die(_("there must be a default domain when --dhcp-fqdn is set"), NULL, EC_BADCONF);
5573
5574 /* If there's access-control config, then ignore --local-service, it's intended
5575 as a system default to keep otherwise unconfigured installations safe. */
5576 if (daemon->if_names || daemon->if_except || daemon->if_addrs || daemon->authserver)
5577 reset_option_bool(OPT_LOCAL_SERVICE);
5578
5579 if (testmode)
5580 {
5581 fprintf(stderr, "dnsmasq: %s.\n", _("syntax check OK"));
5582 exit(0);
5583 }
5584}