1 /* dnsmasq is Copyright (c) 2000-2013 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
143 #ifdef HAVE_GETOPT_LONG
144 static const struct option opts
[] =
146 static const struct myoption opts
[] =
149 { "version", 0, 0, 'v' },
150 { "no-hosts", 0, 0, 'h' },
151 { "no-poll", 0, 0, 'n' },
152 { "help", 0, 0, 'w' },
153 { "no-daemon", 0, 0, 'd' },
154 { "log-queries", 0, 0, 'q' },
155 { "user", 2, 0, 'u' },
156 { "group", 2, 0, 'g' },
157 { "resolv-file", 2, 0, 'r' },
158 { "mx-host", 1, 0, 'm' },
159 { "mx-target", 1, 0, 't' },
160 { "cache-size", 2, 0, 'c' },
161 { "port", 1, 0, 'p' },
162 { "dhcp-leasefile", 2, 0, 'l' },
163 { "dhcp-lease", 1, 0, 'l' },
164 { "dhcp-host", 1, 0, 'G' },
165 { "dhcp-range", 1, 0, 'F' },
166 { "dhcp-option", 1, 0, 'O' },
167 { "dhcp-boot", 1, 0, 'M' },
168 { "domain", 1, 0, 's' },
169 { "domain-suffix", 1, 0, 's' },
170 { "interface", 1, 0, 'i' },
171 { "listen-address", 1, 0, 'a' },
172 { "bogus-priv", 0, 0, 'b' },
173 { "bogus-nxdomain", 1, 0, 'B' },
174 { "selfmx", 0, 0, 'e' },
175 { "filterwin2k", 0, 0, 'f' },
176 { "pid-file", 2, 0, 'x' },
177 { "strict-order", 0, 0, 'o' },
178 { "server", 1, 0, 'S' },
179 { "local", 1, 0, LOPT_LOCAL
},
180 { "address", 1, 0, 'A' },
181 { "conf-file", 2, 0, 'C' },
182 { "no-resolv", 0, 0, 'R' },
183 { "expand-hosts", 0, 0, 'E' },
184 { "localmx", 0, 0, 'L' },
185 { "local-ttl", 1, 0, 'T' },
186 { "no-negcache", 0, 0, 'N' },
187 { "addn-hosts", 1, 0, 'H' },
188 { "query-port", 1, 0, 'Q' },
189 { "except-interface", 1, 0, 'I' },
190 { "no-dhcp-interface", 1, 0, '2' },
191 { "domain-needed", 0, 0, 'D' },
192 { "dhcp-lease-max", 1, 0, 'X' },
193 { "bind-interfaces", 0, 0, 'z' },
194 { "read-ethers", 0, 0, 'Z' },
195 { "alias", 1, 0, 'V' },
196 { "dhcp-vendorclass", 1, 0, 'U' },
197 { "dhcp-userclass", 1, 0, 'j' },
198 { "dhcp-ignore", 1, 0, 'J' },
199 { "edns-packet-max", 1, 0, 'P' },
200 { "keep-in-foreground", 0, 0, 'k' },
201 { "dhcp-authoritative", 0, 0, 'K' },
202 { "srv-host", 1, 0, 'W' },
203 { "localise-queries", 0, 0, 'y' },
204 { "txt-record", 1, 0, 'Y' },
205 { "dns-rr", 1, 0, LOPT_RR
},
206 { "enable-dbus", 2, 0, '1' },
207 { "bootp-dynamic", 2, 0, '3' },
208 { "dhcp-mac", 1, 0, '4' },
209 { "no-ping", 0, 0, '5' },
210 { "dhcp-script", 1, 0, '6' },
211 { "conf-dir", 1, 0, '7' },
212 { "log-facility", 1, 0 ,'8' },
213 { "leasefile-ro", 0, 0, '9' },
214 { "dns-forward-max", 1, 0, '0' },
215 { "clear-on-reload", 0, 0, LOPT_RELOAD
},
216 { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES
},
217 { "enable-tftp", 2, 0, LOPT_TFTP
},
218 { "tftp-secure", 0, 0, LOPT_SECURE
},
219 { "tftp-unique-root", 0, 0, LOPT_APREF
},
220 { "tftp-root", 1, 0, LOPT_PREFIX
},
221 { "tftp-max", 1, 0, LOPT_TFTP_MAX
},
222 { "tftp-lowercase", 0, 0, LOPT_TFTP_LC
},
223 { "ptr-record", 1, 0, LOPT_PTR
},
224 { "naptr-record", 1, 0, LOPT_NAPTR
},
225 { "bridge-interface", 1, 0 , LOPT_BRIDGE
},
226 { "dhcp-option-force", 1, 0, LOPT_FORCE
},
227 { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK
},
228 { "log-dhcp", 0, 0, LOPT_LOG_OPTS
},
229 { "log-async", 2, 0, LOPT_MAX_LOGS
},
230 { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT
},
231 { "dhcp-remoteid", 1, 0, LOPT_REMOTE
},
232 { "dhcp-subscrid", 1, 0, LOPT_SUBSCR
},
233 { "interface-name", 1, 0, LOPT_INTNAME
},
234 { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST
},
235 { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS
},
236 { "dhcp-no-override", 0, 0, LOPT_OVERRIDE
},
237 { "tftp-port-range", 1, 0, LOPT_TFTPPORTS
},
238 { "stop-dns-rebind", 0, 0, LOPT_REBIND
},
239 { "rebind-domain-ok", 1, 0, LOPT_NO_REBIND
},
240 { "all-servers", 0, 0, LOPT_NOLAST
},
241 { "dhcp-match", 1, 0, LOPT_MATCH
},
242 { "dhcp-broadcast", 2, 0, LOPT_BROADCAST
},
243 { "neg-ttl", 1, 0, LOPT_NEGTTL
},
244 { "max-ttl", 1, 0, LOPT_MAXTTL
},
245 { "max-cache-ttl", 1, 0, LOPT_MAXCTTL
},
246 { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT
},
247 { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR
},
248 { "min-port", 1, 0, LOPT_MINPORT
},
249 { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN
},
250 { "cname", 1, 0, LOPT_CNAME
},
251 { "pxe-prompt", 1, 0, LOPT_PXE_PROMT
},
252 { "pxe-service", 1, 0, LOPT_PXE_SERV
},
253 { "test", 0, 0, LOPT_TEST
},
254 { "tag-if", 1, 0, LOPT_TAG_IF
},
255 { "dhcp-proxy", 2, 0, LOPT_PROXY
},
256 { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES
},
257 { "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND
},
258 { "add-mac", 0, 0, LOPT_ADD_MAC
},
259 { "add-subnet", 2, 0, LOPT_ADD_SBNET
},
260 { "proxy-dnssec", 0, 0, LOPT_DNSSEC
},
261 { "dhcp-sequential-ip", 0, 0, LOPT_INCR_ADDR
},
262 { "conntrack", 0, 0, LOPT_CONNTRACK
},
263 { "dhcp-client-update", 0, 0, LOPT_FQDN
},
264 { "dhcp-luascript", 1, 0, LOPT_LUASCRIPT
},
265 { "enable-ra", 0, 0, LOPT_RA
},
266 { "dhcp-duid", 1, 0, LOPT_DUID
},
267 { "host-record", 1, 0, LOPT_HOST_REC
},
268 { "bind-dynamic", 0, 0, LOPT_CLVERBIND
},
269 { "auth-zone", 1, 0, LOPT_AUTHZONE
},
270 { "auth-server", 1, 0, LOPT_AUTHSERV
},
271 { "auth-ttl", 1, 0, LOPT_AUTHTTL
},
272 { "auth-soa", 1, 0, LOPT_AUTHSOA
},
273 { "auth-sec-servers", 1, 0, LOPT_AUTHSFS
},
274 { "auth-peer", 1, 0, LOPT_AUTHPEER
},
275 { "ipset", 1, 0, LOPT_IPSET
},
276 { "synth-domain", 1, 0, LOPT_SYNTH
},
277 #ifdef OPTION6_PREFIX_CLASS
278 { "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS
},
280 { "dhcp-relay", 1, 0, LOPT_RELAY
},
281 { "ra-param", 1, 0, LOPT_RA_PARAM
},
282 { "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP
},
283 { "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6
},
284 { "quiet-ra", 0, 0, LOPT_QUIET_RA
},
289 #define ARG_DUP OPT_LAST
290 #define ARG_ONE OPT_LAST + 1
291 #define ARG_USED_CL OPT_LAST + 2
292 #define ARG_USED_FILE OPT_LAST + 3
297 char * const flagdesc
;
301 { 'a', ARG_DUP
, "<ipaddr>", gettext_noop("Specify local address(es) to listen on."), NULL
},
302 { 'A', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL
},
303 { 'b', OPT_BOGUSPRIV
, NULL
, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL
},
304 { 'B', ARG_DUP
, "<ipaddr>", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL
},
305 { 'c', ARG_ONE
, "<integer>", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
306 { 'C', ARG_DUP
, "<path>", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE
},
307 { 'd', OPT_DEBUG
, NULL
, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL
},
308 { 'D', OPT_NODOTS_LOCAL
, NULL
, gettext_noop("Do NOT forward queries with no domain part."), NULL
},
309 { 'e', OPT_SELFMX
, NULL
, gettext_noop("Return self-pointing MX records for local hosts."), NULL
},
310 { 'E', OPT_EXPAND
, NULL
, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL
},
311 { 'f', OPT_FILTER
, NULL
, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL
},
312 { 'F', ARG_DUP
, "<ipaddr>,...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL
},
313 { 'g', ARG_ONE
, "<groupname>", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP
},
314 { 'G', ARG_DUP
, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL
},
315 { LOPT_DHCP_HOST
, ARG_DUP
, "<path>", gettext_noop("Read DHCP host specs from file."), NULL
},
316 { LOPT_DHCP_OPTS
, ARG_DUP
, "<path>", gettext_noop("Read DHCP option specs from file."), NULL
},
317 { LOPT_TAG_IF
, ARG_DUP
, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL
},
318 { 'h', OPT_NO_HOSTS
, NULL
, gettext_noop("Do NOT load %s file."), HOSTSFILE
},
319 { 'H', ARG_DUP
, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE
},
320 { 'i', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL
},
321 { 'I', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL
},
322 { 'j', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL
},
323 { LOPT_CIRCUIT
, ARG_DUP
, "set:<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL
},
324 { LOPT_REMOTE
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL
},
325 { LOPT_SUBSCR
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL
},
326 { 'J', ARG_DUP
, "tag:<tag>...", gettext_noop("Don't do DHCP for hosts with tag set."), NULL
},
327 { LOPT_BROADCAST
, ARG_DUP
, "[=tag:<tag>...]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL
},
328 { 'k', OPT_NO_FORK
, NULL
, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL
},
329 { 'K', OPT_AUTHORITATIVE
, NULL
, gettext_noop("Assume we are the only DHCP server on the local network."), NULL
},
330 { 'l', ARG_ONE
, "<path>", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE
},
331 { 'L', OPT_LOCALMX
, NULL
, gettext_noop("Return MX records for local hosts."), NULL
},
332 { 'm', ARG_DUP
, "<host_name>,<target>,<pref>", gettext_noop("Specify an MX record."), NULL
},
333 { 'M', ARG_DUP
, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL
},
334 { 'n', OPT_NO_POLL
, NULL
, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE
},
335 { 'N', OPT_NO_NEG
, NULL
, gettext_noop("Do NOT cache failed search results."), NULL
},
336 { 'o', OPT_ORDER
, NULL
, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE
},
337 { 'O', ARG_DUP
, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL
},
338 { LOPT_FORCE
, ARG_DUP
, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL
},
339 { 'p', ARG_ONE
, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL
},
340 { 'P', ARG_ONE
, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
341 { 'q', OPT_LOG
, NULL
, gettext_noop("Log DNS queries."), NULL
},
342 { 'Q', ARG_ONE
, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL
},
343 { 'R', OPT_NO_RESOLV
, NULL
, gettext_noop("Do NOT read resolv.conf."), NULL
},
344 { 'r', ARG_DUP
, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE
},
345 { 'S', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL
},
346 { LOPT_LOCAL
, ARG_DUP
, "/<domain>/", gettext_noop("Never forward queries to specified domains."), NULL
},
347 { 's', ARG_DUP
, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL
},
348 { 't', ARG_ONE
, "<host_name>", gettext_noop("Specify default target in an MX record."), NULL
},
349 { 'T', ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL
},
350 { LOPT_NEGTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL
},
351 { LOPT_MAXTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL
},
352 { 'u', ARG_ONE
, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER
},
353 { 'U', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL
},
354 { 'v', 0, NULL
, gettext_noop("Display dnsmasq version and copyright information."), NULL
},
355 { 'V', ARG_DUP
, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL
},
356 { 'W', ARG_DUP
, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL
},
357 { 'w', 0, NULL
, gettext_noop("Display this message. Use --help dhcp for known DHCP options."), NULL
},
358 { 'x', ARG_ONE
, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE
},
359 { 'X', ARG_ONE
, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
360 { 'y', OPT_LOCALISE
, NULL
, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL
},
361 { 'Y', ARG_DUP
, "<name>,<txt>[,<txt]", gettext_noop("Specify TXT DNS record."), NULL
},
362 { LOPT_PTR
, ARG_DUP
, "<name>,<target>", gettext_noop("Specify PTR DNS record."), NULL
},
363 { LOPT_INTNAME
, ARG_DUP
, "<name>,<interface>", gettext_noop("Give DNS name to IPv4 address of interface."), NULL
},
364 { 'z', OPT_NOWILD
, NULL
, gettext_noop("Bind only to interfaces in use."), NULL
},
365 { 'Z', OPT_ETHERS
, NULL
, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE
},
366 { '1', ARG_ONE
, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL
},
367 { '2', ARG_DUP
, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL
},
368 { '3', ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL
},
369 { '4', ARG_DUP
, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL
},
370 { LOPT_BRIDGE
, ARG_DUP
, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL
},
371 { '5', OPT_NO_PING
, NULL
, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL
},
372 { '6', ARG_ONE
, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL
},
373 { LOPT_LUASCRIPT
, ARG_DUP
, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL
},
374 { LOPT_SCRIPTUSR
, ARG_ONE
, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL
},
375 { '7', ARG_DUP
, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL
},
376 { '8', ARG_ONE
, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL
},
377 { '9', OPT_LEASE_RO
, NULL
, gettext_noop("Do not use leasefile."), NULL
},
378 { '0', ARG_ONE
, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
379 { LOPT_RELOAD
, OPT_RELOAD
, NULL
, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE
},
380 { LOPT_NO_NAMES
, ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL
},
381 { LOPT_OVERRIDE
, OPT_NO_OVERRIDE
, NULL
, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL
},
382 { LOPT_TFTP
, ARG_DUP
, "[=<intr>[,<intr>]]", gettext_noop("Enable integrated read-only TFTP server."), NULL
},
383 { LOPT_PREFIX
, ARG_DUP
, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL
},
384 { LOPT_APREF
, OPT_TFTP_APREF
, NULL
, gettext_noop("Add client IP address to tftp-root."), NULL
},
385 { LOPT_SECURE
, OPT_TFTP_SECURE
, NULL
, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL
},
386 { LOPT_TFTP_MAX
, ARG_ONE
, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
387 { LOPT_NOBLOCK
, OPT_TFTP_NOBLOCK
, NULL
, gettext_noop("Disable the TFTP blocksize extension."), NULL
},
388 { LOPT_TFTP_LC
, OPT_TFTP_LC
, NULL
, gettext_noop("Convert TFTP filenames to lowercase"), NULL
},
389 { LOPT_TFTPPORTS
, ARG_ONE
, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL
},
390 { LOPT_LOG_OPTS
, OPT_LOG_OPTS
, NULL
, gettext_noop("Extra logging for DHCP."), NULL
},
391 { LOPT_MAX_LOGS
, ARG_ONE
, "[=<integer>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL
},
392 { LOPT_REBIND
, OPT_NO_REBIND
, NULL
, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL
},
393 { LOPT_LOC_REBND
, OPT_LOCAL_REBIND
, NULL
, gettext_noop("Allow rebinding of 127.0.0.0/8, for RBL servers."), NULL
},
394 { LOPT_NO_REBIND
, ARG_DUP
, "/<domain>/", gettext_noop("Inhibit DNS-rebind protection on this domain."), NULL
},
395 { LOPT_NOLAST
, OPT_ALL_SERVERS
, NULL
, gettext_noop("Always perform DNS queries to all servers."), NULL
},
396 { LOPT_MATCH
, ARG_DUP
, "set:<tag>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL
},
397 { LOPT_ALTPORT
, ARG_ONE
, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL
},
398 { LOPT_NAPTR
, ARG_DUP
, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL
},
399 { LOPT_MINPORT
, ARG_ONE
, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL
},
400 { LOPT_DHCP_FQDN
, OPT_DHCP_FQDN
, NULL
, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL
},
401 { LOPT_GEN_NAMES
, ARG_DUP
, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL
},
402 { LOPT_PROXY
, ARG_DUP
, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL
},
403 { LOPT_RELAY
, ARG_DUP
, "<local-addr>,<server>[,<interface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL
},
404 { LOPT_CNAME
, ARG_DUP
, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL
},
405 { LOPT_PXE_PROMT
, ARG_DUP
, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL
},
406 { LOPT_PXE_SERV
, ARG_DUP
, "<service>", gettext_noop("Boot service for PXE menu."), NULL
},
407 { LOPT_TEST
, 0, NULL
, gettext_noop("Check configuration syntax."), NULL
},
408 { LOPT_ADD_MAC
, OPT_ADD_MAC
, NULL
, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL
},
409 { LOPT_ADD_SBNET
, ARG_ONE
, "<v4 pref>[,<v6 pref>]", gettext_noop("Add requestor's IP subnet to forwarded DNS queries."), NULL
},
410 { LOPT_DNSSEC
, OPT_DNSSEC
, NULL
, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL
},
411 { LOPT_INCR_ADDR
, OPT_CONSEC_ADDR
, NULL
, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL
},
412 { LOPT_CONNTRACK
, OPT_CONNTRACK
, NULL
, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL
},
413 { LOPT_FQDN
, OPT_FQDN_UPDATE
, NULL
, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL
},
414 { LOPT_RA
, OPT_RA
, NULL
, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL
},
415 { LOPT_DUID
, ARG_ONE
, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL
},
416 { LOPT_HOST_REC
, ARG_DUP
, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL
},
417 { LOPT_RR
, ARG_DUP
, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL
},
418 { LOPT_CLVERBIND
, OPT_CLEVERBIND
, NULL
, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL
},
419 { LOPT_AUTHSERV
, ARG_ONE
, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL
},
420 { LOPT_AUTHZONE
, ARG_DUP
, "<domain>,[<subnet>...]", gettext_noop("Domain to export to global DNS"), NULL
},
421 { LOPT_AUTHTTL
, ARG_ONE
, "<integer>", gettext_noop("Set TTL for authoritative replies"), NULL
},
422 { LOPT_AUTHSOA
, ARG_ONE
, "<serial>[,...]", gettext_noop("Set authoritive zone information"), NULL
},
423 { LOPT_AUTHSFS
, ARG_DUP
, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL
},
424 { LOPT_AUTHPEER
, ARG_DUP
, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL
},
425 { LOPT_IPSET
, ARG_DUP
, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL
},
426 { LOPT_SYNTH
, ARG_DUP
, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL
},
427 #ifdef OPTION6_PREFIX_CLASS
428 { LOPT_PREF_CLSS
, ARG_DUP
, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL
},
430 { LOPT_RA_PARAM
, ARG_DUP
, "<interface>,[high,|low,]<interval>[,<lifetime>]", gettext_noop("Set priority, resend-interval and router-lifetime"), NULL
},
431 { LOPT_QUIET_DHCP
, OPT_QUIET_DHCP
, NULL
, gettext_noop("Do not log routine DHCP."), NULL
},
432 { LOPT_QUIET_DHCP6
, OPT_QUIET_DHCP6
, NULL
, gettext_noop("Do not log routine DHCPv6."), NULL
},
433 { LOPT_QUIET_RA
, OPT_QUIET_RA
, NULL
, gettext_noop("Do not log RA."), NULL
},
434 { 0, 0, NULL
, NULL
, NULL
}
437 /* We hide metacharaters in quoted strings by mapping them into the ASCII control
438 character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the
439 following sequence so that they map to themselves: it is therefore possible to call
440 unhide_metas repeatedly on string without breaking things.
441 The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a
442 couple of other places.
443 Note that space is included here so that
444 --dhcp-option=3, string
445 has five characters, whilst
446 --dhcp-option=3," string"
450 static const char meta
[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
452 static char hide_meta(char c
)
456 for (i
= 0; i
< (sizeof(meta
) - 1); i
++)
463 static char unhide_meta(char cr
)
467 if (c
< (sizeof(meta
) - 1))
473 static void unhide_metas(char *cp
)
477 *cp
= unhide_meta(*cp
);
480 static void *opt_malloc(size_t size
)
486 ret
= whine_malloc(size
);
491 ret
= safe_malloc(size
);
496 static char *opt_string_alloc(char *cp
)
500 if (cp
&& strlen(cp
) != 0)
502 ret
= opt_malloc(strlen(cp
)+1);
505 /* restore hidden metachars */
513 /* find next comma, split string with zero and eliminate spaces.
514 return start of string following comma */
516 static char *split_chr(char *s
, char c
)
520 if (!s
|| !(comma
= strchr(s
, c
)))
526 for (; *comma
== ' '; comma
++);
528 for (; (p
>= s
) && *p
== ' '; p
--)
534 static char *split(char *s
)
536 return split_chr(s
, ',');
539 static char *canonicalise_opt(char *s
)
548 if (!(ret
= canonicalise(s
, &nomem
)) && nomem
)
553 die(_("could not get memory"), NULL
, EC_NOMEM
);
559 static int atoi_check(char *a
, int *res
)
569 if (*p
< '0' || *p
> '9')
576 static int atoi_check16(char *a
, int *res
)
578 if (!(atoi_check(a
, res
)) ||
586 static void add_txt(char *name
, char *txt
)
588 size_t len
= strlen(txt
);
589 struct txt_record
*r
= opt_malloc(sizeof(struct txt_record
));
591 r
->name
= opt_string_alloc(name
);
592 r
->next
= daemon
->txt
;
595 r
->txt
= opt_malloc(len
+1);
598 memcpy((r
->txt
)+1, txt
, len
);
601 static void do_usage(void)
614 { '#', TFTP_MAX_CONNECTIONS
},
618 printf(_("Usage: dnsmasq [options]\n\n"));
619 #ifndef HAVE_GETOPT_LONG
620 printf(_("Use short options only on the command line.\n"));
622 printf(_("Valid options are:\n"));
624 for (i
= 0; usage
[i
].opt
!= 0; i
++)
626 char *desc
= usage
[i
].flagdesc
;
629 if (!desc
|| *desc
== '[')
635 for ( j
= 0; opts
[j
].name
; j
++)
636 if (opts
[j
].val
== usage
[i
].opt
)
638 if (usage
[i
].opt
< 256)
639 sprintf(buff
, "-%c, ", usage
[i
].opt
);
643 sprintf(buff
+4, "--%s%s%s", opts
[j
].name
, eq
, desc
);
644 printf("%-40.40s", buff
);
648 strcpy(buff
, usage
[i
].arg
);
649 for (j
= 0; tab
[j
].handle
; j
++)
650 if (tab
[j
].handle
== *(usage
[i
].arg
))
651 sprintf(buff
, "%d", tab
[j
].val
);
653 printf(_(usage
[i
].desc
), buff
);
658 #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
660 char *parse_server(char *arg
, union mysockaddr
*addr
, union mysockaddr
*source_addr
, char *interface
, int *flags
)
662 int source_port
= 0, serv_port
= NAMESERVER_PORT
;
663 char *portno
, *source
;
669 if ((source
= split_chr(arg
, '@')) && /* is there a source. */
670 (portno
= split_chr(source
, '#')) &&
671 !atoi_check16(portno
, &source_port
))
672 return _("bad port");
674 if ((portno
= split_chr(arg
, '#')) && /* is there a port no. */
675 !atoi_check16(portno
, &serv_port
))
676 return _("bad port");
679 scope_id
= split_chr(arg
, '%');
682 if (inet_pton(AF_INET
, arg
, &addr
->in
.sin_addr
) > 0)
684 addr
->in
.sin_port
= htons(serv_port
);
685 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET
;
686 #ifdef HAVE_SOCKADDR_SA_LEN
687 source_addr
->in
.sin_len
= addr
->in
.sin_len
= sizeof(struct sockaddr_in
);
689 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
690 source_addr
->in
.sin_port
= htons(daemon
->query_port
);
695 *flags
|= SERV_HAS_SOURCE
;
696 source_addr
->in
.sin_port
= htons(source_port
);
697 if (!(inet_pton(AF_INET
, source
, &source_addr
->in
.sin_addr
) > 0))
699 #if defined(SO_BINDTODEVICE)
700 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
701 strncpy(interface
, source
, IF_NAMESIZE
- 1);
703 return _("interface binding not supported");
709 else if (inet_pton(AF_INET6
, arg
, &addr
->in6
.sin6_addr
) > 0)
711 if (scope_id
&& (scope_index
= if_nametoindex(scope_id
)) == 0)
712 return _("bad interface name");
714 addr
->in6
.sin6_port
= htons(serv_port
);
715 addr
->in6
.sin6_scope_id
= scope_index
;
716 source_addr
->in6
.sin6_addr
= in6addr_any
;
717 source_addr
->in6
.sin6_port
= htons(daemon
->query_port
);
718 source_addr
->in6
.sin6_scope_id
= 0;
719 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET6
;
720 addr
->in6
.sin6_flowinfo
= source_addr
->in6
.sin6_flowinfo
= 0;
721 #ifdef HAVE_SOCKADDR_SA_LEN
722 addr
->in6
.sin6_len
= source_addr
->in6
.sin6_len
= sizeof(addr
->in6
);
727 *flags
|= SERV_HAS_SOURCE
;
728 source_addr
->in6
.sin6_port
= htons(source_port
);
729 if (inet_pton(AF_INET6
, source
, &source_addr
->in6
.sin6_addr
) == 0)
731 #if defined(SO_BINDTODEVICE)
732 source_addr
->in6
.sin6_addr
= in6addr_any
;
733 strncpy(interface
, source
, IF_NAMESIZE
- 1);
735 return _("interface binding not supported");
742 return _("bad address");
749 static int is_tag_prefix(char *arg
)
751 if (arg
&& (strstr(arg
, "net:") == arg
|| strstr(arg
, "tag:") == arg
))
757 static char *set_prefix(char *arg
)
759 if (strstr(arg
, "set:") == arg
)
765 /* This is too insanely large to keep in-line in the switch */
766 static int parse_dhcp_opt(char *errstr
, char *arg
, int flags
)
768 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
769 char lenchar
= 0, *cp
;
770 int addrs
, digs
, is_addr
, is_addr6
, is_hex
, is_dec
, is_string
, dots
;
772 struct dhcp_netid
*np
= NULL
;
787 for (cp
= arg
; *cp
; cp
++)
788 if (*cp
< '0' || *cp
> '9')
793 new->opt
= atoi(arg
);
799 if (strstr(arg
, "option:") == arg
)
801 if ((new->opt
= lookup_dhcp_opt(AF_INET
, arg
+7)) != -1)
803 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
804 /* option:<optname> must follow tag and vendor string. */
805 if (!(opt_len
& OT_INTERNAL
) || flags
== DHOPT_MATCH
)
811 else if (strstr(arg
, "option6:") == arg
)
813 for (cp
= arg
+8; *cp
; cp
++)
814 if (*cp
< '0' || *cp
> '9')
819 new->opt
= atoi(arg
+8);
825 if ((new->opt
= lookup_dhcp_opt(AF_INET6
, arg
+8)) != -1)
827 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
828 if (!(opt_len
& OT_INTERNAL
) || flags
== DHOPT_MATCH
)
832 /* option6:<opt>|<optname> must follow tag and vendor string. */
837 else if (strstr(arg
, "vendor:") == arg
)
839 new->u
.vendor_class
= (unsigned char *)opt_string_alloc(arg
+7);
840 new->flags
|= DHOPT_VENDOR
;
842 else if (strstr(arg
, "encap:") == arg
)
844 new->u
.encap
= atoi(arg
+6);
845 new->flags
|= DHOPT_ENCAPSULATE
;
847 else if (strstr(arg
, "vi-encap:") == arg
)
849 new->u
.encap
= atoi(arg
+9);
850 new->flags
|= DHOPT_RFC3925
;
851 if (flags
== DHOPT_MATCH
)
859 new->netid
= opt_malloc(sizeof (struct dhcp_netid
));
860 /* allow optional "net:" or "tag:" for consistency */
861 if (is_tag_prefix(arg
))
862 new->netid
->net
= opt_string_alloc(arg
+4);
864 new->netid
->net
= opt_string_alloc(set_prefix(arg
));
865 new->netid
->next
= np
;
875 if (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))
876 ret_err(_("unsupported encapsulation for IPv6 option"));
879 !(new->flags
& DHOPT_RFC3925
))
880 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
885 !(new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
| DHOPT_RFC3925
)))
886 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
888 /* option may be missing with rfc3925 match */
890 ret_err(_("bad dhcp-option"));
894 /* characterise the value */
897 is_addr
= is_addr6
= is_hex
= is_dec
= is_string
= 1;
900 for (cp
= comma
; (c
= *cp
); cp
++)
909 is_dec
= is_addr
= 0;
913 is_addr6
= is_dec
= is_hex
= 0;
914 if (cp
== comma
) /* leading / means a pathname */
919 is_addr6
= is_dec
= is_hex
= 0;
923 is_hex
= is_addr
= is_addr6
= 0;
926 else if (!(c
>='0' && c
<= '9'))
929 if (cp
[1] == 0 && is_dec
&&
930 (c
== 'b' || c
== 's' || c
== 'i'))
937 if (!((c
>='A' && c
<= 'F') ||
938 (c
>='a' && c
<= 'f') ||
939 (c
== '*' && (flags
& DHOPT_MATCH
))))
942 if (c
!= '[' && c
!= ']')
950 is_dec
= is_addr
= 0;
952 /* We know that some options take addresses */
953 if (opt_len
& OT_ADDR_LIST
)
955 is_string
= is_dec
= is_hex
= 0;
957 if (!is6
&& (!is_addr
|| dots
== 0))
958 ret_err(_("bad IP address"));
960 if (is6
&& !is_addr6
)
961 ret_err(_("bad IPv6 address"));
964 else if (opt_len
& (OT_NAME
| OT_RFC1035_NAME
| OT_CSTRING
))
965 is_addr6
= is_addr
= is_dec
= is_hex
= 0;
967 if (found_dig
&& (opt_len
& OT_TIME
) && strlen(comma
) > 0)
971 switch (comma
[strlen(comma
) - 1])
991 comma
[strlen(comma
) - 1] = 0;
995 new->val
= opt_malloc(4);
997 *((int *)new->val
) = htonl(val
* fac
);
999 else if (is_hex
&& digs
> 1)
1002 new->val
= opt_malloc(new->len
);
1003 parse_hex(comma
, new->val
, digs
, (flags
& DHOPT_MATCH
) ? &new->u
.wildcard_mask
: NULL
, NULL
);
1004 new->flags
|= DHOPT_HEX
;
1008 int i
, val
= atoi(comma
);
1009 /* assume numeric arg is 1 byte except for
1010 options where it is known otherwise.
1011 For vendor class option, we have to hack. */
1014 else if (val
& 0xffff0000)
1016 else if (val
& 0xff00)
1023 else if (lenchar
== 's')
1025 else if (lenchar
== 'i')
1028 new->val
= opt_malloc(new->len
);
1029 for (i
=0; i
<new->len
; i
++)
1030 new->val
[i
] = val
>>((new->len
- i
- 1)*8);
1032 else if (is_addr
&& !is6
)
1037 /* max length of address/subnet descriptor is five bytes,
1038 add one for the option 120 enc byte too */
1039 new->val
= op
= opt_malloc((5 * addrs
) + 1);
1040 new->flags
|= DHOPT_ADDR
;
1042 if (!(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)) &&
1043 new->opt
== OPTION_SIP_SERVER
)
1045 *(op
++) = 1; /* RFC 3361 "enc byte" */
1046 new->flags
&= ~DHOPT_ADDR
;
1052 slash
= split_chr(cp
, '/');
1053 inet_pton(AF_INET
, cp
, &in
);
1056 memcpy(op
, &in
, INADDRSZ
);
1061 unsigned char *p
= (unsigned char *)&in
;
1062 int netsize
= atoi(slash
);
1072 new->flags
&= ~DHOPT_ADDR
; /* cannot re-write descriptor format */
1075 new->len
= op
- new->val
;
1077 else if (is_addr6
&& is6
)
1080 new->val
= op
= opt_malloc(16 * addrs
);
1081 new->flags
|= DHOPT_ADDR6
;
1087 /* check for [1234::7] */
1090 if (strlen(cp
) > 1 && cp
[strlen(cp
)-1] == ']')
1091 cp
[strlen(cp
)-1] = 0;
1093 if (inet_pton(AF_INET6
, cp
, op
))
1099 ret_err(_("bad IPv6 address"));
1101 new->len
= op
- new->val
;
1106 if ((new->opt
== OPTION_DOMAIN_SEARCH
|| new->opt
== OPTION_SIP_SERVER
) &&
1107 !is6
&& !(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)))
1109 /* dns search, RFC 3397, or SIP, RFC 3361 */
1110 unsigned char *q
, *r
, *tail
;
1111 unsigned char *p
, *m
= NULL
, *newp
;
1112 size_t newlen
, len
= 0;
1113 int header_size
= (new->opt
== OPTION_DOMAIN_SEARCH
) ? 0 : 1;
1120 char *in
, *dom
= NULL
;
1122 /* Allow "." as an empty domain */
1123 if (strcmp (arg
, ".") != 0)
1125 if (!(dom
= canonicalise_opt(arg
)))
1126 ret_err(_("bad domain in dhcp-option"));
1128 domlen
= strlen(dom
) + 2;
1131 newp
= opt_malloc(len
+ domlen
+ header_size
);
1134 memcpy(newp
, m
, header_size
+ len
);
1138 p
= m
+ header_size
;
1141 /* add string on the end in RFC1035 format */
1142 for (in
= dom
; in
&& *in
;)
1144 unsigned char *cp
= q
++;
1146 for (j
= 0; *in
&& (*in
!= '.'); in
++, j
++)
1155 /* Now tail-compress using earlier names. */
1157 for (tail
= p
+ len
; *tail
; tail
+= (*tail
) + 1)
1158 for (r
= p
; r
- p
< (int)len
; r
+= (*r
) + 1)
1159 if (strcmp((char *)r
, (char *)tail
) == 0)
1161 PUTSHORT((r
- p
) | 0xc000, tail
);
1172 /* RFC 3361, enc byte is zero for names */
1173 if (new->opt
== OPTION_SIP_SERVER
)
1175 new->len
= (int) len
+ header_size
;
1179 else if (comma
&& (opt_len
& OT_CSTRING
))
1181 /* length fields are two bytes so need 16 bits for each string */
1183 unsigned char *p
, *newp
;
1185 for (i
= 0; comma
[i
]; i
++)
1186 if (comma
[i
] == ',')
1189 newp
= opt_malloc(strlen(comma
)+(2*commas
));
1196 u16 len
= strlen(arg
);
1199 memcpy(p
, arg
, len
);
1207 new->len
= p
- newp
;
1209 else if (comma
&& (opt_len
& OT_RFC1035_NAME
))
1211 unsigned char *p
= NULL
, *newp
, *end
;
1218 char *dom
= canonicalise_opt(arg
);
1220 ret_err(_("bad domain in dhcp-option"));
1222 newp
= opt_malloc(len
+ strlen(dom
) + 2);
1226 memcpy(newp
, p
, len
);
1231 end
= do_rfc1035_name(p
+ len
, dom
);
1246 new->len
= strlen(comma
);
1247 /* keep terminating zero on string */
1248 new->val
= (unsigned char *)opt_string_alloc(comma
);
1249 new->flags
|= DHOPT_STRING
;
1255 ((new->len
> 255) ||
1256 (new->len
> 253 && (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))) ||
1257 (new->len
> 250 && (new->flags
& DHOPT_RFC3925
))))
1258 ret_err(_("dhcp-option too long"));
1260 if (flags
== DHOPT_MATCH
)
1262 if ((new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
)) ||
1265 ret_err(_("illegal dhcp-match"));
1269 new->next
= daemon
->dhcp_match6
;
1270 daemon
->dhcp_match6
= new;
1274 new->next
= daemon
->dhcp_match
;
1275 daemon
->dhcp_match
= new;
1280 new->next
= daemon
->dhcp_opts6
;
1281 daemon
->dhcp_opts6
= new;
1285 new->next
= daemon
->dhcp_opts
;
1286 daemon
->dhcp_opts
= new;
1294 void set_option_bool(unsigned int opt
)
1297 daemon
->options
|= 1u << opt
;
1299 daemon
->options2
|= 1u << (opt
- 32);
1302 void reset_option_bool(unsigned int opt
)
1305 daemon
->options
&= ~(1u << opt
);
1307 daemon
->options2
&= ~(1u << (opt
- 32));
1310 static int one_opt(int option
, char *arg
, char *errstr
, char *gen_err
, int command_line
)
1318 for (i
=0; usage
[i
].opt
!= 0; i
++)
1319 if (usage
[i
].opt
== option
)
1321 int rept
= usage
[i
].rept
;
1326 if (rept
== ARG_USED_CL
)
1327 ret_err(_("illegal repeated flag"));
1328 if (rept
== ARG_ONE
)
1329 usage
[i
].rept
= ARG_USED_CL
;
1333 /* allow file to override command line */
1334 if (rept
== ARG_USED_FILE
)
1335 ret_err(_("illegal repeated keyword"));
1336 if (rept
== ARG_USED_CL
|| rept
== ARG_ONE
)
1337 usage
[i
].rept
= ARG_USED_FILE
;
1340 if (rept
!= ARG_DUP
&& rept
!= ARG_ONE
&& rept
!= ARG_USED_CL
)
1342 set_option_bool(rept
);
1351 case 'C': /* --conf-file */
1353 char *file
= opt_string_alloc(arg
);
1362 case '7': /* --conf-dir */
1366 char *directory
, *path
;
1370 } *ignore_suffix
= NULL
, *li
;
1373 if (!(directory
= opt_string_alloc(arg
)))
1376 for (arg
= comma
; arg
; arg
= comma
)
1379 li
= opt_malloc(sizeof(struct list
));
1380 li
->next
= ignore_suffix
;
1382 /* Have to copy: buffer is overwritten */
1383 li
->suffix
= opt_string_alloc(arg
);
1386 if (!(dir_stream
= opendir(directory
)))
1387 die(_("cannot access directory %s: %s"), directory
, EC_FILE
);
1389 while ((ent
= readdir(dir_stream
)))
1391 size_t len
= strlen(ent
->d_name
);
1394 /* ignore emacs backups and dotfiles */
1396 ent
->d_name
[len
- 1] == '~' ||
1397 (ent
->d_name
[0] == '#' && ent
->d_name
[len
- 1] == '#') ||
1398 ent
->d_name
[0] == '.')
1401 for (li
= ignore_suffix
; li
; li
= li
->next
)
1403 /* check for proscribed suffices */
1404 size_t ls
= strlen(li
->suffix
);
1406 strcmp(li
->suffix
, &ent
->d_name
[len
- ls
]) == 0)
1412 path
= opt_malloc(strlen(directory
) + len
+ 2);
1413 strcpy(path
, directory
);
1415 strcat(path
, ent
->d_name
);
1417 /* files must be readable */
1418 if (stat(path
, &buf
) == -1)
1419 die(_("cannot access %s: %s"), path
, EC_FILE
);
1421 /* only reg files allowed. */
1422 if (S_ISREG(buf
.st_mode
))
1428 closedir(dir_stream
);
1430 for(; ignore_suffix
; ignore_suffix
= li
)
1432 li
= ignore_suffix
->next
;
1433 free(ignore_suffix
->suffix
);
1434 free(ignore_suffix
);
1440 case LOPT_ADD_SBNET
: /* --add-subnet */
1441 set_option_bool(OPT_CLIENT_SUBNET
);
1445 if (!atoi_check(arg
, &daemon
->addr4_netmask
) ||
1446 (comma
&& !atoi_check(comma
, &daemon
->addr6_netmask
)))
1451 case '1': /* --enable-dbus */
1452 set_option_bool(OPT_DBUS
);
1454 daemon
->dbus_name
= opt_string_alloc(arg
);
1456 daemon
->dbus_name
= DNSMASQ_SERVICE
;
1459 case '8': /* --log-facility */
1460 /* may be a filename */
1461 if (strchr(arg
, '/') || strcmp (arg
, "-") == 0)
1462 daemon
->log_file
= opt_string_alloc(arg
);
1466 ret_err(_("setting log facility is not possible under Android"));
1468 for (i
= 0; facilitynames
[i
].c_name
; i
++)
1469 if (hostname_isequal((char *)facilitynames
[i
].c_name
, arg
))
1472 if (facilitynames
[i
].c_name
)
1473 daemon
->log_fac
= facilitynames
[i
].c_val
;
1475 ret_err(_("bad log facility"));
1480 case 'x': /* --pid-file */
1481 daemon
->runfile
= opt_string_alloc(arg
);
1484 case 'r': /* --resolv-file */
1486 char *name
= opt_string_alloc(arg
);
1487 struct resolvc
*new, *list
= daemon
->resolv_files
;
1489 if (list
&& list
->is_default
)
1491 /* replace default resolv file - possibly with nothing */
1494 list
->is_default
= 0;
1502 new = opt_malloc(sizeof(struct resolvc
));
1505 new->is_default
= 0;
1510 daemon
->resolv_files
= list
;
1514 case 'm': /* --mx-host */
1517 struct mx_srv_record
*new;
1518 char *name
, *target
= NULL
;
1520 if ((comma
= split(arg
)))
1523 if ((prefstr
= split(comma
)) && !atoi_check16(prefstr
, &pref
))
1524 ret_err(_("bad MX preference"));
1527 if (!(name
= canonicalise_opt(arg
)) ||
1528 (comma
&& !(target
= canonicalise_opt(comma
))))
1529 ret_err(_("bad MX name"));
1531 new = opt_malloc(sizeof(struct mx_srv_record
));
1532 new->next
= daemon
->mxnames
;
1533 daemon
->mxnames
= new;
1536 new->target
= target
; /* may be NULL */
1541 case 't': /* --mx-target */
1542 if (!(daemon
->mxtarget
= canonicalise_opt(arg
)))
1543 ret_err(_("bad MX target"));
1547 case 'l': /* --dhcp-leasefile */
1548 daemon
->lease_file
= opt_string_alloc(arg
);
1551 /* Sorry about the gross pre-processor abuse */
1552 case '6': /* --dhcp-script */
1553 case LOPT_LUASCRIPT
: /* --dhcp-luascript */
1554 # if defined(NO_FORK)
1555 ret_err(_("cannot run scripts under uClinux"));
1556 # elif !defined(HAVE_SCRIPT)
1557 ret_err(_("recompile with HAVE_SCRIPT defined to enable lease-change scripts"));
1559 if (option
== LOPT_LUASCRIPT
)
1560 # if !defined(HAVE_LUASCRIPT)
1561 ret_err(_("recompile with HAVE_LUASCRIPT defined to enable Lua scripts"));
1563 daemon
->luascript
= opt_string_alloc(arg
);
1566 daemon
->lease_change_command
= opt_string_alloc(arg
);
1569 #endif /* HAVE_DHCP */
1571 case LOPT_DHCP_HOST
: /* --dhcp-hostfile */
1572 case LOPT_DHCP_OPTS
: /* --dhcp-optsfile */
1573 case 'H': /* --addn-hosts */
1575 struct hostsfile
*new = opt_malloc(sizeof(struct hostsfile
));
1576 static int hosts_index
= 1;
1577 new->fname
= opt_string_alloc(arg
);
1578 new->index
= hosts_index
++;
1582 new->next
= daemon
->addn_hosts
;
1583 daemon
->addn_hosts
= new;
1585 else if (option
== LOPT_DHCP_HOST
)
1587 new->next
= daemon
->dhcp_hosts_file
;
1588 daemon
->dhcp_hosts_file
= new;
1590 else if (option
== LOPT_DHCP_OPTS
)
1592 new->next
= daemon
->dhcp_opts_file
;
1593 daemon
->dhcp_opts_file
= new;
1600 case LOPT_AUTHSERV
: /* --auth-server */
1601 if (!(comma
= split(arg
)))
1604 daemon
->authserver
= opt_string_alloc(arg
);
1607 struct iname
*new = opt_malloc(sizeof(struct iname
));
1611 if (inet_pton(AF_INET
, arg
, &new->addr
.in
.sin_addr
) > 0)
1612 new->addr
.sa
.sa_family
= AF_INET
;
1614 else if (inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
1615 new->addr
.sa
.sa_family
= AF_INET6
;
1618 new->name
= opt_string_alloc(arg
);
1620 new->next
= daemon
->authinterface
;
1621 daemon
->authinterface
= new;
1628 case LOPT_AUTHSFS
: /* --auth-sec-servers */
1630 struct name_list
*new;
1634 new = opt_malloc(sizeof(struct name_list
));
1635 new->name
= opt_string_alloc(arg
);
1636 new->next
= daemon
->secondary_forward_server
;
1637 daemon
->secondary_forward_server
= new;
1643 case LOPT_AUTHZONE
: /* --auth-zone */
1645 struct auth_zone
*new;
1649 new = opt_malloc(sizeof(struct auth_zone
));
1650 new->domain
= opt_string_alloc(arg
);
1652 new->next
= daemon
->auth_zones
;
1653 daemon
->auth_zones
= new;
1655 while ((arg
= comma
))
1659 struct subnet
*subnet
= opt_malloc(sizeof(struct subnet
));
1661 subnet
->next
= new->subnet
;
1662 new->subnet
= subnet
;
1665 prefix
= split_chr(arg
, '/');
1667 if (prefix
&& !atoi_check(prefix
, &prefixlen
))
1670 if (inet_pton(AF_INET
, arg
, &subnet
->addr4
))
1672 subnet
->prefixlen
= (prefixlen
== 0) ? 24 : prefixlen
;
1676 else if (inet_pton(AF_INET6
, arg
, &subnet
->addr6
))
1678 subnet
->prefixlen
= (prefixlen
== 0) ? 64 : prefixlen
;
1688 case LOPT_AUTHSOA
: /* --auth-soa */
1690 daemon
->soa_sn
= (u32
)atoi(arg
);
1696 daemon
->hostmaster
= opt_string_alloc(arg
);
1697 for (cp
= daemon
->hostmaster
; *cp
; cp
++)
1705 daemon
->soa_refresh
= (u32
)atoi(arg
);
1710 daemon
->soa_retry
= (u32
)atoi(arg
);
1715 daemon
->soa_expiry
= (u32
)atoi(arg
);
1724 case 's': /* --domain */
1725 case LOPT_SYNTH
: /* --synth-domain */
1726 if (strcmp (arg
, "#") == 0)
1727 set_option_bool(OPT_RESOLV_DOMAIN
);
1732 if (!(d
= canonicalise_opt(arg
)))
1738 struct cond_domain
*new = opt_malloc(sizeof(struct cond_domain
));
1743 unhide_metas(comma
);
1744 if ((netpart
= split_chr(comma
, '/')))
1748 arg
= split(netpart
);
1749 if (!atoi_check(netpart
, &msize
))
1751 else if (inet_pton(AF_INET
, comma
, &new->start
))
1753 int mask
= (1 << (32 - msize
)) - 1;
1755 new->start
.s_addr
= ntohl(htonl(new->start
.s_addr
) & ~mask
);
1756 new->end
.s_addr
= new->start
.s_addr
| htonl(mask
);
1761 if (!(new->prefix
= canonicalise_opt(arg
)) ||
1762 strlen(new->prefix
) > MAXLABEL
- INET_ADDRSTRLEN
)
1763 ret_err(_("bad prefix"));
1765 else if (strcmp(arg
, "local") != 0 ||
1766 (msize
!= 8 && msize
!= 16 && msize
!= 24))
1770 /* generate the equivalent of
1772 local=/xxx.yyy.zzz.in-addr.arpa/ */
1773 struct server
*serv
= opt_malloc(sizeof(struct server
));
1774 in_addr_t a
= ntohl(new->start
.s_addr
) >> 8;
1777 memset(serv
, 0, sizeof(struct server
));
1779 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1780 serv
->next
= daemon
->servers
;
1781 daemon
->servers
= serv
;
1783 serv
= opt_malloc(sizeof(struct server
));
1784 memset(serv
, 0, sizeof(struct server
));
1785 p
= serv
->domain
= opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */
1788 p
+= sprintf(p
, "%d.", a
& 0xff);
1791 p
+= sprintf(p
, "%d.", a
& 0xff);
1793 p
+= sprintf(p
, "%d.in-addr.arpa", a
& 0xff);
1795 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1796 serv
->next
= daemon
->servers
;
1797 daemon
->servers
= serv
;
1802 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1804 u64 mask
= (1LLU << (128 - msize
)) - 1LLU;
1805 u64 addrpart
= addr6part(&new->start6
);
1808 /* prefix==64 overflows the mask calculation above */
1812 new->end6
= new->start6
;
1813 setaddr6part(&new->start6
, addrpart
& ~mask
);
1814 setaddr6part(&new->end6
, addrpart
| mask
);
1822 if (!(new->prefix
= canonicalise_opt(arg
)) ||
1823 strlen(new->prefix
) > MAXLABEL
- INET6_ADDRSTRLEN
)
1824 ret_err(_("bad prefix"));
1826 else if (strcmp(arg
, "local") != 0 || ((msize
& 4) != 0))
1830 /* generate the equivalent of
1832 local=/xxx.yyy.zzz.ip6.arpa/ */
1833 struct server
*serv
= opt_malloc(sizeof(struct server
));
1836 memset(serv
, 0, sizeof(struct server
));
1838 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1839 serv
->next
= daemon
->servers
;
1840 daemon
->servers
= serv
;
1842 serv
= opt_malloc(sizeof(struct server
));
1843 memset(serv
, 0, sizeof(struct server
));
1844 p
= serv
->domain
= opt_malloc(73); /* strlen("32*<n.>ip6.arpa")+1 */
1846 for (i
= msize
-1; i
>= 0; i
-= 4)
1848 int dig
= ((unsigned char *)&new->start6
)[i
>>3];
1849 p
+= sprintf(p
, "%.1x.", (i
>>2) & 1 ? dig
& 15 : dig
>> 4);
1851 p
+= sprintf(p
, "ip6.arpa");
1853 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1854 serv
->next
= daemon
->servers
;
1855 daemon
->servers
= serv
;
1867 prefstr
= split(arg
);
1869 if (inet_pton(AF_INET
, comma
, &new->start
))
1873 new->end
.s_addr
= new->start
.s_addr
;
1874 else if (!inet_pton(AF_INET
, arg
, &new->end
))
1878 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1882 memcpy(&new->end6
, &new->start6
, IN6ADDRSZ
);
1883 else if (!inet_pton(AF_INET6
, arg
, &new->end6
))
1890 if (option
!= 's' && prefstr
)
1892 if (!(new->prefix
= canonicalise_opt(prefstr
)) ||
1893 strlen(new->prefix
) > MAXLABEL
- INET_ADDRSTRLEN
)
1894 ret_err(_("bad prefix"));
1901 new->next
= daemon
->cond_domain
;
1902 daemon
->cond_domain
= new;
1906 new->next
= daemon
->synth_domains
;
1907 daemon
->synth_domains
= new;
1910 else if (option
== 's')
1911 daemon
->domain_suffix
= d
;
1918 case 'u': /* --user */
1919 daemon
->username
= opt_string_alloc(arg
);
1922 case 'g': /* --group */
1923 daemon
->groupname
= opt_string_alloc(arg
);
1924 daemon
->group_set
= 1;
1928 case LOPT_SCRIPTUSR
: /* --scriptuser */
1929 daemon
->scriptuser
= opt_string_alloc(arg
);
1933 case 'i': /* --interface */
1935 struct iname
*new = opt_malloc(sizeof(struct iname
));
1937 new->next
= daemon
->if_names
;
1938 daemon
->if_names
= new;
1939 /* new->name may be NULL if someone does
1940 "interface=" to disable all interfaces except loop. */
1941 new->name
= opt_string_alloc(arg
);
1947 case LOPT_TFTP
: /* --enable-tftp */
1948 set_option_bool(OPT_TFTP
);
1953 case 'I': /* --except-interface */
1954 case '2': /* --no-dhcp-interface */
1956 struct iname
*new = opt_malloc(sizeof(struct iname
));
1958 new->name
= opt_string_alloc(arg
);
1961 new->next
= daemon
->if_except
;
1962 daemon
->if_except
= new;
1964 else if (option
== LOPT_TFTP
)
1966 new->next
= daemon
->tftp_interfaces
;
1967 daemon
->tftp_interfaces
= new;
1971 new->next
= daemon
->dhcp_except
;
1972 daemon
->dhcp_except
= new;
1978 case 'B': /* --bogus-nxdomain */
1980 struct in_addr addr
;
1982 if (arg
&& (inet_pton(AF_INET
, arg
, &addr
) > 0))
1984 struct bogus_addr
*baddr
= opt_malloc(sizeof(struct bogus_addr
));
1985 baddr
->next
= daemon
->bogus_addr
;
1986 daemon
->bogus_addr
= baddr
;
1990 ret_err(gen_err
); /* error */
1994 case 'a': /* --listen-address */
1995 case LOPT_AUTHPEER
: /* --auth-peer */
1997 struct iname
*new = opt_malloc(sizeof(struct iname
));
2000 if (arg
&& (inet_pton(AF_INET
, arg
, &new->addr
.in
.sin_addr
) > 0))
2002 new->addr
.sa
.sa_family
= AF_INET
;
2003 new->addr
.in
.sin_port
= 0;
2004 #ifdef HAVE_SOCKADDR_SA_LEN
2005 new->addr
.in
.sin_len
= sizeof(new->addr
.in
);
2009 else if (arg
&& inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
2011 new->addr
.sa
.sa_family
= AF_INET6
;
2012 new->addr
.in6
.sin6_flowinfo
= 0;
2013 new->addr
.in6
.sin6_scope_id
= 0;
2014 new->addr
.in6
.sin6_port
= 0;
2015 #ifdef HAVE_SOCKADDR_SA_LEN
2016 new->addr
.in6
.sin6_len
= sizeof(new->addr
.in6
);
2026 new->next
= daemon
->if_addrs
;
2027 daemon
->if_addrs
= new;
2031 new->next
= daemon
->auth_peers
;
2032 daemon
->auth_peers
= new;
2038 case 'S': /* --server */
2039 case LOPT_LOCAL
: /* --local */
2040 case 'A': /* --address */
2041 case LOPT_NO_REBIND
: /* --rebind-domain-ok */
2043 struct server
*serv
, *newlist
= NULL
;
2047 if (arg
&& (*arg
== '/' || option
== LOPT_NO_REBIND
))
2049 int rebind
= !(*arg
== '/');
2053 while (rebind
|| (end
= split_chr(arg
, '/')))
2055 char *domain
= NULL
;
2056 /* elide leading dots - they are implied in the search algorithm */
2057 while (*arg
== '.') arg
++;
2058 /* # matches everything and becomes a zero length domain string */
2059 if (strcmp(arg
, "#") == 0)
2061 else if (strlen (arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
2063 serv
= opt_malloc(sizeof(struct server
));
2064 memset(serv
, 0, sizeof(struct server
));
2065 serv
->next
= newlist
;
2067 serv
->domain
= domain
;
2068 serv
->flags
= domain
? SERV_HAS_DOMAIN
: SERV_FOR_NODOTS
;
2078 newlist
= opt_malloc(sizeof(struct server
));
2079 memset(newlist
, 0, sizeof(struct server
));
2084 newlist
->flags
|= SERV_LITERAL_ADDRESS
;
2085 if (!(newlist
->flags
& SERV_TYPE
))
2088 else if (option
== LOPT_NO_REBIND
)
2089 newlist
->flags
|= SERV_NO_REBIND
;
2093 if (!(newlist
->flags
& SERV_NO_REBIND
))
2094 newlist
->flags
|= SERV_NO_ADDR
; /* no server */
2095 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
2099 else if (strcmp(arg
, "#") == 0)
2101 newlist
->flags
|= SERV_USE_RESOLV
; /* treat in ordinary way */
2102 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
2107 char *err
= parse_server(arg
, &newlist
->addr
, &newlist
->source_addr
, newlist
->interface
, &newlist
->flags
);
2115 serv
->next
->flags
= serv
->flags
;
2116 serv
->next
->addr
= serv
->addr
;
2117 serv
->next
->source_addr
= serv
->source_addr
;
2118 strcpy(serv
->next
->interface
, serv
->interface
);
2121 serv
->next
= daemon
->servers
;
2122 daemon
->servers
= newlist
;
2126 case LOPT_IPSET
: /* --ipset */
2128 ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
2132 struct ipsets ipsets_head
;
2133 struct ipsets
*ipsets
= &ipsets_head
;
2136 char **sets
, **sets_pos
;
2137 memset(ipsets
, 0, sizeof(struct ipsets
));
2139 if (arg
&& *arg
== '/')
2142 while ((end
= split_chr(arg
, '/')))
2144 char *domain
= NULL
;
2145 /* elide leading dots - they are implied in the search algorithm */
2148 /* # matches everything and becomes a zero length domain string */
2149 if (strcmp(arg
, "#") == 0 || !*arg
)
2151 else if (strlen(arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
2153 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2154 ipsets
= ipsets
->next
;
2155 memset(ipsets
, 0, sizeof(struct ipsets
));
2156 ipsets
->domain
= domain
;
2162 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2163 ipsets
= ipsets
->next
;
2164 memset(ipsets
, 0, sizeof(struct ipsets
));
2165 ipsets
->domain
= "";
2173 for (end
= arg
; *end
; ++end
)
2177 sets
= sets_pos
= opt_malloc(sizeof(char *) * size
);
2181 *sets_pos
++ = opt_string_alloc(arg
);
2185 for (ipsets
= &ipsets_head
; ipsets
->next
; ipsets
= ipsets
->next
)
2186 ipsets
->next
->sets
= sets
;
2187 ipsets
->next
= daemon
->ipsets
;
2188 daemon
->ipsets
= ipsets_head
.next
;
2194 case 'c': /* --cache-size */
2198 if (!atoi_check(arg
, &size
))
2202 /* zero is OK, and means no caching. */
2206 else if (size
> 10000)
2209 daemon
->cachesize
= size
;
2214 case 'p': /* --port */
2215 if (!atoi_check16(arg
, &daemon
->port
))
2219 case LOPT_MINPORT
: /* --min-port */
2220 if (!atoi_check16(arg
, &daemon
->min_port
))
2224 case '0': /* --dns-forward-max */
2225 if (!atoi_check(arg
, &daemon
->ftabsize
))
2229 case LOPT_MAX_LOGS
: /* --log-async */
2230 daemon
->max_logs
= LOG_MAX
; /* default */
2231 if (arg
&& !atoi_check(arg
, &daemon
->max_logs
))
2233 else if (daemon
->max_logs
> 100)
2234 daemon
->max_logs
= 100;
2237 case 'P': /* --edns-packet-max */
2240 if (!atoi_check(arg
, &i
))
2242 daemon
->edns_pktsz
= (unsigned short)i
;
2246 case 'Q': /* --query-port */
2247 if (!atoi_check16(arg
, &daemon
->query_port
))
2249 /* if explicitly set to zero, use single OS ephemeral port
2250 and disable random ports */
2251 if (daemon
->query_port
== 0)
2255 case 'T': /* --local-ttl */
2256 case LOPT_NEGTTL
: /* --neg-ttl */
2257 case LOPT_MAXTTL
: /* --max-ttl */
2258 case LOPT_MAXCTTL
: /* --max-cache-ttl */
2259 case LOPT_AUTHTTL
: /* --auth-ttl */
2262 if (!atoi_check(arg
, &ttl
))
2264 else if (option
== LOPT_NEGTTL
)
2265 daemon
->neg_ttl
= (unsigned long)ttl
;
2266 else if (option
== LOPT_MAXTTL
)
2267 daemon
->max_ttl
= (unsigned long)ttl
;
2268 else if (option
== LOPT_MAXCTTL
)
2269 daemon
->max_cache_ttl
= (unsigned long)ttl
;
2270 else if (option
== LOPT_AUTHTTL
)
2271 daemon
->auth_ttl
= (unsigned long)ttl
;
2273 daemon
->local_ttl
= (unsigned long)ttl
;
2278 case 'X': /* --dhcp-lease-max */
2279 if (!atoi_check(arg
, &daemon
->dhcp_max
))
2285 case LOPT_TFTP_MAX
: /* --tftp-max */
2286 if (!atoi_check(arg
, &daemon
->tftp_max
))
2290 case LOPT_PREFIX
: /* --tftp-prefix */
2294 struct tftp_prefix
*new = opt_malloc(sizeof(struct tftp_prefix
));
2295 new->interface
= opt_string_alloc(comma
);
2296 new->prefix
= opt_string_alloc(arg
);
2297 new->next
= daemon
->if_prefix
;
2298 daemon
->if_prefix
= new;
2301 daemon
->tftp_prefix
= opt_string_alloc(arg
);
2304 case LOPT_TFTPPORTS
: /* --tftp-port-range */
2305 if (!(comma
= split(arg
)) ||
2306 !atoi_check16(arg
, &daemon
->start_tftp_port
) ||
2307 !atoi_check16(comma
, &daemon
->end_tftp_port
))
2308 ret_err(_("bad port range"));
2310 if (daemon
->start_tftp_port
> daemon
->end_tftp_port
)
2312 int tmp
= daemon
->start_tftp_port
;
2313 daemon
->start_tftp_port
= daemon
->end_tftp_port
;
2314 daemon
->end_tftp_port
= tmp
;
2320 case LOPT_BRIDGE
: /* --bridge-interface */
2322 struct dhcp_bridge
*new = opt_malloc(sizeof(struct dhcp_bridge
));
2323 if (!(comma
= split(arg
)) || strlen(arg
) > IF_NAMESIZE
- 1 )
2324 ret_err(_("bad bridge-interface"));
2326 strcpy(new->iface
, arg
);
2328 new->next
= daemon
->bridges
;
2329 daemon
->bridges
= new;
2334 if (strlen(arg
) != 0 && strlen(arg
) <= IF_NAMESIZE
- 1)
2336 struct dhcp_bridge
*b
= opt_malloc(sizeof(struct dhcp_bridge
));
2337 b
->next
= new->alias
;
2339 strcpy(b
->iface
, arg
);
2347 case 'F': /* --dhcp-range */
2349 int k
, leasepos
= 2;
2350 char *cp
, *a
[8] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2351 struct dhcp_context
*new = opt_malloc(sizeof(struct dhcp_context
));
2353 memset (new, 0, sizeof(*new));
2354 new->lease_time
= DEFLEASE
;
2364 for (cp
= arg
; *cp
; cp
++)
2365 if (!(*cp
== ' ' || *cp
== '.' || *cp
== ':' ||
2366 (*cp
>= 'a' && *cp
<= 'f') || (*cp
>= 'A' && *cp
<= 'F') ||
2367 (*cp
>='0' && *cp
<= '9')))
2370 if (*cp
!= ',' && (comma
= split(arg
)))
2372 if (is_tag_prefix(arg
))
2374 struct dhcp_netid
*tt
= opt_malloc(sizeof (struct dhcp_netid
));
2375 tt
->net
= opt_string_alloc(arg
+4);
2376 tt
->next
= new->filter
;
2377 /* ignore empty tag */
2384 ret_err(_("only one tag allowed"));
2385 else if (strstr(arg
, "set:") == arg
)
2386 new->netid
.net
= opt_string_alloc(arg
+4);
2388 new->netid
.net
= opt_string_alloc(arg
);
2399 for (k
= 1; k
< 8; k
++)
2400 if (!(a
[k
] = split(a
[k
-1])))
2404 ret_err(_("bad dhcp-range"));
2406 if (inet_pton(AF_INET
, a
[0], &new->start
))
2408 new->next
= daemon
->dhcp
;
2410 new->end
= new->start
;
2411 if (strcmp(a
[1], "static") == 0)
2412 new->flags
|= CONTEXT_STATIC
;
2413 else if (strcmp(a
[1], "proxy") == 0)
2414 new->flags
|= CONTEXT_PROXY
;
2415 else if (!inet_pton(AF_INET
, a
[1], &new->end
))
2416 ret_err(_("bad dhcp-range"));
2418 if (ntohl(new->start
.s_addr
) > ntohl(new->end
.s_addr
))
2420 struct in_addr tmp
= new->start
;
2421 new->start
= new->end
;
2425 if (k
>= 3 && strchr(a
[2], '.') &&
2426 (inet_pton(AF_INET
, a
[2], &new->netmask
) > 0))
2428 new->flags
|= CONTEXT_NETMASK
;
2430 if (!is_same_net(new->start
, new->end
, new->netmask
))
2431 ret_err(_("inconsistent DHCP range"));
2434 if (k
>= 4 && strchr(a
[3], '.') &&
2435 (inet_pton(AF_INET
, a
[3], &new->broadcast
) > 0))
2437 new->flags
|= CONTEXT_BRDCAST
;
2442 else if (inet_pton(AF_INET6
, a
[0], &new->start6
))
2444 new->flags
|= CONTEXT_V6
;
2445 new->prefix
= 64; /* default */
2446 new->end6
= new->start6
;
2447 new->next
= daemon
->dhcp6
;
2448 daemon
->dhcp6
= new;
2450 for (leasepos
= 1; leasepos
< k
; leasepos
++)
2452 if (strcmp(a
[leasepos
], "static") == 0)
2453 new->flags
|= CONTEXT_STATIC
| CONTEXT_DHCP
;
2454 else if (strcmp(a
[leasepos
], "ra-only") == 0 || strcmp(a
[leasepos
], "slaac") == 0 )
2455 new->flags
|= CONTEXT_RA_ONLY
| CONTEXT_RA
;
2456 else if (strcmp(a
[leasepos
], "ra-names") == 0)
2457 new->flags
|= CONTEXT_RA_NAME
| CONTEXT_RA
;
2458 else if (strcmp(a
[leasepos
], "ra-stateless") == 0)
2459 new->flags
|= CONTEXT_RA_STATELESS
| CONTEXT_DHCP
| CONTEXT_RA
;
2460 else if (leasepos
== 1 && inet_pton(AF_INET6
, a
[leasepos
], &new->end6
))
2461 new->flags
|= CONTEXT_DHCP
;
2462 else if (strstr(a
[leasepos
], "constructor:") == a
[leasepos
])
2464 new->template_interface
= opt_string_alloc(a
[leasepos
] + 12);
2465 new->flags
|= CONTEXT_TEMPLATE
;
2467 else if (strstr(a
[leasepos
], "constructor-noauth:") == a
[leasepos
])
2469 new->template_interface
= opt_string_alloc(a
[leasepos
] + 19);
2470 new->flags
|= CONTEXT_TEMPLATE
| CONTEXT_NOAUTH
;
2476 /* bare integer < 128 is prefix value */
2480 for (cp
= a
[leasepos
]; *cp
; cp
++)
2481 if (!(*cp
>= '0' && *cp
<= '9'))
2483 if (!*cp
&& (pref
= atoi(a
[leasepos
])) <= 128)
2490 if (new->prefix
!= 64)
2492 if ((new->flags
& (CONTEXT_RA_ONLY
| CONTEXT_RA_NAME
| CONTEXT_RA_STATELESS
)))
2493 ret_err(_("prefix length must be exactly 64 for RA subnets"));
2494 else if (new->flags
& CONTEXT_TEMPLATE
)
2495 ret_err(_("prefix length must be exactly 64 for subnet constructors"));
2498 if (new->prefix
< 64)
2499 ret_err(_("prefix length must be at least 64"));
2501 if (!is_same_net6(&new->start6
, &new->end6
, new->prefix
))
2502 ret_err(_("inconsistent DHCPv6 range"));
2504 /* dhcp-range=:: enables DHCP stateless on any interface */
2505 if (IN6_IS_ADDR_UNSPECIFIED(&new->start6
) && !(new->flags
& CONTEXT_TEMPLATE
))
2508 if (new->flags
& CONTEXT_TEMPLATE
)
2510 struct in6_addr zero
;
2511 memset(&zero
, 0, sizeof(zero
));
2512 if (!is_same_net6(&zero
, &new->start6
, new->prefix
))
2513 ret_err(_("prefix must be zero with \"constructor:\" argument"));
2516 if (addr6part(&new->start6
) > addr6part(&new->end6
))
2518 struct in6_addr tmp
= new->start6
;
2519 new->start6
= new->end6
;
2525 ret_err(_("bad dhcp-range"));
2529 if (strcmp(a
[leasepos
], "infinite") == 0)
2530 new->lease_time
= 0xffffffff;
2531 else if (strcmp(a
[leasepos
], "deprecated") == 0)
2532 new->flags
|= CONTEXT_DEPRECATE
;
2536 if (strlen(a
[leasepos
]) > 0)
2538 switch (a
[leasepos
][strlen(a
[leasepos
]) - 1])
2558 a
[leasepos
][strlen(a
[leasepos
]) - 1] = 0;
2561 for (cp
= a
[leasepos
]; *cp
; cp
++)
2562 if (!(*cp
>= '0' && *cp
<= '9'))
2565 if (*cp
|| (leasepos
+1 < k
))
2566 ret_err(_("bad dhcp-range"));
2568 new->lease_time
= atoi(a
[leasepos
]) * fac
;
2569 /* Leases of a minute or less confuse
2570 some clients, notably Apple's */
2571 if (new->lease_time
< 120)
2572 new->lease_time
= 120;
2580 case 'G': /* --dhcp-host */
2583 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2584 struct dhcp_config
*new;
2587 new = opt_malloc(sizeof(struct dhcp_config
));
2589 new->next
= daemon
->dhcp_conf
;
2590 new->flags
= (option
== LOPT_BANK
) ? CONFIG_BANK
: 0;
2595 for (k
= 1; k
< 7; k
++)
2596 if (!(a
[k
] = split(a
[k
-1])))
2599 for (j
= 0; j
< k
; j
++)
2600 if (strchr(a
[j
], ':')) /* ethernet address, netid or binary CLID */
2604 if ((arg
[0] == 'i' || arg
[0] == 'I') &&
2605 (arg
[1] == 'd' || arg
[1] == 'D') &&
2609 new->flags
|= CONFIG_NOCLID
;
2613 arg
+= 3; /* dump id: */
2614 if (strchr(arg
, ':'))
2615 len
= parse_hex(arg
, (unsigned char *)arg
, -1, NULL
, NULL
);
2619 len
= (int) strlen(arg
);
2624 ret_err(_("bad hex constant"));
2625 else if ((new->clid
= opt_malloc(len
)))
2627 new->flags
|= CONFIG_CLID
;
2628 new->clid_len
= len
;
2629 memcpy(new->clid
, arg
, len
);
2633 /* dhcp-host has strange backwards-compat needs. */
2634 else if (strstr(arg
, "net:") == arg
|| strstr(arg
, "set:") == arg
)
2636 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2637 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2638 newtag
->net
= opt_malloc(strlen(arg
+ 4) + 1);
2639 newlist
->next
= new->netid
;
2640 new->netid
= newlist
;
2641 newlist
->list
= newtag
;
2642 strcpy(newtag
->net
, arg
+4);
2643 unhide_metas(newtag
->net
);
2645 else if (strstr(arg
, "tag:") == arg
)
2646 ret_err(_("cannot match tags in --dhcp-host"));
2648 else if (arg
[0] == '[' && arg
[strlen(arg
)-1] == ']')
2650 arg
[strlen(arg
)-1] = 0;
2653 if (!inet_pton(AF_INET6
, arg
, &new->addr6
))
2654 ret_err(_("bad IPv6 address"));
2656 for (i
= 0; i
< 8; i
++)
2657 if (new->addr6
.s6_addr
[i
] != 0)
2660 /* set WILDCARD if network part all zeros */
2662 new->flags
|= CONFIG_WILDCARD
;
2664 new->flags
|= CONFIG_ADDR6
;
2669 struct hwaddr_config
*newhw
= opt_malloc(sizeof(struct hwaddr_config
));
2670 if ((newhw
->hwaddr_len
= parse_hex(a
[j
], newhw
->hwaddr
, DHCP_CHADDR_MAX
,
2671 &newhw
->wildcard_mask
, &newhw
->hwaddr_type
)) == -1)
2672 ret_err(_("bad hex constant"));
2676 newhw
->next
= new->hwaddr
;
2677 new->hwaddr
= newhw
;
2681 else if (strchr(a
[j
], '.') && (inet_pton(AF_INET
, a
[j
], &in
) > 0))
2683 struct dhcp_config
*configs
;
2686 new->flags
|= CONFIG_ADDR
;
2688 /* If the same IP appears in more than one host config, then DISCOVER
2689 for one of the hosts will get the address, but REQUEST will be NAKed,
2690 since the address is reserved by the other one -> protocol loop. */
2691 for (configs
= daemon
->dhcp_conf
; configs
; configs
= configs
->next
)
2692 if ((configs
->flags
& CONFIG_ADDR
) && configs
->addr
.s_addr
== in
.s_addr
)
2694 sprintf(errstr
, _("duplicate dhcp-host IP address %s"), inet_ntoa(in
));
2700 char *cp
, *lastp
= NULL
, last
= 0;
2703 if (strlen(a
[j
]) > 1)
2705 lastp
= a
[j
] + strlen(a
[j
]) - 1;
2731 for (cp
= a
[j
]; *cp
; cp
++)
2732 if (!isdigit((unsigned char)*cp
) && *cp
!= ' ')
2739 if (strcmp(a
[j
], "infinite") == 0)
2741 new->lease_time
= 0xffffffff;
2742 new->flags
|= CONFIG_TIME
;
2744 else if (strcmp(a
[j
], "ignore") == 0)
2745 new->flags
|= CONFIG_DISABLE
;
2748 if (!(new->hostname
= canonicalise_opt(a
[j
])) ||
2749 !legal_hostname(new->hostname
))
2750 ret_err(_("bad DHCP host name"));
2752 new->flags
|= CONFIG_NAME
;
2753 new->domain
= strip_hostname(new->hostname
);
2758 new->lease_time
= atoi(a
[j
]) * fac
;
2759 /* Leases of a minute or less confuse
2760 some clients, notably Apple's */
2761 if (new->lease_time
< 120)
2762 new->lease_time
= 120;
2763 new->flags
|= CONFIG_TIME
;
2767 daemon
->dhcp_conf
= new;
2771 case LOPT_TAG_IF
: /* --tag-if */
2773 struct tag_if
*new = opt_malloc(sizeof(struct tag_if
));
2779 /* preserve order */
2780 if (!daemon
->tag_if
)
2781 daemon
->tag_if
= new;
2785 for (tmp
= daemon
->tag_if
; tmp
->next
; tmp
= tmp
->next
);
2803 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2804 newtag
->net
= opt_malloc(len
- 3);
2805 strcpy(newtag
->net
, arg
+4);
2806 unhide_metas(newtag
->net
);
2808 if (strstr(arg
, "set:") == arg
)
2810 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2811 newlist
->next
= new->set
;
2813 newlist
->list
= newtag
;
2815 else if (strstr(arg
, "tag:") == arg
)
2817 newtag
->next
= new->tag
;
2832 ret_err(_("bad tag-if"));
2838 case 'O': /* --dhcp-option */
2839 case LOPT_FORCE
: /* --dhcp-option-force */
2841 case LOPT_MATCH
: /* --dhcp-match */
2842 return parse_dhcp_opt(errstr
, arg
,
2843 option
== LOPT_FORCE
? DHOPT_FORCE
:
2844 (option
== LOPT_MATCH
? DHOPT_MATCH
:
2845 (option
== LOPT_OPTS
? DHOPT_BANK
: 0)));
2847 case 'M': /* --dhcp-boot */
2849 struct dhcp_netid
*id
= NULL
;
2850 while (is_tag_prefix(arg
))
2852 struct dhcp_netid
*newid
= opt_malloc(sizeof(struct dhcp_netid
));
2856 newid
->net
= opt_string_alloc(arg
+4);
2864 char *dhcp_file
, *dhcp_sname
= NULL
, *tftp_sname
= NULL
;
2865 struct in_addr dhcp_next_server
;
2866 struct dhcp_boot
*new;
2868 dhcp_file
= opt_string_alloc(arg
);
2869 dhcp_next_server
.s_addr
= 0;
2874 dhcp_sname
= opt_string_alloc(arg
);
2877 unhide_metas(comma
);
2878 if (!(inet_pton(AF_INET
, comma
, &dhcp_next_server
) > 0))
2881 * The user may have specified the tftp hostname here.
2882 * save it so that it can be resolved/looked up during
2883 * actual dhcp_reply().
2886 tftp_sname
= opt_string_alloc(comma
);
2887 dhcp_next_server
.s_addr
= 0;
2892 new = opt_malloc(sizeof(struct dhcp_boot
));
2893 new->file
= dhcp_file
;
2894 new->sname
= dhcp_sname
;
2895 new->tftp_sname
= tftp_sname
;
2896 new->next_server
= dhcp_next_server
;
2898 new->next
= daemon
->boot_config
;
2899 daemon
->boot_config
= new;
2905 case LOPT_PXE_PROMT
: /* --pxe-prompt */
2907 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
2911 new->opt
= 10; /* PXE_MENU_PROMPT */
2913 while (is_tag_prefix(arg
))
2915 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
2917 nn
->next
= new->netid
;
2919 nn
->net
= opt_string_alloc(arg
+4);
2929 new->len
= strlen(arg
) + 1;
2930 new->val
= opt_malloc(new->len
);
2931 memcpy(new->val
+ 1, arg
, new->len
- 1);
2933 new->u
.vendor_class
= (unsigned char *)"PXEClient";
2934 new->flags
= DHOPT_VENDOR
;
2936 if (comma
&& atoi_check(comma
, &timeout
))
2937 *(new->val
) = timeout
;
2941 new->next
= daemon
->dhcp_opts
;
2942 daemon
->dhcp_opts
= new;
2943 daemon
->enable_pxe
= 1;
2949 case LOPT_PXE_SERV
: /* --pxe-service */
2951 struct pxe_service
*new = opt_malloc(sizeof(struct pxe_service
));
2952 char *CSA
[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
2953 "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL
};
2954 static int boottype
= 32768;
2958 new->server
.s_addr
= 0;
2960 while (is_tag_prefix(arg
))
2962 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
2964 nn
->next
= new->netid
;
2966 nn
->net
= opt_string_alloc(arg
+4);
2970 if (arg
&& (comma
= split(arg
)))
2972 for (i
= 0; CSA
[i
]; i
++)
2973 if (strcasecmp(CSA
[i
], arg
) == 0)
2976 if (CSA
[i
] || atoi_check(arg
, &i
))
2982 new->menu
= opt_string_alloc(arg
);
2986 new->type
= 0; /* local boot */
2987 new->basename
= NULL
;
2993 if (atoi_check(arg
, &i
))
2996 new->basename
= NULL
;
3000 new->type
= boottype
++;
3001 new->basename
= opt_string_alloc(arg
);
3006 if (!inet_pton(AF_INET
, comma
, &new->server
))
3008 new->server
.s_addr
= 0;
3009 new->sname
= opt_string_alloc(comma
);
3017 if (!daemon
->pxe_services
)
3018 daemon
->pxe_services
= new;
3021 struct pxe_service
*s
;
3022 for (s
= daemon
->pxe_services
; s
->next
; s
= s
->next
);
3026 daemon
->enable_pxe
= 1;
3035 case '4': /* --dhcp-mac */
3037 if (!(comma
= split(arg
)))
3041 struct dhcp_mac
*new = opt_malloc(sizeof(struct dhcp_mac
));
3042 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
3043 unhide_metas(comma
);
3044 new->hwaddr_len
= parse_hex(comma
, new->hwaddr
, DHCP_CHADDR_MAX
, &new->mask
, &new->hwaddr_type
);
3045 if (new->hwaddr_len
== -1)
3049 new->next
= daemon
->dhcp_macs
;
3050 daemon
->dhcp_macs
= new;
3056 #ifdef OPTION6_PREFIX_CLASS
3057 case LOPT_PREF_CLSS
: /* --dhcp-prefix-class */
3059 struct prefix_class
*new = opt_malloc(sizeof(struct prefix_class
));
3061 if (!(comma
= split(arg
)) ||
3062 !atoi_check16(comma
, &new->class))
3065 new->tag
.net
= opt_string_alloc(set_prefix(arg
));
3066 new->next
= daemon
->prefix_classes
;
3067 daemon
->prefix_classes
= new;
3074 case 'U': /* --dhcp-vendorclass */
3075 case 'j': /* --dhcp-userclass */
3076 case LOPT_CIRCUIT
: /* --dhcp-circuitid */
3077 case LOPT_REMOTE
: /* --dhcp-remoteid */
3078 case LOPT_SUBSCR
: /* --dhcp-subscrid */
3082 struct dhcp_vendor
*new = opt_malloc(sizeof(struct dhcp_vendor
));
3084 if (!(comma
= split(arg
)))
3087 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
3088 /* check for hex string - must digits may include : must not have nothing else,
3089 only allowed for agent-options. */
3092 if ((comma
= split(arg
)))
3094 if (option
!= 'U' || strstr(arg
, "enterprise:") != arg
)
3097 new->enterprise
= atoi(arg
+11);
3102 for (p
= (unsigned char *)comma
; *p
; p
++)
3107 unhide_metas(comma
);
3108 if (option
== 'U' || option
== 'j' || *p
|| !dig
)
3110 new->len
= strlen(comma
);
3111 new->data
= opt_malloc(new->len
);
3112 memcpy(new->data
, comma
, new->len
);
3116 new->len
= parse_hex(comma
, (unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
3117 new->data
= opt_malloc(new->len
);
3118 memcpy(new->data
, comma
, new->len
);
3124 new->match_type
= MATCH_USER
;
3127 new->match_type
= MATCH_VENDOR
;
3130 new->match_type
= MATCH_CIRCUIT
;
3133 new->match_type
= MATCH_REMOTE
;
3136 new->match_type
= MATCH_SUBSCRIBER
;
3139 new->next
= daemon
->dhcp_vendors
;
3140 daemon
->dhcp_vendors
= new;
3145 case LOPT_ALTPORT
: /* --dhcp-alternate-port */
3148 daemon
->dhcp_server_port
= DHCP_SERVER_ALTPORT
;
3149 daemon
->dhcp_client_port
= DHCP_CLIENT_ALTPORT
;
3154 if (!atoi_check16(arg
, &daemon
->dhcp_server_port
) ||
3155 (comma
&& !atoi_check16(comma
, &daemon
->dhcp_client_port
)))
3156 ret_err(_("invalid port number"));
3158 daemon
->dhcp_client_port
= daemon
->dhcp_server_port
+1;
3162 case 'J': /* --dhcp-ignore */
3163 case LOPT_NO_NAMES
: /* --dhcp-ignore-names */
3164 case LOPT_BROADCAST
: /* --dhcp-broadcast */
3165 case '3': /* --bootp-dynamic */
3166 case LOPT_GEN_NAMES
: /* --dhcp-generate-names */
3168 struct dhcp_netid_list
*new = opt_malloc(sizeof(struct dhcp_netid_list
));
3169 struct dhcp_netid
*list
= NULL
;
3172 new->next
= daemon
->dhcp_ignore
;
3173 daemon
->dhcp_ignore
= new;
3175 else if (option
== LOPT_BROADCAST
)
3177 new->next
= daemon
->force_broadcast
;
3178 daemon
->force_broadcast
= new;
3180 else if (option
== '3')
3182 new->next
= daemon
->bootp_dynamic
;
3183 daemon
->bootp_dynamic
= new;
3185 else if (option
== LOPT_GEN_NAMES
)
3187 new->next
= daemon
->dhcp_gen_names
;
3188 daemon
->dhcp_gen_names
= new;
3192 new->next
= daemon
->dhcp_ignore_names
;
3193 daemon
->dhcp_ignore_names
= new;
3197 struct dhcp_netid
*member
= opt_malloc(sizeof(struct dhcp_netid
));
3199 member
->next
= list
;
3201 if (is_tag_prefix(arg
))
3202 member
->net
= opt_string_alloc(arg
+4);
3204 member
->net
= opt_string_alloc(arg
);
3212 case LOPT_PROXY
: /* --dhcp-proxy */
3213 daemon
->override
= 1;
3215 struct addr_list
*new = opt_malloc(sizeof(struct addr_list
));
3217 if (!(inet_pton(AF_INET
, arg
, &new->addr
) > 0))
3218 ret_err(_("bad dhcp-proxy address"));
3219 new->next
= daemon
->override_relays
;
3220 daemon
->override_relays
= new;
3225 case LOPT_RELAY
: /* --dhcp-relay */
3227 struct dhcp_relay
*new = opt_malloc(sizeof(struct dhcp_relay
));
3229 new->interface
= opt_string_alloc(split(comma
));
3230 new->iface_index
= 0;
3231 if (inet_pton(AF_INET
, arg
, &new->local
) && inet_pton(AF_INET
, comma
, &new->server
))
3233 new->next
= daemon
->relay4
;
3234 daemon
->relay4
= new;
3237 else if (inet_pton(AF_INET6
, arg
, &new->local
) && inet_pton(AF_INET6
, comma
, &new->server
))
3239 new->next
= daemon
->relay6
;
3240 daemon
->relay6
= new;
3244 ret_err(_("Bad dhcp-relay"));
3252 case LOPT_RA_PARAM
: /* --ra-param */
3253 if ((comma
= split(arg
)))
3255 struct ra_interface
*new = opt_malloc(sizeof(struct ra_interface
));
3258 new->name
= opt_string_alloc(arg
);
3259 if (strcasestr(comma
, "high") == comma
|| strcasestr(comma
, "low") == comma
)
3261 if (*comma
== 'l' || *comma
== 'L')
3265 comma
= split(comma
);
3268 if (!atoi_check(comma
, &new->interval
) ||
3269 (arg
&& !atoi_check(arg
, &new->lifetime
)))
3270 ret_err(_("bad RA-params"));
3272 new->next
= daemon
->ra_interfaces
;
3273 daemon
->ra_interfaces
= new;
3277 case LOPT_DUID
: /* --dhcp-duid */
3278 if (!(comma
= split(arg
)) || !atoi_check(arg
, (int *)&daemon
->duid_enterprise
))
3279 ret_err(_("bad DUID"));
3282 daemon
->duid_config_len
= parse_hex(comma
,(unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
3283 daemon
->duid_config
= opt_malloc(daemon
->duid_config_len
);
3284 memcpy(daemon
->duid_config
, comma
, daemon
->duid_config_len
);
3289 case 'V': /* --alias */
3291 char *dash
, *a
[3] = { NULL
, NULL
, NULL
};
3293 struct doctor
*new = opt_malloc(sizeof(struct doctor
));
3294 new->next
= daemon
->doctors
;
3295 daemon
->doctors
= new;
3296 new->mask
.s_addr
= 0xffffffff;
3297 new->end
.s_addr
= 0;
3300 for (k
= 1; k
< 3; k
++)
3302 if (!(a
[k
] = split(a
[k
-1])))
3307 dash
= split_chr(a
[0], '-');
3310 (!(inet_pton(AF_INET
, a
[0], &new->in
) > 0)) ||
3311 (!(inet_pton(AF_INET
, a
[1], &new->out
) > 0)))
3315 inet_pton(AF_INET
, a
[2], &new->mask
);
3318 (!(inet_pton(AF_INET
, dash
, &new->end
) > 0) ||
3319 !is_same_net(new->in
, new->end
, new->mask
) ||
3320 ntohl(new->in
.s_addr
) > ntohl(new->end
.s_addr
)))
3321 ret_err(_("invalid alias range"));
3326 case LOPT_INTNAME
: /* --interface-name */
3328 struct interface_name
*new, **up
;
3329 char *domain
= NULL
;
3333 if (!comma
|| !(domain
= canonicalise_opt(arg
)))
3334 ret_err(_("bad interface name"));
3336 new = opt_malloc(sizeof(struct interface_name
));
3342 /* Add to the end of the list, so that first name
3343 of an interface is used for PTR lookups. */
3344 for (up
= &daemon
->int_names
; *up
; up
= &((*up
)->next
));
3347 new->intr
= opt_string_alloc(comma
);
3351 case LOPT_CNAME
: /* --cname */
3357 if (!(comma
= split(arg
)))
3360 alias
= canonicalise_opt(arg
);
3361 target
= canonicalise_opt(comma
);
3363 if (!alias
|| !target
)
3364 ret_err(_("bad CNAME"));
3367 for (new = daemon
->cnames
; new; new = new->next
)
3368 if (hostname_isequal(new->alias
, arg
))
3369 ret_err(_("duplicate CNAME"));
3370 new = opt_malloc(sizeof(struct cname
));
3371 new->next
= daemon
->cnames
;
3372 daemon
->cnames
= new;
3374 new->target
= target
;
3380 case LOPT_PTR
: /* --ptr-record */
3382 struct ptr_record
*new;
3383 char *dom
, *target
= NULL
;
3387 if (!(dom
= canonicalise_opt(arg
)) ||
3388 (comma
&& !(target
= canonicalise_opt(comma
))))
3389 ret_err(_("bad PTR record"));
3392 new = opt_malloc(sizeof(struct ptr_record
));
3393 new->next
= daemon
->ptr
;
3401 case LOPT_NAPTR
: /* --naptr-record */
3403 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
3407 char *name
, *replace
= NULL
;
3410 for (k
= 1; k
< 7; k
++)
3411 if (!(a
[k
] = split(a
[k
-1])))
3416 !(name
= canonicalise_opt(a
[0])) ||
3417 !atoi_check16(a
[1], &order
) ||
3418 !atoi_check16(a
[2], &pref
) ||
3419 (k
== 7 && !(replace
= canonicalise_opt(a
[6]))))
3420 ret_err(_("bad NAPTR record"));
3423 new = opt_malloc(sizeof(struct naptr
));
3424 new->next
= daemon
->naptr
;
3425 daemon
->naptr
= new;
3427 new->flags
= opt_string_alloc(a
[3]);
3428 new->services
= opt_string_alloc(a
[4]);
3429 new->regexp
= opt_string_alloc(a
[5]);
3430 new->replace
= replace
;
3437 case LOPT_RR
: /* dns-rr */
3439 struct txt_record
*new;
3445 data
= split(comma
);
3447 new = opt_malloc(sizeof(struct txt_record
));
3448 new->next
= daemon
->rr
;
3451 if (!atoi_check(comma
, &val
) ||
3452 !(new->name
= canonicalise_opt(arg
)) ||
3453 (data
&& (len
= parse_hex(data
, (unsigned char *)data
, -1, NULL
, NULL
)) == -1U))
3454 ret_err(_("bad RR record"));
3461 new->txt
=opt_malloc(len
);
3463 memcpy(new->txt
, data
, len
);
3469 case 'Y': /* --txt-record */
3471 struct txt_record
*new;
3472 unsigned char *p
, *cnt
;
3477 new = opt_malloc(sizeof(struct txt_record
));
3478 new->next
= daemon
->txt
;
3482 if (!(new->name
= canonicalise_opt(arg
)))
3483 ret_err(_("bad TXT record"));
3485 len
= comma
? strlen(comma
) : 0;
3486 len
+= (len
/255) + 1; /* room for extra counts */
3487 new->txt
= p
= opt_malloc(len
);
3492 while (comma
&& *comma
)
3494 unsigned char c
= (unsigned char)*comma
++;
3496 if (c
== ',' || *cnt
== 255)
3505 *p
++ = unhide_meta(c
);
3510 new->len
= p
- new->txt
;
3515 case 'W': /* --srv-host */
3517 int port
= 1, priority
= 0, weight
= 0;
3518 char *name
, *target
= NULL
;
3519 struct mx_srv_record
*new;
3523 if (!(name
= canonicalise_opt(arg
)))
3524 ret_err(_("bad SRV record"));
3530 if (!(target
= canonicalise_opt(arg
)))
3531 ret_err(_("bad SRV target"));
3537 if (!atoi_check16(arg
, &port
))
3538 ret_err(_("invalid port number"));
3544 if (!atoi_check16(arg
, &priority
))
3545 ret_err(_("invalid priority"));
3551 if (!atoi_check16(arg
, &weight
))
3552 ret_err(_("invalid weight"));
3558 new = opt_malloc(sizeof(struct mx_srv_record
));
3559 new->next
= daemon
->mxnames
;
3560 daemon
->mxnames
= new;
3563 new->target
= target
;
3564 new->srvport
= port
;
3565 new->priority
= priority
;
3566 new->weight
= weight
;
3570 case LOPT_HOST_REC
: /* --host-record */
3572 struct host_record
*new = opt_malloc(sizeof(struct host_record
));
3573 memset(new, 0, sizeof(struct host_record
));
3575 if (!arg
|| !(comma
= split(arg
)))
3576 ret_err(_("Bad host-record"));
3580 struct all_addr addr
;
3581 if (inet_pton(AF_INET
, arg
, &addr
))
3582 new->addr
= addr
.addr
.addr4
;
3584 else if (inet_pton(AF_INET6
, arg
, &addr
))
3585 new->addr6
= addr
.addr
.addr6
;
3590 char *canon
= canonicalise(arg
, &nomem
);
3591 struct name_list
*nl
= opt_malloc(sizeof(struct name_list
));
3593 ret_err(_("Bad name in host-record"));
3596 /* keep order, so that PTR record goes to first name */
3602 struct name_list
*tmp
;
3603 for (tmp
= new->names
; tmp
->next
; tmp
= tmp
->next
);
3612 /* Keep list order */
3613 if (!daemon
->host_records_tail
)
3614 daemon
->host_records
= new;
3616 daemon
->host_records_tail
->next
= new;
3618 daemon
->host_records_tail
= new;
3623 ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DBus support)"));
3630 static void read_file(char *file
, FILE *f
, int hard_opt
)
3632 volatile int lineno
= 0;
3633 char *buff
= daemon
->namebuff
;
3635 while (fgets(buff
, MAXDNAME
, f
))
3637 int white
, i
, option
= hard_opt
;
3638 char *errmess
, *p
, *arg
= NULL
, *start
;
3641 /* Memory allocation failure longjmps here if mem_recover == 1 */
3644 if (setjmp(mem_jmp
))
3652 /* Implement quotes, inside quotes we allow \\ \" \n and \t
3653 metacharacters get hidden also strip comments */
3654 for (white
= 1, p
= buff
; *p
; p
++)
3658 memmove(p
, p
+1, strlen(p
+1)+1);
3660 for(; *p
&& *p
!= '"'; p
++)
3662 if (*p
== '\\' && strchr("\"tnebr\\", p
[1]))
3666 else if (p
[1] == 'n')
3668 else if (p
[1] == 'b')
3670 else if (p
[1] == 'r')
3672 else if (p
[1] == 'e') /* escape */
3674 memmove(p
, p
+1, strlen(p
+1)+1);
3681 errmess
= _("missing \"");
3685 memmove(p
, p
+1, strlen(p
+1)+1);
3695 if (white
&& *p
== '#')
3705 /* strip leading spaces */
3706 for (start
= buff
; *start
&& *start
== ' '; start
++);
3708 /* strip trailing spaces */
3709 for (len
= strlen(start
); (len
!= 0) && (start
[len
-1] == ' '); len
--);
3718 else if ((p
=strchr(start
, '=')))
3720 /* allow spaces around "=" */
3721 for (arg
= p
+1; *arg
== ' '; arg
++);
3722 for (; p
>= start
&& (*p
== ' ' || *p
== '='); p
--)
3730 for (option
= 0, i
= 0; opts
[i
].name
; i
++)
3731 if (strcmp(opts
[i
].name
, start
) == 0)
3733 option
= opts
[i
].val
;
3738 errmess
= _("bad option");
3739 else if (opts
[i
].has_arg
== 0 && arg
)
3740 errmess
= _("extraneous parameter");
3741 else if (opts
[i
].has_arg
== 1 && !arg
)
3742 errmess
= _("missing parameter");
3747 strcpy(daemon
->namebuff
, errmess
);
3749 if (errmess
|| !one_opt(option
, arg
, buff
, _("error"), 0))
3751 sprintf(daemon
->namebuff
+ strlen(daemon
->namebuff
), _(" at line %d of %s"), lineno
, file
);
3753 my_syslog(LOG_ERR
, "%s", daemon
->namebuff
);
3755 die("%s", daemon
->namebuff
, EC_BADCONF
);
3763 static int one_file(char *file
, int hard_opt
)
3767 static int read_stdin
= 0;
3768 static struct fileread
{
3771 struct fileread
*next
;
3772 } *filesread
= NULL
;
3774 if (hard_opt
== '7')
3776 /* default conf-file reading */
3781 if (hard_opt
== 0 && strcmp(file
, "-") == 0)
3783 if (read_stdin
== 1)
3791 /* ignore repeated files. */
3792 struct stat statbuf
;
3794 if (hard_opt
== 0 && stat(file
, &statbuf
) == 0)
3798 for (r
= filesread
; r
; r
= r
->next
)
3799 if (r
->dev
== statbuf
.st_dev
&& r
->ino
== statbuf
.st_ino
)
3802 r
= safe_malloc(sizeof(struct fileread
));
3803 r
->next
= filesread
;
3805 r
->dev
= statbuf
.st_dev
;
3806 r
->ino
= statbuf
.st_ino
;
3809 if (!(f
= fopen(file
, "r")))
3811 if (errno
== ENOENT
&& nofile_ok
)
3812 return 1; /* No conffile, all done. */
3815 char *str
= _("cannot read %s: %s");
3818 my_syslog(LOG_ERR
, str
, file
, strerror(errno
));
3822 die(str
, file
, EC_FILE
);
3827 read_file(file
, f
, hard_opt
);
3831 /* expand any name which is a directory */
3832 struct hostsfile
*expand_filelist(struct hostsfile
*list
)
3835 struct hostsfile
*ah
;
3837 for (i
= 0, ah
= list
; ah
; ah
= ah
->next
)
3842 if (ah
->flags
& AH_DIR
)
3843 ah
->flags
|= AH_INACTIVE
;
3845 ah
->flags
&= ~AH_INACTIVE
;
3848 for (ah
= list
; ah
; ah
= ah
->next
)
3849 if (!(ah
->flags
& AH_INACTIVE
))
3852 if (stat(ah
->fname
, &buf
) != -1 && S_ISDIR(buf
.st_mode
))
3857 /* don't read this as a file */
3858 ah
->flags
|= AH_INACTIVE
;
3860 if (!(dir_stream
= opendir(ah
->fname
)))
3861 my_syslog(LOG_ERR
, _("cannot access directory %s: %s"),
3862 ah
->fname
, strerror(errno
));
3865 while ((ent
= readdir(dir_stream
)))
3867 size_t lendir
= strlen(ah
->fname
);
3868 size_t lenfile
= strlen(ent
->d_name
);
3869 struct hostsfile
*ah1
;
3872 /* ignore emacs backups and dotfiles */
3874 ent
->d_name
[lenfile
- 1] == '~' ||
3875 (ent
->d_name
[0] == '#' && ent
->d_name
[lenfile
- 1] == '#') ||
3876 ent
->d_name
[0] == '.')
3879 /* see if we have an existing record.
3882 path to match is ah1->fname */
3884 for (ah1
= list
; ah1
; ah1
= ah1
->next
)
3886 if (lendir
< strlen(ah1
->fname
) &&
3887 strstr(ah1
->fname
, ah
->fname
) == ah1
->fname
&&
3888 ah1
->fname
[lendir
] == '/' &&
3889 strcmp(ah1
->fname
+ lendir
+ 1, ent
->d_name
) == 0)
3891 ah1
->flags
&= ~AH_INACTIVE
;
3896 /* make new record */
3899 if (!(ah1
= whine_malloc(sizeof(struct hostsfile
))))
3902 if (!(path
= whine_malloc(lendir
+ lenfile
+ 2)))
3908 strcpy(path
, ah
->fname
);
3910 strcat(path
, ent
->d_name
);
3913 ah1
->flags
= AH_DIR
;
3918 /* inactivate record if not regular file */
3919 if ((ah1
->flags
& AH_DIR
) && stat(ah1
->fname
, &buf
) != -1 && !S_ISREG(buf
.st_mode
))
3920 ah1
->flags
|= AH_INACTIVE
;
3923 closedir(dir_stream
);
3933 void reread_dhcp(void)
3935 struct hostsfile
*hf
;
3937 if (daemon
->dhcp_hosts_file
)
3939 struct dhcp_config
*configs
, *cp
, **up
;
3941 /* remove existing... */
3942 for (up
= &daemon
->dhcp_conf
, configs
= daemon
->dhcp_conf
; configs
; configs
= cp
)
3946 if (configs
->flags
& CONFIG_BANK
)
3948 struct hwaddr_config
*mac
, *tmp
;
3949 struct dhcp_netid_list
*list
, *tmplist
;
3951 for (mac
= configs
->hwaddr
; mac
; mac
= tmp
)
3957 if (configs
->flags
& CONFIG_CLID
)
3958 free(configs
->clid
);
3960 for (list
= configs
->netid
; list
; list
= tmplist
)
3963 tmplist
= list
->next
;
3967 if (configs
->flags
& CONFIG_NAME
)
3968 free(configs
->hostname
);
3970 *up
= configs
->next
;
3974 up
= &configs
->next
;
3977 daemon
->dhcp_hosts_file
= expand_filelist(daemon
->dhcp_hosts_file
);
3978 for (hf
= daemon
->dhcp_hosts_file
; hf
; hf
= hf
->next
)
3979 if (!(hf
->flags
& AH_INACTIVE
))
3981 if (one_file(hf
->fname
, LOPT_BANK
))
3982 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
3986 if (daemon
->dhcp_opts_file
)
3988 struct dhcp_opt
*opts
, *cp
, **up
;
3989 struct dhcp_netid
*id
, *next
;
3991 for (up
= &daemon
->dhcp_opts
, opts
= daemon
->dhcp_opts
; opts
; opts
= cp
)
3995 if (opts
->flags
& DHOPT_BANK
)
3997 if ((opts
->flags
& DHOPT_VENDOR
))
3998 free(opts
->u
.vendor_class
);
4000 for (id
= opts
->netid
; id
; id
= next
)
4013 daemon
->dhcp_opts_file
= expand_filelist(daemon
->dhcp_opts_file
);
4014 for (hf
= daemon
->dhcp_opts_file
; hf
; hf
= hf
->next
)
4015 if (!(hf
->flags
& AH_INACTIVE
))
4017 if (one_file(hf
->fname
, LOPT_OPTS
))
4018 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
4024 void read_opts(int argc
, char **argv
, char *compile_opts
)
4026 char *buff
= opt_malloc(MAXDNAME
);
4027 int option
, conffile_opt
= '7', testmode
= 0;
4028 char *arg
, *conffile
= CONFFILE
;
4032 daemon
= opt_malloc(sizeof(struct daemon
));
4033 memset(daemon
, 0, sizeof(struct daemon
));
4034 daemon
->namebuff
= buff
;
4036 /* Set defaults - everything else is zero or NULL */
4037 daemon
->cachesize
= CACHESIZ
;
4038 daemon
->ftabsize
= FTABSIZ
;
4039 daemon
->port
= NAMESERVER_PORT
;
4040 daemon
->dhcp_client_port
= DHCP_CLIENT_PORT
;
4041 daemon
->dhcp_server_port
= DHCP_SERVER_PORT
;
4042 daemon
->default_resolv
.is_default
= 1;
4043 daemon
->default_resolv
.name
= RESOLVFILE
;
4044 daemon
->resolv_files
= &daemon
->default_resolv
;
4045 daemon
->username
= CHUSER
;
4046 daemon
->runfile
= RUNFILE
;
4047 daemon
->dhcp_max
= MAXLEASES
;
4048 daemon
->tftp_max
= TFTP_MAX_CONNECTIONS
;
4049 daemon
->edns_pktsz
= EDNS_PKTSZ
;
4050 daemon
->log_fac
= -1;
4051 daemon
->auth_ttl
= AUTH_TTL
;
4052 daemon
->soa_refresh
= SOA_REFRESH
;
4053 daemon
->soa_retry
= SOA_RETRY
;
4054 daemon
->soa_expiry
= SOA_EXPIRY
;
4055 add_txt("version.bind", "dnsmasq-" VERSION
);
4056 add_txt("authors.bind", "Simon Kelley");
4057 add_txt("copyright.bind", COPYRIGHT
);
4061 #ifdef HAVE_GETOPT_LONG
4062 option
= getopt_long(argc
, argv
, OPTSTRING
, opts
, NULL
);
4064 option
= getopt(argc
, argv
, OPTSTRING
);
4069 for (; optind
< argc
; optind
++)
4071 unsigned char *c
= (unsigned char *)argv
[optind
];
4072 for (; *c
!= 0; c
++)
4074 die(_("junk found in command line"), NULL
, EC_BADCONF
);
4079 /* Copy optarg so that argv doesn't get changed */
4082 strncpy(buff
, optarg
, MAXDNAME
);
4083 buff
[MAXDNAME
-1] = 0;
4089 /* command-line only stuff */
4090 if (option
== LOPT_TEST
)
4092 else if (option
== 'w')
4095 if (argc
== 3 && strcmp(argv
[2], "dhcp") == 0)
4098 else if (argc
== 3 && strcmp(argv
[2], "dhcp6") == 0)
4107 else if (option
== 'v')
4109 printf(_("Dnsmasq version %s %s\n"), VERSION
, COPYRIGHT
);
4110 printf(_("Compile time options: %s\n\n"), compile_opts
);
4111 printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
4112 printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
4113 printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
4116 else if (option
== 'C')
4118 conffile_opt
= 0; /* file must exist */
4119 conffile
= opt_string_alloc(arg
);
4123 #ifdef HAVE_GETOPT_LONG
4124 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try --help"), 1))
4126 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try -w"), 1))
4128 die(_("bad command line options: %s"), daemon
->namebuff
, EC_BADCONF
);
4133 one_file(conffile
, conffile_opt
);
4135 /* port might not be known when the address is parsed - fill in here */
4136 if (daemon
->servers
)
4139 for (tmp
= daemon
->servers
; tmp
; tmp
= tmp
->next
)
4140 if (!(tmp
->flags
& SERV_HAS_SOURCE
))
4142 if (tmp
->source_addr
.sa
.sa_family
== AF_INET
)
4143 tmp
->source_addr
.in
.sin_port
= htons(daemon
->query_port
);
4145 else if (tmp
->source_addr
.sa
.sa_family
== AF_INET6
)
4146 tmp
->source_addr
.in6
.sin6_port
= htons(daemon
->query_port
);
4151 if (daemon
->if_addrs
)
4154 for(tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
4155 if (tmp
->addr
.sa
.sa_family
== AF_INET
)
4156 tmp
->addr
.in
.sin_port
= htons(daemon
->port
);
4158 else if (tmp
->addr
.sa
.sa_family
== AF_INET6
)
4159 tmp
->addr
.in6
.sin6_port
= htons(daemon
->port
);
4163 /* create default, if not specified */
4164 if (daemon
->authserver
&& !daemon
->hostmaster
)
4166 strcpy(buff
, "hostmaster.");
4167 strcat(buff
, daemon
->authserver
);
4168 daemon
->hostmaster
= opt_string_alloc(buff
);
4171 /* only one of these need be specified: the other defaults to the host-name */
4172 if (option_bool(OPT_LOCALMX
) || daemon
->mxnames
|| daemon
->mxtarget
)
4174 struct mx_srv_record
*mx
;
4176 if (gethostname(buff
, MAXDNAME
) == -1)
4177 die(_("cannot get host-name: %s"), NULL
, EC_MISC
);
4179 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
4180 if (!mx
->issrv
&& hostname_isequal(mx
->name
, buff
))
4183 if ((daemon
->mxtarget
|| option_bool(OPT_LOCALMX
)) && !mx
)
4185 mx
= opt_malloc(sizeof(struct mx_srv_record
));
4186 mx
->next
= daemon
->mxnames
;
4189 mx
->name
= opt_string_alloc(buff
);
4190 daemon
->mxnames
= mx
;
4193 if (!daemon
->mxtarget
)
4194 daemon
->mxtarget
= opt_string_alloc(buff
);
4196 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
4197 if (!mx
->issrv
&& !mx
->target
)
4198 mx
->target
= daemon
->mxtarget
;
4201 if (!option_bool(OPT_NO_RESOLV
) &&
4202 daemon
->resolv_files
&&
4203 daemon
->resolv_files
->next
&&
4204 option_bool(OPT_NO_POLL
))
4205 die(_("only one resolv.conf file allowed in no-poll mode."), NULL
, EC_BADCONF
);
4207 if (option_bool(OPT_RESOLV_DOMAIN
))
4212 if (option_bool(OPT_NO_RESOLV
) ||
4213 !daemon
->resolv_files
||
4214 (daemon
->resolv_files
)->next
)
4215 die(_("must have exactly one resolv.conf to read domain from."), NULL
, EC_BADCONF
);
4217 if (!(f
= fopen((daemon
->resolv_files
)->name
, "r")))
4218 die(_("failed to read %s: %s"), (daemon
->resolv_files
)->name
, EC_FILE
);
4220 while ((line
= fgets(buff
, MAXDNAME
, f
)))
4222 char *token
= strtok(line
, " \t\n\r");
4224 if (!token
|| strcmp(token
, "search") != 0)
4227 if ((token
= strtok(NULL
, " \t\n\r")) &&
4228 (daemon
->domain_suffix
= canonicalise_opt(token
)))
4234 if (!daemon
->domain_suffix
)
4235 die(_("no search directive found in %s"), (daemon
->resolv_files
)->name
, EC_MISC
);
4238 if (daemon
->domain_suffix
)
4240 /* add domain for any srv record without one. */
4241 struct mx_srv_record
*srv
;
4243 for (srv
= daemon
->mxnames
; srv
; srv
= srv
->next
)
4245 strchr(srv
->name
, '.') &&
4246 strchr(srv
->name
, '.') == strrchr(srv
->name
, '.'))
4248 strcpy(buff
, srv
->name
);
4250 strcat(buff
, daemon
->domain_suffix
);
4252 srv
->name
= opt_string_alloc(buff
);
4255 else if (option_bool(OPT_DHCP_FQDN
))
4256 die(_("there must be a default domain when --dhcp-fqdn is set"), NULL
, EC_BADCONF
);
4260 fprintf(stderr
, "dnsmasq: %s.\n", _("syntax check OK"));