1 /* dnsmasq is Copyright (c) 2000-2014 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
147 #ifdef HAVE_GETOPT_LONG
148 static const struct option opts
[] =
150 static const struct myoption opts
[] =
153 { "version", 0, 0, 'v' },
154 { "no-hosts", 0, 0, 'h' },
155 { "no-poll", 0, 0, 'n' },
156 { "help", 0, 0, 'w' },
157 { "no-daemon", 0, 0, 'd' },
158 { "log-queries", 0, 0, 'q' },
159 { "user", 2, 0, 'u' },
160 { "group", 2, 0, 'g' },
161 { "resolv-file", 2, 0, 'r' },
162 { "servers-file", 1, 0, LOPT_SERVERS_FILE
},
163 { "mx-host", 1, 0, 'm' },
164 { "mx-target", 1, 0, 't' },
165 { "cache-size", 2, 0, 'c' },
166 { "port", 1, 0, 'p' },
167 { "dhcp-leasefile", 2, 0, 'l' },
168 { "dhcp-lease", 1, 0, 'l' },
169 { "dhcp-host", 1, 0, 'G' },
170 { "dhcp-range", 1, 0, 'F' },
171 { "dhcp-option", 1, 0, 'O' },
172 { "dhcp-boot", 1, 0, 'M' },
173 { "domain", 1, 0, 's' },
174 { "domain-suffix", 1, 0, 's' },
175 { "interface", 1, 0, 'i' },
176 { "listen-address", 1, 0, 'a' },
177 { "bogus-priv", 0, 0, 'b' },
178 { "bogus-nxdomain", 1, 0, 'B' },
179 { "selfmx", 0, 0, 'e' },
180 { "filterwin2k", 0, 0, 'f' },
181 { "pid-file", 2, 0, 'x' },
182 { "strict-order", 0, 0, 'o' },
183 { "server", 1, 0, 'S' },
184 { "rev-server", 1, 0, LOPT_REV_SERV
},
185 { "local", 1, 0, LOPT_LOCAL
},
186 { "address", 1, 0, 'A' },
187 { "conf-file", 2, 0, 'C' },
188 { "no-resolv", 0, 0, 'R' },
189 { "expand-hosts", 0, 0, 'E' },
190 { "localmx", 0, 0, 'L' },
191 { "local-ttl", 1, 0, 'T' },
192 { "no-negcache", 0, 0, 'N' },
193 { "addn-hosts", 1, 0, 'H' },
194 { "query-port", 1, 0, 'Q' },
195 { "except-interface", 1, 0, 'I' },
196 { "no-dhcp-interface", 1, 0, '2' },
197 { "domain-needed", 0, 0, 'D' },
198 { "dhcp-lease-max", 1, 0, 'X' },
199 { "bind-interfaces", 0, 0, 'z' },
200 { "read-ethers", 0, 0, 'Z' },
201 { "alias", 1, 0, 'V' },
202 { "dhcp-vendorclass", 1, 0, 'U' },
203 { "dhcp-userclass", 1, 0, 'j' },
204 { "dhcp-ignore", 1, 0, 'J' },
205 { "edns-packet-max", 1, 0, 'P' },
206 { "keep-in-foreground", 0, 0, 'k' },
207 { "dhcp-authoritative", 0, 0, 'K' },
208 { "srv-host", 1, 0, 'W' },
209 { "localise-queries", 0, 0, 'y' },
210 { "txt-record", 1, 0, 'Y' },
211 { "dns-rr", 1, 0, LOPT_RR
},
212 { "enable-dbus", 2, 0, '1' },
213 { "bootp-dynamic", 2, 0, '3' },
214 { "dhcp-mac", 1, 0, '4' },
215 { "no-ping", 0, 0, '5' },
216 { "dhcp-script", 1, 0, '6' },
217 { "conf-dir", 1, 0, '7' },
218 { "log-facility", 1, 0 ,'8' },
219 { "leasefile-ro", 0, 0, '9' },
220 { "dns-forward-max", 1, 0, '0' },
221 { "clear-on-reload", 0, 0, LOPT_RELOAD
},
222 { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES
},
223 { "enable-tftp", 2, 0, LOPT_TFTP
},
224 { "tftp-secure", 0, 0, LOPT_SECURE
},
225 { "tftp-unique-root", 0, 0, LOPT_APREF
},
226 { "tftp-root", 1, 0, LOPT_PREFIX
},
227 { "tftp-max", 1, 0, LOPT_TFTP_MAX
},
228 { "tftp-lowercase", 0, 0, LOPT_TFTP_LC
},
229 { "ptr-record", 1, 0, LOPT_PTR
},
230 { "naptr-record", 1, 0, LOPT_NAPTR
},
231 { "bridge-interface", 1, 0 , LOPT_BRIDGE
},
232 { "dhcp-option-force", 1, 0, LOPT_FORCE
},
233 { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK
},
234 { "log-dhcp", 0, 0, LOPT_LOG_OPTS
},
235 { "log-async", 2, 0, LOPT_MAX_LOGS
},
236 { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT
},
237 { "dhcp-remoteid", 1, 0, LOPT_REMOTE
},
238 { "dhcp-subscrid", 1, 0, LOPT_SUBSCR
},
239 { "interface-name", 1, 0, LOPT_INTNAME
},
240 { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST
},
241 { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS
},
242 { "dhcp-no-override", 0, 0, LOPT_OVERRIDE
},
243 { "tftp-port-range", 1, 0, LOPT_TFTPPORTS
},
244 { "stop-dns-rebind", 0, 0, LOPT_REBIND
},
245 { "rebind-domain-ok", 1, 0, LOPT_NO_REBIND
},
246 { "all-servers", 0, 0, LOPT_NOLAST
},
247 { "dhcp-match", 1, 0, LOPT_MATCH
},
248 { "dhcp-broadcast", 2, 0, LOPT_BROADCAST
},
249 { "neg-ttl", 1, 0, LOPT_NEGTTL
},
250 { "max-ttl", 1, 0, LOPT_MAXTTL
},
251 { "max-cache-ttl", 1, 0, LOPT_MAXCTTL
},
252 { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT
},
253 { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR
},
254 { "min-port", 1, 0, LOPT_MINPORT
},
255 { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN
},
256 { "cname", 1, 0, LOPT_CNAME
},
257 { "pxe-prompt", 1, 0, LOPT_PXE_PROMT
},
258 { "pxe-service", 1, 0, LOPT_PXE_SERV
},
259 { "test", 0, 0, LOPT_TEST
},
260 { "tag-if", 1, 0, LOPT_TAG_IF
},
261 { "dhcp-proxy", 2, 0, LOPT_PROXY
},
262 { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES
},
263 { "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND
},
264 { "add-mac", 0, 0, LOPT_ADD_MAC
},
265 { "add-subnet", 2, 0, LOPT_ADD_SBNET
},
266 { "proxy-dnssec", 0, 0, LOPT_DNSSEC
},
267 { "dhcp-sequential-ip", 0, 0, LOPT_INCR_ADDR
},
268 { "conntrack", 0, 0, LOPT_CONNTRACK
},
269 { "dhcp-client-update", 0, 0, LOPT_FQDN
},
270 { "dhcp-luascript", 1, 0, LOPT_LUASCRIPT
},
271 { "enable-ra", 0, 0, LOPT_RA
},
272 { "dhcp-duid", 1, 0, LOPT_DUID
},
273 { "host-record", 1, 0, LOPT_HOST_REC
},
274 { "bind-dynamic", 0, 0, LOPT_CLVERBIND
},
275 { "auth-zone", 1, 0, LOPT_AUTHZONE
},
276 { "auth-server", 1, 0, LOPT_AUTHSERV
},
277 { "auth-ttl", 1, 0, LOPT_AUTHTTL
},
278 { "auth-soa", 1, 0, LOPT_AUTHSOA
},
279 { "auth-sec-servers", 1, 0, LOPT_AUTHSFS
},
280 { "auth-peer", 1, 0, LOPT_AUTHPEER
},
281 { "ipset", 1, 0, LOPT_IPSET
},
282 { "synth-domain", 1, 0, LOPT_SYNTH
},
283 { "dnssec", 0, 0, LOPT_SEC_VALID
},
284 { "trust-anchor", 1, 0, LOPT_TRUST_ANCHOR
},
285 { "dnssec-debug", 0, 0, LOPT_DNSSEC_DEBUG
},
286 #ifdef OPTION6_PREFIX_CLASS
287 { "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS
},
289 { "dhcp-relay", 1, 0, LOPT_RELAY
},
290 { "ra-param", 1, 0, LOPT_RA_PARAM
},
291 { "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP
},
292 { "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6
},
293 { "quiet-ra", 0, 0, LOPT_QUIET_RA
},
298 #define ARG_DUP OPT_LAST
299 #define ARG_ONE OPT_LAST + 1
300 #define ARG_USED_CL OPT_LAST + 2
301 #define ARG_USED_FILE OPT_LAST + 3
306 char * const flagdesc
;
310 { 'a', ARG_DUP
, "<ipaddr>", gettext_noop("Specify local address(es) to listen on."), NULL
},
311 { 'A', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL
},
312 { 'b', OPT_BOGUSPRIV
, NULL
, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL
},
313 { 'B', ARG_DUP
, "<ipaddr>", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL
},
314 { 'c', ARG_ONE
, "<integer>", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
315 { 'C', ARG_DUP
, "<path>", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE
},
316 { 'd', OPT_DEBUG
, NULL
, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL
},
317 { 'D', OPT_NODOTS_LOCAL
, NULL
, gettext_noop("Do NOT forward queries with no domain part."), NULL
},
318 { 'e', OPT_SELFMX
, NULL
, gettext_noop("Return self-pointing MX records for local hosts."), NULL
},
319 { 'E', OPT_EXPAND
, NULL
, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL
},
320 { 'f', OPT_FILTER
, NULL
, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL
},
321 { 'F', ARG_DUP
, "<ipaddr>,...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL
},
322 { 'g', ARG_ONE
, "<groupname>", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP
},
323 { 'G', ARG_DUP
, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL
},
324 { LOPT_DHCP_HOST
, ARG_DUP
, "<path>", gettext_noop("Read DHCP host specs from file."), NULL
},
325 { LOPT_DHCP_OPTS
, ARG_DUP
, "<path>", gettext_noop("Read DHCP option specs from file."), NULL
},
326 { LOPT_TAG_IF
, ARG_DUP
, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL
},
327 { 'h', OPT_NO_HOSTS
, NULL
, gettext_noop("Do NOT load %s file."), HOSTSFILE
},
328 { 'H', ARG_DUP
, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE
},
329 { 'i', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL
},
330 { 'I', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL
},
331 { 'j', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL
},
332 { LOPT_CIRCUIT
, ARG_DUP
, "set:<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL
},
333 { LOPT_REMOTE
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL
},
334 { LOPT_SUBSCR
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL
},
335 { 'J', ARG_DUP
, "tag:<tag>...", gettext_noop("Don't do DHCP for hosts with tag set."), NULL
},
336 { LOPT_BROADCAST
, ARG_DUP
, "[=tag:<tag>...]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL
},
337 { 'k', OPT_NO_FORK
, NULL
, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL
},
338 { 'K', OPT_AUTHORITATIVE
, NULL
, gettext_noop("Assume we are the only DHCP server on the local network."), NULL
},
339 { 'l', ARG_ONE
, "<path>", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE
},
340 { 'L', OPT_LOCALMX
, NULL
, gettext_noop("Return MX records for local hosts."), NULL
},
341 { 'm', ARG_DUP
, "<host_name>,<target>,<pref>", gettext_noop("Specify an MX record."), NULL
},
342 { 'M', ARG_DUP
, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL
},
343 { 'n', OPT_NO_POLL
, NULL
, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE
},
344 { 'N', OPT_NO_NEG
, NULL
, gettext_noop("Do NOT cache failed search results."), NULL
},
345 { 'o', OPT_ORDER
, NULL
, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE
},
346 { 'O', ARG_DUP
, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL
},
347 { LOPT_FORCE
, ARG_DUP
, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL
},
348 { 'p', ARG_ONE
, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL
},
349 { 'P', ARG_ONE
, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
350 { 'q', OPT_LOG
, NULL
, gettext_noop("Log DNS queries."), NULL
},
351 { 'Q', ARG_ONE
, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL
},
352 { 'R', OPT_NO_RESOLV
, NULL
, gettext_noop("Do NOT read resolv.conf."), NULL
},
353 { 'r', ARG_DUP
, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE
},
354 { LOPT_SERVERS_FILE
, ARG_ONE
, "<path>", gettext_noop("Specify path to file with server= options"), NULL
},
355 { 'S', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL
},
356 { LOPT_REV_SERV
, ARG_DUP
, "<addr>/<prefix>,<ipaddr>", gettext_noop("Specify address of upstream servers for reverse address queries"), NULL
},
357 { LOPT_LOCAL
, ARG_DUP
, "/<domain>/", gettext_noop("Never forward queries to specified domains."), NULL
},
358 { 's', ARG_DUP
, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL
},
359 { 't', ARG_ONE
, "<host_name>", gettext_noop("Specify default target in an MX record."), NULL
},
360 { 'T', ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL
},
361 { LOPT_NEGTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL
},
362 { LOPT_MAXTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL
},
363 { 'u', ARG_ONE
, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER
},
364 { 'U', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL
},
365 { 'v', 0, NULL
, gettext_noop("Display dnsmasq version and copyright information."), NULL
},
366 { 'V', ARG_DUP
, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL
},
367 { 'W', ARG_DUP
, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL
},
368 { 'w', 0, NULL
, gettext_noop("Display this message. Use --help dhcp for known DHCP options."), NULL
},
369 { 'x', ARG_ONE
, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE
},
370 { 'X', ARG_ONE
, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
371 { 'y', OPT_LOCALISE
, NULL
, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL
},
372 { 'Y', ARG_DUP
, "<name>,<txt>[,<txt]", gettext_noop("Specify TXT DNS record."), NULL
},
373 { LOPT_PTR
, ARG_DUP
, "<name>,<target>", gettext_noop("Specify PTR DNS record."), NULL
},
374 { LOPT_INTNAME
, ARG_DUP
, "<name>,<interface>", gettext_noop("Give DNS name to IPv4 address of interface."), NULL
},
375 { 'z', OPT_NOWILD
, NULL
, gettext_noop("Bind only to interfaces in use."), NULL
},
376 { 'Z', OPT_ETHERS
, NULL
, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE
},
377 { '1', ARG_ONE
, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL
},
378 { '2', ARG_DUP
, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL
},
379 { '3', ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL
},
380 { '4', ARG_DUP
, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL
},
381 { LOPT_BRIDGE
, ARG_DUP
, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL
},
382 { '5', OPT_NO_PING
, NULL
, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL
},
383 { '6', ARG_ONE
, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL
},
384 { LOPT_LUASCRIPT
, ARG_DUP
, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL
},
385 { LOPT_SCRIPTUSR
, ARG_ONE
, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL
},
386 { '7', ARG_DUP
, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL
},
387 { '8', ARG_ONE
, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL
},
388 { '9', OPT_LEASE_RO
, NULL
, gettext_noop("Do not use leasefile."), NULL
},
389 { '0', ARG_ONE
, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
390 { LOPT_RELOAD
, OPT_RELOAD
, NULL
, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE
},
391 { LOPT_NO_NAMES
, ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL
},
392 { LOPT_OVERRIDE
, OPT_NO_OVERRIDE
, NULL
, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL
},
393 { LOPT_TFTP
, ARG_DUP
, "[=<intr>[,<intr>]]", gettext_noop("Enable integrated read-only TFTP server."), NULL
},
394 { LOPT_PREFIX
, ARG_DUP
, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL
},
395 { LOPT_APREF
, OPT_TFTP_APREF
, NULL
, gettext_noop("Add client IP address to tftp-root."), NULL
},
396 { LOPT_SECURE
, OPT_TFTP_SECURE
, NULL
, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL
},
397 { LOPT_TFTP_MAX
, ARG_ONE
, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
398 { LOPT_NOBLOCK
, OPT_TFTP_NOBLOCK
, NULL
, gettext_noop("Disable the TFTP blocksize extension."), NULL
},
399 { LOPT_TFTP_LC
, OPT_TFTP_LC
, NULL
, gettext_noop("Convert TFTP filenames to lowercase"), NULL
},
400 { LOPT_TFTPPORTS
, ARG_ONE
, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL
},
401 { LOPT_LOG_OPTS
, OPT_LOG_OPTS
, NULL
, gettext_noop("Extra logging for DHCP."), NULL
},
402 { LOPT_MAX_LOGS
, ARG_ONE
, "[=<integer>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL
},
403 { LOPT_REBIND
, OPT_NO_REBIND
, NULL
, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL
},
404 { LOPT_LOC_REBND
, OPT_LOCAL_REBIND
, NULL
, gettext_noop("Allow rebinding of 127.0.0.0/8, for RBL servers."), NULL
},
405 { LOPT_NO_REBIND
, ARG_DUP
, "/<domain>/", gettext_noop("Inhibit DNS-rebind protection on this domain."), NULL
},
406 { LOPT_NOLAST
, OPT_ALL_SERVERS
, NULL
, gettext_noop("Always perform DNS queries to all servers."), NULL
},
407 { LOPT_MATCH
, ARG_DUP
, "set:<tag>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL
},
408 { LOPT_ALTPORT
, ARG_ONE
, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL
},
409 { LOPT_NAPTR
, ARG_DUP
, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL
},
410 { LOPT_MINPORT
, ARG_ONE
, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL
},
411 { LOPT_DHCP_FQDN
, OPT_DHCP_FQDN
, NULL
, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL
},
412 { LOPT_GEN_NAMES
, ARG_DUP
, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL
},
413 { LOPT_PROXY
, ARG_DUP
, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL
},
414 { LOPT_RELAY
, ARG_DUP
, "<local-addr>,<server>[,<interface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL
},
415 { LOPT_CNAME
, ARG_DUP
, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL
},
416 { LOPT_PXE_PROMT
, ARG_DUP
, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL
},
417 { LOPT_PXE_SERV
, ARG_DUP
, "<service>", gettext_noop("Boot service for PXE menu."), NULL
},
418 { LOPT_TEST
, 0, NULL
, gettext_noop("Check configuration syntax."), NULL
},
419 { LOPT_ADD_MAC
, OPT_ADD_MAC
, NULL
, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL
},
420 { LOPT_ADD_SBNET
, ARG_ONE
, "<v4 pref>[,<v6 pref>]", gettext_noop("Add requestor's IP subnet to forwarded DNS queries."), NULL
},
421 { LOPT_DNSSEC
, OPT_DNSSEC_PROXY
, NULL
, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL
},
422 { LOPT_INCR_ADDR
, OPT_CONSEC_ADDR
, NULL
, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL
},
423 { LOPT_CONNTRACK
, OPT_CONNTRACK
, NULL
, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL
},
424 { LOPT_FQDN
, OPT_FQDN_UPDATE
, NULL
, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL
},
425 { LOPT_RA
, OPT_RA
, NULL
, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL
},
426 { LOPT_DUID
, ARG_ONE
, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL
},
427 { LOPT_HOST_REC
, ARG_DUP
, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL
},
428 { LOPT_RR
, ARG_DUP
, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL
},
429 { LOPT_CLVERBIND
, OPT_CLEVERBIND
, NULL
, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL
},
430 { LOPT_AUTHSERV
, ARG_ONE
, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL
},
431 { LOPT_AUTHZONE
, ARG_DUP
, "<domain>,[<subnet>...]", gettext_noop("Domain to export to global DNS"), NULL
},
432 { LOPT_AUTHTTL
, ARG_ONE
, "<integer>", gettext_noop("Set TTL for authoritative replies"), NULL
},
433 { LOPT_AUTHSOA
, ARG_ONE
, "<serial>[,...]", gettext_noop("Set authoritive zone information"), NULL
},
434 { LOPT_AUTHSFS
, ARG_DUP
, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL
},
435 { LOPT_AUTHPEER
, ARG_DUP
, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL
},
436 { LOPT_IPSET
, ARG_DUP
, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL
},
437 { LOPT_SYNTH
, ARG_DUP
, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL
},
438 { LOPT_SEC_VALID
, OPT_DNSSEC_VALID
, NULL
, gettext_noop("Activate DNSSEC validation"), NULL
},
439 { LOPT_TRUST_ANCHOR
, ARG_DUP
, "<domain>,[<class>],...", gettext_noop("Specify trust anchor key digest."), NULL
},
440 { LOPT_DNSSEC_DEBUG
, OPT_DNSSEC_DEBUG
, NULL
, gettext_noop("Disable upstream checking for DNSSEC debugging."), NULL
},
441 #ifdef OPTION6_PREFIX_CLASS
442 { LOPT_PREF_CLSS
, ARG_DUP
, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL
},
444 { LOPT_RA_PARAM
, ARG_DUP
, "<interface>,[high,|low,]<interval>[,<lifetime>]", gettext_noop("Set priority, resend-interval and router-lifetime"), NULL
},
445 { LOPT_QUIET_DHCP
, OPT_QUIET_DHCP
, NULL
, gettext_noop("Do not log routine DHCP."), NULL
},
446 { LOPT_QUIET_DHCP6
, OPT_QUIET_DHCP6
, NULL
, gettext_noop("Do not log routine DHCPv6."), NULL
},
447 { LOPT_QUIET_RA
, OPT_QUIET_RA
, NULL
, gettext_noop("Do not log RA."), NULL
},
448 { 0, 0, NULL
, NULL
, NULL
}
451 /* We hide metacharaters in quoted strings by mapping them into the ASCII control
452 character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the
453 following sequence so that they map to themselves: it is therefore possible to call
454 unhide_metas repeatedly on string without breaking things.
455 The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a
456 couple of other places.
457 Note that space is included here so that
458 --dhcp-option=3, string
459 has five characters, whilst
460 --dhcp-option=3," string"
464 static const char meta
[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
466 static char hide_meta(char c
)
470 for (i
= 0; i
< (sizeof(meta
) - 1); i
++)
477 static char unhide_meta(char cr
)
481 if (c
< (sizeof(meta
) - 1))
487 static void unhide_metas(char *cp
)
491 *cp
= unhide_meta(*cp
);
494 static void *opt_malloc(size_t size
)
500 ret
= whine_malloc(size
);
505 ret
= safe_malloc(size
);
510 static char *opt_string_alloc(char *cp
)
514 if (cp
&& strlen(cp
) != 0)
516 ret
= opt_malloc(strlen(cp
)+1);
519 /* restore hidden metachars */
527 /* find next comma, split string with zero and eliminate spaces.
528 return start of string following comma */
530 static char *split_chr(char *s
, char c
)
534 if (!s
|| !(comma
= strchr(s
, c
)))
540 for (; *comma
== ' '; comma
++);
542 for (; (p
>= s
) && *p
== ' '; p
--)
548 static char *split(char *s
)
550 return split_chr(s
, ',');
553 static char *canonicalise_opt(char *s
)
562 if (!(ret
= canonicalise(s
, &nomem
)) && nomem
)
567 die(_("could not get memory"), NULL
, EC_NOMEM
);
573 static int atoi_check(char *a
, int *res
)
583 if (*p
< '0' || *p
> '9')
590 static int atoi_check16(char *a
, int *res
)
592 if (!(atoi_check(a
, res
)) ||
601 static int atoi_check8(char *a
, int *res
)
603 if (!(atoi_check(a
, res
)) ||
612 static void add_txt(char *name
, char *txt
)
614 size_t len
= strlen(txt
);
615 struct txt_record
*r
= opt_malloc(sizeof(struct txt_record
));
617 r
->name
= opt_string_alloc(name
);
618 r
->next
= daemon
->txt
;
621 r
->txt
= opt_malloc(len
+1);
624 memcpy((r
->txt
)+1, txt
, len
);
627 static void do_usage(void)
640 { '#', TFTP_MAX_CONNECTIONS
},
644 printf(_("Usage: dnsmasq [options]\n\n"));
645 #ifndef HAVE_GETOPT_LONG
646 printf(_("Use short options only on the command line.\n"));
648 printf(_("Valid options are:\n"));
650 for (i
= 0; usage
[i
].opt
!= 0; i
++)
652 char *desc
= usage
[i
].flagdesc
;
655 if (!desc
|| *desc
== '[')
661 for ( j
= 0; opts
[j
].name
; j
++)
662 if (opts
[j
].val
== usage
[i
].opt
)
664 if (usage
[i
].opt
< 256)
665 sprintf(buff
, "-%c, ", usage
[i
].opt
);
669 sprintf(buff
+4, "--%s%s%s", opts
[j
].name
, eq
, desc
);
670 printf("%-40.40s", buff
);
674 strcpy(buff
, usage
[i
].arg
);
675 for (j
= 0; tab
[j
].handle
; j
++)
676 if (tab
[j
].handle
== *(usage
[i
].arg
))
677 sprintf(buff
, "%d", tab
[j
].val
);
679 printf(_(usage
[i
].desc
), buff
);
684 #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
686 char *parse_server(char *arg
, union mysockaddr
*addr
, union mysockaddr
*source_addr
, char *interface
, int *flags
)
688 int source_port
= 0, serv_port
= NAMESERVER_PORT
;
689 char *portno
, *source
;
695 if (!arg
|| strlen(arg
) == 0)
697 *flags
|= SERV_NO_ADDR
;
702 if ((source
= split_chr(arg
, '@')) && /* is there a source. */
703 (portno
= split_chr(source
, '#')) &&
704 !atoi_check16(portno
, &source_port
))
705 return _("bad port");
707 if ((portno
= split_chr(arg
, '#')) && /* is there a port no. */
708 !atoi_check16(portno
, &serv_port
))
709 return _("bad port");
712 scope_id
= split_chr(arg
, '%');
715 if (inet_pton(AF_INET
, arg
, &addr
->in
.sin_addr
) > 0)
717 addr
->in
.sin_port
= htons(serv_port
);
718 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET
;
719 #ifdef HAVE_SOCKADDR_SA_LEN
720 source_addr
->in
.sin_len
= addr
->in
.sin_len
= sizeof(struct sockaddr_in
);
722 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
723 source_addr
->in
.sin_port
= htons(daemon
->query_port
);
728 *flags
|= SERV_HAS_SOURCE
;
729 source_addr
->in
.sin_port
= htons(source_port
);
730 if (!(inet_pton(AF_INET
, source
, &source_addr
->in
.sin_addr
) > 0))
732 #if defined(SO_BINDTODEVICE)
733 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
734 strncpy(interface
, source
, IF_NAMESIZE
- 1);
736 return _("interface binding not supported");
742 else if (inet_pton(AF_INET6
, arg
, &addr
->in6
.sin6_addr
) > 0)
744 if (scope_id
&& (scope_index
= if_nametoindex(scope_id
)) == 0)
745 return _("bad interface name");
747 addr
->in6
.sin6_port
= htons(serv_port
);
748 addr
->in6
.sin6_scope_id
= scope_index
;
749 source_addr
->in6
.sin6_addr
= in6addr_any
;
750 source_addr
->in6
.sin6_port
= htons(daemon
->query_port
);
751 source_addr
->in6
.sin6_scope_id
= 0;
752 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET6
;
753 addr
->in6
.sin6_flowinfo
= source_addr
->in6
.sin6_flowinfo
= 0;
754 #ifdef HAVE_SOCKADDR_SA_LEN
755 addr
->in6
.sin6_len
= source_addr
->in6
.sin6_len
= sizeof(addr
->in6
);
760 *flags
|= SERV_HAS_SOURCE
;
761 source_addr
->in6
.sin6_port
= htons(source_port
);
762 if (inet_pton(AF_INET6
, source
, &source_addr
->in6
.sin6_addr
) == 0)
764 #if defined(SO_BINDTODEVICE)
765 source_addr
->in6
.sin6_addr
= in6addr_any
;
766 strncpy(interface
, source
, IF_NAMESIZE
- 1);
768 return _("interface binding not supported");
775 return _("bad address");
780 static struct server
*add_rev4(struct in_addr addr
, int msize
)
782 struct server
*serv
= opt_malloc(sizeof(struct server
));
783 in_addr_t a
= ntohl(addr
.s_addr
) >> 8;
786 memset(serv
, 0, sizeof(struct server
));
787 p
= serv
->domain
= opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */
790 p
+= sprintf(p
, "%d.", a
& 0xff);
793 p
+= sprintf(p
, "%d.", a
& 0xff);
795 p
+= sprintf(p
, "%d.in-addr.arpa", a
& 0xff);
797 serv
->flags
= SERV_HAS_DOMAIN
;
798 serv
->next
= daemon
->servers
;
799 daemon
->servers
= serv
;
805 static struct server
*add_rev6(struct in6_addr
*addr
, int msize
)
807 struct server
*serv
= opt_malloc(sizeof(struct server
));
811 memset(serv
, 0, sizeof(struct server
));
812 p
= serv
->domain
= opt_malloc(73); /* strlen("32*<n.>ip6.arpa")+1 */
814 for (i
= msize
-1; i
>= 0; i
-= 4)
816 int dig
= ((unsigned char *)addr
)[i
>>3];
817 p
+= sprintf(p
, "%.1x.", (i
>>2) & 1 ? dig
& 15 : dig
>> 4);
819 p
+= sprintf(p
, "ip6.arpa");
821 serv
->flags
= SERV_HAS_DOMAIN
;
822 serv
->next
= daemon
->servers
;
823 daemon
->servers
= serv
;
830 static int is_tag_prefix(char *arg
)
832 if (arg
&& (strstr(arg
, "net:") == arg
|| strstr(arg
, "tag:") == arg
))
838 static char *set_prefix(char *arg
)
840 if (strstr(arg
, "set:") == arg
)
846 /* This is too insanely large to keep in-line in the switch */
847 static int parse_dhcp_opt(char *errstr
, char *arg
, int flags
)
849 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
850 char lenchar
= 0, *cp
;
851 int addrs
, digs
, is_addr
, is_addr6
, is_hex
, is_dec
, is_string
, dots
;
853 struct dhcp_netid
*np
= NULL
;
868 for (cp
= arg
; *cp
; cp
++)
869 if (*cp
< '0' || *cp
> '9')
874 new->opt
= atoi(arg
);
880 if (strstr(arg
, "option:") == arg
)
882 if ((new->opt
= lookup_dhcp_opt(AF_INET
, arg
+7)) != -1)
884 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
885 /* option:<optname> must follow tag and vendor string. */
886 if (!(opt_len
& OT_INTERNAL
) || flags
== DHOPT_MATCH
)
892 else if (strstr(arg
, "option6:") == arg
)
894 for (cp
= arg
+8; *cp
; cp
++)
895 if (*cp
< '0' || *cp
> '9')
900 new->opt
= atoi(arg
+8);
906 if ((new->opt
= lookup_dhcp_opt(AF_INET6
, arg
+8)) != -1)
908 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
909 if (!(opt_len
& OT_INTERNAL
) || flags
== DHOPT_MATCH
)
913 /* option6:<opt>|<optname> must follow tag and vendor string. */
918 else if (strstr(arg
, "vendor:") == arg
)
920 new->u
.vendor_class
= (unsigned char *)opt_string_alloc(arg
+7);
921 new->flags
|= DHOPT_VENDOR
;
923 else if (strstr(arg
, "encap:") == arg
)
925 new->u
.encap
= atoi(arg
+6);
926 new->flags
|= DHOPT_ENCAPSULATE
;
928 else if (strstr(arg
, "vi-encap:") == arg
)
930 new->u
.encap
= atoi(arg
+9);
931 new->flags
|= DHOPT_RFC3925
;
932 if (flags
== DHOPT_MATCH
)
940 new->netid
= opt_malloc(sizeof (struct dhcp_netid
));
941 /* allow optional "net:" or "tag:" for consistency */
942 if (is_tag_prefix(arg
))
943 new->netid
->net
= opt_string_alloc(arg
+4);
945 new->netid
->net
= opt_string_alloc(set_prefix(arg
));
946 new->netid
->next
= np
;
956 if (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))
957 ret_err(_("unsupported encapsulation for IPv6 option"));
960 !(new->flags
& DHOPT_RFC3925
))
961 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
966 !(new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
| DHOPT_RFC3925
)))
967 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
969 /* option may be missing with rfc3925 match */
971 ret_err(_("bad dhcp-option"));
975 /* characterise the value */
978 is_addr
= is_addr6
= is_hex
= is_dec
= is_string
= 1;
981 for (cp
= comma
; (c
= *cp
); cp
++)
990 is_dec
= is_addr
= 0;
994 is_addr6
= is_dec
= is_hex
= 0;
995 if (cp
== comma
) /* leading / means a pathname */
1000 is_addr6
= is_dec
= is_hex
= 0;
1004 is_hex
= is_addr
= is_addr6
= 0;
1006 is_dec
= is_hex
= 0;
1007 else if (!(c
>='0' && c
<= '9'))
1010 if (cp
[1] == 0 && is_dec
&&
1011 (c
== 'b' || c
== 's' || c
== 'i'))
1018 if (!((c
>='A' && c
<= 'F') ||
1019 (c
>='a' && c
<= 'f') ||
1020 (c
== '*' && (flags
& DHOPT_MATCH
))))
1023 if (c
!= '[' && c
!= ']')
1031 is_dec
= is_addr
= 0;
1033 /* We know that some options take addresses */
1034 if (opt_len
& OT_ADDR_LIST
)
1036 is_string
= is_dec
= is_hex
= 0;
1038 if (!is6
&& (!is_addr
|| dots
== 0))
1039 ret_err(_("bad IP address"));
1041 if (is6
&& !is_addr6
)
1042 ret_err(_("bad IPv6 address"));
1045 else if (opt_len
& (OT_NAME
| OT_RFC1035_NAME
| OT_CSTRING
))
1046 is_addr6
= is_addr
= is_dec
= is_hex
= 0;
1048 if (found_dig
&& (opt_len
& OT_TIME
) && strlen(comma
) > 0)
1052 switch (comma
[strlen(comma
) - 1])
1072 comma
[strlen(comma
) - 1] = 0;
1076 new->val
= opt_malloc(4);
1078 *((int *)new->val
) = htonl(val
* fac
);
1080 else if (is_hex
&& digs
> 1)
1083 new->val
= opt_malloc(new->len
);
1084 parse_hex(comma
, new->val
, digs
, (flags
& DHOPT_MATCH
) ? &new->u
.wildcard_mask
: NULL
, NULL
);
1085 new->flags
|= DHOPT_HEX
;
1089 int i
, val
= atoi(comma
);
1090 /* assume numeric arg is 1 byte except for
1091 options where it is known otherwise.
1092 For vendor class option, we have to hack. */
1095 else if (val
& 0xffff0000)
1097 else if (val
& 0xff00)
1104 else if (lenchar
== 's')
1106 else if (lenchar
== 'i')
1109 new->val
= opt_malloc(new->len
);
1110 for (i
=0; i
<new->len
; i
++)
1111 new->val
[i
] = val
>>((new->len
- i
- 1)*8);
1113 else if (is_addr
&& !is6
)
1118 /* max length of address/subnet descriptor is five bytes,
1119 add one for the option 120 enc byte too */
1120 new->val
= op
= opt_malloc((5 * addrs
) + 1);
1121 new->flags
|= DHOPT_ADDR
;
1123 if (!(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)) &&
1124 new->opt
== OPTION_SIP_SERVER
)
1126 *(op
++) = 1; /* RFC 3361 "enc byte" */
1127 new->flags
&= ~DHOPT_ADDR
;
1133 slash
= split_chr(cp
, '/');
1134 inet_pton(AF_INET
, cp
, &in
);
1137 memcpy(op
, &in
, INADDRSZ
);
1142 unsigned char *p
= (unsigned char *)&in
;
1143 int netsize
= atoi(slash
);
1153 new->flags
&= ~DHOPT_ADDR
; /* cannot re-write descriptor format */
1156 new->len
= op
- new->val
;
1158 else if (is_addr6
&& is6
)
1161 new->val
= op
= opt_malloc(16 * addrs
);
1162 new->flags
|= DHOPT_ADDR6
;
1168 /* check for [1234::7] */
1171 if (strlen(cp
) > 1 && cp
[strlen(cp
)-1] == ']')
1172 cp
[strlen(cp
)-1] = 0;
1174 if (inet_pton(AF_INET6
, cp
, op
))
1180 ret_err(_("bad IPv6 address"));
1182 new->len
= op
- new->val
;
1187 if ((new->opt
== OPTION_DOMAIN_SEARCH
|| new->opt
== OPTION_SIP_SERVER
) &&
1188 !is6
&& !(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)))
1190 /* dns search, RFC 3397, or SIP, RFC 3361 */
1191 unsigned char *q
, *r
, *tail
;
1192 unsigned char *p
, *m
= NULL
, *newp
;
1193 size_t newlen
, len
= 0;
1194 int header_size
= (new->opt
== OPTION_DOMAIN_SEARCH
) ? 0 : 1;
1201 char *in
, *dom
= NULL
;
1203 /* Allow "." as an empty domain */
1204 if (strcmp (arg
, ".") != 0)
1206 if (!(dom
= canonicalise_opt(arg
)))
1207 ret_err(_("bad domain in dhcp-option"));
1209 domlen
= strlen(dom
) + 2;
1212 newp
= opt_malloc(len
+ domlen
+ header_size
);
1215 memcpy(newp
, m
, header_size
+ len
);
1219 p
= m
+ header_size
;
1222 /* add string on the end in RFC1035 format */
1223 for (in
= dom
; in
&& *in
;)
1225 unsigned char *cp
= q
++;
1227 for (j
= 0; *in
&& (*in
!= '.'); in
++, j
++)
1236 /* Now tail-compress using earlier names. */
1238 for (tail
= p
+ len
; *tail
; tail
+= (*tail
) + 1)
1239 for (r
= p
; r
- p
< (int)len
; r
+= (*r
) + 1)
1240 if (strcmp((char *)r
, (char *)tail
) == 0)
1242 PUTSHORT((r
- p
) | 0xc000, tail
);
1253 /* RFC 3361, enc byte is zero for names */
1254 if (new->opt
== OPTION_SIP_SERVER
)
1256 new->len
= (int) len
+ header_size
;
1260 else if (comma
&& (opt_len
& OT_CSTRING
))
1262 /* length fields are two bytes so need 16 bits for each string */
1264 unsigned char *p
, *newp
;
1266 for (i
= 0; comma
[i
]; i
++)
1267 if (comma
[i
] == ',')
1270 newp
= opt_malloc(strlen(comma
)+(2*commas
));
1277 u16 len
= strlen(arg
);
1280 memcpy(p
, arg
, len
);
1288 new->len
= p
- newp
;
1290 else if (comma
&& (opt_len
& OT_RFC1035_NAME
))
1292 unsigned char *p
= NULL
, *newp
, *end
;
1299 char *dom
= canonicalise_opt(arg
);
1301 ret_err(_("bad domain in dhcp-option"));
1303 newp
= opt_malloc(len
+ strlen(dom
) + 2);
1307 memcpy(newp
, p
, len
);
1312 end
= do_rfc1035_name(p
+ len
, dom
);
1327 new->len
= strlen(comma
);
1328 /* keep terminating zero on string */
1329 new->val
= (unsigned char *)opt_string_alloc(comma
);
1330 new->flags
|= DHOPT_STRING
;
1336 ((new->len
> 255) ||
1337 (new->len
> 253 && (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))) ||
1338 (new->len
> 250 && (new->flags
& DHOPT_RFC3925
))))
1339 ret_err(_("dhcp-option too long"));
1341 if (flags
== DHOPT_MATCH
)
1343 if ((new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
)) ||
1346 ret_err(_("illegal dhcp-match"));
1350 new->next
= daemon
->dhcp_match6
;
1351 daemon
->dhcp_match6
= new;
1355 new->next
= daemon
->dhcp_match
;
1356 daemon
->dhcp_match
= new;
1361 new->next
= daemon
->dhcp_opts6
;
1362 daemon
->dhcp_opts6
= new;
1366 new->next
= daemon
->dhcp_opts
;
1367 daemon
->dhcp_opts
= new;
1375 void set_option_bool(unsigned int opt
)
1378 daemon
->options
|= 1u << opt
;
1380 daemon
->options2
|= 1u << (opt
- 32);
1383 void reset_option_bool(unsigned int opt
)
1386 daemon
->options
&= ~(1u << opt
);
1388 daemon
->options2
&= ~(1u << (opt
- 32));
1391 static int one_opt(int option
, char *arg
, char *errstr
, char *gen_err
, int command_line
, int servers_only
)
1399 for (i
=0; usage
[i
].opt
!= 0; i
++)
1400 if (usage
[i
].opt
== option
)
1402 int rept
= usage
[i
].rept
;
1407 if (rept
== ARG_USED_CL
)
1408 ret_err(_("illegal repeated flag"));
1409 if (rept
== ARG_ONE
)
1410 usage
[i
].rept
= ARG_USED_CL
;
1414 /* allow file to override command line */
1415 if (rept
== ARG_USED_FILE
)
1416 ret_err(_("illegal repeated keyword"));
1417 if (rept
== ARG_USED_CL
|| rept
== ARG_ONE
)
1418 usage
[i
].rept
= ARG_USED_FILE
;
1421 if (rept
!= ARG_DUP
&& rept
!= ARG_ONE
&& rept
!= ARG_USED_CL
)
1423 set_option_bool(rept
);
1432 case 'C': /* --conf-file */
1434 char *file
= opt_string_alloc(arg
);
1443 case '7': /* --conf-dir */
1447 char *directory
, *path
;
1451 } *ignore_suffix
= NULL
, *li
;
1454 if (!(directory
= opt_string_alloc(arg
)))
1457 for (arg
= comma
; arg
; arg
= comma
)
1460 li
= opt_malloc(sizeof(struct list
));
1461 li
->next
= ignore_suffix
;
1463 /* Have to copy: buffer is overwritten */
1464 li
->suffix
= opt_string_alloc(arg
);
1467 if (!(dir_stream
= opendir(directory
)))
1468 die(_("cannot access directory %s: %s"), directory
, EC_FILE
);
1470 while ((ent
= readdir(dir_stream
)))
1472 size_t len
= strlen(ent
->d_name
);
1475 /* ignore emacs backups and dotfiles */
1477 ent
->d_name
[len
- 1] == '~' ||
1478 (ent
->d_name
[0] == '#' && ent
->d_name
[len
- 1] == '#') ||
1479 ent
->d_name
[0] == '.')
1482 for (li
= ignore_suffix
; li
; li
= li
->next
)
1484 /* check for proscribed suffices */
1485 size_t ls
= strlen(li
->suffix
);
1487 strcmp(li
->suffix
, &ent
->d_name
[len
- ls
]) == 0)
1493 path
= opt_malloc(strlen(directory
) + len
+ 2);
1494 strcpy(path
, directory
);
1496 strcat(path
, ent
->d_name
);
1498 /* files must be readable */
1499 if (stat(path
, &buf
) == -1)
1500 die(_("cannot access %s: %s"), path
, EC_FILE
);
1502 /* only reg files allowed. */
1503 if (S_ISREG(buf
.st_mode
))
1509 closedir(dir_stream
);
1511 for(; ignore_suffix
; ignore_suffix
= li
)
1513 li
= ignore_suffix
->next
;
1514 free(ignore_suffix
->suffix
);
1515 free(ignore_suffix
);
1521 case LOPT_ADD_SBNET
: /* --add-subnet */
1522 set_option_bool(OPT_CLIENT_SUBNET
);
1526 if (!atoi_check(arg
, &daemon
->addr4_netmask
) ||
1527 (comma
&& !atoi_check(comma
, &daemon
->addr6_netmask
)))
1532 case '1': /* --enable-dbus */
1533 set_option_bool(OPT_DBUS
);
1535 daemon
->dbus_name
= opt_string_alloc(arg
);
1537 daemon
->dbus_name
= DNSMASQ_SERVICE
;
1540 case '8': /* --log-facility */
1541 /* may be a filename */
1542 if (strchr(arg
, '/') || strcmp (arg
, "-") == 0)
1543 daemon
->log_file
= opt_string_alloc(arg
);
1547 ret_err(_("setting log facility is not possible under Android"));
1549 for (i
= 0; facilitynames
[i
].c_name
; i
++)
1550 if (hostname_isequal((char *)facilitynames
[i
].c_name
, arg
))
1553 if (facilitynames
[i
].c_name
)
1554 daemon
->log_fac
= facilitynames
[i
].c_val
;
1556 ret_err(_("bad log facility"));
1561 case 'x': /* --pid-file */
1562 daemon
->runfile
= opt_string_alloc(arg
);
1565 case 'r': /* --resolv-file */
1567 char *name
= opt_string_alloc(arg
);
1568 struct resolvc
*new, *list
= daemon
->resolv_files
;
1570 if (list
&& list
->is_default
)
1572 /* replace default resolv file - possibly with nothing */
1575 list
->is_default
= 0;
1583 new = opt_malloc(sizeof(struct resolvc
));
1586 new->is_default
= 0;
1591 daemon
->resolv_files
= list
;
1595 case LOPT_SERVERS_FILE
:
1596 daemon
->servers_file
= opt_string_alloc(arg
);
1599 case 'm': /* --mx-host */
1602 struct mx_srv_record
*new;
1603 char *name
, *target
= NULL
;
1605 if ((comma
= split(arg
)))
1608 if ((prefstr
= split(comma
)) && !atoi_check16(prefstr
, &pref
))
1609 ret_err(_("bad MX preference"));
1612 if (!(name
= canonicalise_opt(arg
)) ||
1613 (comma
&& !(target
= canonicalise_opt(comma
))))
1614 ret_err(_("bad MX name"));
1616 new = opt_malloc(sizeof(struct mx_srv_record
));
1617 new->next
= daemon
->mxnames
;
1618 daemon
->mxnames
= new;
1621 new->target
= target
; /* may be NULL */
1626 case 't': /* --mx-target */
1627 if (!(daemon
->mxtarget
= canonicalise_opt(arg
)))
1628 ret_err(_("bad MX target"));
1632 case 'l': /* --dhcp-leasefile */
1633 daemon
->lease_file
= opt_string_alloc(arg
);
1636 /* Sorry about the gross pre-processor abuse */
1637 case '6': /* --dhcp-script */
1638 case LOPT_LUASCRIPT
: /* --dhcp-luascript */
1639 # if defined(NO_FORK)
1640 ret_err(_("cannot run scripts under uClinux"));
1641 # elif !defined(HAVE_SCRIPT)
1642 ret_err(_("recompile with HAVE_SCRIPT defined to enable lease-change scripts"));
1644 if (option
== LOPT_LUASCRIPT
)
1645 # if !defined(HAVE_LUASCRIPT)
1646 ret_err(_("recompile with HAVE_LUASCRIPT defined to enable Lua scripts"));
1648 daemon
->luascript
= opt_string_alloc(arg
);
1651 daemon
->lease_change_command
= opt_string_alloc(arg
);
1654 #endif /* HAVE_DHCP */
1656 case LOPT_DHCP_HOST
: /* --dhcp-hostfile */
1657 case LOPT_DHCP_OPTS
: /* --dhcp-optsfile */
1658 case 'H': /* --addn-hosts */
1660 struct hostsfile
*new = opt_malloc(sizeof(struct hostsfile
));
1661 static int hosts_index
= 1;
1662 new->fname
= opt_string_alloc(arg
);
1663 new->index
= hosts_index
++;
1667 new->next
= daemon
->addn_hosts
;
1668 daemon
->addn_hosts
= new;
1670 else if (option
== LOPT_DHCP_HOST
)
1672 new->next
= daemon
->dhcp_hosts_file
;
1673 daemon
->dhcp_hosts_file
= new;
1675 else if (option
== LOPT_DHCP_OPTS
)
1677 new->next
= daemon
->dhcp_opts_file
;
1678 daemon
->dhcp_opts_file
= new;
1685 case LOPT_AUTHSERV
: /* --auth-server */
1686 if (!(comma
= split(arg
)))
1689 daemon
->authserver
= opt_string_alloc(arg
);
1692 struct iname
*new = opt_malloc(sizeof(struct iname
));
1696 if (inet_pton(AF_INET
, arg
, &new->addr
.in
.sin_addr
) > 0)
1697 new->addr
.sa
.sa_family
= AF_INET
;
1699 else if (inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
1700 new->addr
.sa
.sa_family
= AF_INET6
;
1704 char *fam
= split_chr(arg
, '/');
1705 new->name
= opt_string_alloc(arg
);
1706 new->addr
.sa
.sa_family
= 0;
1709 if (strcmp(fam
, "4") == 0)
1710 new->addr
.sa
.sa_family
= AF_INET
;
1712 else if (strcmp(fam
, "6") == 0)
1713 new->addr
.sa
.sa_family
= AF_INET6
;
1719 new->next
= daemon
->authinterface
;
1720 daemon
->authinterface
= new;
1727 case LOPT_AUTHSFS
: /* --auth-sec-servers */
1729 struct name_list
*new;
1733 new = opt_malloc(sizeof(struct name_list
));
1734 new->name
= opt_string_alloc(arg
);
1735 new->next
= daemon
->secondary_forward_server
;
1736 daemon
->secondary_forward_server
= new;
1742 case LOPT_AUTHZONE
: /* --auth-zone */
1744 struct auth_zone
*new;
1748 new = opt_malloc(sizeof(struct auth_zone
));
1749 new->domain
= opt_string_alloc(arg
);
1751 new->interface_names
= NULL
;
1752 new->next
= daemon
->auth_zones
;
1753 daemon
->auth_zones
= new;
1755 while ((arg
= comma
))
1759 struct addrlist
*subnet
= NULL
;
1760 struct all_addr addr
;
1763 prefix
= split_chr(arg
, '/');
1765 if (prefix
&& !atoi_check(prefix
, &prefixlen
))
1768 if (inet_pton(AF_INET
, arg
, &addr
.addr
.addr4
))
1770 subnet
= opt_malloc(sizeof(struct addrlist
));
1771 subnet
->prefixlen
= (prefixlen
== 0) ? 24 : prefixlen
;
1772 subnet
->flags
= ADDRLIST_LITERAL
;
1775 else if (inet_pton(AF_INET6
, arg
, &addr
.addr
.addr6
))
1777 subnet
= opt_malloc(sizeof(struct addrlist
));
1778 subnet
->prefixlen
= (prefixlen
== 0) ? 64 : prefixlen
;
1779 subnet
->flags
= ADDRLIST_LITERAL
| ADDRLIST_IPV6
;
1784 struct auth_name_list
*name
= opt_malloc(sizeof(struct auth_name_list
));
1785 name
->name
= opt_string_alloc(arg
);
1786 name
->flags
= AUTH4
| AUTH6
;
1787 name
->next
= new->interface_names
;
1788 new->interface_names
= name
;
1792 name
->flags
&= ~AUTH6
;
1794 else if (prefixlen
== 6)
1795 name
->flags
&= ~AUTH4
;
1804 subnet
->addr
= addr
;
1805 subnet
->next
= new->subnet
;
1806 new->subnet
= subnet
;
1812 case LOPT_AUTHSOA
: /* --auth-soa */
1814 daemon
->soa_sn
= (u32
)atoi(arg
);
1820 daemon
->hostmaster
= opt_string_alloc(arg
);
1821 for (cp
= daemon
->hostmaster
; *cp
; cp
++)
1829 daemon
->soa_refresh
= (u32
)atoi(arg
);
1834 daemon
->soa_retry
= (u32
)atoi(arg
);
1839 daemon
->soa_expiry
= (u32
)atoi(arg
);
1848 case 's': /* --domain */
1849 case LOPT_SYNTH
: /* --synth-domain */
1850 if (strcmp (arg
, "#") == 0)
1851 set_option_bool(OPT_RESOLV_DOMAIN
);
1856 if (!(d
= canonicalise_opt(arg
)))
1862 struct cond_domain
*new = opt_malloc(sizeof(struct cond_domain
));
1867 unhide_metas(comma
);
1868 if ((netpart
= split_chr(comma
, '/')))
1872 arg
= split(netpart
);
1873 if (!atoi_check(netpart
, &msize
))
1875 else if (inet_pton(AF_INET
, comma
, &new->start
))
1877 int mask
= (1 << (32 - msize
)) - 1;
1879 new->start
.s_addr
= ntohl(htonl(new->start
.s_addr
) & ~mask
);
1880 new->end
.s_addr
= new->start
.s_addr
| htonl(mask
);
1885 if (!(new->prefix
= canonicalise_opt(arg
)) ||
1886 strlen(new->prefix
) > MAXLABEL
- INET_ADDRSTRLEN
)
1887 ret_err(_("bad prefix"));
1889 else if (strcmp(arg
, "local") != 0 ||
1890 (msize
!= 8 && msize
!= 16 && msize
!= 24))
1894 /* generate the equivalent of
1896 local=/xxx.yyy.zzz.in-addr.arpa/ */
1897 struct server
*serv
= add_rev4(new->start
, msize
);
1898 serv
->flags
|= SERV_NO_ADDR
;
1903 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1905 u64 mask
= (1LLU << (128 - msize
)) - 1LLU;
1906 u64 addrpart
= addr6part(&new->start6
);
1909 /* prefix==64 overflows the mask calculation above */
1913 new->end6
= new->start6
;
1914 setaddr6part(&new->start6
, addrpart
& ~mask
);
1915 setaddr6part(&new->end6
, addrpart
| mask
);
1923 if (!(new->prefix
= canonicalise_opt(arg
)) ||
1924 strlen(new->prefix
) > MAXLABEL
- INET6_ADDRSTRLEN
)
1925 ret_err(_("bad prefix"));
1927 else if (strcmp(arg
, "local") != 0 || ((msize
& 4) != 0))
1931 /* generate the equivalent of
1933 local=/xxx.yyy.zzz.ip6.arpa/ */
1934 struct server
*serv
= add_rev6(&new->start6
, msize
);
1935 serv
->flags
|= SERV_NO_ADDR
;
1947 prefstr
= split(arg
);
1949 if (inet_pton(AF_INET
, comma
, &new->start
))
1953 new->end
.s_addr
= new->start
.s_addr
;
1954 else if (!inet_pton(AF_INET
, arg
, &new->end
))
1958 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1962 memcpy(&new->end6
, &new->start6
, IN6ADDRSZ
);
1963 else if (!inet_pton(AF_INET6
, arg
, &new->end6
))
1970 if (option
!= 's' && prefstr
)
1972 if (!(new->prefix
= canonicalise_opt(prefstr
)) ||
1973 strlen(new->prefix
) > MAXLABEL
- INET_ADDRSTRLEN
)
1974 ret_err(_("bad prefix"));
1981 new->next
= daemon
->cond_domain
;
1982 daemon
->cond_domain
= new;
1986 new->next
= daemon
->synth_domains
;
1987 daemon
->synth_domains
= new;
1990 else if (option
== 's')
1991 daemon
->domain_suffix
= d
;
1998 case 'u': /* --user */
1999 daemon
->username
= opt_string_alloc(arg
);
2002 case 'g': /* --group */
2003 daemon
->groupname
= opt_string_alloc(arg
);
2004 daemon
->group_set
= 1;
2008 case LOPT_SCRIPTUSR
: /* --scriptuser */
2009 daemon
->scriptuser
= opt_string_alloc(arg
);
2013 case 'i': /* --interface */
2015 struct iname
*new = opt_malloc(sizeof(struct iname
));
2017 new->next
= daemon
->if_names
;
2018 daemon
->if_names
= new;
2019 /* new->name may be NULL if someone does
2020 "interface=" to disable all interfaces except loop. */
2021 new->name
= opt_string_alloc(arg
);
2027 case LOPT_TFTP
: /* --enable-tftp */
2028 set_option_bool(OPT_TFTP
);
2033 case 'I': /* --except-interface */
2034 case '2': /* --no-dhcp-interface */
2036 struct iname
*new = opt_malloc(sizeof(struct iname
));
2038 new->name
= opt_string_alloc(arg
);
2041 new->next
= daemon
->if_except
;
2042 daemon
->if_except
= new;
2044 else if (option
== LOPT_TFTP
)
2046 new->next
= daemon
->tftp_interfaces
;
2047 daemon
->tftp_interfaces
= new;
2051 new->next
= daemon
->dhcp_except
;
2052 daemon
->dhcp_except
= new;
2058 case 'B': /* --bogus-nxdomain */
2060 struct in_addr addr
;
2062 if (arg
&& (inet_pton(AF_INET
, arg
, &addr
) > 0))
2064 struct bogus_addr
*baddr
= opt_malloc(sizeof(struct bogus_addr
));
2065 baddr
->next
= daemon
->bogus_addr
;
2066 daemon
->bogus_addr
= baddr
;
2070 ret_err(gen_err
); /* error */
2074 case 'a': /* --listen-address */
2075 case LOPT_AUTHPEER
: /* --auth-peer */
2077 struct iname
*new = opt_malloc(sizeof(struct iname
));
2080 if (arg
&& (inet_pton(AF_INET
, arg
, &new->addr
.in
.sin_addr
) > 0))
2082 new->addr
.sa
.sa_family
= AF_INET
;
2083 new->addr
.in
.sin_port
= 0;
2084 #ifdef HAVE_SOCKADDR_SA_LEN
2085 new->addr
.in
.sin_len
= sizeof(new->addr
.in
);
2089 else if (arg
&& inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
2091 new->addr
.sa
.sa_family
= AF_INET6
;
2092 new->addr
.in6
.sin6_flowinfo
= 0;
2093 new->addr
.in6
.sin6_scope_id
= 0;
2094 new->addr
.in6
.sin6_port
= 0;
2095 #ifdef HAVE_SOCKADDR_SA_LEN
2096 new->addr
.in6
.sin6_len
= sizeof(new->addr
.in6
);
2106 new->next
= daemon
->if_addrs
;
2107 daemon
->if_addrs
= new;
2111 new->next
= daemon
->auth_peers
;
2112 daemon
->auth_peers
= new;
2118 case 'S': /* --server */
2119 case LOPT_LOCAL
: /* --local */
2120 case 'A': /* --address */
2121 case LOPT_NO_REBIND
: /* --rebind-domain-ok */
2123 struct server
*serv
, *newlist
= NULL
;
2127 if (arg
&& (*arg
== '/' || option
== LOPT_NO_REBIND
))
2129 int rebind
= !(*arg
== '/');
2133 while (rebind
|| (end
= split_chr(arg
, '/')))
2135 char *domain
= NULL
;
2136 /* elide leading dots - they are implied in the search algorithm */
2137 while (*arg
== '.') arg
++;
2138 /* # matches everything and becomes a zero length domain string */
2139 if (strcmp(arg
, "#") == 0)
2141 else if (strlen (arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
2143 serv
= opt_malloc(sizeof(struct server
));
2144 memset(serv
, 0, sizeof(struct server
));
2145 serv
->next
= newlist
;
2147 serv
->domain
= domain
;
2148 serv
->flags
= domain
? SERV_HAS_DOMAIN
: SERV_FOR_NODOTS
;
2158 newlist
= opt_malloc(sizeof(struct server
));
2159 memset(newlist
, 0, sizeof(struct server
));
2162 if (servers_only
&& option
== 'S')
2163 newlist
->flags
|= SERV_FROM_FILE
;
2167 newlist
->flags
|= SERV_LITERAL_ADDRESS
;
2168 if (!(newlist
->flags
& SERV_TYPE
))
2171 else if (option
== LOPT_NO_REBIND
)
2172 newlist
->flags
|= SERV_NO_REBIND
;
2176 if (!(newlist
->flags
& SERV_NO_REBIND
))
2177 newlist
->flags
|= SERV_NO_ADDR
; /* no server */
2178 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
2182 else if (strcmp(arg
, "#") == 0)
2184 newlist
->flags
|= SERV_USE_RESOLV
; /* treat in ordinary way */
2185 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
2190 char *err
= parse_server(arg
, &newlist
->addr
, &newlist
->source_addr
, newlist
->interface
, &newlist
->flags
);
2198 serv
->next
->flags
= serv
->flags
;
2199 serv
->next
->addr
= serv
->addr
;
2200 serv
->next
->source_addr
= serv
->source_addr
;
2201 strcpy(serv
->next
->interface
, serv
->interface
);
2204 serv
->next
= daemon
->servers
;
2205 daemon
->servers
= newlist
;
2209 case LOPT_REV_SERV
: /* --rev-server */
2213 struct server
*serv
;
2214 struct in_addr addr4
;
2216 struct in6_addr addr6
;
2220 if (!arg
|| !(comma
=split(arg
)) || !(string
= split_chr(arg
, '/')) || !atoi_check(string
, &size
))
2223 if (inet_pton(AF_INET
, arg
, &addr4
))
2224 serv
= add_rev4(addr4
, size
);
2226 else if (inet_pton(AF_INET6
, arg
, &addr6
))
2227 serv
= add_rev6(&addr6
, size
);
2232 string
= parse_server(comma
, &serv
->addr
, &serv
->source_addr
, serv
->interface
, &serv
->flags
);
2238 serv
->flags
|= SERV_FROM_FILE
;
2243 case LOPT_IPSET
: /* --ipset */
2245 ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
2249 struct ipsets ipsets_head
;
2250 struct ipsets
*ipsets
= &ipsets_head
;
2253 char **sets
, **sets_pos
;
2254 memset(ipsets
, 0, sizeof(struct ipsets
));
2256 if (arg
&& *arg
== '/')
2259 while ((end
= split_chr(arg
, '/')))
2261 char *domain
= NULL
;
2262 /* elide leading dots - they are implied in the search algorithm */
2265 /* # matches everything and becomes a zero length domain string */
2266 if (strcmp(arg
, "#") == 0 || !*arg
)
2268 else if (strlen(arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
2270 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2271 ipsets
= ipsets
->next
;
2272 memset(ipsets
, 0, sizeof(struct ipsets
));
2273 ipsets
->domain
= domain
;
2279 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2280 ipsets
= ipsets
->next
;
2281 memset(ipsets
, 0, sizeof(struct ipsets
));
2282 ipsets
->domain
= "";
2290 for (end
= arg
; *end
; ++end
)
2294 sets
= sets_pos
= opt_malloc(sizeof(char *) * size
);
2298 *sets_pos
++ = opt_string_alloc(arg
);
2302 for (ipsets
= &ipsets_head
; ipsets
->next
; ipsets
= ipsets
->next
)
2303 ipsets
->next
->sets
= sets
;
2304 ipsets
->next
= daemon
->ipsets
;
2305 daemon
->ipsets
= ipsets_head
.next
;
2311 case 'c': /* --cache-size */
2315 if (!atoi_check(arg
, &size
))
2319 /* zero is OK, and means no caching. */
2323 else if (size
> 10000)
2326 daemon
->cachesize
= size
;
2331 case 'p': /* --port */
2332 if (!atoi_check16(arg
, &daemon
->port
))
2336 case LOPT_MINPORT
: /* --min-port */
2337 if (!atoi_check16(arg
, &daemon
->min_port
))
2341 case '0': /* --dns-forward-max */
2342 if (!atoi_check(arg
, &daemon
->ftabsize
))
2346 case LOPT_MAX_LOGS
: /* --log-async */
2347 daemon
->max_logs
= LOG_MAX
; /* default */
2348 if (arg
&& !atoi_check(arg
, &daemon
->max_logs
))
2350 else if (daemon
->max_logs
> 100)
2351 daemon
->max_logs
= 100;
2354 case 'P': /* --edns-packet-max */
2357 if (!atoi_check(arg
, &i
))
2359 daemon
->edns_pktsz
= (unsigned short)i
;
2363 case 'Q': /* --query-port */
2364 if (!atoi_check16(arg
, &daemon
->query_port
))
2366 /* if explicitly set to zero, use single OS ephemeral port
2367 and disable random ports */
2368 if (daemon
->query_port
== 0)
2372 case 'T': /* --local-ttl */
2373 case LOPT_NEGTTL
: /* --neg-ttl */
2374 case LOPT_MAXTTL
: /* --max-ttl */
2375 case LOPT_MAXCTTL
: /* --max-cache-ttl */
2376 case LOPT_AUTHTTL
: /* --auth-ttl */
2379 if (!atoi_check(arg
, &ttl
))
2381 else if (option
== LOPT_NEGTTL
)
2382 daemon
->neg_ttl
= (unsigned long)ttl
;
2383 else if (option
== LOPT_MAXTTL
)
2384 daemon
->max_ttl
= (unsigned long)ttl
;
2385 else if (option
== LOPT_MAXCTTL
)
2386 daemon
->max_cache_ttl
= (unsigned long)ttl
;
2387 else if (option
== LOPT_AUTHTTL
)
2388 daemon
->auth_ttl
= (unsigned long)ttl
;
2390 daemon
->local_ttl
= (unsigned long)ttl
;
2395 case 'X': /* --dhcp-lease-max */
2396 if (!atoi_check(arg
, &daemon
->dhcp_max
))
2402 case LOPT_TFTP_MAX
: /* --tftp-max */
2403 if (!atoi_check(arg
, &daemon
->tftp_max
))
2407 case LOPT_PREFIX
: /* --tftp-prefix */
2411 struct tftp_prefix
*new = opt_malloc(sizeof(struct tftp_prefix
));
2412 new->interface
= opt_string_alloc(comma
);
2413 new->prefix
= opt_string_alloc(arg
);
2414 new->next
= daemon
->if_prefix
;
2415 daemon
->if_prefix
= new;
2418 daemon
->tftp_prefix
= opt_string_alloc(arg
);
2421 case LOPT_TFTPPORTS
: /* --tftp-port-range */
2422 if (!(comma
= split(arg
)) ||
2423 !atoi_check16(arg
, &daemon
->start_tftp_port
) ||
2424 !atoi_check16(comma
, &daemon
->end_tftp_port
))
2425 ret_err(_("bad port range"));
2427 if (daemon
->start_tftp_port
> daemon
->end_tftp_port
)
2429 int tmp
= daemon
->start_tftp_port
;
2430 daemon
->start_tftp_port
= daemon
->end_tftp_port
;
2431 daemon
->end_tftp_port
= tmp
;
2437 case LOPT_BRIDGE
: /* --bridge-interface */
2439 struct dhcp_bridge
*new = opt_malloc(sizeof(struct dhcp_bridge
));
2440 if (!(comma
= split(arg
)) || strlen(arg
) > IF_NAMESIZE
- 1 )
2441 ret_err(_("bad bridge-interface"));
2443 strcpy(new->iface
, arg
);
2445 new->next
= daemon
->bridges
;
2446 daemon
->bridges
= new;
2451 if (strlen(arg
) != 0 && strlen(arg
) <= IF_NAMESIZE
- 1)
2453 struct dhcp_bridge
*b
= opt_malloc(sizeof(struct dhcp_bridge
));
2454 b
->next
= new->alias
;
2456 strcpy(b
->iface
, arg
);
2464 case 'F': /* --dhcp-range */
2466 int k
, leasepos
= 2;
2467 char *cp
, *a
[8] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2468 struct dhcp_context
*new = opt_malloc(sizeof(struct dhcp_context
));
2470 memset (new, 0, sizeof(*new));
2471 new->lease_time
= DEFLEASE
;
2481 for (cp
= arg
; *cp
; cp
++)
2482 if (!(*cp
== ' ' || *cp
== '.' || *cp
== ':' ||
2483 (*cp
>= 'a' && *cp
<= 'f') || (*cp
>= 'A' && *cp
<= 'F') ||
2484 (*cp
>='0' && *cp
<= '9')))
2487 if (*cp
!= ',' && (comma
= split(arg
)))
2489 if (is_tag_prefix(arg
))
2491 struct dhcp_netid
*tt
= opt_malloc(sizeof (struct dhcp_netid
));
2492 tt
->net
= opt_string_alloc(arg
+4);
2493 tt
->next
= new->filter
;
2494 /* ignore empty tag */
2501 ret_err(_("only one tag allowed"));
2502 else if (strstr(arg
, "set:") == arg
)
2503 new->netid
.net
= opt_string_alloc(arg
+4);
2505 new->netid
.net
= opt_string_alloc(arg
);
2516 for (k
= 1; k
< 8; k
++)
2517 if (!(a
[k
] = split(a
[k
-1])))
2521 ret_err(_("bad dhcp-range"));
2523 if (inet_pton(AF_INET
, a
[0], &new->start
))
2525 new->next
= daemon
->dhcp
;
2527 new->end
= new->start
;
2528 if (strcmp(a
[1], "static") == 0)
2529 new->flags
|= CONTEXT_STATIC
;
2530 else if (strcmp(a
[1], "proxy") == 0)
2531 new->flags
|= CONTEXT_PROXY
;
2532 else if (!inet_pton(AF_INET
, a
[1], &new->end
))
2533 ret_err(_("bad dhcp-range"));
2535 if (ntohl(new->start
.s_addr
) > ntohl(new->end
.s_addr
))
2537 struct in_addr tmp
= new->start
;
2538 new->start
= new->end
;
2542 if (k
>= 3 && strchr(a
[2], '.') &&
2543 (inet_pton(AF_INET
, a
[2], &new->netmask
) > 0))
2545 new->flags
|= CONTEXT_NETMASK
;
2547 if (!is_same_net(new->start
, new->end
, new->netmask
))
2548 ret_err(_("inconsistent DHCP range"));
2551 if (k
>= 4 && strchr(a
[3], '.') &&
2552 (inet_pton(AF_INET
, a
[3], &new->broadcast
) > 0))
2554 new->flags
|= CONTEXT_BRDCAST
;
2559 else if (inet_pton(AF_INET6
, a
[0], &new->start6
))
2561 new->flags
|= CONTEXT_V6
;
2562 new->prefix
= 64; /* default */
2563 new->end6
= new->start6
;
2564 new->next
= daemon
->dhcp6
;
2565 daemon
->dhcp6
= new;
2567 for (leasepos
= 1; leasepos
< k
; leasepos
++)
2569 if (strcmp(a
[leasepos
], "static") == 0)
2570 new->flags
|= CONTEXT_STATIC
| CONTEXT_DHCP
;
2571 else if (strcmp(a
[leasepos
], "ra-only") == 0 || strcmp(a
[leasepos
], "slaac") == 0 )
2572 new->flags
|= CONTEXT_RA_ONLY
| CONTEXT_RA
;
2573 else if (strcmp(a
[leasepos
], "ra-names") == 0)
2574 new->flags
|= CONTEXT_RA_NAME
| CONTEXT_RA
;
2575 else if (strcmp(a
[leasepos
], "ra-stateless") == 0)
2576 new->flags
|= CONTEXT_RA_STATELESS
| CONTEXT_DHCP
| CONTEXT_RA
;
2577 else if (leasepos
== 1 && inet_pton(AF_INET6
, a
[leasepos
], &new->end6
))
2578 new->flags
|= CONTEXT_DHCP
;
2579 else if (strstr(a
[leasepos
], "constructor:") == a
[leasepos
])
2581 new->template_interface
= opt_string_alloc(a
[leasepos
] + 12);
2582 new->flags
|= CONTEXT_TEMPLATE
;
2588 /* bare integer < 128 is prefix value */
2592 for (cp
= a
[leasepos
]; *cp
; cp
++)
2593 if (!(*cp
>= '0' && *cp
<= '9'))
2595 if (!*cp
&& (pref
= atoi(a
[leasepos
])) <= 128)
2602 if (new->prefix
!= 64)
2604 if ((new->flags
& (CONTEXT_RA_ONLY
| CONTEXT_RA_NAME
| CONTEXT_RA_STATELESS
)))
2605 ret_err(_("prefix length must be exactly 64 for RA subnets"));
2606 else if (new->flags
& CONTEXT_TEMPLATE
)
2607 ret_err(_("prefix length must be exactly 64 for subnet constructors"));
2610 if (new->prefix
< 64)
2611 ret_err(_("prefix length must be at least 64"));
2613 if (!is_same_net6(&new->start6
, &new->end6
, new->prefix
))
2614 ret_err(_("inconsistent DHCPv6 range"));
2616 /* dhcp-range=:: enables DHCP stateless on any interface */
2617 if (IN6_IS_ADDR_UNSPECIFIED(&new->start6
) && !(new->flags
& CONTEXT_TEMPLATE
))
2620 if (new->flags
& CONTEXT_TEMPLATE
)
2622 struct in6_addr zero
;
2623 memset(&zero
, 0, sizeof(zero
));
2624 if (!is_same_net6(&zero
, &new->start6
, new->prefix
))
2625 ret_err(_("prefix must be zero with \"constructor:\" argument"));
2628 if (addr6part(&new->start6
) > addr6part(&new->end6
))
2630 struct in6_addr tmp
= new->start6
;
2631 new->start6
= new->end6
;
2637 ret_err(_("bad dhcp-range"));
2641 if (strcmp(a
[leasepos
], "infinite") == 0)
2642 new->lease_time
= 0xffffffff;
2643 else if (strcmp(a
[leasepos
], "deprecated") == 0)
2644 new->flags
|= CONTEXT_DEPRECATE
;
2648 if (strlen(a
[leasepos
]) > 0)
2650 switch (a
[leasepos
][strlen(a
[leasepos
]) - 1])
2670 a
[leasepos
][strlen(a
[leasepos
]) - 1] = 0;
2673 for (cp
= a
[leasepos
]; *cp
; cp
++)
2674 if (!(*cp
>= '0' && *cp
<= '9'))
2677 if (*cp
|| (leasepos
+1 < k
))
2678 ret_err(_("bad dhcp-range"));
2680 new->lease_time
= atoi(a
[leasepos
]) * fac
;
2681 /* Leases of a minute or less confuse
2682 some clients, notably Apple's */
2683 if (new->lease_time
< 120)
2684 new->lease_time
= 120;
2692 case 'G': /* --dhcp-host */
2695 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2696 struct dhcp_config
*new;
2699 new = opt_malloc(sizeof(struct dhcp_config
));
2701 new->next
= daemon
->dhcp_conf
;
2702 new->flags
= (option
== LOPT_BANK
) ? CONFIG_BANK
: 0;
2707 for (k
= 1; k
< 7; k
++)
2708 if (!(a
[k
] = split(a
[k
-1])))
2711 for (j
= 0; j
< k
; j
++)
2712 if (strchr(a
[j
], ':')) /* ethernet address, netid or binary CLID */
2716 if ((arg
[0] == 'i' || arg
[0] == 'I') &&
2717 (arg
[1] == 'd' || arg
[1] == 'D') &&
2721 new->flags
|= CONFIG_NOCLID
;
2725 arg
+= 3; /* dump id: */
2726 if (strchr(arg
, ':'))
2727 len
= parse_hex(arg
, (unsigned char *)arg
, -1, NULL
, NULL
);
2731 len
= (int) strlen(arg
);
2736 ret_err(_("bad hex constant"));
2737 else if ((new->clid
= opt_malloc(len
)))
2739 new->flags
|= CONFIG_CLID
;
2740 new->clid_len
= len
;
2741 memcpy(new->clid
, arg
, len
);
2745 /* dhcp-host has strange backwards-compat needs. */
2746 else if (strstr(arg
, "net:") == arg
|| strstr(arg
, "set:") == arg
)
2748 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2749 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2750 newtag
->net
= opt_malloc(strlen(arg
+ 4) + 1);
2751 newlist
->next
= new->netid
;
2752 new->netid
= newlist
;
2753 newlist
->list
= newtag
;
2754 strcpy(newtag
->net
, arg
+4);
2755 unhide_metas(newtag
->net
);
2757 else if (strstr(arg
, "tag:") == arg
)
2758 ret_err(_("cannot match tags in --dhcp-host"));
2760 else if (arg
[0] == '[' && arg
[strlen(arg
)-1] == ']')
2762 arg
[strlen(arg
)-1] = 0;
2765 if (!inet_pton(AF_INET6
, arg
, &new->addr6
))
2766 ret_err(_("bad IPv6 address"));
2768 for (i
= 0; i
< 8; i
++)
2769 if (new->addr6
.s6_addr
[i
] != 0)
2772 /* set WILDCARD if network part all zeros */
2774 new->flags
|= CONFIG_WILDCARD
;
2776 new->flags
|= CONFIG_ADDR6
;
2781 struct hwaddr_config
*newhw
= opt_malloc(sizeof(struct hwaddr_config
));
2782 if ((newhw
->hwaddr_len
= parse_hex(a
[j
], newhw
->hwaddr
, DHCP_CHADDR_MAX
,
2783 &newhw
->wildcard_mask
, &newhw
->hwaddr_type
)) == -1)
2784 ret_err(_("bad hex constant"));
2788 newhw
->next
= new->hwaddr
;
2789 new->hwaddr
= newhw
;
2793 else if (strchr(a
[j
], '.') && (inet_pton(AF_INET
, a
[j
], &in
) > 0))
2795 struct dhcp_config
*configs
;
2798 new->flags
|= CONFIG_ADDR
;
2800 /* If the same IP appears in more than one host config, then DISCOVER
2801 for one of the hosts will get the address, but REQUEST will be NAKed,
2802 since the address is reserved by the other one -> protocol loop. */
2803 for (configs
= daemon
->dhcp_conf
; configs
; configs
= configs
->next
)
2804 if ((configs
->flags
& CONFIG_ADDR
) && configs
->addr
.s_addr
== in
.s_addr
)
2806 sprintf(errstr
, _("duplicate dhcp-host IP address %s"), inet_ntoa(in
));
2812 char *cp
, *lastp
= NULL
, last
= 0;
2813 int fac
= 1, isdig
= 0;
2815 if (strlen(a
[j
]) > 1)
2817 lastp
= a
[j
] + strlen(a
[j
]) - 1;
2843 for (cp
= a
[j
]; *cp
; cp
++)
2844 if (isdigit((unsigned char)*cp
))
2846 else if (*cp
!= ' ')
2853 if (strcmp(a
[j
], "infinite") == 0)
2855 new->lease_time
= 0xffffffff;
2856 new->flags
|= CONFIG_TIME
;
2858 else if (strcmp(a
[j
], "ignore") == 0)
2859 new->flags
|= CONFIG_DISABLE
;
2862 if (!(new->hostname
= canonicalise_opt(a
[j
])) ||
2863 !legal_hostname(new->hostname
))
2864 ret_err(_("bad DHCP host name"));
2866 new->flags
|= CONFIG_NAME
;
2867 new->domain
= strip_hostname(new->hostname
);
2872 new->lease_time
= atoi(a
[j
]) * fac
;
2873 /* Leases of a minute or less confuse
2874 some clients, notably Apple's */
2875 if (new->lease_time
< 120)
2876 new->lease_time
= 120;
2877 new->flags
|= CONFIG_TIME
;
2881 daemon
->dhcp_conf
= new;
2885 case LOPT_TAG_IF
: /* --tag-if */
2887 struct tag_if
*new = opt_malloc(sizeof(struct tag_if
));
2893 /* preserve order */
2894 if (!daemon
->tag_if
)
2895 daemon
->tag_if
= new;
2899 for (tmp
= daemon
->tag_if
; tmp
->next
; tmp
= tmp
->next
);
2917 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2918 newtag
->net
= opt_malloc(len
- 3);
2919 strcpy(newtag
->net
, arg
+4);
2920 unhide_metas(newtag
->net
);
2922 if (strstr(arg
, "set:") == arg
)
2924 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2925 newlist
->next
= new->set
;
2927 newlist
->list
= newtag
;
2929 else if (strstr(arg
, "tag:") == arg
)
2931 newtag
->next
= new->tag
;
2946 ret_err(_("bad tag-if"));
2952 case 'O': /* --dhcp-option */
2953 case LOPT_FORCE
: /* --dhcp-option-force */
2955 case LOPT_MATCH
: /* --dhcp-match */
2956 return parse_dhcp_opt(errstr
, arg
,
2957 option
== LOPT_FORCE
? DHOPT_FORCE
:
2958 (option
== LOPT_MATCH
? DHOPT_MATCH
:
2959 (option
== LOPT_OPTS
? DHOPT_BANK
: 0)));
2961 case 'M': /* --dhcp-boot */
2963 struct dhcp_netid
*id
= NULL
;
2964 while (is_tag_prefix(arg
))
2966 struct dhcp_netid
*newid
= opt_malloc(sizeof(struct dhcp_netid
));
2970 newid
->net
= opt_string_alloc(arg
+4);
2978 char *dhcp_file
, *dhcp_sname
= NULL
, *tftp_sname
= NULL
;
2979 struct in_addr dhcp_next_server
;
2980 struct dhcp_boot
*new;
2982 dhcp_file
= opt_string_alloc(arg
);
2983 dhcp_next_server
.s_addr
= 0;
2988 dhcp_sname
= opt_string_alloc(arg
);
2991 unhide_metas(comma
);
2992 if (!(inet_pton(AF_INET
, comma
, &dhcp_next_server
) > 0))
2995 * The user may have specified the tftp hostname here.
2996 * save it so that it can be resolved/looked up during
2997 * actual dhcp_reply().
3000 tftp_sname
= opt_string_alloc(comma
);
3001 dhcp_next_server
.s_addr
= 0;
3006 new = opt_malloc(sizeof(struct dhcp_boot
));
3007 new->file
= dhcp_file
;
3008 new->sname
= dhcp_sname
;
3009 new->tftp_sname
= tftp_sname
;
3010 new->next_server
= dhcp_next_server
;
3012 new->next
= daemon
->boot_config
;
3013 daemon
->boot_config
= new;
3019 case LOPT_PXE_PROMT
: /* --pxe-prompt */
3021 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
3025 new->opt
= 10; /* PXE_MENU_PROMPT */
3027 while (is_tag_prefix(arg
))
3029 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
3031 nn
->next
= new->netid
;
3033 nn
->net
= opt_string_alloc(arg
+4);
3043 new->len
= strlen(arg
) + 1;
3044 new->val
= opt_malloc(new->len
);
3045 memcpy(new->val
+ 1, arg
, new->len
- 1);
3047 new->u
.vendor_class
= (unsigned char *)"PXEClient";
3048 new->flags
= DHOPT_VENDOR
;
3050 if (comma
&& atoi_check(comma
, &timeout
))
3051 *(new->val
) = timeout
;
3055 new->next
= daemon
->dhcp_opts
;
3056 daemon
->dhcp_opts
= new;
3057 daemon
->enable_pxe
= 1;
3063 case LOPT_PXE_SERV
: /* --pxe-service */
3065 struct pxe_service
*new = opt_malloc(sizeof(struct pxe_service
));
3066 char *CSA
[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
3067 "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL
};
3068 static int boottype
= 32768;
3072 new->server
.s_addr
= 0;
3074 while (is_tag_prefix(arg
))
3076 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
3078 nn
->next
= new->netid
;
3080 nn
->net
= opt_string_alloc(arg
+4);
3084 if (arg
&& (comma
= split(arg
)))
3086 for (i
= 0; CSA
[i
]; i
++)
3087 if (strcasecmp(CSA
[i
], arg
) == 0)
3090 if (CSA
[i
] || atoi_check(arg
, &i
))
3096 new->menu
= opt_string_alloc(arg
);
3100 new->type
= 0; /* local boot */
3101 new->basename
= NULL
;
3107 if (atoi_check(arg
, &i
))
3110 new->basename
= NULL
;
3114 new->type
= boottype
++;
3115 new->basename
= opt_string_alloc(arg
);
3120 if (!inet_pton(AF_INET
, comma
, &new->server
))
3122 new->server
.s_addr
= 0;
3123 new->sname
= opt_string_alloc(comma
);
3131 if (!daemon
->pxe_services
)
3132 daemon
->pxe_services
= new;
3135 struct pxe_service
*s
;
3136 for (s
= daemon
->pxe_services
; s
->next
; s
= s
->next
);
3140 daemon
->enable_pxe
= 1;
3149 case '4': /* --dhcp-mac */
3151 if (!(comma
= split(arg
)))
3155 struct dhcp_mac
*new = opt_malloc(sizeof(struct dhcp_mac
));
3156 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
3157 unhide_metas(comma
);
3158 new->hwaddr_len
= parse_hex(comma
, new->hwaddr
, DHCP_CHADDR_MAX
, &new->mask
, &new->hwaddr_type
);
3159 if (new->hwaddr_len
== -1)
3163 new->next
= daemon
->dhcp_macs
;
3164 daemon
->dhcp_macs
= new;
3170 #ifdef OPTION6_PREFIX_CLASS
3171 case LOPT_PREF_CLSS
: /* --dhcp-prefix-class */
3173 struct prefix_class
*new = opt_malloc(sizeof(struct prefix_class
));
3175 if (!(comma
= split(arg
)) ||
3176 !atoi_check16(comma
, &new->class))
3179 new->tag
.net
= opt_string_alloc(set_prefix(arg
));
3180 new->next
= daemon
->prefix_classes
;
3181 daemon
->prefix_classes
= new;
3188 case 'U': /* --dhcp-vendorclass */
3189 case 'j': /* --dhcp-userclass */
3190 case LOPT_CIRCUIT
: /* --dhcp-circuitid */
3191 case LOPT_REMOTE
: /* --dhcp-remoteid */
3192 case LOPT_SUBSCR
: /* --dhcp-subscrid */
3196 struct dhcp_vendor
*new = opt_malloc(sizeof(struct dhcp_vendor
));
3198 if (!(comma
= split(arg
)))
3201 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
3202 /* check for hex string - must digits may include : must not have nothing else,
3203 only allowed for agent-options. */
3206 if ((comma
= split(arg
)))
3208 if (option
!= 'U' || strstr(arg
, "enterprise:") != arg
)
3211 new->enterprise
= atoi(arg
+11);
3216 for (p
= (unsigned char *)comma
; *p
; p
++)
3221 unhide_metas(comma
);
3222 if (option
== 'U' || option
== 'j' || *p
|| !dig
)
3224 new->len
= strlen(comma
);
3225 new->data
= opt_malloc(new->len
);
3226 memcpy(new->data
, comma
, new->len
);
3230 new->len
= parse_hex(comma
, (unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
3231 new->data
= opt_malloc(new->len
);
3232 memcpy(new->data
, comma
, new->len
);
3238 new->match_type
= MATCH_USER
;
3241 new->match_type
= MATCH_VENDOR
;
3244 new->match_type
= MATCH_CIRCUIT
;
3247 new->match_type
= MATCH_REMOTE
;
3250 new->match_type
= MATCH_SUBSCRIBER
;
3253 new->next
= daemon
->dhcp_vendors
;
3254 daemon
->dhcp_vendors
= new;
3259 case LOPT_ALTPORT
: /* --dhcp-alternate-port */
3262 daemon
->dhcp_server_port
= DHCP_SERVER_ALTPORT
;
3263 daemon
->dhcp_client_port
= DHCP_CLIENT_ALTPORT
;
3268 if (!atoi_check16(arg
, &daemon
->dhcp_server_port
) ||
3269 (comma
&& !atoi_check16(comma
, &daemon
->dhcp_client_port
)))
3270 ret_err(_("invalid port number"));
3272 daemon
->dhcp_client_port
= daemon
->dhcp_server_port
+1;
3276 case 'J': /* --dhcp-ignore */
3277 case LOPT_NO_NAMES
: /* --dhcp-ignore-names */
3278 case LOPT_BROADCAST
: /* --dhcp-broadcast */
3279 case '3': /* --bootp-dynamic */
3280 case LOPT_GEN_NAMES
: /* --dhcp-generate-names */
3282 struct dhcp_netid_list
*new = opt_malloc(sizeof(struct dhcp_netid_list
));
3283 struct dhcp_netid
*list
= NULL
;
3286 new->next
= daemon
->dhcp_ignore
;
3287 daemon
->dhcp_ignore
= new;
3289 else if (option
== LOPT_BROADCAST
)
3291 new->next
= daemon
->force_broadcast
;
3292 daemon
->force_broadcast
= new;
3294 else if (option
== '3')
3296 new->next
= daemon
->bootp_dynamic
;
3297 daemon
->bootp_dynamic
= new;
3299 else if (option
== LOPT_GEN_NAMES
)
3301 new->next
= daemon
->dhcp_gen_names
;
3302 daemon
->dhcp_gen_names
= new;
3306 new->next
= daemon
->dhcp_ignore_names
;
3307 daemon
->dhcp_ignore_names
= new;
3311 struct dhcp_netid
*member
= opt_malloc(sizeof(struct dhcp_netid
));
3313 member
->next
= list
;
3315 if (is_tag_prefix(arg
))
3316 member
->net
= opt_string_alloc(arg
+4);
3318 member
->net
= opt_string_alloc(arg
);
3326 case LOPT_PROXY
: /* --dhcp-proxy */
3327 daemon
->override
= 1;
3329 struct addr_list
*new = opt_malloc(sizeof(struct addr_list
));
3331 if (!(inet_pton(AF_INET
, arg
, &new->addr
) > 0))
3332 ret_err(_("bad dhcp-proxy address"));
3333 new->next
= daemon
->override_relays
;
3334 daemon
->override_relays
= new;
3339 case LOPT_RELAY
: /* --dhcp-relay */
3341 struct dhcp_relay
*new = opt_malloc(sizeof(struct dhcp_relay
));
3343 new->interface
= opt_string_alloc(split(comma
));
3344 new->iface_index
= 0;
3345 if (inet_pton(AF_INET
, arg
, &new->local
) && inet_pton(AF_INET
, comma
, &new->server
))
3347 new->next
= daemon
->relay4
;
3348 daemon
->relay4
= new;
3351 else if (inet_pton(AF_INET6
, arg
, &new->local
) && inet_pton(AF_INET6
, comma
, &new->server
))
3353 new->next
= daemon
->relay6
;
3354 daemon
->relay6
= new;
3358 ret_err(_("Bad dhcp-relay"));
3366 case LOPT_RA_PARAM
: /* --ra-param */
3367 if ((comma
= split(arg
)))
3369 struct ra_interface
*new = opt_malloc(sizeof(struct ra_interface
));
3372 new->name
= opt_string_alloc(arg
);
3373 if (strcasestr(comma
, "high") == comma
|| strcasestr(comma
, "low") == comma
)
3375 if (*comma
== 'l' || *comma
== 'L')
3379 comma
= split(comma
);
3382 if (!atoi_check(comma
, &new->interval
) ||
3383 (arg
&& !atoi_check(arg
, &new->lifetime
)))
3384 ret_err(_("bad RA-params"));
3386 new->next
= daemon
->ra_interfaces
;
3387 daemon
->ra_interfaces
= new;
3391 case LOPT_DUID
: /* --dhcp-duid */
3392 if (!(comma
= split(arg
)) || !atoi_check(arg
, (int *)&daemon
->duid_enterprise
))
3393 ret_err(_("bad DUID"));
3396 daemon
->duid_config_len
= parse_hex(comma
,(unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
3397 daemon
->duid_config
= opt_malloc(daemon
->duid_config_len
);
3398 memcpy(daemon
->duid_config
, comma
, daemon
->duid_config_len
);
3403 case 'V': /* --alias */
3405 char *dash
, *a
[3] = { NULL
, NULL
, NULL
};
3407 struct doctor
*new = opt_malloc(sizeof(struct doctor
));
3408 new->next
= daemon
->doctors
;
3409 daemon
->doctors
= new;
3410 new->mask
.s_addr
= 0xffffffff;
3411 new->end
.s_addr
= 0;
3414 for (k
= 1; k
< 3; k
++)
3416 if (!(a
[k
] = split(a
[k
-1])))
3421 dash
= split_chr(a
[0], '-');
3424 (!(inet_pton(AF_INET
, a
[0], &new->in
) > 0)) ||
3425 (!(inet_pton(AF_INET
, a
[1], &new->out
) > 0)))
3429 inet_pton(AF_INET
, a
[2], &new->mask
);
3432 (!(inet_pton(AF_INET
, dash
, &new->end
) > 0) ||
3433 !is_same_net(new->in
, new->end
, new->mask
) ||
3434 ntohl(new->in
.s_addr
) > ntohl(new->end
.s_addr
)))
3435 ret_err(_("invalid alias range"));
3440 case LOPT_INTNAME
: /* --interface-name */
3442 struct interface_name
*new, **up
;
3443 char *domain
= NULL
;
3447 if (!comma
|| !(domain
= canonicalise_opt(arg
)))
3448 ret_err(_("bad interface name"));
3450 new = opt_malloc(sizeof(struct interface_name
));
3454 /* Add to the end of the list, so that first name
3455 of an interface is used for PTR lookups. */
3456 for (up
= &daemon
->int_names
; *up
; up
= &((*up
)->next
));
3460 arg
= split_chr(comma
, '/');
3463 if (strcmp(arg
, "4") == 0)
3464 new->family
= AF_INET
;
3466 else if (strcmp(arg
, "6") == 0)
3467 new->family
= AF_INET6
;
3472 new->intr
= opt_string_alloc(comma
);
3476 case LOPT_CNAME
: /* --cname */
3482 if (!(comma
= split(arg
)))
3485 alias
= canonicalise_opt(arg
);
3486 target
= canonicalise_opt(comma
);
3488 if (!alias
|| !target
)
3489 ret_err(_("bad CNAME"));
3492 for (new = daemon
->cnames
; new; new = new->next
)
3493 if (hostname_isequal(new->alias
, arg
))
3494 ret_err(_("duplicate CNAME"));
3495 new = opt_malloc(sizeof(struct cname
));
3496 new->next
= daemon
->cnames
;
3497 daemon
->cnames
= new;
3499 new->target
= target
;
3505 case LOPT_PTR
: /* --ptr-record */
3507 struct ptr_record
*new;
3508 char *dom
, *target
= NULL
;
3512 if (!(dom
= canonicalise_opt(arg
)) ||
3513 (comma
&& !(target
= canonicalise_opt(comma
))))
3514 ret_err(_("bad PTR record"));
3517 new = opt_malloc(sizeof(struct ptr_record
));
3518 new->next
= daemon
->ptr
;
3526 case LOPT_NAPTR
: /* --naptr-record */
3528 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
3532 char *name
, *replace
= NULL
;
3535 for (k
= 1; k
< 7; k
++)
3536 if (!(a
[k
] = split(a
[k
-1])))
3541 !(name
= canonicalise_opt(a
[0])) ||
3542 !atoi_check16(a
[1], &order
) ||
3543 !atoi_check16(a
[2], &pref
) ||
3544 (k
== 7 && !(replace
= canonicalise_opt(a
[6]))))
3545 ret_err(_("bad NAPTR record"));
3548 new = opt_malloc(sizeof(struct naptr
));
3549 new->next
= daemon
->naptr
;
3550 daemon
->naptr
= new;
3552 new->flags
= opt_string_alloc(a
[3]);
3553 new->services
= opt_string_alloc(a
[4]);
3554 new->regexp
= opt_string_alloc(a
[5]);
3555 new->replace
= replace
;
3562 case LOPT_RR
: /* dns-rr */
3564 struct txt_record
*new;
3570 data
= split(comma
);
3572 new = opt_malloc(sizeof(struct txt_record
));
3573 new->next
= daemon
->rr
;
3576 if (!atoi_check(comma
, &val
) ||
3577 !(new->name
= canonicalise_opt(arg
)) ||
3578 (data
&& (len
= parse_hex(data
, (unsigned char *)data
, -1, NULL
, NULL
)) == -1U))
3579 ret_err(_("bad RR record"));
3586 new->txt
=opt_malloc(len
);
3588 memcpy(new->txt
, data
, len
);
3594 case 'Y': /* --txt-record */
3596 struct txt_record
*new;
3597 unsigned char *p
, *cnt
;
3602 new = opt_malloc(sizeof(struct txt_record
));
3603 new->next
= daemon
->txt
;
3607 if (!(new->name
= canonicalise_opt(arg
)))
3608 ret_err(_("bad TXT record"));
3610 len
= comma
? strlen(comma
) : 0;
3611 len
+= (len
/255) + 1; /* room for extra counts */
3612 new->txt
= p
= opt_malloc(len
);
3617 while (comma
&& *comma
)
3619 unsigned char c
= (unsigned char)*comma
++;
3621 if (c
== ',' || *cnt
== 255)
3630 *p
++ = unhide_meta(c
);
3635 new->len
= p
- new->txt
;
3640 case 'W': /* --srv-host */
3642 int port
= 1, priority
= 0, weight
= 0;
3643 char *name
, *target
= NULL
;
3644 struct mx_srv_record
*new;
3648 if (!(name
= canonicalise_opt(arg
)))
3649 ret_err(_("bad SRV record"));
3655 if (!(target
= canonicalise_opt(arg
)))
3656 ret_err(_("bad SRV target"));
3662 if (!atoi_check16(arg
, &port
))
3663 ret_err(_("invalid port number"));
3669 if (!atoi_check16(arg
, &priority
))
3670 ret_err(_("invalid priority"));
3676 if (!atoi_check16(arg
, &weight
))
3677 ret_err(_("invalid weight"));
3683 new = opt_malloc(sizeof(struct mx_srv_record
));
3684 new->next
= daemon
->mxnames
;
3685 daemon
->mxnames
= new;
3688 new->target
= target
;
3689 new->srvport
= port
;
3690 new->priority
= priority
;
3691 new->weight
= weight
;
3695 case LOPT_HOST_REC
: /* --host-record */
3697 struct host_record
*new = opt_malloc(sizeof(struct host_record
));
3698 memset(new, 0, sizeof(struct host_record
));
3700 if (!arg
|| !(comma
= split(arg
)))
3701 ret_err(_("Bad host-record"));
3705 struct all_addr addr
;
3706 if (inet_pton(AF_INET
, arg
, &addr
))
3707 new->addr
= addr
.addr
.addr4
;
3709 else if (inet_pton(AF_INET6
, arg
, &addr
))
3710 new->addr6
= addr
.addr
.addr6
;
3715 char *canon
= canonicalise(arg
, &nomem
);
3716 struct name_list
*nl
= opt_malloc(sizeof(struct name_list
));
3718 ret_err(_("Bad name in host-record"));
3721 /* keep order, so that PTR record goes to first name */
3727 struct name_list
*tmp
;
3728 for (tmp
= new->names
; tmp
->next
; tmp
= tmp
->next
);
3737 /* Keep list order */
3738 if (!daemon
->host_records_tail
)
3739 daemon
->host_records
= new;
3741 daemon
->host_records_tail
->next
= new;
3743 daemon
->host_records_tail
= new;
3748 case LOPT_TRUST_ANCHOR
:
3750 struct ds_config
*new = opt_malloc(sizeof(struct ds_config
));
3751 char *cp
, *cp1
, *keyhex
, *digest
, *algo
= NULL
;
3756 if ((comma
= split(arg
)) && (algo
= split(comma
)))
3759 if (strcmp(comma
, "IN") == 0)
3761 else if (strcmp(comma
, "CH") == 0)
3763 else if (strcmp(comma
, "HS") == 0)
3770 algo
= split(comma
);
3774 if (!comma
|| !algo
|| !(digest
= split(algo
)) || !(keyhex
= split(digest
)) ||
3775 !atoi_check16(comma
, &new->keytag
) ||
3776 !atoi_check8(algo
, &new->algo
) ||
3777 !atoi_check8(digest
, &new->digest_type
) ||
3778 !(new->name
= canonicalise_opt(arg
)))
3779 ret_err(_("bad trust anchor"));
3781 /* Upper bound on length */
3782 len
= (2*strlen(keyhex
))+1;
3783 new->digest
= opt_malloc(len
);
3784 unhide_metas(keyhex
);
3785 /* 4034: "Whitespace is allowed within digits" */
3786 for (cp
= keyhex
; *cp
; )
3788 for (cp1
= cp
; *cp1
; cp1
++)
3792 if ((new->digestlen
= parse_hex(keyhex
, (unsigned char *)new->digest
, len
, NULL
, NULL
)) == -1)
3793 ret_err(_("bad HEX in trust anchor"));
3795 new->next
= daemon
->ds
;
3803 ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"));
3810 static void read_file(char *file
, FILE *f
, int hard_opt
)
3812 volatile int lineno
= 0;
3813 char *buff
= daemon
->namebuff
;
3815 while (fgets(buff
, MAXDNAME
, f
))
3818 volatile int option
= (hard_opt
== LOPT_REV_SERV
) ? 0 : hard_opt
;
3819 char *errmess
, *p
, *arg
= NULL
, *start
;
3822 /* Memory allocation failure longjmps here if mem_recover == 1 */
3823 if (option
!= 0 || hard_opt
== LOPT_REV_SERV
)
3825 if (setjmp(mem_jmp
))
3833 /* Implement quotes, inside quotes we allow \\ \" \n and \t
3834 metacharacters get hidden also strip comments */
3835 for (white
= 1, p
= buff
; *p
; p
++)
3839 memmove(p
, p
+1, strlen(p
+1)+1);
3841 for(; *p
&& *p
!= '"'; p
++)
3843 if (*p
== '\\' && strchr("\"tnebr\\", p
[1]))
3847 else if (p
[1] == 'n')
3849 else if (p
[1] == 'b')
3851 else if (p
[1] == 'r')
3853 else if (p
[1] == 'e') /* escape */
3855 memmove(p
, p
+1, strlen(p
+1)+1);
3862 errmess
= _("missing \"");
3866 memmove(p
, p
+1, strlen(p
+1)+1);
3876 if (white
&& *p
== '#')
3886 /* strip leading spaces */
3887 for (start
= buff
; *start
&& *start
== ' '; start
++);
3889 /* strip trailing spaces */
3890 for (len
= strlen(start
); (len
!= 0) && (start
[len
-1] == ' '); len
--);
3899 else if ((p
=strchr(start
, '=')))
3901 /* allow spaces around "=" */
3902 for (arg
= p
+1; *arg
== ' '; arg
++);
3903 for (; p
>= start
&& (*p
== ' ' || *p
== '='); p
--)
3911 for (option
= 0, i
= 0; opts
[i
].name
; i
++)
3912 if (strcmp(opts
[i
].name
, start
) == 0)
3914 option
= opts
[i
].val
;
3919 errmess
= _("bad option");
3920 else if (opts
[i
].has_arg
== 0 && arg
)
3921 errmess
= _("extraneous parameter");
3922 else if (opts
[i
].has_arg
== 1 && !arg
)
3923 errmess
= _("missing parameter");
3924 else if (hard_opt
== LOPT_REV_SERV
&& option
!= 'S' && option
!= LOPT_REV_SERV
)
3925 errmess
= _("illegal option");
3930 strcpy(daemon
->namebuff
, errmess
);
3932 if (errmess
|| !one_opt(option
, arg
, buff
, _("error"), 0, hard_opt
== LOPT_REV_SERV
))
3934 sprintf(daemon
->namebuff
+ strlen(daemon
->namebuff
), _(" at line %d of %s"), lineno
, file
);
3936 my_syslog(LOG_ERR
, "%s", daemon
->namebuff
);
3938 die("%s", daemon
->namebuff
, EC_BADCONF
);
3946 static int one_file(char *file
, int hard_opt
)
3950 static int read_stdin
= 0;
3951 static struct fileread
{
3954 struct fileread
*next
;
3955 } *filesread
= NULL
;
3957 if (hard_opt
== '7')
3959 /* default conf-file reading */
3964 if (hard_opt
== 0 && strcmp(file
, "-") == 0)
3966 if (read_stdin
== 1)
3974 /* ignore repeated files. */
3975 struct stat statbuf
;
3977 if (hard_opt
== 0 && stat(file
, &statbuf
) == 0)
3981 for (r
= filesread
; r
; r
= r
->next
)
3982 if (r
->dev
== statbuf
.st_dev
&& r
->ino
== statbuf
.st_ino
)
3985 r
= safe_malloc(sizeof(struct fileread
));
3986 r
->next
= filesread
;
3988 r
->dev
= statbuf
.st_dev
;
3989 r
->ino
= statbuf
.st_ino
;
3992 if (!(f
= fopen(file
, "r")))
3994 if (errno
== ENOENT
&& nofile_ok
)
3995 return 1; /* No conffile, all done. */
3998 char *str
= _("cannot read %s: %s");
4001 my_syslog(LOG_ERR
, str
, file
, strerror(errno
));
4005 die(str
, file
, EC_FILE
);
4010 read_file(file
, f
, hard_opt
);
4014 /* expand any name which is a directory */
4015 struct hostsfile
*expand_filelist(struct hostsfile
*list
)
4018 struct hostsfile
*ah
;
4020 for (i
= 0, ah
= list
; ah
; ah
= ah
->next
)
4025 if (ah
->flags
& AH_DIR
)
4026 ah
->flags
|= AH_INACTIVE
;
4028 ah
->flags
&= ~AH_INACTIVE
;
4031 for (ah
= list
; ah
; ah
= ah
->next
)
4032 if (!(ah
->flags
& AH_INACTIVE
))
4035 if (stat(ah
->fname
, &buf
) != -1 && S_ISDIR(buf
.st_mode
))
4040 /* don't read this as a file */
4041 ah
->flags
|= AH_INACTIVE
;
4043 if (!(dir_stream
= opendir(ah
->fname
)))
4044 my_syslog(LOG_ERR
, _("cannot access directory %s: %s"),
4045 ah
->fname
, strerror(errno
));
4048 while ((ent
= readdir(dir_stream
)))
4050 size_t lendir
= strlen(ah
->fname
);
4051 size_t lenfile
= strlen(ent
->d_name
);
4052 struct hostsfile
*ah1
;
4055 /* ignore emacs backups and dotfiles */
4057 ent
->d_name
[lenfile
- 1] == '~' ||
4058 (ent
->d_name
[0] == '#' && ent
->d_name
[lenfile
- 1] == '#') ||
4059 ent
->d_name
[0] == '.')
4062 /* see if we have an existing record.
4065 path to match is ah1->fname */
4067 for (ah1
= list
; ah1
; ah1
= ah1
->next
)
4069 if (lendir
< strlen(ah1
->fname
) &&
4070 strstr(ah1
->fname
, ah
->fname
) == ah1
->fname
&&
4071 ah1
->fname
[lendir
] == '/' &&
4072 strcmp(ah1
->fname
+ lendir
+ 1, ent
->d_name
) == 0)
4074 ah1
->flags
&= ~AH_INACTIVE
;
4079 /* make new record */
4082 if (!(ah1
= whine_malloc(sizeof(struct hostsfile
))))
4085 if (!(path
= whine_malloc(lendir
+ lenfile
+ 2)))
4091 strcpy(path
, ah
->fname
);
4093 strcat(path
, ent
->d_name
);
4096 ah1
->flags
= AH_DIR
;
4101 /* inactivate record if not regular file */
4102 if ((ah1
->flags
& AH_DIR
) && stat(ah1
->fname
, &buf
) != -1 && !S_ISREG(buf
.st_mode
))
4103 ah1
->flags
|= AH_INACTIVE
;
4106 closedir(dir_stream
);
4114 void read_servers_file(void)
4118 if (!(f
= fopen(daemon
->servers_file
, "r")))
4120 my_syslog(LOG_ERR
, _("cannot read %s: %s"), daemon
->servers_file
, strerror(errno
));
4124 mark_servers(SERV_FROM_FILE
);
4127 read_file(daemon
->servers_file
, f
, LOPT_REV_SERV
);
4132 void reread_dhcp(void)
4134 struct hostsfile
*hf
;
4136 if (daemon
->dhcp_hosts_file
)
4138 struct dhcp_config
*configs
, *cp
, **up
;
4140 /* remove existing... */
4141 for (up
= &daemon
->dhcp_conf
, configs
= daemon
->dhcp_conf
; configs
; configs
= cp
)
4145 if (configs
->flags
& CONFIG_BANK
)
4147 struct hwaddr_config
*mac
, *tmp
;
4148 struct dhcp_netid_list
*list
, *tmplist
;
4150 for (mac
= configs
->hwaddr
; mac
; mac
= tmp
)
4156 if (configs
->flags
& CONFIG_CLID
)
4157 free(configs
->clid
);
4159 for (list
= configs
->netid
; list
; list
= tmplist
)
4162 tmplist
= list
->next
;
4166 if (configs
->flags
& CONFIG_NAME
)
4167 free(configs
->hostname
);
4169 *up
= configs
->next
;
4173 up
= &configs
->next
;
4176 daemon
->dhcp_hosts_file
= expand_filelist(daemon
->dhcp_hosts_file
);
4177 for (hf
= daemon
->dhcp_hosts_file
; hf
; hf
= hf
->next
)
4178 if (!(hf
->flags
& AH_INACTIVE
))
4180 if (one_file(hf
->fname
, LOPT_BANK
))
4181 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
4185 if (daemon
->dhcp_opts_file
)
4187 struct dhcp_opt
*opts
, *cp
, **up
;
4188 struct dhcp_netid
*id
, *next
;
4190 for (up
= &daemon
->dhcp_opts
, opts
= daemon
->dhcp_opts
; opts
; opts
= cp
)
4194 if (opts
->flags
& DHOPT_BANK
)
4196 if ((opts
->flags
& DHOPT_VENDOR
))
4197 free(opts
->u
.vendor_class
);
4199 for (id
= opts
->netid
; id
; id
= next
)
4212 daemon
->dhcp_opts_file
= expand_filelist(daemon
->dhcp_opts_file
);
4213 for (hf
= daemon
->dhcp_opts_file
; hf
; hf
= hf
->next
)
4214 if (!(hf
->flags
& AH_INACTIVE
))
4216 if (one_file(hf
->fname
, LOPT_OPTS
))
4217 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
4223 void read_opts(int argc
, char **argv
, char *compile_opts
)
4225 char *buff
= opt_malloc(MAXDNAME
);
4226 int option
, conffile_opt
= '7', testmode
= 0;
4227 char *arg
, *conffile
= CONFFILE
;
4231 daemon
= opt_malloc(sizeof(struct daemon
));
4232 memset(daemon
, 0, sizeof(struct daemon
));
4233 daemon
->namebuff
= buff
;
4235 /* Set defaults - everything else is zero or NULL */
4236 daemon
->cachesize
= CACHESIZ
;
4237 daemon
->ftabsize
= FTABSIZ
;
4238 daemon
->port
= NAMESERVER_PORT
;
4239 daemon
->dhcp_client_port
= DHCP_CLIENT_PORT
;
4240 daemon
->dhcp_server_port
= DHCP_SERVER_PORT
;
4241 daemon
->default_resolv
.is_default
= 1;
4242 daemon
->default_resolv
.name
= RESOLVFILE
;
4243 daemon
->resolv_files
= &daemon
->default_resolv
;
4244 daemon
->username
= CHUSER
;
4245 daemon
->runfile
= RUNFILE
;
4246 daemon
->dhcp_max
= MAXLEASES
;
4247 daemon
->tftp_max
= TFTP_MAX_CONNECTIONS
;
4248 daemon
->edns_pktsz
= EDNS_PKTSZ
;
4249 daemon
->log_fac
= -1;
4250 daemon
->auth_ttl
= AUTH_TTL
;
4251 daemon
->soa_refresh
= SOA_REFRESH
;
4252 daemon
->soa_retry
= SOA_RETRY
;
4253 daemon
->soa_expiry
= SOA_EXPIRY
;
4254 add_txt("version.bind", "dnsmasq-" VERSION
);
4255 add_txt("authors.bind", "Simon Kelley");
4256 add_txt("copyright.bind", COPYRIGHT
);
4260 #ifdef HAVE_GETOPT_LONG
4261 option
= getopt_long(argc
, argv
, OPTSTRING
, opts
, NULL
);
4263 option
= getopt(argc
, argv
, OPTSTRING
);
4268 for (; optind
< argc
; optind
++)
4270 unsigned char *c
= (unsigned char *)argv
[optind
];
4271 for (; *c
!= 0; c
++)
4273 die(_("junk found in command line"), NULL
, EC_BADCONF
);
4278 /* Copy optarg so that argv doesn't get changed */
4281 strncpy(buff
, optarg
, MAXDNAME
);
4282 buff
[MAXDNAME
-1] = 0;
4288 /* command-line only stuff */
4289 if (option
== LOPT_TEST
)
4291 else if (option
== 'w')
4294 if (argc
== 3 && strcmp(argv
[2], "dhcp") == 0)
4297 else if (argc
== 3 && strcmp(argv
[2], "dhcp6") == 0)
4306 else if (option
== 'v')
4308 printf(_("Dnsmasq version %s %s\n"), VERSION
, COPYRIGHT
);
4309 printf(_("Compile time options: %s\n\n"), compile_opts
);
4310 printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
4311 printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
4312 printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
4315 else if (option
== 'C')
4317 conffile_opt
= 0; /* file must exist */
4318 conffile
= opt_string_alloc(arg
);
4322 #ifdef HAVE_GETOPT_LONG
4323 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try --help"), 1, 0))
4325 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try -w"), 1, 0))
4327 die(_("bad command line options: %s"), daemon
->namebuff
, EC_BADCONF
);
4332 one_file(conffile
, conffile_opt
);
4334 /* port might not be known when the address is parsed - fill in here */
4335 if (daemon
->servers
)
4338 for (tmp
= daemon
->servers
; tmp
; tmp
= tmp
->next
)
4339 if (!(tmp
->flags
& SERV_HAS_SOURCE
))
4341 if (tmp
->source_addr
.sa
.sa_family
== AF_INET
)
4342 tmp
->source_addr
.in
.sin_port
= htons(daemon
->query_port
);
4344 else if (tmp
->source_addr
.sa
.sa_family
== AF_INET6
)
4345 tmp
->source_addr
.in6
.sin6_port
= htons(daemon
->query_port
);
4350 if (daemon
->if_addrs
)
4353 for(tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
4354 if (tmp
->addr
.sa
.sa_family
== AF_INET
)
4355 tmp
->addr
.in
.sin_port
= htons(daemon
->port
);
4357 else if (tmp
->addr
.sa
.sa_family
== AF_INET6
)
4358 tmp
->addr
.in6
.sin6_port
= htons(daemon
->port
);
4362 /* create default, if not specified */
4363 if (daemon
->authserver
&& !daemon
->hostmaster
)
4365 strcpy(buff
, "hostmaster.");
4366 strcat(buff
, daemon
->authserver
);
4367 daemon
->hostmaster
= opt_string_alloc(buff
);
4370 /* only one of these need be specified: the other defaults to the host-name */
4371 if (option_bool(OPT_LOCALMX
) || daemon
->mxnames
|| daemon
->mxtarget
)
4373 struct mx_srv_record
*mx
;
4375 if (gethostname(buff
, MAXDNAME
) == -1)
4376 die(_("cannot get host-name: %s"), NULL
, EC_MISC
);
4378 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
4379 if (!mx
->issrv
&& hostname_isequal(mx
->name
, buff
))
4382 if ((daemon
->mxtarget
|| option_bool(OPT_LOCALMX
)) && !mx
)
4384 mx
= opt_malloc(sizeof(struct mx_srv_record
));
4385 mx
->next
= daemon
->mxnames
;
4388 mx
->name
= opt_string_alloc(buff
);
4389 daemon
->mxnames
= mx
;
4392 if (!daemon
->mxtarget
)
4393 daemon
->mxtarget
= opt_string_alloc(buff
);
4395 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
4396 if (!mx
->issrv
&& !mx
->target
)
4397 mx
->target
= daemon
->mxtarget
;
4400 if (!option_bool(OPT_NO_RESOLV
) &&
4401 daemon
->resolv_files
&&
4402 daemon
->resolv_files
->next
&&
4403 option_bool(OPT_NO_POLL
))
4404 die(_("only one resolv.conf file allowed in no-poll mode."), NULL
, EC_BADCONF
);
4406 if (option_bool(OPT_RESOLV_DOMAIN
))
4411 if (option_bool(OPT_NO_RESOLV
) ||
4412 !daemon
->resolv_files
||
4413 (daemon
->resolv_files
)->next
)
4414 die(_("must have exactly one resolv.conf to read domain from."), NULL
, EC_BADCONF
);
4416 if (!(f
= fopen((daemon
->resolv_files
)->name
, "r")))
4417 die(_("failed to read %s: %s"), (daemon
->resolv_files
)->name
, EC_FILE
);
4419 while ((line
= fgets(buff
, MAXDNAME
, f
)))
4421 char *token
= strtok(line
, " \t\n\r");
4423 if (!token
|| strcmp(token
, "search") != 0)
4426 if ((token
= strtok(NULL
, " \t\n\r")) &&
4427 (daemon
->domain_suffix
= canonicalise_opt(token
)))
4433 if (!daemon
->domain_suffix
)
4434 die(_("no search directive found in %s"), (daemon
->resolv_files
)->name
, EC_MISC
);
4437 if (daemon
->domain_suffix
)
4439 /* add domain for any srv record without one. */
4440 struct mx_srv_record
*srv
;
4442 for (srv
= daemon
->mxnames
; srv
; srv
= srv
->next
)
4444 strchr(srv
->name
, '.') &&
4445 strchr(srv
->name
, '.') == strrchr(srv
->name
, '.'))
4447 strcpy(buff
, srv
->name
);
4449 strcat(buff
, daemon
->domain_suffix
);
4451 srv
->name
= opt_string_alloc(buff
);
4454 else if (option_bool(OPT_DHCP_FQDN
))
4455 die(_("there must be a default domain when --dhcp-fqdn is set"), NULL
, EC_BADCONF
);
4459 fprintf(stderr
, "dnsmasq: %s.\n", _("syntax check OK"));