]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/option.c
1 /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 /* define this to get facilitynames */
22 static volatile int mem_recover
= 0;
23 static jmp_buf mem_jmp
;
24 static int one_file(char *file
, int hard_opt
);
26 /* Solaris headers don't have facility names. */
27 #ifdef HAVE_SOLARIS_NETWORK
35 { "daemon", LOG_DAEMON
},
37 { "syslog", LOG_SYSLOG
},
41 { "audit", LOG_AUDIT
},
43 { "local0", LOG_LOCAL0
},
44 { "local1", LOG_LOCAL1
},
45 { "local2", LOG_LOCAL2
},
46 { "local3", LOG_LOCAL3
},
47 { "local4", LOG_LOCAL4
},
48 { "local5", LOG_LOCAL5
},
49 { "local6", LOG_LOCAL6
},
50 { "local7", LOG_LOCAL7
},
55 #ifndef HAVE_GETOPT_LONG
64 #define OPTSTRING "951yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:4:6:7:8:0:3:"
66 /* options which don't have a one-char version */
67 #define LOPT_RELOAD 256
68 #define LOPT_NO_NAMES 257
70 #define LOPT_SECURE 259
71 #define LOPT_PREFIX 260
73 #define LOPT_BRIDGE 262
74 #define LOPT_TFTP_MAX 263
75 #define LOPT_FORCE 264
76 #define LOPT_NOBLOCK 265
77 #define LOPT_LOG_OPTS 266
78 #define LOPT_MAX_LOGS 267
79 #define LOPT_CIRCUIT 268
80 #define LOPT_REMOTE 269
81 #define LOPT_SUBSCR 270
82 #define LOPT_INTNAME 271
84 #define LOPT_DHCP_HOST 273
85 #define LOPT_APREF 274
86 #define LOPT_OVERRIDE 275
87 #define LOPT_TFTPPORTS 276
88 #define LOPT_REBIND 277
89 #define LOPT_NOLAST 278
91 #define LOPT_DHCP_OPTS 280
92 #define LOPT_MATCH 281
93 #define LOPT_BROADCAST 282
94 #define LOPT_NEGTTL 283
95 #define LOPT_ALTPORT 284
96 #define LOPT_SCRIPTUSR 285
97 #define LOPT_LOCAL 286
98 #define LOPT_NAPTR 287
99 #define LOPT_MINPORT 288
100 #define LOPT_DHCP_FQDN 289
101 #define LOPT_CNAME 290
102 #define LOPT_PXE_PROMT 291
103 #define LOPT_PXE_SERV 292
104 #define LOPT_TEST 293
105 #define LOPT_TAG_IF 294
106 #define LOPT_PROXY 295
107 #define LOPT_GEN_NAMES 296
108 #define LOPT_MAXTTL 297
109 #define LOPT_NO_REBIND 298
110 #define LOPT_LOC_REBND 299
111 #define LOPT_ADD_MAC 300
112 #define LOPT_DNSSEC 301
113 #define LOPT_INCR_ADDR 302
114 #define LOPT_CONNTRACK 303
115 #define LOPT_FQDN 304
116 #define LOPT_LUASCRIPT 305
118 #define LOPT_DUID 307
119 #define LOPT_HOST_REC 308
120 #define LOPT_TFTP_LC 309
122 #define LOPT_CLVERBIND 311
123 #define LOPT_MAXCTTL 312
124 #define LOPT_AUTHZONE 313
125 #define LOPT_AUTHSERV 314
126 #define LOPT_AUTHTTL 315
127 #define LOPT_AUTHSOA 316
128 #define LOPT_AUTHSFS 317
129 #define LOPT_AUTHPEER 318
130 #define LOPT_IPSET 319
131 #define LOPT_SYNTH 320
132 #ifdef OPTION6_PREFIX_CLASS
133 #define LOPT_PREF_CLSS 321
135 #define LOPT_RELAY 323
136 #define LOPT_RA_PARAM 324
137 #define LOPT_ADD_SBNET 325
138 #define LOPT_QUIET_DHCP 326
139 #define LOPT_QUIET_DHCP6 327
140 #define LOPT_QUIET_RA 328
141 #define LOPT_SEC_VALID 329
142 #define LOPT_TRUST_ANCHOR 330
143 #define LOPT_DNSSEC_DEBUG 331
144 #define LOPT_REV_SERV 332
145 #define LOPT_SERVERS_FILE 333
146 #define LOPT_DNSSEC_CHECK 334
147 #define LOPT_LOCAL_SERVICE 335
148 #define LOPT_DNSSEC_TIME 336
149 #define LOPT_LOOP_DETECT 337
150 #define LOPT_IGNORE_ADDR 338
151 #define LOPT_MINCTTL 339
152 #define LOPT_DHCP_INOTIFY 340
153 #define LOPT_DHOPT_INOTIFY 341
154 #define LOPT_HOST_INOTIFY 342
155 #define LOPT_DNSSEC_STAMP 343
156 #define LOPT_TFTP_NO_FAIL 344
158 #ifdef HAVE_GETOPT_LONG
159 static const struct option opts
[] =
161 static const struct myoption opts
[] =
164 { "version", 0, 0, 'v' },
165 { "no-hosts", 0, 0, 'h' },
166 { "no-poll", 0, 0, 'n' },
167 { "help", 0, 0, 'w' },
168 { "no-daemon", 0, 0, 'd' },
169 { "log-queries", 2, 0, 'q' },
170 { "user", 2, 0, 'u' },
171 { "group", 2, 0, 'g' },
172 { "resolv-file", 2, 0, 'r' },
173 { "servers-file", 1, 0, LOPT_SERVERS_FILE
},
174 { "mx-host", 1, 0, 'm' },
175 { "mx-target", 1, 0, 't' },
176 { "cache-size", 2, 0, 'c' },
177 { "port", 1, 0, 'p' },
178 { "dhcp-leasefile", 2, 0, 'l' },
179 { "dhcp-lease", 1, 0, 'l' },
180 { "dhcp-host", 1, 0, 'G' },
181 { "dhcp-range", 1, 0, 'F' },
182 { "dhcp-option", 1, 0, 'O' },
183 { "dhcp-boot", 1, 0, 'M' },
184 { "domain", 1, 0, 's' },
185 { "domain-suffix", 1, 0, 's' },
186 { "interface", 1, 0, 'i' },
187 { "listen-address", 1, 0, 'a' },
188 { "local-service", 0, 0, LOPT_LOCAL_SERVICE
},
189 { "bogus-priv", 0, 0, 'b' },
190 { "bogus-nxdomain", 1, 0, 'B' },
191 { "ignore-address", 1, 0, LOPT_IGNORE_ADDR
},
192 { "selfmx", 0, 0, 'e' },
193 { "filterwin2k", 0, 0, 'f' },
194 { "pid-file", 2, 0, 'x' },
195 { "strict-order", 0, 0, 'o' },
196 { "server", 1, 0, 'S' },
197 { "rev-server", 1, 0, LOPT_REV_SERV
},
198 { "local", 1, 0, LOPT_LOCAL
},
199 { "address", 1, 0, 'A' },
200 { "conf-file", 2, 0, 'C' },
201 { "no-resolv", 0, 0, 'R' },
202 { "expand-hosts", 0, 0, 'E' },
203 { "localmx", 0, 0, 'L' },
204 { "local-ttl", 1, 0, 'T' },
205 { "no-negcache", 0, 0, 'N' },
206 { "addn-hosts", 1, 0, 'H' },
207 { "hostsdir", 1, 0, LOPT_HOST_INOTIFY
},
208 { "query-port", 1, 0, 'Q' },
209 { "except-interface", 1, 0, 'I' },
210 { "no-dhcp-interface", 1, 0, '2' },
211 { "domain-needed", 0, 0, 'D' },
212 { "dhcp-lease-max", 1, 0, 'X' },
213 { "bind-interfaces", 0, 0, 'z' },
214 { "read-ethers", 0, 0, 'Z' },
215 { "alias", 1, 0, 'V' },
216 { "dhcp-vendorclass", 1, 0, 'U' },
217 { "dhcp-userclass", 1, 0, 'j' },
218 { "dhcp-ignore", 1, 0, 'J' },
219 { "edns-packet-max", 1, 0, 'P' },
220 { "keep-in-foreground", 0, 0, 'k' },
221 { "dhcp-authoritative", 0, 0, 'K' },
222 { "srv-host", 1, 0, 'W' },
223 { "localise-queries", 0, 0, 'y' },
224 { "txt-record", 1, 0, 'Y' },
225 { "dns-rr", 1, 0, LOPT_RR
},
226 { "enable-dbus", 2, 0, '1' },
227 { "bootp-dynamic", 2, 0, '3' },
228 { "dhcp-mac", 1, 0, '4' },
229 { "no-ping", 0, 0, '5' },
230 { "dhcp-script", 1, 0, '6' },
231 { "conf-dir", 1, 0, '7' },
232 { "log-facility", 1, 0 ,'8' },
233 { "leasefile-ro", 0, 0, '9' },
234 { "dns-forward-max", 1, 0, '0' },
235 { "clear-on-reload", 0, 0, LOPT_RELOAD
},
236 { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES
},
237 { "enable-tftp", 2, 0, LOPT_TFTP
},
238 { "tftp-secure", 0, 0, LOPT_SECURE
},
239 { "tftp-no-fail", 0, 0, LOPT_TFTP_NO_FAIL
},
240 { "tftp-unique-root", 0, 0, LOPT_APREF
},
241 { "tftp-root", 1, 0, LOPT_PREFIX
},
242 { "tftp-max", 1, 0, LOPT_TFTP_MAX
},
243 { "tftp-lowercase", 0, 0, LOPT_TFTP_LC
},
244 { "ptr-record", 1, 0, LOPT_PTR
},
245 { "naptr-record", 1, 0, LOPT_NAPTR
},
246 { "bridge-interface", 1, 0 , LOPT_BRIDGE
},
247 { "dhcp-option-force", 1, 0, LOPT_FORCE
},
248 { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK
},
249 { "log-dhcp", 0, 0, LOPT_LOG_OPTS
},
250 { "log-async", 2, 0, LOPT_MAX_LOGS
},
251 { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT
},
252 { "dhcp-remoteid", 1, 0, LOPT_REMOTE
},
253 { "dhcp-subscrid", 1, 0, LOPT_SUBSCR
},
254 { "interface-name", 1, 0, LOPT_INTNAME
},
255 { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST
},
256 { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS
},
257 { "dhcp-hostsdir", 1, 0, LOPT_DHCP_INOTIFY
},
258 { "dhcp-optsdir", 1, 0, LOPT_DHOPT_INOTIFY
},
259 { "dhcp-no-override", 0, 0, LOPT_OVERRIDE
},
260 { "tftp-port-range", 1, 0, LOPT_TFTPPORTS
},
261 { "stop-dns-rebind", 0, 0, LOPT_REBIND
},
262 { "rebind-domain-ok", 1, 0, LOPT_NO_REBIND
},
263 { "all-servers", 0, 0, LOPT_NOLAST
},
264 { "dhcp-match", 1, 0, LOPT_MATCH
},
265 { "dhcp-broadcast", 2, 0, LOPT_BROADCAST
},
266 { "neg-ttl", 1, 0, LOPT_NEGTTL
},
267 { "max-ttl", 1, 0, LOPT_MAXTTL
},
268 { "min-cache-ttl", 1, 0, LOPT_MINCTTL
},
269 { "max-cache-ttl", 1, 0, LOPT_MAXCTTL
},
270 { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT
},
271 { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR
},
272 { "min-port", 1, 0, LOPT_MINPORT
},
273 { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN
},
274 { "cname", 1, 0, LOPT_CNAME
},
275 { "pxe-prompt", 1, 0, LOPT_PXE_PROMT
},
276 { "pxe-service", 1, 0, LOPT_PXE_SERV
},
277 { "test", 0, 0, LOPT_TEST
},
278 { "tag-if", 1, 0, LOPT_TAG_IF
},
279 { "dhcp-proxy", 2, 0, LOPT_PROXY
},
280 { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES
},
281 { "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND
},
282 { "add-mac", 0, 0, LOPT_ADD_MAC
},
283 { "add-subnet", 2, 0, LOPT_ADD_SBNET
},
284 { "proxy-dnssec", 0, 0, LOPT_DNSSEC
},
285 { "dhcp-sequential-ip", 0, 0, LOPT_INCR_ADDR
},
286 { "conntrack", 0, 0, LOPT_CONNTRACK
},
287 { "dhcp-client-update", 0, 0, LOPT_FQDN
},
288 { "dhcp-luascript", 1, 0, LOPT_LUASCRIPT
},
289 { "enable-ra", 0, 0, LOPT_RA
},
290 { "dhcp-duid", 1, 0, LOPT_DUID
},
291 { "host-record", 1, 0, LOPT_HOST_REC
},
292 { "bind-dynamic", 0, 0, LOPT_CLVERBIND
},
293 { "auth-zone", 1, 0, LOPT_AUTHZONE
},
294 { "auth-server", 1, 0, LOPT_AUTHSERV
},
295 { "auth-ttl", 1, 0, LOPT_AUTHTTL
},
296 { "auth-soa", 1, 0, LOPT_AUTHSOA
},
297 { "auth-sec-servers", 1, 0, LOPT_AUTHSFS
},
298 { "auth-peer", 1, 0, LOPT_AUTHPEER
},
299 { "ipset", 1, 0, LOPT_IPSET
},
300 { "synth-domain", 1, 0, LOPT_SYNTH
},
301 { "dnssec", 0, 0, LOPT_SEC_VALID
},
302 { "trust-anchor", 1, 0, LOPT_TRUST_ANCHOR
},
303 { "dnssec-debug", 0, 0, LOPT_DNSSEC_DEBUG
},
304 { "dnssec-check-unsigned", 0, 0, LOPT_DNSSEC_CHECK
},
305 { "dnssec-no-timecheck", 0, 0, LOPT_DNSSEC_TIME
},
306 { "dnssec-timestamp", 1, 0, LOPT_DNSSEC_STAMP
},
307 #ifdef OPTION6_PREFIX_CLASS
308 { "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS
},
310 { "dhcp-relay", 1, 0, LOPT_RELAY
},
311 { "ra-param", 1, 0, LOPT_RA_PARAM
},
312 { "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP
},
313 { "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6
},
314 { "quiet-ra", 0, 0, LOPT_QUIET_RA
},
315 { "dns-loop-detect", 0, 0, LOPT_LOOP_DETECT
},
320 #define ARG_DUP OPT_LAST
321 #define ARG_ONE OPT_LAST + 1
322 #define ARG_USED_CL OPT_LAST + 2
323 #define ARG_USED_FILE OPT_LAST + 3
328 char * const flagdesc
;
332 { 'a', ARG_DUP
, "<ipaddr>", gettext_noop("Specify local address(es) to listen on."), NULL
},
333 { 'A', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL
},
334 { 'b', OPT_BOGUSPRIV
, NULL
, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL
},
335 { 'B', ARG_DUP
, "<ipaddr>", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL
},
336 { 'c', ARG_ONE
, "<integer>", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
337 { 'C', ARG_DUP
, "<path>", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE
},
338 { 'd', OPT_DEBUG
, NULL
, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL
},
339 { 'D', OPT_NODOTS_LOCAL
, NULL
, gettext_noop("Do NOT forward queries with no domain part."), NULL
},
340 { 'e', OPT_SELFMX
, NULL
, gettext_noop("Return self-pointing MX records for local hosts."), NULL
},
341 { 'E', OPT_EXPAND
, NULL
, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL
},
342 { 'f', OPT_FILTER
, NULL
, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL
},
343 { 'F', ARG_DUP
, "<ipaddr>,...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL
},
344 { 'g', ARG_ONE
, "<groupname>", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP
},
345 { 'G', ARG_DUP
, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL
},
346 { LOPT_DHCP_HOST
, ARG_DUP
, "<path>", gettext_noop("Read DHCP host specs from file."), NULL
},
347 { LOPT_DHCP_OPTS
, ARG_DUP
, "<path>", gettext_noop("Read DHCP option specs from file."), NULL
},
348 { LOPT_DHCP_INOTIFY
, ARG_DUP
, "<path>", gettext_noop("Read DHCP host specs from a directory."), NULL
},
349 { LOPT_DHOPT_INOTIFY
, ARG_DUP
, "<path>", gettext_noop("Read DHCP options from a directory."), NULL
},
350 { LOPT_TAG_IF
, ARG_DUP
, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL
},
351 { 'h', OPT_NO_HOSTS
, NULL
, gettext_noop("Do NOT load %s file."), HOSTSFILE
},
352 { 'H', ARG_DUP
, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE
},
353 { LOPT_HOST_INOTIFY
, ARG_DUP
, "<path>", gettext_noop("Read hosts files from a directory."), NULL
},
354 { 'i', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL
},
355 { 'I', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL
},
356 { 'j', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL
},
357 { LOPT_CIRCUIT
, ARG_DUP
, "set:<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL
},
358 { LOPT_REMOTE
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL
},
359 { LOPT_SUBSCR
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL
},
360 { 'J', ARG_DUP
, "tag:<tag>...", gettext_noop("Don't do DHCP for hosts with tag set."), NULL
},
361 { LOPT_BROADCAST
, ARG_DUP
, "[=tag:<tag>...]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL
},
362 { 'k', OPT_NO_FORK
, NULL
, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL
},
363 { 'K', OPT_AUTHORITATIVE
, NULL
, gettext_noop("Assume we are the only DHCP server on the local network."), NULL
},
364 { 'l', ARG_ONE
, "<path>", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE
},
365 { 'L', OPT_LOCALMX
, NULL
, gettext_noop("Return MX records for local hosts."), NULL
},
366 { 'm', ARG_DUP
, "<host_name>,<target>,<pref>", gettext_noop("Specify an MX record."), NULL
},
367 { 'M', ARG_DUP
, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL
},
368 { 'n', OPT_NO_POLL
, NULL
, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE
},
369 { 'N', OPT_NO_NEG
, NULL
, gettext_noop("Do NOT cache failed search results."), NULL
},
370 { 'o', OPT_ORDER
, NULL
, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE
},
371 { 'O', ARG_DUP
, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL
},
372 { LOPT_FORCE
, ARG_DUP
, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL
},
373 { 'p', ARG_ONE
, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL
},
374 { 'P', ARG_ONE
, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
375 { 'q', ARG_DUP
, NULL
, gettext_noop("Log DNS queries."), NULL
},
376 { 'Q', ARG_ONE
, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL
},
377 { 'R', OPT_NO_RESOLV
, NULL
, gettext_noop("Do NOT read resolv.conf."), NULL
},
378 { 'r', ARG_DUP
, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE
},
379 { LOPT_SERVERS_FILE
, ARG_ONE
, "<path>", gettext_noop("Specify path to file with server= options"), NULL
},
380 { 'S', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL
},
381 { LOPT_REV_SERV
, ARG_DUP
, "<addr>/<prefix>,<ipaddr>", gettext_noop("Specify address of upstream servers for reverse address queries"), NULL
},
382 { LOPT_LOCAL
, ARG_DUP
, "/<domain>/", gettext_noop("Never forward queries to specified domains."), NULL
},
383 { 's', ARG_DUP
, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL
},
384 { 't', ARG_ONE
, "<host_name>", gettext_noop("Specify default target in an MX record."), NULL
},
385 { 'T', ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL
},
386 { LOPT_NEGTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL
},
387 { LOPT_MAXTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL
},
388 { LOPT_MAXCTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live ceiling for cache."), NULL
},
389 { LOPT_MINCTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live floor for cache."), NULL
},
390 { 'u', ARG_ONE
, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER
},
391 { 'U', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL
},
392 { 'v', 0, NULL
, gettext_noop("Display dnsmasq version and copyright information."), NULL
},
393 { 'V', ARG_DUP
, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL
},
394 { 'W', ARG_DUP
, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL
},
395 { 'w', 0, NULL
, gettext_noop("Display this message. Use --help dhcp for known DHCP options."), NULL
},
396 { 'x', ARG_ONE
, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE
},
397 { 'X', ARG_ONE
, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
398 { 'y', OPT_LOCALISE
, NULL
, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL
},
399 { 'Y', ARG_DUP
, "<name>,<txt>[,<txt]", gettext_noop("Specify TXT DNS record."), NULL
},
400 { LOPT_PTR
, ARG_DUP
, "<name>,<target>", gettext_noop("Specify PTR DNS record."), NULL
},
401 { LOPT_INTNAME
, ARG_DUP
, "<name>,<interface>", gettext_noop("Give DNS name to IPv4 address of interface."), NULL
},
402 { 'z', OPT_NOWILD
, NULL
, gettext_noop("Bind only to interfaces in use."), NULL
},
403 { 'Z', OPT_ETHERS
, NULL
, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE
},
404 { '1', ARG_ONE
, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL
},
405 { '2', ARG_DUP
, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL
},
406 { '3', ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL
},
407 { '4', ARG_DUP
, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL
},
408 { LOPT_BRIDGE
, ARG_DUP
, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL
},
409 { '5', OPT_NO_PING
, NULL
, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL
},
410 { '6', ARG_ONE
, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL
},
411 { LOPT_LUASCRIPT
, ARG_DUP
, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL
},
412 { LOPT_SCRIPTUSR
, ARG_ONE
, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL
},
413 { '7', ARG_DUP
, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL
},
414 { '8', ARG_ONE
, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL
},
415 { '9', OPT_LEASE_RO
, NULL
, gettext_noop("Do not use leasefile."), NULL
},
416 { '0', ARG_ONE
, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
417 { LOPT_RELOAD
, OPT_RELOAD
, NULL
, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE
},
418 { LOPT_NO_NAMES
, ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL
},
419 { LOPT_OVERRIDE
, OPT_NO_OVERRIDE
, NULL
, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL
},
420 { LOPT_TFTP
, ARG_DUP
, "[=<intr>[,<intr>]]", gettext_noop("Enable integrated read-only TFTP server."), NULL
},
421 { LOPT_PREFIX
, ARG_DUP
, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL
},
422 { LOPT_APREF
, OPT_TFTP_APREF
, NULL
, gettext_noop("Add client IP address to tftp-root."), NULL
},
423 { LOPT_SECURE
, OPT_TFTP_SECURE
, NULL
, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL
},
424 { LOPT_TFTP_NO_FAIL
, OPT_TFTP_NO_FAIL
, NULL
, gettext_noop("Do not terminate the service if TFTP directories are inaccessible."), NULL
},
425 { LOPT_TFTP_MAX
, ARG_ONE
, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
426 { LOPT_NOBLOCK
, OPT_TFTP_NOBLOCK
, NULL
, gettext_noop("Disable the TFTP blocksize extension."), NULL
},
427 { LOPT_TFTP_LC
, OPT_TFTP_LC
, NULL
, gettext_noop("Convert TFTP filenames to lowercase"), NULL
},
428 { LOPT_TFTPPORTS
, ARG_ONE
, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL
},
429 { LOPT_LOG_OPTS
, OPT_LOG_OPTS
, NULL
, gettext_noop("Extra logging for DHCP."), NULL
},
430 { LOPT_MAX_LOGS
, ARG_ONE
, "[=<integer>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL
},
431 { LOPT_REBIND
, OPT_NO_REBIND
, NULL
, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL
},
432 { LOPT_LOC_REBND
, OPT_LOCAL_REBIND
, NULL
, gettext_noop("Allow rebinding of 127.0.0.0/8, for RBL servers."), NULL
},
433 { LOPT_NO_REBIND
, ARG_DUP
, "/<domain>/", gettext_noop("Inhibit DNS-rebind protection on this domain."), NULL
},
434 { LOPT_NOLAST
, OPT_ALL_SERVERS
, NULL
, gettext_noop("Always perform DNS queries to all servers."), NULL
},
435 { LOPT_MATCH
, ARG_DUP
, "set:<tag>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL
},
436 { LOPT_ALTPORT
, ARG_ONE
, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL
},
437 { LOPT_NAPTR
, ARG_DUP
, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL
},
438 { LOPT_MINPORT
, ARG_ONE
, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL
},
439 { LOPT_DHCP_FQDN
, OPT_DHCP_FQDN
, NULL
, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL
},
440 { LOPT_GEN_NAMES
, ARG_DUP
, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL
},
441 { LOPT_PROXY
, ARG_DUP
, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL
},
442 { LOPT_RELAY
, ARG_DUP
, "<local-addr>,<server>[,<interface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL
},
443 { LOPT_CNAME
, ARG_DUP
, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL
},
444 { LOPT_PXE_PROMT
, ARG_DUP
, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL
},
445 { LOPT_PXE_SERV
, ARG_DUP
, "<service>", gettext_noop("Boot service for PXE menu."), NULL
},
446 { LOPT_TEST
, 0, NULL
, gettext_noop("Check configuration syntax."), NULL
},
447 { LOPT_ADD_MAC
, OPT_ADD_MAC
, NULL
, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL
},
448 { LOPT_ADD_SBNET
, ARG_ONE
, "<v4 pref>[,<v6 pref>]", gettext_noop("Add requestor's IP subnet to forwarded DNS queries."), NULL
},
449 { LOPT_DNSSEC
, OPT_DNSSEC_PROXY
, NULL
, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL
},
450 { LOPT_INCR_ADDR
, OPT_CONSEC_ADDR
, NULL
, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL
},
451 { LOPT_CONNTRACK
, OPT_CONNTRACK
, NULL
, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL
},
452 { LOPT_FQDN
, OPT_FQDN_UPDATE
, NULL
, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL
},
453 { LOPT_RA
, OPT_RA
, NULL
, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL
},
454 { LOPT_DUID
, ARG_ONE
, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL
},
455 { LOPT_HOST_REC
, ARG_DUP
, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL
},
456 { LOPT_RR
, ARG_DUP
, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL
},
457 { LOPT_CLVERBIND
, OPT_CLEVERBIND
, NULL
, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL
},
458 { LOPT_AUTHSERV
, ARG_ONE
, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL
},
459 { LOPT_AUTHZONE
, ARG_DUP
, "<domain>,[<subnet>...]", gettext_noop("Domain to export to global DNS"), NULL
},
460 { LOPT_AUTHTTL
, ARG_ONE
, "<integer>", gettext_noop("Set TTL for authoritative replies"), NULL
},
461 { LOPT_AUTHSOA
, ARG_ONE
, "<serial>[,...]", gettext_noop("Set authoritive zone information"), NULL
},
462 { LOPT_AUTHSFS
, ARG_DUP
, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL
},
463 { LOPT_AUTHPEER
, ARG_DUP
, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL
},
464 { LOPT_IPSET
, ARG_DUP
, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL
},
465 { LOPT_SYNTH
, ARG_DUP
, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL
},
466 { LOPT_SEC_VALID
, OPT_DNSSEC_VALID
, NULL
, gettext_noop("Activate DNSSEC validation"), NULL
},
467 { LOPT_TRUST_ANCHOR
, ARG_DUP
, "<domain>,[<class>],...", gettext_noop("Specify trust anchor key digest."), NULL
},
468 { LOPT_DNSSEC_DEBUG
, OPT_DNSSEC_DEBUG
, NULL
, gettext_noop("Disable upstream checking for DNSSEC debugging."), NULL
},
469 { LOPT_DNSSEC_CHECK
, OPT_DNSSEC_NO_SIGN
, NULL
, gettext_noop("Ensure answers without DNSSEC are in unsigned zones."), NULL
},
470 { LOPT_DNSSEC_TIME
, OPT_DNSSEC_TIME
, NULL
, gettext_noop("Don't check DNSSEC signature timestamps until first cache-reload"), NULL
},
471 { LOPT_DNSSEC_STAMP
, ARG_ONE
, "<path>", gettext_noop("Timestamp file to verify system clock for DNSSEC"), NULL
},
472 #ifdef OPTION6_PREFIX_CLASS
473 { LOPT_PREF_CLSS
, ARG_DUP
, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL
},
475 { LOPT_RA_PARAM
, ARG_DUP
, "<interface>,[high,|low,]<interval>[,<lifetime>]", gettext_noop("Set priority, resend-interval and router-lifetime"), NULL
},
476 { LOPT_QUIET_DHCP
, OPT_QUIET_DHCP
, NULL
, gettext_noop("Do not log routine DHCP."), NULL
},
477 { LOPT_QUIET_DHCP6
, OPT_QUIET_DHCP6
, NULL
, gettext_noop("Do not log routine DHCPv6."), NULL
},
478 { LOPT_QUIET_RA
, OPT_QUIET_RA
, NULL
, gettext_noop("Do not log RA."), NULL
},
479 { LOPT_LOCAL_SERVICE
, OPT_LOCAL_SERVICE
, NULL
, gettext_noop("Accept queries only from directly-connected networks"), NULL
},
480 { LOPT_LOOP_DETECT
, OPT_LOOP_DETECT
, NULL
, gettext_noop("Detect and remove DNS forwarding loops"), NULL
},
481 { LOPT_IGNORE_ADDR
, ARG_DUP
, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL
},
482 { 0, 0, NULL
, NULL
, NULL
}
485 /* We hide metacharaters in quoted strings by mapping them into the ASCII control
486 character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the
487 following sequence so that they map to themselves: it is therefore possible to call
488 unhide_metas repeatedly on string without breaking things.
489 The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a
490 couple of other places.
491 Note that space is included here so that
492 --dhcp-option=3, string
493 has five characters, whilst
494 --dhcp-option=3," string"
498 static const char meta
[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
500 static char hide_meta(char c
)
504 for (i
= 0; i
< (sizeof(meta
) - 1); i
++)
511 static char unhide_meta(char cr
)
515 if (c
< (sizeof(meta
) - 1))
521 static void unhide_metas(char *cp
)
525 *cp
= unhide_meta(*cp
);
528 static void *opt_malloc(size_t size
)
534 ret
= whine_malloc(size
);
539 ret
= safe_malloc(size
);
544 static char *opt_string_alloc(char *cp
)
548 if (cp
&& strlen(cp
) != 0)
550 ret
= opt_malloc(strlen(cp
)+1);
553 /* restore hidden metachars */
561 /* find next comma, split string with zero and eliminate spaces.
562 return start of string following comma */
564 static char *split_chr(char *s
, char c
)
568 if (!s
|| !(comma
= strchr(s
, c
)))
574 for (; *comma
== ' '; comma
++);
576 for (; (p
>= s
) && *p
== ' '; p
--)
582 static char *split(char *s
)
584 return split_chr(s
, ',');
587 static char *canonicalise_opt(char *s
)
596 if (!(ret
= canonicalise(s
, &nomem
)) && nomem
)
601 die(_("could not get memory"), NULL
, EC_NOMEM
);
607 static int atoi_check(char *a
, int *res
)
617 if (*p
< '0' || *p
> '9')
624 static int atoi_check16(char *a
, int *res
)
626 if (!(atoi_check(a
, res
)) ||
635 static int atoi_check8(char *a
, int *res
)
637 if (!(atoi_check(a
, res
)) ||
646 static void add_txt(char *name
, char *txt
, int stat
)
648 struct txt_record
*r
= opt_malloc(sizeof(struct txt_record
));
652 size_t len
= strlen(txt
);
653 r
->txt
= opt_malloc(len
+1);
656 memcpy((r
->txt
)+1, txt
, len
);
660 r
->name
= opt_string_alloc(name
);
661 r
->next
= daemon
->txt
;
666 static void do_usage(void)
679 { '#', TFTP_MAX_CONNECTIONS
},
683 printf(_("Usage: dnsmasq [options]\n\n"));
684 #ifndef HAVE_GETOPT_LONG
685 printf(_("Use short options only on the command line.\n"));
687 printf(_("Valid options are:\n"));
689 for (i
= 0; usage
[i
].opt
!= 0; i
++)
691 char *desc
= usage
[i
].flagdesc
;
694 if (!desc
|| *desc
== '[')
700 for ( j
= 0; opts
[j
].name
; j
++)
701 if (opts
[j
].val
== usage
[i
].opt
)
703 if (usage
[i
].opt
< 256)
704 sprintf(buff
, "-%c, ", usage
[i
].opt
);
708 sprintf(buff
+4, "--%s%s%s", opts
[j
].name
, eq
, desc
);
709 printf("%-40.40s", buff
);
713 strcpy(buff
, usage
[i
].arg
);
714 for (j
= 0; tab
[j
].handle
; j
++)
715 if (tab
[j
].handle
== *(usage
[i
].arg
))
716 sprintf(buff
, "%d", tab
[j
].val
);
718 printf(_(usage
[i
].desc
), buff
);
723 #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
725 char *parse_server(char *arg
, union mysockaddr
*addr
, union mysockaddr
*source_addr
, char *interface
, int *flags
)
727 int source_port
= 0, serv_port
= NAMESERVER_PORT
;
728 char *portno
, *source
;
734 if (!arg
|| strlen(arg
) == 0)
736 *flags
|= SERV_NO_ADDR
;
741 if ((source
= split_chr(arg
, '@')) && /* is there a source. */
742 (portno
= split_chr(source
, '#')) &&
743 !atoi_check16(portno
, &source_port
))
744 return _("bad port");
746 if ((portno
= split_chr(arg
, '#')) && /* is there a port no. */
747 !atoi_check16(portno
, &serv_port
))
748 return _("bad port");
751 scope_id
= split_chr(arg
, '%');
754 if (inet_pton(AF_INET
, arg
, &addr
->in
.sin_addr
) > 0)
756 addr
->in
.sin_port
= htons(serv_port
);
757 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET
;
758 #ifdef HAVE_SOCKADDR_SA_LEN
759 source_addr
->in
.sin_len
= addr
->in
.sin_len
= sizeof(struct sockaddr_in
);
761 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
762 source_addr
->in
.sin_port
= htons(daemon
->query_port
);
767 *flags
|= SERV_HAS_SOURCE
;
768 source_addr
->in
.sin_port
= htons(source_port
);
769 if (!(inet_pton(AF_INET
, source
, &source_addr
->in
.sin_addr
) > 0))
771 #if defined(SO_BINDTODEVICE)
772 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
773 strncpy(interface
, source
, IF_NAMESIZE
- 1);
775 return _("interface binding not supported");
781 else if (inet_pton(AF_INET6
, arg
, &addr
->in6
.sin6_addr
) > 0)
783 if (scope_id
&& (scope_index
= if_nametoindex(scope_id
)) == 0)
784 return _("bad interface name");
786 addr
->in6
.sin6_port
= htons(serv_port
);
787 addr
->in6
.sin6_scope_id
= scope_index
;
788 source_addr
->in6
.sin6_addr
= in6addr_any
;
789 source_addr
->in6
.sin6_port
= htons(daemon
->query_port
);
790 source_addr
->in6
.sin6_scope_id
= 0;
791 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET6
;
792 addr
->in6
.sin6_flowinfo
= source_addr
->in6
.sin6_flowinfo
= 0;
793 #ifdef HAVE_SOCKADDR_SA_LEN
794 addr
->in6
.sin6_len
= source_addr
->in6
.sin6_len
= sizeof(addr
->in6
);
799 *flags
|= SERV_HAS_SOURCE
;
800 source_addr
->in6
.sin6_port
= htons(source_port
);
801 if (inet_pton(AF_INET6
, source
, &source_addr
->in6
.sin6_addr
) == 0)
803 #if defined(SO_BINDTODEVICE)
804 source_addr
->in6
.sin6_addr
= in6addr_any
;
805 strncpy(interface
, source
, IF_NAMESIZE
- 1);
807 return _("interface binding not supported");
814 return _("bad address");
819 static struct server
*add_rev4(struct in_addr addr
, int msize
)
821 struct server
*serv
= opt_malloc(sizeof(struct server
));
822 in_addr_t a
= ntohl(addr
.s_addr
) >> 8;
825 memset(serv
, 0, sizeof(struct server
));
826 p
= serv
->domain
= opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */
829 p
+= sprintf(p
, "%d.", a
& 0xff);
832 p
+= sprintf(p
, "%d.", a
& 0xff);
834 p
+= sprintf(p
, "%d.in-addr.arpa", a
& 0xff);
836 serv
->flags
= SERV_HAS_DOMAIN
;
837 serv
->next
= daemon
->servers
;
838 daemon
->servers
= serv
;
844 static struct server
*add_rev6(struct in6_addr
*addr
, int msize
)
846 struct server
*serv
= opt_malloc(sizeof(struct server
));
850 memset(serv
, 0, sizeof(struct server
));
851 p
= serv
->domain
= opt_malloc(73); /* strlen("32*<n.>ip6.arpa")+1 */
853 for (i
= msize
-1; i
>= 0; i
-= 4)
855 int dig
= ((unsigned char *)addr
)[i
>>3];
856 p
+= sprintf(p
, "%.1x.", (i
>>2) & 1 ? dig
& 15 : dig
>> 4);
858 p
+= sprintf(p
, "ip6.arpa");
860 serv
->flags
= SERV_HAS_DOMAIN
;
861 serv
->next
= daemon
->servers
;
862 daemon
->servers
= serv
;
869 static int is_tag_prefix(char *arg
)
871 if (arg
&& (strstr(arg
, "net:") == arg
|| strstr(arg
, "tag:") == arg
))
877 static char *set_prefix(char *arg
)
879 if (strstr(arg
, "set:") == arg
)
885 /* This is too insanely large to keep in-line in the switch */
886 static int parse_dhcp_opt(char *errstr
, char *arg
, int flags
)
888 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
889 char lenchar
= 0, *cp
;
890 int addrs
, digs
, is_addr
, is_addr6
, is_hex
, is_dec
, is_string
, dots
;
892 struct dhcp_netid
*np
= NULL
;
907 for (cp
= arg
; *cp
; cp
++)
908 if (*cp
< '0' || *cp
> '9')
913 new->opt
= atoi(arg
);
919 if (strstr(arg
, "option:") == arg
)
921 if ((new->opt
= lookup_dhcp_opt(AF_INET
, arg
+7)) != -1)
923 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
924 /* option:<optname> must follow tag and vendor string. */
925 if (!(opt_len
& OT_INTERNAL
) || flags
== DHOPT_MATCH
)
931 else if (strstr(arg
, "option6:") == arg
)
933 for (cp
= arg
+8; *cp
; cp
++)
934 if (*cp
< '0' || *cp
> '9')
939 new->opt
= atoi(arg
+8);
945 if ((new->opt
= lookup_dhcp_opt(AF_INET6
, arg
+8)) != -1)
947 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
948 if (!(opt_len
& OT_INTERNAL
) || flags
== DHOPT_MATCH
)
952 /* option6:<opt>|<optname> must follow tag and vendor string. */
957 else if (strstr(arg
, "vendor:") == arg
)
959 new->u
.vendor_class
= (unsigned char *)opt_string_alloc(arg
+7);
960 new->flags
|= DHOPT_VENDOR
;
962 else if (strstr(arg
, "encap:") == arg
)
964 new->u
.encap
= atoi(arg
+6);
965 new->flags
|= DHOPT_ENCAPSULATE
;
967 else if (strstr(arg
, "vi-encap:") == arg
)
969 new->u
.encap
= atoi(arg
+9);
970 new->flags
|= DHOPT_RFC3925
;
971 if (flags
== DHOPT_MATCH
)
979 new->netid
= opt_malloc(sizeof (struct dhcp_netid
));
980 /* allow optional "net:" or "tag:" for consistency */
981 if (is_tag_prefix(arg
))
982 new->netid
->net
= opt_string_alloc(arg
+4);
984 new->netid
->net
= opt_string_alloc(set_prefix(arg
));
985 new->netid
->next
= np
;
995 if (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))
996 ret_err(_("unsupported encapsulation for IPv6 option"));
999 !(new->flags
& DHOPT_RFC3925
))
1000 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
1005 !(new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
| DHOPT_RFC3925
)))
1006 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
1008 /* option may be missing with rfc3925 match */
1010 ret_err(_("bad dhcp-option"));
1014 /* characterise the value */
1017 is_addr
= is_addr6
= is_hex
= is_dec
= is_string
= 1;
1020 for (cp
= comma
; (c
= *cp
); cp
++)
1024 is_dec
= is_hex
= 0;
1029 is_dec
= is_addr
= 0;
1033 is_addr6
= is_dec
= is_hex
= 0;
1034 if (cp
== comma
) /* leading / means a pathname */
1039 is_addr6
= is_dec
= is_hex
= 0;
1043 is_hex
= is_addr
= is_addr6
= 0;
1045 is_dec
= is_hex
= 0;
1046 else if (!(c
>='0' && c
<= '9'))
1049 if (cp
[1] == 0 && is_dec
&&
1050 (c
== 'b' || c
== 's' || c
== 'i'))
1057 if (!((c
>='A' && c
<= 'F') ||
1058 (c
>='a' && c
<= 'f') ||
1059 (c
== '*' && (flags
& DHOPT_MATCH
))))
1062 if (c
!= '[' && c
!= ']')
1070 is_dec
= is_addr
= 0;
1072 /* We know that some options take addresses */
1073 if (opt_len
& OT_ADDR_LIST
)
1075 is_string
= is_dec
= is_hex
= 0;
1077 if (!is6
&& (!is_addr
|| dots
== 0))
1078 ret_err(_("bad IP address"));
1080 if (is6
&& !is_addr6
)
1081 ret_err(_("bad IPv6 address"));
1084 else if (opt_len
& (OT_NAME
| OT_RFC1035_NAME
| OT_CSTRING
))
1085 is_addr6
= is_addr
= is_dec
= is_hex
= 0;
1087 if (found_dig
&& (opt_len
& OT_TIME
) && strlen(comma
) > 0)
1091 switch (comma
[strlen(comma
) - 1])
1111 comma
[strlen(comma
) - 1] = 0;
1115 new->val
= opt_malloc(4);
1117 *((int *)new->val
) = htonl(val
* fac
);
1119 else if (is_hex
&& digs
> 1)
1122 new->val
= opt_malloc(new->len
);
1123 parse_hex(comma
, new->val
, digs
, (flags
& DHOPT_MATCH
) ? &new->u
.wildcard_mask
: NULL
, NULL
);
1124 new->flags
|= DHOPT_HEX
;
1128 int i
, val
= atoi(comma
);
1129 /* assume numeric arg is 1 byte except for
1130 options where it is known otherwise.
1131 For vendor class option, we have to hack. */
1134 else if (val
& 0xffff0000)
1136 else if (val
& 0xff00)
1143 else if (lenchar
== 's')
1145 else if (lenchar
== 'i')
1148 new->val
= opt_malloc(new->len
);
1149 for (i
=0; i
<new->len
; i
++)
1150 new->val
[i
] = val
>>((new->len
- i
- 1)*8);
1152 else if (is_addr
&& !is6
)
1157 /* max length of address/subnet descriptor is five bytes,
1158 add one for the option 120 enc byte too */
1159 new->val
= op
= opt_malloc((5 * addrs
) + 1);
1160 new->flags
|= DHOPT_ADDR
;
1162 if (!(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)) &&
1163 new->opt
== OPTION_SIP_SERVER
)
1165 *(op
++) = 1; /* RFC 3361 "enc byte" */
1166 new->flags
&= ~DHOPT_ADDR
;
1172 slash
= split_chr(cp
, '/');
1173 inet_pton(AF_INET
, cp
, &in
);
1176 memcpy(op
, &in
, INADDRSZ
);
1181 unsigned char *p
= (unsigned char *)&in
;
1182 int netsize
= atoi(slash
);
1192 new->flags
&= ~DHOPT_ADDR
; /* cannot re-write descriptor format */
1195 new->len
= op
- new->val
;
1197 else if (is_addr6
&& is6
)
1200 new->val
= op
= opt_malloc(16 * addrs
);
1201 new->flags
|= DHOPT_ADDR6
;
1207 /* check for [1234::7] */
1210 if (strlen(cp
) > 1 && cp
[strlen(cp
)-1] == ']')
1211 cp
[strlen(cp
)-1] = 0;
1213 if (inet_pton(AF_INET6
, cp
, op
))
1219 ret_err(_("bad IPv6 address"));
1221 new->len
= op
- new->val
;
1226 if ((new->opt
== OPTION_DOMAIN_SEARCH
|| new->opt
== OPTION_SIP_SERVER
) &&
1227 !is6
&& !(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)))
1229 /* dns search, RFC 3397, or SIP, RFC 3361 */
1230 unsigned char *q
, *r
, *tail
;
1231 unsigned char *p
, *m
= NULL
, *newp
;
1232 size_t newlen
, len
= 0;
1233 int header_size
= (new->opt
== OPTION_DOMAIN_SEARCH
) ? 0 : 1;
1240 char *in
, *dom
= NULL
;
1242 /* Allow "." as an empty domain */
1243 if (strcmp (arg
, ".") != 0)
1245 if (!(dom
= canonicalise_opt(arg
)))
1246 ret_err(_("bad domain in dhcp-option"));
1248 domlen
= strlen(dom
) + 2;
1251 newp
= opt_malloc(len
+ domlen
+ header_size
);
1254 memcpy(newp
, m
, header_size
+ len
);
1258 p
= m
+ header_size
;
1261 /* add string on the end in RFC1035 format */
1262 for (in
= dom
; in
&& *in
;)
1264 unsigned char *cp
= q
++;
1266 for (j
= 0; *in
&& (*in
!= '.'); in
++, j
++)
1275 /* Now tail-compress using earlier names. */
1277 for (tail
= p
+ len
; *tail
; tail
+= (*tail
) + 1)
1278 for (r
= p
; r
- p
< (int)len
; r
+= (*r
) + 1)
1279 if (strcmp((char *)r
, (char *)tail
) == 0)
1281 PUTSHORT((r
- p
) | 0xc000, tail
);
1292 /* RFC 3361, enc byte is zero for names */
1293 if (new->opt
== OPTION_SIP_SERVER
)
1295 new->len
= (int) len
+ header_size
;
1299 else if (comma
&& (opt_len
& OT_CSTRING
))
1301 /* length fields are two bytes so need 16 bits for each string */
1303 unsigned char *p
, *newp
;
1305 for (i
= 0; comma
[i
]; i
++)
1306 if (comma
[i
] == ',')
1309 newp
= opt_malloc(strlen(comma
)+(2*commas
));
1316 u16 len
= strlen(arg
);
1319 memcpy(p
, arg
, len
);
1327 new->len
= p
- newp
;
1329 else if (comma
&& (opt_len
& OT_RFC1035_NAME
))
1331 unsigned char *p
= NULL
, *newp
, *end
;
1338 char *dom
= canonicalise_opt(arg
);
1340 ret_err(_("bad domain in dhcp-option"));
1342 newp
= opt_malloc(len
+ strlen(dom
) + 2);
1346 memcpy(newp
, p
, len
);
1351 end
= do_rfc1035_name(p
+ len
, dom
);
1366 new->len
= strlen(comma
);
1367 /* keep terminating zero on string */
1368 new->val
= (unsigned char *)opt_string_alloc(comma
);
1369 new->flags
|= DHOPT_STRING
;
1375 ((new->len
> 255) ||
1376 (new->len
> 253 && (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))) ||
1377 (new->len
> 250 && (new->flags
& DHOPT_RFC3925
))))
1378 ret_err(_("dhcp-option too long"));
1380 if (flags
== DHOPT_MATCH
)
1382 if ((new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
)) ||
1385 ret_err(_("illegal dhcp-match"));
1389 new->next
= daemon
->dhcp_match6
;
1390 daemon
->dhcp_match6
= new;
1394 new->next
= daemon
->dhcp_match
;
1395 daemon
->dhcp_match
= new;
1400 new->next
= daemon
->dhcp_opts6
;
1401 daemon
->dhcp_opts6
= new;
1405 new->next
= daemon
->dhcp_opts
;
1406 daemon
->dhcp_opts
= new;
1414 void set_option_bool(unsigned int opt
)
1417 daemon
->options
|= 1u << opt
;
1419 daemon
->options2
|= 1u << (opt
- 32);
1422 void reset_option_bool(unsigned int opt
)
1425 daemon
->options
&= ~(1u << opt
);
1427 daemon
->options2
&= ~(1u << (opt
- 32));
1430 static int one_opt(int option
, char *arg
, char *errstr
, char *gen_err
, int command_line
, int servers_only
)
1438 for (i
=0; usage
[i
].opt
!= 0; i
++)
1439 if (usage
[i
].opt
== option
)
1441 int rept
= usage
[i
].rept
;
1446 if (rept
== ARG_USED_CL
)
1447 ret_err(_("illegal repeated flag"));
1448 if (rept
== ARG_ONE
)
1449 usage
[i
].rept
= ARG_USED_CL
;
1453 /* allow file to override command line */
1454 if (rept
== ARG_USED_FILE
)
1455 ret_err(_("illegal repeated keyword"));
1456 if (rept
== ARG_USED_CL
|| rept
== ARG_ONE
)
1457 usage
[i
].rept
= ARG_USED_FILE
;
1460 if (rept
!= ARG_DUP
&& rept
!= ARG_ONE
&& rept
!= ARG_USED_CL
)
1462 set_option_bool(rept
);
1471 case 'C': /* --conf-file */
1473 char *file
= opt_string_alloc(arg
);
1482 case '7': /* --conf-dir */
1486 char *directory
, *path
;
1490 } *ignore_suffix
= NULL
, *match_suffix
= NULL
, *li
;
1493 if (!(directory
= opt_string_alloc(arg
)))
1496 for (arg
= comma
; arg
; arg
= comma
)
1499 if (strlen(arg
) != 0)
1501 li
= opt_malloc(sizeof(struct list
));
1504 li
->next
= match_suffix
;
1506 /* Have to copy: buffer is overwritten */
1507 li
->suffix
= opt_string_alloc(arg
+1);
1511 li
->next
= ignore_suffix
;
1513 /* Have to copy: buffer is overwritten */
1514 li
->suffix
= opt_string_alloc(arg
);
1519 if (!(dir_stream
= opendir(directory
)))
1520 die(_("cannot access directory %s: %s"), directory
, EC_FILE
);
1522 while ((ent
= readdir(dir_stream
)))
1524 size_t len
= strlen(ent
->d_name
);
1527 /* ignore emacs backups and dotfiles */
1529 ent
->d_name
[len
- 1] == '~' ||
1530 (ent
->d_name
[0] == '#' && ent
->d_name
[len
- 1] == '#') ||
1531 ent
->d_name
[0] == '.')
1536 for (li
= match_suffix
; li
; li
= li
->next
)
1538 /* check for required suffices */
1539 size_t ls
= strlen(li
->suffix
);
1541 strcmp(li
->suffix
, &ent
->d_name
[len
- ls
]) == 0)
1548 for (li
= ignore_suffix
; li
; li
= li
->next
)
1550 /* check for proscribed suffices */
1551 size_t ls
= strlen(li
->suffix
);
1553 strcmp(li
->suffix
, &ent
->d_name
[len
- ls
]) == 0)
1559 path
= opt_malloc(strlen(directory
) + len
+ 2);
1560 strcpy(path
, directory
);
1562 strcat(path
, ent
->d_name
);
1564 /* files must be readable */
1565 if (stat(path
, &buf
) == -1)
1566 die(_("cannot access %s: %s"), path
, EC_FILE
);
1568 /* only reg files allowed. */
1569 if (S_ISREG(buf
.st_mode
))
1575 closedir(dir_stream
);
1577 for(; ignore_suffix
; ignore_suffix
= li
)
1579 li
= ignore_suffix
->next
;
1580 free(ignore_suffix
->suffix
);
1581 free(ignore_suffix
);
1583 for(; match_suffix
; match_suffix
= li
)
1585 li
= match_suffix
->next
;
1586 free(match_suffix
->suffix
);
1592 case LOPT_ADD_SBNET
: /* --add-subnet */
1593 set_option_bool(OPT_CLIENT_SUBNET
);
1597 if (!atoi_check(arg
, &daemon
->addr4_netmask
) ||
1598 (comma
&& !atoi_check(comma
, &daemon
->addr6_netmask
)))
1603 case '1': /* --enable-dbus */
1604 set_option_bool(OPT_DBUS
);
1606 daemon
->dbus_name
= opt_string_alloc(arg
);
1608 daemon
->dbus_name
= DNSMASQ_SERVICE
;
1611 case '8': /* --log-facility */
1612 /* may be a filename */
1613 if (strchr(arg
, '/') || strcmp (arg
, "-") == 0)
1614 daemon
->log_file
= opt_string_alloc(arg
);
1618 ret_err(_("setting log facility is not possible under Android"));
1620 for (i
= 0; facilitynames
[i
].c_name
; i
++)
1621 if (hostname_isequal((char *)facilitynames
[i
].c_name
, arg
))
1624 if (facilitynames
[i
].c_name
)
1625 daemon
->log_fac
= facilitynames
[i
].c_val
;
1627 ret_err(_("bad log facility"));
1632 case 'x': /* --pid-file */
1633 daemon
->runfile
= opt_string_alloc(arg
);
1636 case 'r': /* --resolv-file */
1638 char *name
= opt_string_alloc(arg
);
1639 struct resolvc
*new, *list
= daemon
->resolv_files
;
1641 if (list
&& list
->is_default
)
1643 /* replace default resolv file - possibly with nothing */
1646 list
->is_default
= 0;
1654 new = opt_malloc(sizeof(struct resolvc
));
1657 new->is_default
= 0;
1662 daemon
->resolv_files
= list
;
1666 case LOPT_SERVERS_FILE
:
1667 daemon
->servers_file
= opt_string_alloc(arg
);
1670 case 'm': /* --mx-host */
1673 struct mx_srv_record
*new;
1674 char *name
, *target
= NULL
;
1676 if ((comma
= split(arg
)))
1679 if ((prefstr
= split(comma
)) && !atoi_check16(prefstr
, &pref
))
1680 ret_err(_("bad MX preference"));
1683 if (!(name
= canonicalise_opt(arg
)) ||
1684 (comma
&& !(target
= canonicalise_opt(comma
))))
1685 ret_err(_("bad MX name"));
1687 new = opt_malloc(sizeof(struct mx_srv_record
));
1688 new->next
= daemon
->mxnames
;
1689 daemon
->mxnames
= new;
1692 new->target
= target
; /* may be NULL */
1697 case 't': /* --mx-target */
1698 if (!(daemon
->mxtarget
= canonicalise_opt(arg
)))
1699 ret_err(_("bad MX target"));
1703 case 'l': /* --dhcp-leasefile */
1704 daemon
->lease_file
= opt_string_alloc(arg
);
1707 /* Sorry about the gross pre-processor abuse */
1708 case '6': /* --dhcp-script */
1709 case LOPT_LUASCRIPT
: /* --dhcp-luascript */
1710 # if defined(NO_FORK)
1711 ret_err(_("cannot run scripts under uClinux"));
1712 # elif !defined(HAVE_SCRIPT)
1713 ret_err(_("recompile with HAVE_SCRIPT defined to enable lease-change scripts"));
1715 if (option
== LOPT_LUASCRIPT
)
1716 # if !defined(HAVE_LUASCRIPT)
1717 ret_err(_("recompile with HAVE_LUASCRIPT defined to enable Lua scripts"));
1719 daemon
->luascript
= opt_string_alloc(arg
);
1722 daemon
->lease_change_command
= opt_string_alloc(arg
);
1725 #endif /* HAVE_DHCP */
1727 case LOPT_DHCP_HOST
: /* --dhcp-hostsfile */
1728 case LOPT_DHCP_OPTS
: /* --dhcp-optsfile */
1729 case LOPT_DHCP_INOTIFY
: /* --dhcp-hostsdir */
1730 case LOPT_DHOPT_INOTIFY
: /* --dhcp-optsdir */
1731 case LOPT_HOST_INOTIFY
: /* --hostsdir */
1732 case 'H': /* --addn-hosts */
1734 struct hostsfile
*new = opt_malloc(sizeof(struct hostsfile
));
1735 static unsigned int hosts_index
= SRC_AH
;
1736 new->fname
= opt_string_alloc(arg
);
1737 new->index
= hosts_index
++;
1741 new->next
= daemon
->addn_hosts
;
1742 daemon
->addn_hosts
= new;
1744 else if (option
== LOPT_DHCP_HOST
)
1746 new->next
= daemon
->dhcp_hosts_file
;
1747 daemon
->dhcp_hosts_file
= new;
1749 else if (option
== LOPT_DHCP_OPTS
)
1751 new->next
= daemon
->dhcp_opts_file
;
1752 daemon
->dhcp_opts_file
= new;
1756 new->next
= daemon
->dynamic_dirs
;
1757 daemon
->dynamic_dirs
= new;
1758 if (option
== LOPT_DHCP_INOTIFY
)
1759 new->flags
|= AH_DHCP_HST
;
1760 else if (option
== LOPT_DHOPT_INOTIFY
)
1761 new->flags
|= AH_DHCP_OPT
;
1762 else if (option
== LOPT_HOST_INOTIFY
)
1763 new->flags
|= AH_HOSTS
;
1771 case LOPT_AUTHSERV
: /* --auth-server */
1772 if (!(comma
= split(arg
)))
1775 daemon
->authserver
= opt_string_alloc(arg
);
1778 struct iname
*new = opt_malloc(sizeof(struct iname
));
1782 if (inet_pton(AF_INET
, arg
, &new->addr
.in
.sin_addr
) > 0)
1783 new->addr
.sa
.sa_family
= AF_INET
;
1785 else if (inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
1786 new->addr
.sa
.sa_family
= AF_INET6
;
1790 char *fam
= split_chr(arg
, '/');
1791 new->name
= opt_string_alloc(arg
);
1792 new->addr
.sa
.sa_family
= 0;
1795 if (strcmp(fam
, "4") == 0)
1796 new->addr
.sa
.sa_family
= AF_INET
;
1798 else if (strcmp(fam
, "6") == 0)
1799 new->addr
.sa
.sa_family
= AF_INET6
;
1805 new->next
= daemon
->authinterface
;
1806 daemon
->authinterface
= new;
1813 case LOPT_AUTHSFS
: /* --auth-sec-servers */
1815 struct name_list
*new;
1819 new = opt_malloc(sizeof(struct name_list
));
1820 new->name
= opt_string_alloc(arg
);
1821 new->next
= daemon
->secondary_forward_server
;
1822 daemon
->secondary_forward_server
= new;
1828 case LOPT_AUTHZONE
: /* --auth-zone */
1830 struct auth_zone
*new;
1834 new = opt_malloc(sizeof(struct auth_zone
));
1835 new->domain
= opt_string_alloc(arg
);
1837 new->interface_names
= NULL
;
1838 new->next
= daemon
->auth_zones
;
1839 daemon
->auth_zones
= new;
1841 while ((arg
= comma
))
1845 struct addrlist
*subnet
= NULL
;
1846 struct all_addr addr
;
1849 prefix
= split_chr(arg
, '/');
1851 if (prefix
&& !atoi_check(prefix
, &prefixlen
))
1854 if (inet_pton(AF_INET
, arg
, &addr
.addr
.addr4
))
1856 subnet
= opt_malloc(sizeof(struct addrlist
));
1857 subnet
->prefixlen
= (prefixlen
== 0) ? 24 : prefixlen
;
1858 subnet
->flags
= ADDRLIST_LITERAL
;
1861 else if (inet_pton(AF_INET6
, arg
, &addr
.addr
.addr6
))
1863 subnet
= opt_malloc(sizeof(struct addrlist
));
1864 subnet
->prefixlen
= (prefixlen
== 0) ? 64 : prefixlen
;
1865 subnet
->flags
= ADDRLIST_LITERAL
| ADDRLIST_IPV6
;
1870 struct auth_name_list
*name
= opt_malloc(sizeof(struct auth_name_list
));
1871 name
->name
= opt_string_alloc(arg
);
1872 name
->flags
= AUTH4
| AUTH6
;
1873 name
->next
= new->interface_names
;
1874 new->interface_names
= name
;
1878 name
->flags
&= ~AUTH6
;
1880 else if (prefixlen
== 6)
1881 name
->flags
&= ~AUTH4
;
1890 subnet
->addr
= addr
;
1891 subnet
->next
= new->subnet
;
1892 new->subnet
= subnet
;
1898 case LOPT_AUTHSOA
: /* --auth-soa */
1900 daemon
->soa_sn
= (u32
)atoi(arg
);
1906 daemon
->hostmaster
= opt_string_alloc(arg
);
1907 for (cp
= daemon
->hostmaster
; *cp
; cp
++)
1915 daemon
->soa_refresh
= (u32
)atoi(arg
);
1920 daemon
->soa_retry
= (u32
)atoi(arg
);
1925 daemon
->soa_expiry
= (u32
)atoi(arg
);
1934 case 's': /* --domain */
1935 case LOPT_SYNTH
: /* --synth-domain */
1936 if (strcmp (arg
, "#") == 0)
1937 set_option_bool(OPT_RESOLV_DOMAIN
);
1942 if (!(d
= canonicalise_opt(arg
)))
1948 struct cond_domain
*new = opt_malloc(sizeof(struct cond_domain
));
1953 unhide_metas(comma
);
1954 if ((netpart
= split_chr(comma
, '/')))
1958 arg
= split(netpart
);
1959 if (!atoi_check(netpart
, &msize
))
1961 else if (inet_pton(AF_INET
, comma
, &new->start
))
1963 int mask
= (1 << (32 - msize
)) - 1;
1965 new->start
.s_addr
= ntohl(htonl(new->start
.s_addr
) & ~mask
);
1966 new->end
.s_addr
= new->start
.s_addr
| htonl(mask
);
1971 if (!(new->prefix
= canonicalise_opt(arg
)) ||
1972 strlen(new->prefix
) > MAXLABEL
- INET_ADDRSTRLEN
)
1973 ret_err(_("bad prefix"));
1975 else if (strcmp(arg
, "local") != 0 ||
1976 (msize
!= 8 && msize
!= 16 && msize
!= 24))
1980 /* generate the equivalent of
1981 local=/xxx.yyy.zzz.in-addr.arpa/ */
1982 struct server
*serv
= add_rev4(new->start
, msize
);
1983 serv
->flags
|= SERV_NO_ADDR
;
1985 /* local=/<domain>/ */
1986 serv
= opt_malloc(sizeof(struct server
));
1987 memset(serv
, 0, sizeof(struct server
));
1989 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1990 serv
->next
= daemon
->servers
;
1991 daemon
->servers
= serv
;
1996 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1998 u64 mask
= (1LLU << (128 - msize
)) - 1LLU;
1999 u64 addrpart
= addr6part(&new->start6
);
2002 /* prefix==64 overflows the mask calculation above */
2006 new->end6
= new->start6
;
2007 setaddr6part(&new->start6
, addrpart
& ~mask
);
2008 setaddr6part(&new->end6
, addrpart
| mask
);
2016 if (!(new->prefix
= canonicalise_opt(arg
)) ||
2017 strlen(new->prefix
) > MAXLABEL
- INET6_ADDRSTRLEN
)
2018 ret_err(_("bad prefix"));
2020 else if (strcmp(arg
, "local") != 0 || ((msize
& 4) != 0))
2024 /* generate the equivalent of
2025 local=/xxx.yyy.zzz.ip6.arpa/ */
2026 struct server
*serv
= add_rev6(&new->start6
, msize
);
2027 serv
->flags
|= SERV_NO_ADDR
;
2029 /* local=/<domain>/ */
2030 serv
= opt_malloc(sizeof(struct server
));
2031 memset(serv
, 0, sizeof(struct server
));
2033 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
2034 serv
->next
= daemon
->servers
;
2035 daemon
->servers
= serv
;
2047 prefstr
= split(arg
);
2049 if (inet_pton(AF_INET
, comma
, &new->start
))
2053 new->end
.s_addr
= new->start
.s_addr
;
2054 else if (!inet_pton(AF_INET
, arg
, &new->end
))
2058 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
2062 memcpy(&new->end6
, &new->start6
, IN6ADDRSZ
);
2063 else if (!inet_pton(AF_INET6
, arg
, &new->end6
))
2070 if (option
!= 's' && prefstr
)
2072 if (!(new->prefix
= canonicalise_opt(prefstr
)) ||
2073 strlen(new->prefix
) > MAXLABEL
- INET_ADDRSTRLEN
)
2074 ret_err(_("bad prefix"));
2081 new->next
= daemon
->cond_domain
;
2082 daemon
->cond_domain
= new;
2086 new->next
= daemon
->synth_domains
;
2087 daemon
->synth_domains
= new;
2090 else if (option
== 's')
2091 daemon
->domain_suffix
= d
;
2098 case 'u': /* --user */
2099 daemon
->username
= opt_string_alloc(arg
);
2102 case 'g': /* --group */
2103 daemon
->groupname
= opt_string_alloc(arg
);
2104 daemon
->group_set
= 1;
2108 case LOPT_SCRIPTUSR
: /* --scriptuser */
2109 daemon
->scriptuser
= opt_string_alloc(arg
);
2113 case 'i': /* --interface */
2115 struct iname
*new = opt_malloc(sizeof(struct iname
));
2117 new->next
= daemon
->if_names
;
2118 daemon
->if_names
= new;
2119 /* new->name may be NULL if someone does
2120 "interface=" to disable all interfaces except loop. */
2121 new->name
= opt_string_alloc(arg
);
2127 case LOPT_TFTP
: /* --enable-tftp */
2128 set_option_bool(OPT_TFTP
);
2133 case 'I': /* --except-interface */
2134 case '2': /* --no-dhcp-interface */
2136 struct iname
*new = opt_malloc(sizeof(struct iname
));
2138 new->name
= opt_string_alloc(arg
);
2141 new->next
= daemon
->if_except
;
2142 daemon
->if_except
= new;
2144 else if (option
== LOPT_TFTP
)
2146 new->next
= daemon
->tftp_interfaces
;
2147 daemon
->tftp_interfaces
= new;
2151 new->next
= daemon
->dhcp_except
;
2152 daemon
->dhcp_except
= new;
2158 case 'B': /* --bogus-nxdomain */
2159 case LOPT_IGNORE_ADDR
: /* --ignore-address */
2161 struct in_addr addr
;
2163 if (arg
&& (inet_pton(AF_INET
, arg
, &addr
) > 0))
2165 struct bogus_addr
*baddr
= opt_malloc(sizeof(struct bogus_addr
));
2168 baddr
->next
= daemon
->bogus_addr
;
2169 daemon
->bogus_addr
= baddr
;
2173 baddr
->next
= daemon
->ignore_addr
;
2174 daemon
->ignore_addr
= baddr
;
2179 ret_err(gen_err
); /* error */
2183 case 'a': /* --listen-address */
2184 case LOPT_AUTHPEER
: /* --auth-peer */
2186 struct iname
*new = opt_malloc(sizeof(struct iname
));
2189 if (arg
&& (inet_pton(AF_INET
, arg
, &new->addr
.in
.sin_addr
) > 0))
2191 new->addr
.sa
.sa_family
= AF_INET
;
2192 new->addr
.in
.sin_port
= 0;
2193 #ifdef HAVE_SOCKADDR_SA_LEN
2194 new->addr
.in
.sin_len
= sizeof(new->addr
.in
);
2198 else if (arg
&& inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
2200 new->addr
.sa
.sa_family
= AF_INET6
;
2201 new->addr
.in6
.sin6_flowinfo
= 0;
2202 new->addr
.in6
.sin6_scope_id
= 0;
2203 new->addr
.in6
.sin6_port
= 0;
2204 #ifdef HAVE_SOCKADDR_SA_LEN
2205 new->addr
.in6
.sin6_len
= sizeof(new->addr
.in6
);
2215 new->next
= daemon
->if_addrs
;
2216 daemon
->if_addrs
= new;
2220 new->next
= daemon
->auth_peers
;
2221 daemon
->auth_peers
= new;
2227 case 'S': /* --server */
2228 case LOPT_LOCAL
: /* --local */
2229 case 'A': /* --address */
2230 case LOPT_NO_REBIND
: /* --rebind-domain-ok */
2232 struct server
*serv
, *newlist
= NULL
;
2236 if (arg
&& (*arg
== '/' || option
== LOPT_NO_REBIND
))
2238 int rebind
= !(*arg
== '/');
2242 while (rebind
|| (end
= split_chr(arg
, '/')))
2244 char *domain
= NULL
;
2245 /* elide leading dots - they are implied in the search algorithm */
2246 while (*arg
== '.') arg
++;
2247 /* # matches everything and becomes a zero length domain string */
2248 if (strcmp(arg
, "#") == 0)
2250 else if (strlen (arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
2252 serv
= opt_malloc(sizeof(struct server
));
2253 memset(serv
, 0, sizeof(struct server
));
2254 serv
->next
= newlist
;
2256 serv
->domain
= domain
;
2257 serv
->flags
= domain
? SERV_HAS_DOMAIN
: SERV_FOR_NODOTS
;
2267 newlist
= opt_malloc(sizeof(struct server
));
2268 memset(newlist
, 0, sizeof(struct server
));
2270 newlist
->uid
= rand32();
2274 if (servers_only
&& option
== 'S')
2275 newlist
->flags
|= SERV_FROM_FILE
;
2279 newlist
->flags
|= SERV_LITERAL_ADDRESS
;
2280 if (!(newlist
->flags
& SERV_TYPE
))
2283 else if (option
== LOPT_NO_REBIND
)
2284 newlist
->flags
|= SERV_NO_REBIND
;
2288 if (!(newlist
->flags
& SERV_NO_REBIND
))
2289 newlist
->flags
|= SERV_NO_ADDR
; /* no server */
2292 else if (strcmp(arg
, "#") == 0)
2294 newlist
->flags
|= SERV_USE_RESOLV
; /* treat in ordinary way */
2295 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
2300 char *err
= parse_server(arg
, &newlist
->addr
, &newlist
->source_addr
, newlist
->interface
, &newlist
->flags
);
2308 serv
->next
->flags
= serv
->flags
;
2309 serv
->next
->addr
= serv
->addr
;
2310 serv
->next
->source_addr
= serv
->source_addr
;
2311 strcpy(serv
->next
->interface
, serv
->interface
);
2314 serv
->next
= daemon
->servers
;
2315 daemon
->servers
= newlist
;
2319 case LOPT_REV_SERV
: /* --rev-server */
2323 struct server
*serv
;
2324 struct in_addr addr4
;
2326 struct in6_addr addr6
;
2330 if (!arg
|| !(comma
=split(arg
)) || !(string
= split_chr(arg
, '/')) || !atoi_check(string
, &size
))
2333 if (inet_pton(AF_INET
, arg
, &addr4
))
2334 serv
= add_rev4(addr4
, size
);
2336 else if (inet_pton(AF_INET6
, arg
, &addr6
))
2337 serv
= add_rev6(&addr6
, size
);
2342 string
= parse_server(comma
, &serv
->addr
, &serv
->source_addr
, serv
->interface
, &serv
->flags
);
2348 serv
->flags
|= SERV_FROM_FILE
;
2353 case LOPT_IPSET
: /* --ipset */
2355 ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
2359 struct ipsets ipsets_head
;
2360 struct ipsets
*ipsets
= &ipsets_head
;
2363 char **sets
, **sets_pos
;
2364 memset(ipsets
, 0, sizeof(struct ipsets
));
2366 if (arg
&& *arg
== '/')
2369 while ((end
= split_chr(arg
, '/')))
2371 char *domain
= NULL
;
2372 /* elide leading dots - they are implied in the search algorithm */
2375 /* # matches everything and becomes a zero length domain string */
2376 if (strcmp(arg
, "#") == 0 || !*arg
)
2378 else if (strlen(arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
2380 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2381 ipsets
= ipsets
->next
;
2382 memset(ipsets
, 0, sizeof(struct ipsets
));
2383 ipsets
->domain
= domain
;
2389 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2390 ipsets
= ipsets
->next
;
2391 memset(ipsets
, 0, sizeof(struct ipsets
));
2392 ipsets
->domain
= "";
2400 for (end
= arg
; *end
; ++end
)
2404 sets
= sets_pos
= opt_malloc(sizeof(char *) * size
);
2408 *sets_pos
++ = opt_string_alloc(arg
);
2412 for (ipsets
= &ipsets_head
; ipsets
->next
; ipsets
= ipsets
->next
)
2413 ipsets
->next
->sets
= sets
;
2414 ipsets
->next
= daemon
->ipsets
;
2415 daemon
->ipsets
= ipsets_head
.next
;
2421 case 'c': /* --cache-size */
2425 if (!atoi_check(arg
, &size
))
2429 /* zero is OK, and means no caching. */
2433 else if (size
> 10000)
2436 daemon
->cachesize
= size
;
2441 case 'p': /* --port */
2442 if (!atoi_check16(arg
, &daemon
->port
))
2446 case LOPT_MINPORT
: /* --min-port */
2447 if (!atoi_check16(arg
, &daemon
->min_port
))
2451 case '0': /* --dns-forward-max */
2452 if (!atoi_check(arg
, &daemon
->ftabsize
))
2456 case 'q': /* --log-queries */
2457 set_option_bool(OPT_LOG
);
2458 if (arg
&& strcmp(arg
, "extra") == 0)
2459 set_option_bool(OPT_EXTRALOG
);
2462 case LOPT_MAX_LOGS
: /* --log-async */
2463 daemon
->max_logs
= LOG_MAX
; /* default */
2464 if (arg
&& !atoi_check(arg
, &daemon
->max_logs
))
2466 else if (daemon
->max_logs
> 100)
2467 daemon
->max_logs
= 100;
2470 case 'P': /* --edns-packet-max */
2473 if (!atoi_check(arg
, &i
))
2475 daemon
->edns_pktsz
= (unsigned short)i
;
2479 case 'Q': /* --query-port */
2480 if (!atoi_check16(arg
, &daemon
->query_port
))
2482 /* if explicitly set to zero, use single OS ephemeral port
2483 and disable random ports */
2484 if (daemon
->query_port
== 0)
2488 case 'T': /* --local-ttl */
2489 case LOPT_NEGTTL
: /* --neg-ttl */
2490 case LOPT_MAXTTL
: /* --max-ttl */
2491 case LOPT_MINCTTL
: /* --min-cache-ttl */
2492 case LOPT_MAXCTTL
: /* --max-cache-ttl */
2493 case LOPT_AUTHTTL
: /* --auth-ttl */
2496 if (!atoi_check(arg
, &ttl
))
2498 else if (option
== LOPT_NEGTTL
)
2499 daemon
->neg_ttl
= (unsigned long)ttl
;
2500 else if (option
== LOPT_MAXTTL
)
2501 daemon
->max_ttl
= (unsigned long)ttl
;
2502 else if (option
== LOPT_MINCTTL
)
2504 if (ttl
> TTL_FLOOR_LIMIT
)
2505 ttl
= TTL_FLOOR_LIMIT
;
2506 daemon
->min_cache_ttl
= (unsigned long)ttl
;
2508 else if (option
== LOPT_MAXCTTL
)
2509 daemon
->max_cache_ttl
= (unsigned long)ttl
;
2510 else if (option
== LOPT_AUTHTTL
)
2511 daemon
->auth_ttl
= (unsigned long)ttl
;
2513 daemon
->local_ttl
= (unsigned long)ttl
;
2518 case 'X': /* --dhcp-lease-max */
2519 if (!atoi_check(arg
, &daemon
->dhcp_max
))
2525 case LOPT_TFTP_MAX
: /* --tftp-max */
2526 if (!atoi_check(arg
, &daemon
->tftp_max
))
2530 case LOPT_PREFIX
: /* --tftp-prefix */
2534 struct tftp_prefix
*new = opt_malloc(sizeof(struct tftp_prefix
));
2535 new->interface
= opt_string_alloc(comma
);
2536 new->prefix
= opt_string_alloc(arg
);
2537 new->next
= daemon
->if_prefix
;
2538 daemon
->if_prefix
= new;
2541 daemon
->tftp_prefix
= opt_string_alloc(arg
);
2544 case LOPT_TFTPPORTS
: /* --tftp-port-range */
2545 if (!(comma
= split(arg
)) ||
2546 !atoi_check16(arg
, &daemon
->start_tftp_port
) ||
2547 !atoi_check16(comma
, &daemon
->end_tftp_port
))
2548 ret_err(_("bad port range"));
2550 if (daemon
->start_tftp_port
> daemon
->end_tftp_port
)
2552 int tmp
= daemon
->start_tftp_port
;
2553 daemon
->start_tftp_port
= daemon
->end_tftp_port
;
2554 daemon
->end_tftp_port
= tmp
;
2560 case LOPT_BRIDGE
: /* --bridge-interface */
2562 struct dhcp_bridge
*new = opt_malloc(sizeof(struct dhcp_bridge
));
2563 if (!(comma
= split(arg
)) || strlen(arg
) > IF_NAMESIZE
- 1 )
2564 ret_err(_("bad bridge-interface"));
2566 strcpy(new->iface
, arg
);
2568 new->next
= daemon
->bridges
;
2569 daemon
->bridges
= new;
2574 if (strlen(arg
) != 0 && strlen(arg
) <= IF_NAMESIZE
- 1)
2576 struct dhcp_bridge
*b
= opt_malloc(sizeof(struct dhcp_bridge
));
2577 b
->next
= new->alias
;
2579 strcpy(b
->iface
, arg
);
2587 case 'F': /* --dhcp-range */
2589 int k
, leasepos
= 2;
2590 char *cp
, *a
[8] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2591 struct dhcp_context
*new = opt_malloc(sizeof(struct dhcp_context
));
2593 memset (new, 0, sizeof(*new));
2594 new->lease_time
= DEFLEASE
;
2604 for (cp
= arg
; *cp
; cp
++)
2605 if (!(*cp
== ' ' || *cp
== '.' || *cp
== ':' ||
2606 (*cp
>= 'a' && *cp
<= 'f') || (*cp
>= 'A' && *cp
<= 'F') ||
2607 (*cp
>='0' && *cp
<= '9')))
2610 if (*cp
!= ',' && (comma
= split(arg
)))
2612 if (is_tag_prefix(arg
))
2614 struct dhcp_netid
*tt
= opt_malloc(sizeof (struct dhcp_netid
));
2615 tt
->net
= opt_string_alloc(arg
+4);
2616 tt
->next
= new->filter
;
2617 /* ignore empty tag */
2624 ret_err(_("only one tag allowed"));
2625 else if (strstr(arg
, "set:") == arg
)
2626 new->netid
.net
= opt_string_alloc(arg
+4);
2628 new->netid
.net
= opt_string_alloc(arg
);
2639 for (k
= 1; k
< 8; k
++)
2640 if (!(a
[k
] = split(a
[k
-1])))
2644 ret_err(_("bad dhcp-range"));
2646 if (inet_pton(AF_INET
, a
[0], &new->start
))
2648 new->next
= daemon
->dhcp
;
2650 new->end
= new->start
;
2651 if (strcmp(a
[1], "static") == 0)
2652 new->flags
|= CONTEXT_STATIC
;
2653 else if (strcmp(a
[1], "proxy") == 0)
2654 new->flags
|= CONTEXT_PROXY
;
2655 else if (!inet_pton(AF_INET
, a
[1], &new->end
))
2656 ret_err(_("bad dhcp-range"));
2658 if (ntohl(new->start
.s_addr
) > ntohl(new->end
.s_addr
))
2660 struct in_addr tmp
= new->start
;
2661 new->start
= new->end
;
2665 if (k
>= 3 && strchr(a
[2], '.') &&
2666 (inet_pton(AF_INET
, a
[2], &new->netmask
) > 0))
2668 new->flags
|= CONTEXT_NETMASK
;
2670 if (!is_same_net(new->start
, new->end
, new->netmask
))
2671 ret_err(_("inconsistent DHCP range"));
2674 if (k
>= 4 && strchr(a
[3], '.') &&
2675 (inet_pton(AF_INET
, a
[3], &new->broadcast
) > 0))
2677 new->flags
|= CONTEXT_BRDCAST
;
2682 else if (inet_pton(AF_INET6
, a
[0], &new->start6
))
2684 new->flags
|= CONTEXT_V6
;
2685 new->prefix
= 64; /* default */
2686 new->end6
= new->start6
;
2687 new->next
= daemon
->dhcp6
;
2688 daemon
->dhcp6
= new;
2690 for (leasepos
= 1; leasepos
< k
; leasepos
++)
2692 if (strcmp(a
[leasepos
], "static") == 0)
2693 new->flags
|= CONTEXT_STATIC
| CONTEXT_DHCP
;
2694 else if (strcmp(a
[leasepos
], "ra-only") == 0 || strcmp(a
[leasepos
], "slaac") == 0 )
2695 new->flags
|= CONTEXT_RA
;
2696 else if (strcmp(a
[leasepos
], "ra-names") == 0)
2697 new->flags
|= CONTEXT_RA_NAME
| CONTEXT_RA
;
2698 else if (strcmp(a
[leasepos
], "ra-advrouter") == 0)
2699 new->flags
|= CONTEXT_RA_ROUTER
| CONTEXT_RA
;
2700 else if (strcmp(a
[leasepos
], "ra-stateless") == 0)
2701 new->flags
|= CONTEXT_RA_STATELESS
| CONTEXT_DHCP
| CONTEXT_RA
;
2702 else if (strcmp(a
[leasepos
], "off-link") == 0)
2703 new->flags
|= CONTEXT_RA_OFF_LINK
;
2704 else if (leasepos
== 1 && inet_pton(AF_INET6
, a
[leasepos
], &new->end6
))
2705 new->flags
|= CONTEXT_DHCP
;
2706 else if (strstr(a
[leasepos
], "constructor:") == a
[leasepos
])
2708 new->template_interface
= opt_string_alloc(a
[leasepos
] + 12);
2709 new->flags
|= CONTEXT_TEMPLATE
;
2715 /* bare integer < 128 is prefix value */
2719 for (cp
= a
[leasepos
]; *cp
; cp
++)
2720 if (!(*cp
>= '0' && *cp
<= '9'))
2722 if (!*cp
&& (pref
= atoi(a
[leasepos
])) <= 128)
2729 if (new->prefix
!= 64)
2731 if (new->flags
& CONTEXT_RA
)
2732 ret_err(_("prefix length must be exactly 64 for RA subnets"));
2733 else if (new->flags
& CONTEXT_TEMPLATE
)
2734 ret_err(_("prefix length must be exactly 64 for subnet constructors"));
2737 if (new->prefix
< 64)
2738 ret_err(_("prefix length must be at least 64"));
2740 if (!is_same_net6(&new->start6
, &new->end6
, new->prefix
))
2741 ret_err(_("inconsistent DHCPv6 range"));
2743 /* dhcp-range=:: enables DHCP stateless on any interface */
2744 if (IN6_IS_ADDR_UNSPECIFIED(&new->start6
) && !(new->flags
& CONTEXT_TEMPLATE
))
2747 if (new->flags
& CONTEXT_TEMPLATE
)
2749 struct in6_addr zero
;
2750 memset(&zero
, 0, sizeof(zero
));
2751 if (!is_same_net6(&zero
, &new->start6
, new->prefix
))
2752 ret_err(_("prefix must be zero with \"constructor:\" argument"));
2755 if (addr6part(&new->start6
) > addr6part(&new->end6
))
2757 struct in6_addr tmp
= new->start6
;
2758 new->start6
= new->end6
;
2764 ret_err(_("bad dhcp-range"));
2768 if (strcmp(a
[leasepos
], "infinite") == 0)
2769 new->lease_time
= 0xffffffff;
2770 else if (strcmp(a
[leasepos
], "deprecated") == 0)
2771 new->flags
|= CONTEXT_DEPRECATE
;
2775 if (strlen(a
[leasepos
]) > 0)
2777 switch (a
[leasepos
][strlen(a
[leasepos
]) - 1])
2797 a
[leasepos
][strlen(a
[leasepos
]) - 1] = 0;
2800 for (cp
= a
[leasepos
]; *cp
; cp
++)
2801 if (!(*cp
>= '0' && *cp
<= '9'))
2804 if (*cp
|| (leasepos
+1 < k
))
2805 ret_err(_("bad dhcp-range"));
2807 new->lease_time
= atoi(a
[leasepos
]) * fac
;
2808 /* Leases of a minute or less confuse
2809 some clients, notably Apple's */
2810 if (new->lease_time
< 120)
2811 new->lease_time
= 120;
2819 case 'G': /* --dhcp-host */
2822 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2823 struct dhcp_config
*new;
2826 new = opt_malloc(sizeof(struct dhcp_config
));
2828 new->next
= daemon
->dhcp_conf
;
2829 new->flags
= (option
== LOPT_BANK
) ? CONFIG_BANK
: 0;
2834 for (k
= 1; k
< 7; k
++)
2835 if (!(a
[k
] = split(a
[k
-1])))
2838 for (j
= 0; j
< k
; j
++)
2839 if (strchr(a
[j
], ':')) /* ethernet address, netid or binary CLID */
2843 if ((arg
[0] == 'i' || arg
[0] == 'I') &&
2844 (arg
[1] == 'd' || arg
[1] == 'D') &&
2848 new->flags
|= CONFIG_NOCLID
;
2852 arg
+= 3; /* dump id: */
2853 if (strchr(arg
, ':'))
2854 len
= parse_hex(arg
, (unsigned char *)arg
, -1, NULL
, NULL
);
2858 len
= (int) strlen(arg
);
2863 ret_err(_("bad hex constant"));
2864 else if ((new->clid
= opt_malloc(len
)))
2866 new->flags
|= CONFIG_CLID
;
2867 new->clid_len
= len
;
2868 memcpy(new->clid
, arg
, len
);
2872 /* dhcp-host has strange backwards-compat needs. */
2873 else if (strstr(arg
, "net:") == arg
|| strstr(arg
, "set:") == arg
)
2875 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2876 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2877 newtag
->net
= opt_malloc(strlen(arg
+ 4) + 1);
2878 newlist
->next
= new->netid
;
2879 new->netid
= newlist
;
2880 newlist
->list
= newtag
;
2881 strcpy(newtag
->net
, arg
+4);
2882 unhide_metas(newtag
->net
);
2884 else if (strstr(arg
, "tag:") == arg
)
2885 ret_err(_("cannot match tags in --dhcp-host"));
2887 else if (arg
[0] == '[' && arg
[strlen(arg
)-1] == ']')
2889 arg
[strlen(arg
)-1] = 0;
2892 if (!inet_pton(AF_INET6
, arg
, &new->addr6
))
2893 ret_err(_("bad IPv6 address"));
2895 for (i
= 0; i
< 8; i
++)
2896 if (new->addr6
.s6_addr
[i
] != 0)
2899 /* set WILDCARD if network part all zeros */
2901 new->flags
|= CONFIG_WILDCARD
;
2903 new->flags
|= CONFIG_ADDR6
;
2908 struct hwaddr_config
*newhw
= opt_malloc(sizeof(struct hwaddr_config
));
2909 if ((newhw
->hwaddr_len
= parse_hex(a
[j
], newhw
->hwaddr
, DHCP_CHADDR_MAX
,
2910 &newhw
->wildcard_mask
, &newhw
->hwaddr_type
)) == -1)
2911 ret_err(_("bad hex constant"));
2915 newhw
->next
= new->hwaddr
;
2916 new->hwaddr
= newhw
;
2920 else if (strchr(a
[j
], '.') && (inet_pton(AF_INET
, a
[j
], &in
) > 0))
2922 struct dhcp_config
*configs
;
2925 new->flags
|= CONFIG_ADDR
;
2927 /* If the same IP appears in more than one host config, then DISCOVER
2928 for one of the hosts will get the address, but REQUEST will be NAKed,
2929 since the address is reserved by the other one -> protocol loop. */
2930 for (configs
= daemon
->dhcp_conf
; configs
; configs
= configs
->next
)
2931 if ((configs
->flags
& CONFIG_ADDR
) && configs
->addr
.s_addr
== in
.s_addr
)
2933 sprintf(errstr
, _("duplicate dhcp-host IP address %s"), inet_ntoa(in
));
2939 char *cp
, *lastp
= NULL
, last
= 0;
2940 int fac
= 1, isdig
= 0;
2942 if (strlen(a
[j
]) > 1)
2944 lastp
= a
[j
] + strlen(a
[j
]) - 1;
2970 for (cp
= a
[j
]; *cp
; cp
++)
2971 if (isdigit((unsigned char)*cp
))
2973 else if (*cp
!= ' ')
2980 if (strcmp(a
[j
], "infinite") == 0)
2982 new->lease_time
= 0xffffffff;
2983 new->flags
|= CONFIG_TIME
;
2985 else if (strcmp(a
[j
], "ignore") == 0)
2986 new->flags
|= CONFIG_DISABLE
;
2989 if (!(new->hostname
= canonicalise_opt(a
[j
])) ||
2990 !legal_hostname(new->hostname
))
2991 ret_err(_("bad DHCP host name"));
2993 new->flags
|= CONFIG_NAME
;
2994 new->domain
= strip_hostname(new->hostname
);
2999 new->lease_time
= atoi(a
[j
]) * fac
;
3000 /* Leases of a minute or less confuse
3001 some clients, notably Apple's */
3002 if (new->lease_time
< 120)
3003 new->lease_time
= 120;
3004 new->flags
|= CONFIG_TIME
;
3008 daemon
->dhcp_conf
= new;
3012 case LOPT_TAG_IF
: /* --tag-if */
3014 struct tag_if
*new = opt_malloc(sizeof(struct tag_if
));
3020 /* preserve order */
3021 if (!daemon
->tag_if
)
3022 daemon
->tag_if
= new;
3026 for (tmp
= daemon
->tag_if
; tmp
->next
; tmp
= tmp
->next
);
3044 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
3045 newtag
->net
= opt_malloc(len
- 3);
3046 strcpy(newtag
->net
, arg
+4);
3047 unhide_metas(newtag
->net
);
3049 if (strstr(arg
, "set:") == arg
)
3051 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
3052 newlist
->next
= new->set
;
3054 newlist
->list
= newtag
;
3056 else if (strstr(arg
, "tag:") == arg
)
3058 newtag
->next
= new->tag
;
3073 ret_err(_("bad tag-if"));
3079 case 'O': /* --dhcp-option */
3080 case LOPT_FORCE
: /* --dhcp-option-force */
3082 case LOPT_MATCH
: /* --dhcp-match */
3083 return parse_dhcp_opt(errstr
, arg
,
3084 option
== LOPT_FORCE
? DHOPT_FORCE
:
3085 (option
== LOPT_MATCH
? DHOPT_MATCH
:
3086 (option
== LOPT_OPTS
? DHOPT_BANK
: 0)));
3088 case 'M': /* --dhcp-boot */
3090 struct dhcp_netid
*id
= NULL
;
3091 while (is_tag_prefix(arg
))
3093 struct dhcp_netid
*newid
= opt_malloc(sizeof(struct dhcp_netid
));
3097 newid
->net
= opt_string_alloc(arg
+4);
3105 char *dhcp_file
, *dhcp_sname
= NULL
, *tftp_sname
= NULL
;
3106 struct in_addr dhcp_next_server
;
3107 struct dhcp_boot
*new;
3109 dhcp_file
= opt_string_alloc(arg
);
3110 dhcp_next_server
.s_addr
= 0;
3115 dhcp_sname
= opt_string_alloc(arg
);
3118 unhide_metas(comma
);
3119 if (!(inet_pton(AF_INET
, comma
, &dhcp_next_server
) > 0))
3122 * The user may have specified the tftp hostname here.
3123 * save it so that it can be resolved/looked up during
3124 * actual dhcp_reply().
3127 tftp_sname
= opt_string_alloc(comma
);
3128 dhcp_next_server
.s_addr
= 0;
3133 new = opt_malloc(sizeof(struct dhcp_boot
));
3134 new->file
= dhcp_file
;
3135 new->sname
= dhcp_sname
;
3136 new->tftp_sname
= tftp_sname
;
3137 new->next_server
= dhcp_next_server
;
3139 new->next
= daemon
->boot_config
;
3140 daemon
->boot_config
= new;
3146 case LOPT_PXE_PROMT
: /* --pxe-prompt */
3148 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
3152 new->opt
= 10; /* PXE_MENU_PROMPT */
3154 while (is_tag_prefix(arg
))
3156 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
3158 nn
->next
= new->netid
;
3160 nn
->net
= opt_string_alloc(arg
+4);
3170 new->len
= strlen(arg
) + 1;
3171 new->val
= opt_malloc(new->len
);
3172 memcpy(new->val
+ 1, arg
, new->len
- 1);
3174 new->u
.vendor_class
= (unsigned char *)"PXEClient";
3175 new->flags
= DHOPT_VENDOR
;
3177 if (comma
&& atoi_check(comma
, &timeout
))
3178 *(new->val
) = timeout
;
3182 new->next
= daemon
->dhcp_opts
;
3183 daemon
->dhcp_opts
= new;
3184 daemon
->enable_pxe
= 1;
3190 case LOPT_PXE_SERV
: /* --pxe-service */
3192 struct pxe_service
*new = opt_malloc(sizeof(struct pxe_service
));
3193 char *CSA
[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
3194 "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL
};
3195 static int boottype
= 32768;
3199 new->server
.s_addr
= 0;
3201 while (is_tag_prefix(arg
))
3203 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
3205 nn
->next
= new->netid
;
3207 nn
->net
= opt_string_alloc(arg
+4);
3211 if (arg
&& (comma
= split(arg
)))
3213 for (i
= 0; CSA
[i
]; i
++)
3214 if (strcasecmp(CSA
[i
], arg
) == 0)
3217 if (CSA
[i
] || atoi_check(arg
, &i
))
3223 new->menu
= opt_string_alloc(arg
);
3227 new->type
= 0; /* local boot */
3228 new->basename
= NULL
;
3234 if (atoi_check(arg
, &i
))
3237 new->basename
= NULL
;
3241 new->type
= boottype
++;
3242 new->basename
= opt_string_alloc(arg
);
3247 if (!inet_pton(AF_INET
, comma
, &new->server
))
3249 new->server
.s_addr
= 0;
3250 new->sname
= opt_string_alloc(comma
);
3258 if (!daemon
->pxe_services
)
3259 daemon
->pxe_services
= new;
3262 struct pxe_service
*s
;
3263 for (s
= daemon
->pxe_services
; s
->next
; s
= s
->next
);
3267 daemon
->enable_pxe
= 1;
3276 case '4': /* --dhcp-mac */
3278 if (!(comma
= split(arg
)))
3282 struct dhcp_mac
*new = opt_malloc(sizeof(struct dhcp_mac
));
3283 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
3284 unhide_metas(comma
);
3285 new->hwaddr_len
= parse_hex(comma
, new->hwaddr
, DHCP_CHADDR_MAX
, &new->mask
, &new->hwaddr_type
);
3286 if (new->hwaddr_len
== -1)
3290 new->next
= daemon
->dhcp_macs
;
3291 daemon
->dhcp_macs
= new;
3297 #ifdef OPTION6_PREFIX_CLASS
3298 case LOPT_PREF_CLSS
: /* --dhcp-prefix-class */
3300 struct prefix_class
*new = opt_malloc(sizeof(struct prefix_class
));
3302 if (!(comma
= split(arg
)) ||
3303 !atoi_check16(comma
, &new->class))
3306 new->tag
.net
= opt_string_alloc(set_prefix(arg
));
3307 new->next
= daemon
->prefix_classes
;
3308 daemon
->prefix_classes
= new;
3315 case 'U': /* --dhcp-vendorclass */
3316 case 'j': /* --dhcp-userclass */
3317 case LOPT_CIRCUIT
: /* --dhcp-circuitid */
3318 case LOPT_REMOTE
: /* --dhcp-remoteid */
3319 case LOPT_SUBSCR
: /* --dhcp-subscrid */
3323 struct dhcp_vendor
*new = opt_malloc(sizeof(struct dhcp_vendor
));
3325 if (!(comma
= split(arg
)))
3328 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
3329 /* check for hex string - must digits may include : must not have nothing else,
3330 only allowed for agent-options. */
3333 if ((comma
= split(arg
)))
3335 if (option
!= 'U' || strstr(arg
, "enterprise:") != arg
)
3338 new->enterprise
= atoi(arg
+11);
3343 for (p
= (unsigned char *)comma
; *p
; p
++)
3348 unhide_metas(comma
);
3349 if (option
== 'U' || option
== 'j' || *p
|| !dig
)
3351 new->len
= strlen(comma
);
3352 new->data
= opt_malloc(new->len
);
3353 memcpy(new->data
, comma
, new->len
);
3357 new->len
= parse_hex(comma
, (unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
3358 new->data
= opt_malloc(new->len
);
3359 memcpy(new->data
, comma
, new->len
);
3365 new->match_type
= MATCH_USER
;
3368 new->match_type
= MATCH_VENDOR
;
3371 new->match_type
= MATCH_CIRCUIT
;
3374 new->match_type
= MATCH_REMOTE
;
3377 new->match_type
= MATCH_SUBSCRIBER
;
3380 new->next
= daemon
->dhcp_vendors
;
3381 daemon
->dhcp_vendors
= new;
3386 case LOPT_ALTPORT
: /* --dhcp-alternate-port */
3389 daemon
->dhcp_server_port
= DHCP_SERVER_ALTPORT
;
3390 daemon
->dhcp_client_port
= DHCP_CLIENT_ALTPORT
;
3395 if (!atoi_check16(arg
, &daemon
->dhcp_server_port
) ||
3396 (comma
&& !atoi_check16(comma
, &daemon
->dhcp_client_port
)))
3397 ret_err(_("invalid port number"));
3399 daemon
->dhcp_client_port
= daemon
->dhcp_server_port
+1;
3403 case 'J': /* --dhcp-ignore */
3404 case LOPT_NO_NAMES
: /* --dhcp-ignore-names */
3405 case LOPT_BROADCAST
: /* --dhcp-broadcast */
3406 case '3': /* --bootp-dynamic */
3407 case LOPT_GEN_NAMES
: /* --dhcp-generate-names */
3409 struct dhcp_netid_list
*new = opt_malloc(sizeof(struct dhcp_netid_list
));
3410 struct dhcp_netid
*list
= NULL
;
3413 new->next
= daemon
->dhcp_ignore
;
3414 daemon
->dhcp_ignore
= new;
3416 else if (option
== LOPT_BROADCAST
)
3418 new->next
= daemon
->force_broadcast
;
3419 daemon
->force_broadcast
= new;
3421 else if (option
== '3')
3423 new->next
= daemon
->bootp_dynamic
;
3424 daemon
->bootp_dynamic
= new;
3426 else if (option
== LOPT_GEN_NAMES
)
3428 new->next
= daemon
->dhcp_gen_names
;
3429 daemon
->dhcp_gen_names
= new;
3433 new->next
= daemon
->dhcp_ignore_names
;
3434 daemon
->dhcp_ignore_names
= new;
3438 struct dhcp_netid
*member
= opt_malloc(sizeof(struct dhcp_netid
));
3440 member
->next
= list
;
3442 if (is_tag_prefix(arg
))
3443 member
->net
= opt_string_alloc(arg
+4);
3445 member
->net
= opt_string_alloc(arg
);
3453 case LOPT_PROXY
: /* --dhcp-proxy */
3454 daemon
->override
= 1;
3456 struct addr_list
*new = opt_malloc(sizeof(struct addr_list
));
3458 if (!(inet_pton(AF_INET
, arg
, &new->addr
) > 0))
3459 ret_err(_("bad dhcp-proxy address"));
3460 new->next
= daemon
->override_relays
;
3461 daemon
->override_relays
= new;
3466 case LOPT_RELAY
: /* --dhcp-relay */
3468 struct dhcp_relay
*new = opt_malloc(sizeof(struct dhcp_relay
));
3470 new->interface
= opt_string_alloc(split(comma
));
3471 new->iface_index
= 0;
3472 if (inet_pton(AF_INET
, arg
, &new->local
) && inet_pton(AF_INET
, comma
, &new->server
))
3474 new->next
= daemon
->relay4
;
3475 daemon
->relay4
= new;
3478 else if (inet_pton(AF_INET6
, arg
, &new->local
) && inet_pton(AF_INET6
, comma
, &new->server
))
3480 new->next
= daemon
->relay6
;
3481 daemon
->relay6
= new;
3485 ret_err(_("Bad dhcp-relay"));
3493 case LOPT_RA_PARAM
: /* --ra-param */
3494 if ((comma
= split(arg
)))
3496 struct ra_interface
*new = opt_malloc(sizeof(struct ra_interface
));
3499 new->name
= opt_string_alloc(arg
);
3500 if (strcasestr(comma
, "high") == comma
|| strcasestr(comma
, "low") == comma
)
3502 if (*comma
== 'l' || *comma
== 'L')
3506 comma
= split(comma
);
3509 if (!atoi_check(comma
, &new->interval
) ||
3510 (arg
&& !atoi_check(arg
, &new->lifetime
)))
3511 ret_err(_("bad RA-params"));
3513 new->next
= daemon
->ra_interfaces
;
3514 daemon
->ra_interfaces
= new;
3518 case LOPT_DUID
: /* --dhcp-duid */
3519 if (!(comma
= split(arg
)) || !atoi_check(arg
, (int *)&daemon
->duid_enterprise
))
3520 ret_err(_("bad DUID"));
3523 daemon
->duid_config_len
= parse_hex(comma
,(unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
3524 daemon
->duid_config
= opt_malloc(daemon
->duid_config_len
);
3525 memcpy(daemon
->duid_config
, comma
, daemon
->duid_config_len
);
3530 case 'V': /* --alias */
3532 char *dash
, *a
[3] = { NULL
, NULL
, NULL
};
3534 struct doctor
*new = opt_malloc(sizeof(struct doctor
));
3535 new->next
= daemon
->doctors
;
3536 daemon
->doctors
= new;
3537 new->mask
.s_addr
= 0xffffffff;
3538 new->end
.s_addr
= 0;
3541 for (k
= 1; k
< 3; k
++)
3543 if (!(a
[k
] = split(a
[k
-1])))
3548 dash
= split_chr(a
[0], '-');
3551 (!(inet_pton(AF_INET
, a
[0], &new->in
) > 0)) ||
3552 (!(inet_pton(AF_INET
, a
[1], &new->out
) > 0)))
3556 inet_pton(AF_INET
, a
[2], &new->mask
);
3559 (!(inet_pton(AF_INET
, dash
, &new->end
) > 0) ||
3560 !is_same_net(new->in
, new->end
, new->mask
) ||
3561 ntohl(new->in
.s_addr
) > ntohl(new->end
.s_addr
)))
3562 ret_err(_("invalid alias range"));
3567 case LOPT_INTNAME
: /* --interface-name */
3569 struct interface_name
*new, **up
;
3570 char *domain
= NULL
;
3574 if (!comma
|| !(domain
= canonicalise_opt(arg
)))
3575 ret_err(_("bad interface name"));
3577 new = opt_malloc(sizeof(struct interface_name
));
3581 /* Add to the end of the list, so that first name
3582 of an interface is used for PTR lookups. */
3583 for (up
= &daemon
->int_names
; *up
; up
= &((*up
)->next
));
3587 arg
= split_chr(comma
, '/');
3590 if (strcmp(arg
, "4") == 0)
3591 new->family
= AF_INET
;
3593 else if (strcmp(arg
, "6") == 0)
3594 new->family
= AF_INET6
;
3599 new->intr
= opt_string_alloc(comma
);
3603 case LOPT_CNAME
: /* --cname */
3609 if (!(comma
= split(arg
)))
3612 alias
= canonicalise_opt(arg
);
3613 target
= canonicalise_opt(comma
);
3615 if (!alias
|| !target
)
3616 ret_err(_("bad CNAME"));
3619 for (new = daemon
->cnames
; new; new = new->next
)
3620 if (hostname_isequal(new->alias
, arg
))
3621 ret_err(_("duplicate CNAME"));
3622 new = opt_malloc(sizeof(struct cname
));
3623 new->next
= daemon
->cnames
;
3624 daemon
->cnames
= new;
3626 new->target
= target
;
3632 case LOPT_PTR
: /* --ptr-record */
3634 struct ptr_record
*new;
3635 char *dom
, *target
= NULL
;
3639 if (!(dom
= canonicalise_opt(arg
)) ||
3640 (comma
&& !(target
= canonicalise_opt(comma
))))
3641 ret_err(_("bad PTR record"));
3644 new = opt_malloc(sizeof(struct ptr_record
));
3645 new->next
= daemon
->ptr
;
3653 case LOPT_NAPTR
: /* --naptr-record */
3655 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
3659 char *name
, *replace
= NULL
;
3662 for (k
= 1; k
< 7; k
++)
3663 if (!(a
[k
] = split(a
[k
-1])))
3668 !(name
= canonicalise_opt(a
[0])) ||
3669 !atoi_check16(a
[1], &order
) ||
3670 !atoi_check16(a
[2], &pref
) ||
3671 (k
== 7 && !(replace
= canonicalise_opt(a
[6]))))
3672 ret_err(_("bad NAPTR record"));
3675 new = opt_malloc(sizeof(struct naptr
));
3676 new->next
= daemon
->naptr
;
3677 daemon
->naptr
= new;
3679 new->flags
= opt_string_alloc(a
[3]);
3680 new->services
= opt_string_alloc(a
[4]);
3681 new->regexp
= opt_string_alloc(a
[5]);
3682 new->replace
= replace
;
3689 case LOPT_RR
: /* dns-rr */
3691 struct txt_record
*new;
3697 data
= split(comma
);
3699 new = opt_malloc(sizeof(struct txt_record
));
3700 new->next
= daemon
->rr
;
3703 if (!atoi_check(comma
, &val
) ||
3704 !(new->name
= canonicalise_opt(arg
)) ||
3705 (data
&& (len
= parse_hex(data
, (unsigned char *)data
, -1, NULL
, NULL
)) == -1U))
3706 ret_err(_("bad RR record"));
3713 new->txt
=opt_malloc(len
);
3715 memcpy(new->txt
, data
, len
);
3721 case 'Y': /* --txt-record */
3723 struct txt_record
*new;
3724 unsigned char *p
, *cnt
;
3729 new = opt_malloc(sizeof(struct txt_record
));
3730 new->next
= daemon
->txt
;
3735 if (!(new->name
= canonicalise_opt(arg
)))
3736 ret_err(_("bad TXT record"));
3738 len
= comma
? strlen(comma
) : 0;
3739 len
+= (len
/255) + 1; /* room for extra counts */
3740 new->txt
= p
= opt_malloc(len
);
3745 while (comma
&& *comma
)
3747 unsigned char c
= (unsigned char)*comma
++;
3749 if (c
== ',' || *cnt
== 255)
3758 *p
++ = unhide_meta(c
);
3763 new->len
= p
- new->txt
;
3768 case 'W': /* --srv-host */
3770 int port
= 1, priority
= 0, weight
= 0;
3771 char *name
, *target
= NULL
;
3772 struct mx_srv_record
*new;
3776 if (!(name
= canonicalise_opt(arg
)))
3777 ret_err(_("bad SRV record"));
3783 if (!(target
= canonicalise_opt(arg
)))
3784 ret_err(_("bad SRV target"));
3790 if (!atoi_check16(arg
, &port
))
3791 ret_err(_("invalid port number"));
3797 if (!atoi_check16(arg
, &priority
))
3798 ret_err(_("invalid priority"));
3804 if (!atoi_check16(arg
, &weight
))
3805 ret_err(_("invalid weight"));
3811 new = opt_malloc(sizeof(struct mx_srv_record
));
3812 new->next
= daemon
->mxnames
;
3813 daemon
->mxnames
= new;
3816 new->target
= target
;
3817 new->srvport
= port
;
3818 new->priority
= priority
;
3819 new->weight
= weight
;
3823 case LOPT_HOST_REC
: /* --host-record */
3825 struct host_record
*new = opt_malloc(sizeof(struct host_record
));
3826 memset(new, 0, sizeof(struct host_record
));
3828 if (!arg
|| !(comma
= split(arg
)))
3829 ret_err(_("Bad host-record"));
3833 struct all_addr addr
;
3834 if (inet_pton(AF_INET
, arg
, &addr
))
3835 new->addr
= addr
.addr
.addr4
;
3837 else if (inet_pton(AF_INET6
, arg
, &addr
))
3838 new->addr6
= addr
.addr
.addr6
;
3843 char *canon
= canonicalise(arg
, &nomem
);
3844 struct name_list
*nl
= opt_malloc(sizeof(struct name_list
));
3846 ret_err(_("Bad name in host-record"));
3849 /* keep order, so that PTR record goes to first name */
3855 struct name_list
*tmp
;
3856 for (tmp
= new->names
; tmp
->next
; tmp
= tmp
->next
);
3865 /* Keep list order */
3866 if (!daemon
->host_records_tail
)
3867 daemon
->host_records
= new;
3869 daemon
->host_records_tail
->next
= new;
3871 daemon
->host_records_tail
= new;
3876 case LOPT_DNSSEC_STAMP
:
3877 daemon
->timestamp_file
= opt_string_alloc(arg
);
3880 case LOPT_TRUST_ANCHOR
:
3882 struct ds_config
*new = opt_malloc(sizeof(struct ds_config
));
3883 char *cp
, *cp1
, *keyhex
, *digest
, *algo
= NULL
;
3888 if ((comma
= split(arg
)) && (algo
= split(comma
)))
3891 if (strcmp(comma
, "IN") == 0)
3893 else if (strcmp(comma
, "CH") == 0)
3895 else if (strcmp(comma
, "HS") == 0)
3902 algo
= split(comma
);
3906 if (!comma
|| !algo
|| !(digest
= split(algo
)) || !(keyhex
= split(digest
)) ||
3907 !atoi_check16(comma
, &new->keytag
) ||
3908 !atoi_check8(algo
, &new->algo
) ||
3909 !atoi_check8(digest
, &new->digest_type
) ||
3910 !(new->name
= canonicalise_opt(arg
)))
3911 ret_err(_("bad trust anchor"));
3913 /* Upper bound on length */
3914 len
= (2*strlen(keyhex
))+1;
3915 new->digest
= opt_malloc(len
);
3916 unhide_metas(keyhex
);
3917 /* 4034: "Whitespace is allowed within digits" */
3918 for (cp
= keyhex
; *cp
; )
3920 for (cp1
= cp
; *cp1
; cp1
++)
3924 if ((new->digestlen
= parse_hex(keyhex
, (unsigned char *)new->digest
, len
, NULL
, NULL
)) == -1)
3925 ret_err(_("bad HEX in trust anchor"));
3927 new->next
= daemon
->ds
;
3935 ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"));
3942 static void read_file(char *file
, FILE *f
, int hard_opt
)
3944 volatile int lineno
= 0;
3945 char *buff
= daemon
->namebuff
;
3947 while (fgets(buff
, MAXDNAME
, f
))
3950 volatile int option
= (hard_opt
== LOPT_REV_SERV
) ? 0 : hard_opt
;
3951 char *errmess
, *p
, *arg
= NULL
, *start
;
3954 /* Memory allocation failure longjmps here if mem_recover == 1 */
3955 if (option
!= 0 || hard_opt
== LOPT_REV_SERV
)
3957 if (setjmp(mem_jmp
))
3965 /* Implement quotes, inside quotes we allow \\ \" \n and \t
3966 metacharacters get hidden also strip comments */
3967 for (white
= 1, p
= buff
; *p
; p
++)
3971 memmove(p
, p
+1, strlen(p
+1)+1);
3973 for(; *p
&& *p
!= '"'; p
++)
3975 if (*p
== '\\' && strchr("\"tnebr\\", p
[1]))
3979 else if (p
[1] == 'n')
3981 else if (p
[1] == 'b')
3983 else if (p
[1] == 'r')
3985 else if (p
[1] == 'e') /* escape */
3987 memmove(p
, p
+1, strlen(p
+1)+1);
3994 errmess
= _("missing \"");
3998 memmove(p
, p
+1, strlen(p
+1)+1);
4008 if (white
&& *p
== '#')
4018 /* strip leading spaces */
4019 for (start
= buff
; *start
&& *start
== ' '; start
++);
4021 /* strip trailing spaces */
4022 for (len
= strlen(start
); (len
!= 0) && (start
[len
-1] == ' '); len
--);
4031 else if ((p
=strchr(start
, '=')))
4033 /* allow spaces around "=" */
4034 for (arg
= p
+1; *arg
== ' '; arg
++);
4035 for (; p
>= start
&& (*p
== ' ' || *p
== '='); p
--)
4043 for (option
= 0, i
= 0; opts
[i
].name
; i
++)
4044 if (strcmp(opts
[i
].name
, start
) == 0)
4046 option
= opts
[i
].val
;
4051 errmess
= _("bad option");
4052 else if (opts
[i
].has_arg
== 0 && arg
)
4053 errmess
= _("extraneous parameter");
4054 else if (opts
[i
].has_arg
== 1 && !arg
)
4055 errmess
= _("missing parameter");
4056 else if (hard_opt
== LOPT_REV_SERV
&& option
!= 'S' && option
!= LOPT_REV_SERV
)
4057 errmess
= _("illegal option");
4062 strcpy(daemon
->namebuff
, errmess
);
4064 if (errmess
|| !one_opt(option
, arg
, buff
, _("error"), 0, hard_opt
== LOPT_REV_SERV
))
4066 sprintf(daemon
->namebuff
+ strlen(daemon
->namebuff
), _(" at line %d of %s"), lineno
, file
);
4068 my_syslog(LOG_ERR
, "%s", daemon
->namebuff
);
4070 die("%s", daemon
->namebuff
, EC_BADCONF
);
4079 int option_read_dynfile(char *file
, int flags
)
4081 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), file
);
4083 if (flags
& AH_DHCP_HST
)
4084 return one_file(file
, LOPT_BANK
);
4085 else if (flags
& AH_DHCP_OPT
)
4086 return one_file(file
, LOPT_OPTS
);
4092 static int one_file(char *file
, int hard_opt
)
4096 static int read_stdin
= 0;
4097 static struct fileread
{
4100 struct fileread
*next
;
4101 } *filesread
= NULL
;
4103 if (hard_opt
== '7')
4105 /* default conf-file reading */
4110 if (hard_opt
== 0 && strcmp(file
, "-") == 0)
4112 if (read_stdin
== 1)
4120 /* ignore repeated files. */
4121 struct stat statbuf
;
4123 if (hard_opt
== 0 && stat(file
, &statbuf
) == 0)
4127 for (r
= filesread
; r
; r
= r
->next
)
4128 if (r
->dev
== statbuf
.st_dev
&& r
->ino
== statbuf
.st_ino
)
4131 r
= safe_malloc(sizeof(struct fileread
));
4132 r
->next
= filesread
;
4134 r
->dev
= statbuf
.st_dev
;
4135 r
->ino
= statbuf
.st_ino
;
4138 if (!(f
= fopen(file
, "r")))
4140 if (errno
== ENOENT
&& nofile_ok
)
4141 return 1; /* No conffile, all done. */
4144 char *str
= _("cannot read %s: %s");
4147 my_syslog(LOG_ERR
, str
, file
, strerror(errno
));
4151 die(str
, file
, EC_FILE
);
4156 read_file(file
, f
, hard_opt
);
4160 /* expand any name which is a directory */
4161 struct hostsfile
*expand_filelist(struct hostsfile
*list
)
4164 struct hostsfile
*ah
;
4166 /* find largest used index */
4167 for (i
= SRC_AH
, ah
= list
; ah
; ah
= ah
->next
)
4172 if (ah
->flags
& AH_DIR
)
4173 ah
->flags
|= AH_INACTIVE
;
4175 ah
->flags
&= ~AH_INACTIVE
;
4178 for (ah
= list
; ah
; ah
= ah
->next
)
4179 if (!(ah
->flags
& AH_INACTIVE
))
4182 if (stat(ah
->fname
, &buf
) != -1 && S_ISDIR(buf
.st_mode
))
4187 /* don't read this as a file */
4188 ah
->flags
|= AH_INACTIVE
;
4190 if (!(dir_stream
= opendir(ah
->fname
)))
4191 my_syslog(LOG_ERR
, _("cannot access directory %s: %s"),
4192 ah
->fname
, strerror(errno
));
4195 while ((ent
= readdir(dir_stream
)))
4197 size_t lendir
= strlen(ah
->fname
);
4198 size_t lenfile
= strlen(ent
->d_name
);
4199 struct hostsfile
*ah1
;
4202 /* ignore emacs backups and dotfiles */
4204 ent
->d_name
[lenfile
- 1] == '~' ||
4205 (ent
->d_name
[0] == '#' && ent
->d_name
[lenfile
- 1] == '#') ||
4206 ent
->d_name
[0] == '.')
4209 /* see if we have an existing record.
4212 path to match is ah1->fname */
4214 for (ah1
= list
; ah1
; ah1
= ah1
->next
)
4216 if (lendir
< strlen(ah1
->fname
) &&
4217 strstr(ah1
->fname
, ah
->fname
) == ah1
->fname
&&
4218 ah1
->fname
[lendir
] == '/' &&
4219 strcmp(ah1
->fname
+ lendir
+ 1, ent
->d_name
) == 0)
4221 ah1
->flags
&= ~AH_INACTIVE
;
4226 /* make new record */
4229 if (!(ah1
= whine_malloc(sizeof(struct hostsfile
))))
4232 if (!(path
= whine_malloc(lendir
+ lenfile
+ 2)))
4238 strcpy(path
, ah
->fname
);
4240 strcat(path
, ent
->d_name
);
4243 ah1
->flags
= AH_DIR
;
4248 /* inactivate record if not regular file */
4249 if ((ah1
->flags
& AH_DIR
) && stat(ah1
->fname
, &buf
) != -1 && !S_ISREG(buf
.st_mode
))
4250 ah1
->flags
|= AH_INACTIVE
;
4253 closedir(dir_stream
);
4261 void read_servers_file(void)
4265 if (!(f
= fopen(daemon
->servers_file
, "r")))
4267 my_syslog(LOG_ERR
, _("cannot read %s: %s"), daemon
->servers_file
, strerror(errno
));
4271 mark_servers(SERV_FROM_FILE
);
4274 read_file(daemon
->servers_file
, f
, LOPT_REV_SERV
);
4279 void reread_dhcp(void)
4281 struct hostsfile
*hf
;
4283 if (daemon
->dhcp_hosts_file
)
4285 struct dhcp_config
*configs
, *cp
, **up
;
4287 /* remove existing... */
4288 for (up
= &daemon
->dhcp_conf
, configs
= daemon
->dhcp_conf
; configs
; configs
= cp
)
4292 if (configs
->flags
& CONFIG_BANK
)
4294 struct hwaddr_config
*mac
, *tmp
;
4295 struct dhcp_netid_list
*list
, *tmplist
;
4297 for (mac
= configs
->hwaddr
; mac
; mac
= tmp
)
4303 if (configs
->flags
& CONFIG_CLID
)
4304 free(configs
->clid
);
4306 for (list
= configs
->netid
; list
; list
= tmplist
)
4309 tmplist
= list
->next
;
4313 if (configs
->flags
& CONFIG_NAME
)
4314 free(configs
->hostname
);
4316 *up
= configs
->next
;
4320 up
= &configs
->next
;
4323 daemon
->dhcp_hosts_file
= expand_filelist(daemon
->dhcp_hosts_file
);
4324 for (hf
= daemon
->dhcp_hosts_file
; hf
; hf
= hf
->next
)
4325 if (!(hf
->flags
& AH_INACTIVE
))
4327 if (one_file(hf
->fname
, LOPT_BANK
))
4328 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
4332 if (daemon
->dhcp_opts_file
)
4334 struct dhcp_opt
*opts
, *cp
, **up
;
4335 struct dhcp_netid
*id
, *next
;
4337 for (up
= &daemon
->dhcp_opts
, opts
= daemon
->dhcp_opts
; opts
; opts
= cp
)
4341 if (opts
->flags
& DHOPT_BANK
)
4343 if ((opts
->flags
& DHOPT_VENDOR
))
4344 free(opts
->u
.vendor_class
);
4346 for (id
= opts
->netid
; id
; id
= next
)
4359 daemon
->dhcp_opts_file
= expand_filelist(daemon
->dhcp_opts_file
);
4360 for (hf
= daemon
->dhcp_opts_file
; hf
; hf
= hf
->next
)
4361 if (!(hf
->flags
& AH_INACTIVE
))
4363 if (one_file(hf
->fname
, LOPT_OPTS
))
4364 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
4370 void read_opts(int argc
, char **argv
, char *compile_opts
)
4372 char *buff
= opt_malloc(MAXDNAME
);
4373 int option
, conffile_opt
= '7', testmode
= 0;
4374 char *arg
, *conffile
= CONFFILE
;
4378 daemon
= opt_malloc(sizeof(struct daemon
));
4379 memset(daemon
, 0, sizeof(struct daemon
));
4380 daemon
->namebuff
= buff
;
4382 /* Set defaults - everything else is zero or NULL */
4383 daemon
->cachesize
= CACHESIZ
;
4384 daemon
->ftabsize
= FTABSIZ
;
4385 daemon
->port
= NAMESERVER_PORT
;
4386 daemon
->dhcp_client_port
= DHCP_CLIENT_PORT
;
4387 daemon
->dhcp_server_port
= DHCP_SERVER_PORT
;
4388 daemon
->default_resolv
.is_default
= 1;
4389 daemon
->default_resolv
.name
= RESOLVFILE
;
4390 daemon
->resolv_files
= &daemon
->default_resolv
;
4391 daemon
->username
= CHUSER
;
4392 daemon
->runfile
= RUNFILE
;
4393 daemon
->dhcp_max
= MAXLEASES
;
4394 daemon
->tftp_max
= TFTP_MAX_CONNECTIONS
;
4395 daemon
->edns_pktsz
= EDNS_PKTSZ
;
4396 daemon
->log_fac
= -1;
4397 daemon
->auth_ttl
= AUTH_TTL
;
4398 daemon
->soa_refresh
= SOA_REFRESH
;
4399 daemon
->soa_retry
= SOA_RETRY
;
4400 daemon
->soa_expiry
= SOA_EXPIRY
;
4402 add_txt("version.bind", "dnsmasq-" VERSION
, 0 );
4403 add_txt("authors.bind", "Simon Kelley", 0);
4404 add_txt("copyright.bind", COPYRIGHT
, 0);
4405 add_txt("cachesize.bind", NULL
, TXT_STAT_CACHESIZE
);
4406 add_txt("insertions.bind", NULL
, TXT_STAT_INSERTS
);
4407 add_txt("evictions.bind", NULL
, TXT_STAT_EVICTIONS
);
4408 add_txt("misses.bind", NULL
, TXT_STAT_MISSES
);
4409 add_txt("hits.bind", NULL
, TXT_STAT_HITS
);
4411 add_txt("auth.bind", NULL
, TXT_STAT_AUTH
);
4413 add_txt("servers.bind", NULL
, TXT_STAT_SERVERS
);
4417 #ifdef HAVE_GETOPT_LONG
4418 option
= getopt_long(argc
, argv
, OPTSTRING
, opts
, NULL
);
4420 option
= getopt(argc
, argv
, OPTSTRING
);
4425 for (; optind
< argc
; optind
++)
4427 unsigned char *c
= (unsigned char *)argv
[optind
];
4428 for (; *c
!= 0; c
++)
4430 die(_("junk found in command line"), NULL
, EC_BADCONF
);
4435 /* Copy optarg so that argv doesn't get changed */
4438 strncpy(buff
, optarg
, MAXDNAME
);
4439 buff
[MAXDNAME
-1] = 0;
4445 /* command-line only stuff */
4446 if (option
== LOPT_TEST
)
4448 else if (option
== 'w')
4451 if (argc
== 3 && strcmp(argv
[2], "dhcp") == 0)
4454 else if (argc
== 3 && strcmp(argv
[2], "dhcp6") == 0)
4463 else if (option
== 'v')
4465 printf(_("Dnsmasq version %s %s\n"), VERSION
, COPYRIGHT
);
4466 printf(_("Compile time options: %s\n\n"), compile_opts
);
4467 printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
4468 printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
4469 printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
4472 else if (option
== 'C')
4474 conffile_opt
= 0; /* file must exist */
4475 conffile
= opt_string_alloc(arg
);
4479 #ifdef HAVE_GETOPT_LONG
4480 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try --help"), 1, 0))
4482 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try -w"), 1, 0))
4484 die(_("bad command line options: %s"), daemon
->namebuff
, EC_BADCONF
);
4490 one_file(conffile
, conffile_opt
);
4491 if (conffile_opt
== 0)
4495 /* port might not be known when the address is parsed - fill in here */
4496 if (daemon
->servers
)
4499 for (tmp
= daemon
->servers
; tmp
; tmp
= tmp
->next
)
4501 tmp
->edns_pktsz
= daemon
->edns_pktsz
;
4503 if (!(tmp
->flags
& SERV_HAS_SOURCE
))
4505 if (tmp
->source_addr
.sa
.sa_family
== AF_INET
)
4506 tmp
->source_addr
.in
.sin_port
= htons(daemon
->query_port
);
4508 else if (tmp
->source_addr
.sa
.sa_family
== AF_INET6
)
4509 tmp
->source_addr
.in6
.sin6_port
= htons(daemon
->query_port
);
4515 if (daemon
->if_addrs
)
4518 for(tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
4519 if (tmp
->addr
.sa
.sa_family
== AF_INET
)
4520 tmp
->addr
.in
.sin_port
= htons(daemon
->port
);
4522 else if (tmp
->addr
.sa
.sa_family
== AF_INET6
)
4523 tmp
->addr
.in6
.sin6_port
= htons(daemon
->port
);
4527 /* create default, if not specified */
4528 if (daemon
->authserver
&& !daemon
->hostmaster
)
4530 strcpy(buff
, "hostmaster.");
4531 strcat(buff
, daemon
->authserver
);
4532 daemon
->hostmaster
= opt_string_alloc(buff
);
4535 /* only one of these need be specified: the other defaults to the host-name */
4536 if (option_bool(OPT_LOCALMX
) || daemon
->mxnames
|| daemon
->mxtarget
)
4538 struct mx_srv_record
*mx
;
4540 if (gethostname(buff
, MAXDNAME
) == -1)
4541 die(_("cannot get host-name: %s"), NULL
, EC_MISC
);
4543 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
4544 if (!mx
->issrv
&& hostname_isequal(mx
->name
, buff
))
4547 if ((daemon
->mxtarget
|| option_bool(OPT_LOCALMX
)) && !mx
)
4549 mx
= opt_malloc(sizeof(struct mx_srv_record
));
4550 mx
->next
= daemon
->mxnames
;
4553 mx
->name
= opt_string_alloc(buff
);
4554 daemon
->mxnames
= mx
;
4557 if (!daemon
->mxtarget
)
4558 daemon
->mxtarget
= opt_string_alloc(buff
);
4560 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
4561 if (!mx
->issrv
&& !mx
->target
)
4562 mx
->target
= daemon
->mxtarget
;
4565 if (!option_bool(OPT_NO_RESOLV
) &&
4566 daemon
->resolv_files
&&
4567 daemon
->resolv_files
->next
&&
4568 option_bool(OPT_NO_POLL
))
4569 die(_("only one resolv.conf file allowed in no-poll mode."), NULL
, EC_BADCONF
);
4571 if (option_bool(OPT_RESOLV_DOMAIN
))
4576 if (option_bool(OPT_NO_RESOLV
) ||
4577 !daemon
->resolv_files
||
4578 (daemon
->resolv_files
)->next
)
4579 die(_("must have exactly one resolv.conf to read domain from."), NULL
, EC_BADCONF
);
4581 if (!(f
= fopen((daemon
->resolv_files
)->name
, "r")))
4582 die(_("failed to read %s: %s"), (daemon
->resolv_files
)->name
, EC_FILE
);
4584 while ((line
= fgets(buff
, MAXDNAME
, f
)))
4586 char *token
= strtok(line
, " \t\n\r");
4588 if (!token
|| strcmp(token
, "search") != 0)
4591 if ((token
= strtok(NULL
, " \t\n\r")) &&
4592 (daemon
->domain_suffix
= canonicalise_opt(token
)))
4598 if (!daemon
->domain_suffix
)
4599 die(_("no search directive found in %s"), (daemon
->resolv_files
)->name
, EC_MISC
);
4602 if (daemon
->domain_suffix
)
4604 /* add domain for any srv record without one. */
4605 struct mx_srv_record
*srv
;
4607 for (srv
= daemon
->mxnames
; srv
; srv
= srv
->next
)
4609 strchr(srv
->name
, '.') &&
4610 strchr(srv
->name
, '.') == strrchr(srv
->name
, '.'))
4612 strcpy(buff
, srv
->name
);
4614 strcat(buff
, daemon
->domain_suffix
);
4616 srv
->name
= opt_string_alloc(buff
);
4619 else if (option_bool(OPT_DHCP_FQDN
))
4620 die(_("there must be a default domain when --dhcp-fqdn is set"), NULL
, EC_BADCONF
);
4622 /* If there's access-control config, then ignore --local-service, it's intended
4623 as a system default to keep otherwise unconfigured installations safe. */
4624 if (daemon
->if_names
|| daemon
->if_except
|| daemon
->if_addrs
|| daemon
->authserver
)
4625 reset_option_bool(OPT_LOCAL_SERVICE
);
4629 fprintf(stderr
, "dnsmasq: %s.\n", _("syntax check OK"));