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_FAST_RA 322
136 #define LOPT_RELAY 323
138 #ifdef HAVE_QUIET_DHCP //Originally TOMATO option
139 #define LOPT_QUIET_DHCP 324
140 #define LOPT_QUIET_DHCP6 325
141 #define LOPT_QUIET_RA 326
144 #ifdef HAVE_GETOPT_LONG
145 static const struct option opts
[] =
147 static const struct myoption opts
[] =
150 { "version", 0, 0, 'v' },
151 { "no-hosts", 0, 0, 'h' },
152 { "no-poll", 0, 0, 'n' },
153 { "help", 0, 0, 'w' },
154 { "no-daemon", 0, 0, 'd' },
155 { "log-queries", 0, 0, 'q' },
156 { "user", 2, 0, 'u' },
157 { "group", 2, 0, 'g' },
158 { "resolv-file", 2, 0, 'r' },
159 { "mx-host", 1, 0, 'm' },
160 { "mx-target", 1, 0, 't' },
161 { "cache-size", 2, 0, 'c' },
162 { "port", 1, 0, 'p' },
163 { "dhcp-leasefile", 2, 0, 'l' },
164 { "dhcp-lease", 1, 0, 'l' },
165 { "dhcp-host", 1, 0, 'G' },
166 { "dhcp-range", 1, 0, 'F' },
167 { "dhcp-option", 1, 0, 'O' },
168 { "dhcp-boot", 1, 0, 'M' },
169 { "domain", 1, 0, 's' },
170 { "domain-suffix", 1, 0, 's' },
171 { "interface", 1, 0, 'i' },
172 { "listen-address", 1, 0, 'a' },
173 { "bogus-priv", 0, 0, 'b' },
174 { "bogus-nxdomain", 1, 0, 'B' },
175 { "selfmx", 0, 0, 'e' },
176 { "filterwin2k", 0, 0, 'f' },
177 { "pid-file", 2, 0, 'x' },
178 { "strict-order", 0, 0, 'o' },
179 { "server", 1, 0, 'S' },
180 { "local", 1, 0, LOPT_LOCAL
},
181 { "address", 1, 0, 'A' },
182 { "conf-file", 2, 0, 'C' },
183 { "no-resolv", 0, 0, 'R' },
184 { "expand-hosts", 0, 0, 'E' },
185 { "localmx", 0, 0, 'L' },
186 { "local-ttl", 1, 0, 'T' },
187 { "no-negcache", 0, 0, 'N' },
188 { "addn-hosts", 1, 0, 'H' },
189 { "query-port", 1, 0, 'Q' },
190 { "except-interface", 1, 0, 'I' },
191 { "no-dhcp-interface", 1, 0, '2' },
192 { "domain-needed", 0, 0, 'D' },
193 { "dhcp-lease-max", 1, 0, 'X' },
194 { "bind-interfaces", 0, 0, 'z' },
195 { "read-ethers", 0, 0, 'Z' },
196 { "alias", 1, 0, 'V' },
197 { "dhcp-vendorclass", 1, 0, 'U' },
198 { "dhcp-userclass", 1, 0, 'j' },
199 { "dhcp-ignore", 1, 0, 'J' },
200 { "edns-packet-max", 1, 0, 'P' },
201 { "keep-in-foreground", 0, 0, 'k' },
202 { "dhcp-authoritative", 0, 0, 'K' },
203 { "srv-host", 1, 0, 'W' },
204 { "localise-queries", 0, 0, 'y' },
205 { "txt-record", 1, 0, 'Y' },
206 { "dns-rr", 1, 0, LOPT_RR
},
207 { "enable-dbus", 2, 0, '1' },
208 { "bootp-dynamic", 2, 0, '3' },
209 { "dhcp-mac", 1, 0, '4' },
210 { "no-ping", 0, 0, '5' },
211 { "dhcp-script", 1, 0, '6' },
212 { "conf-dir", 1, 0, '7' },
213 { "log-facility", 1, 0 ,'8' },
214 { "leasefile-ro", 0, 0, '9' },
215 { "dns-forward-max", 1, 0, '0' },
216 { "clear-on-reload", 0, 0, LOPT_RELOAD
},
217 { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES
},
218 { "enable-tftp", 2, 0, LOPT_TFTP
},
219 { "tftp-secure", 0, 0, LOPT_SECURE
},
220 { "tftp-unique-root", 0, 0, LOPT_APREF
},
221 { "tftp-root", 1, 0, LOPT_PREFIX
},
222 { "tftp-max", 1, 0, LOPT_TFTP_MAX
},
223 { "tftp-lowercase", 0, 0, LOPT_TFTP_LC
},
224 { "ptr-record", 1, 0, LOPT_PTR
},
225 { "naptr-record", 1, 0, LOPT_NAPTR
},
226 { "bridge-interface", 1, 0 , LOPT_BRIDGE
},
227 { "dhcp-option-force", 1, 0, LOPT_FORCE
},
228 { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK
},
229 { "log-dhcp", 0, 0, LOPT_LOG_OPTS
},
230 { "log-async", 2, 0, LOPT_MAX_LOGS
},
231 { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT
},
232 { "dhcp-remoteid", 1, 0, LOPT_REMOTE
},
233 { "dhcp-subscrid", 1, 0, LOPT_SUBSCR
},
234 { "interface-name", 1, 0, LOPT_INTNAME
},
235 { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST
},
236 { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS
},
237 { "dhcp-no-override", 0, 0, LOPT_OVERRIDE
},
238 { "tftp-port-range", 1, 0, LOPT_TFTPPORTS
},
239 { "stop-dns-rebind", 0, 0, LOPT_REBIND
},
240 { "rebind-domain-ok", 1, 0, LOPT_NO_REBIND
},
241 { "all-servers", 0, 0, LOPT_NOLAST
},
242 { "dhcp-match", 1, 0, LOPT_MATCH
},
243 { "dhcp-broadcast", 2, 0, LOPT_BROADCAST
},
244 { "neg-ttl", 1, 0, LOPT_NEGTTL
},
245 { "max-ttl", 1, 0, LOPT_MAXTTL
},
246 { "max-cache-ttl", 1, 0, LOPT_MAXCTTL
},
247 { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT
},
248 { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR
},
249 { "min-port", 1, 0, LOPT_MINPORT
},
250 { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN
},
251 { "cname", 1, 0, LOPT_CNAME
},
252 { "pxe-prompt", 1, 0, LOPT_PXE_PROMT
},
253 { "pxe-service", 1, 0, LOPT_PXE_SERV
},
254 { "test", 0, 0, LOPT_TEST
},
255 { "tag-if", 1, 0, LOPT_TAG_IF
},
256 { "dhcp-proxy", 2, 0, LOPT_PROXY
},
257 { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES
},
258 { "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND
},
259 { "add-mac", 0, 0, LOPT_ADD_MAC
},
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 { "force-fast-ra", 0, 0, LOPT_FAST_RA
},
281 { "dhcp-relay", 1, 0, LOPT_RELAY
},
282 #ifdef HAVE_QUIET_DHCP //Originally TOMATO option
283 { "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP
},
284 { "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6
},
285 { "quiet-ra", 0, 0, LOPT_QUIET_RA
},
291 #define ARG_DUP OPT_LAST
292 #define ARG_ONE OPT_LAST + 1
293 #define ARG_USED_CL OPT_LAST + 2
294 #define ARG_USED_FILE OPT_LAST + 3
299 char * const flagdesc
;
303 { 'a', ARG_DUP
, "<ipaddr>", gettext_noop("Specify local address(es) to listen on."), NULL
},
304 { 'A', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL
},
305 { 'b', OPT_BOGUSPRIV
, NULL
, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL
},
306 { 'B', ARG_DUP
, "<ipaddr>", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL
},
307 { 'c', ARG_ONE
, "<integer>", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
308 { 'C', ARG_DUP
, "<path>", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE
},
309 { 'd', OPT_DEBUG
, NULL
, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL
},
310 { 'D', OPT_NODOTS_LOCAL
, NULL
, gettext_noop("Do NOT forward queries with no domain part."), NULL
},
311 { 'e', OPT_SELFMX
, NULL
, gettext_noop("Return self-pointing MX records for local hosts."), NULL
},
312 { 'E', OPT_EXPAND
, NULL
, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL
},
313 { 'f', OPT_FILTER
, NULL
, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL
},
314 { 'F', ARG_DUP
, "<ipaddr>,...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL
},
315 { 'g', ARG_ONE
, "<groupname>", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP
},
316 { 'G', ARG_DUP
, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL
},
317 { LOPT_DHCP_HOST
, ARG_DUP
, "<path>", gettext_noop("Read DHCP host specs from file."), NULL
},
318 { LOPT_DHCP_OPTS
, ARG_DUP
, "<path>", gettext_noop("Read DHCP option specs from file."), NULL
},
319 { LOPT_TAG_IF
, ARG_DUP
, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL
},
320 { 'h', OPT_NO_HOSTS
, NULL
, gettext_noop("Do NOT load %s file."), HOSTSFILE
},
321 { 'H', ARG_DUP
, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE
},
322 { 'i', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL
},
323 { 'I', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL
},
324 { 'j', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL
},
325 { LOPT_CIRCUIT
, ARG_DUP
, "set:<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL
},
326 { LOPT_REMOTE
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL
},
327 { LOPT_SUBSCR
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL
},
328 { 'J', ARG_DUP
, "tag:<tag>...", gettext_noop("Don't do DHCP for hosts with tag set."), NULL
},
329 { LOPT_BROADCAST
, ARG_DUP
, "[=tag:<tag>...]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL
},
330 { 'k', OPT_NO_FORK
, NULL
, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL
},
331 { 'K', OPT_AUTHORITATIVE
, NULL
, gettext_noop("Assume we are the only DHCP server on the local network."), NULL
},
332 { 'l', ARG_ONE
, "<path>", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE
},
333 { 'L', OPT_LOCALMX
, NULL
, gettext_noop("Return MX records for local hosts."), NULL
},
334 { 'm', ARG_DUP
, "<host_name>,<target>,<pref>", gettext_noop("Specify an MX record."), NULL
},
335 { 'M', ARG_DUP
, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL
},
336 { 'n', OPT_NO_POLL
, NULL
, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE
},
337 { 'N', OPT_NO_NEG
, NULL
, gettext_noop("Do NOT cache failed search results."), NULL
},
338 { 'o', OPT_ORDER
, NULL
, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE
},
339 { 'O', ARG_DUP
, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL
},
340 { LOPT_FORCE
, ARG_DUP
, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL
},
341 { 'p', ARG_ONE
, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL
},
342 { 'P', ARG_ONE
, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
343 { 'q', OPT_LOG
, NULL
, gettext_noop("Log DNS queries."), NULL
},
344 { 'Q', ARG_ONE
, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL
},
345 { 'R', OPT_NO_RESOLV
, NULL
, gettext_noop("Do NOT read resolv.conf."), NULL
},
346 { 'r', ARG_DUP
, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE
},
347 { 'S', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL
},
348 { LOPT_LOCAL
, ARG_DUP
, "/<domain>/", gettext_noop("Never forward queries to specified domains."), NULL
},
349 { 's', ARG_DUP
, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL
},
350 { 't', ARG_ONE
, "<host_name>", gettext_noop("Specify default target in an MX record."), NULL
},
351 { 'T', ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL
},
352 { LOPT_NEGTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL
},
353 { LOPT_MAXTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL
},
354 { 'u', ARG_ONE
, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER
},
355 { 'U', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL
},
356 { 'v', 0, NULL
, gettext_noop("Display dnsmasq version and copyright information."), NULL
},
357 { 'V', ARG_DUP
, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL
},
358 { 'W', ARG_DUP
, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL
},
359 { 'w', 0, NULL
, gettext_noop("Display this message. Use --help dhcp for known DHCP options."), NULL
},
360 { 'x', ARG_ONE
, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE
},
361 { 'X', ARG_ONE
, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
362 { 'y', OPT_LOCALISE
, NULL
, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL
},
363 { 'Y', ARG_DUP
, "<name>,<txt>[,<txt]", gettext_noop("Specify TXT DNS record."), NULL
},
364 { LOPT_PTR
, ARG_DUP
, "<name>,<target>", gettext_noop("Specify PTR DNS record."), NULL
},
365 { LOPT_INTNAME
, ARG_DUP
, "<name>,<interface>", gettext_noop("Give DNS name to IPv4 address of interface."), NULL
},
366 { 'z', OPT_NOWILD
, NULL
, gettext_noop("Bind only to interfaces in use."), NULL
},
367 { 'Z', OPT_ETHERS
, NULL
, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE
},
368 { '1', ARG_ONE
, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL
},
369 { '2', ARG_DUP
, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL
},
370 { '3', ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL
},
371 { '4', ARG_DUP
, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL
},
372 { LOPT_BRIDGE
, ARG_DUP
, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL
},
373 { '5', OPT_NO_PING
, NULL
, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL
},
374 { '6', ARG_ONE
, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL
},
375 { LOPT_LUASCRIPT
, ARG_DUP
, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL
},
376 { LOPT_SCRIPTUSR
, ARG_ONE
, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL
},
377 { '7', ARG_DUP
, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL
},
378 { '8', ARG_ONE
, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL
},
379 { '9', OPT_LEASE_RO
, NULL
, gettext_noop("Do not use leasefile."), NULL
},
380 { '0', ARG_ONE
, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
381 { LOPT_RELOAD
, OPT_RELOAD
, NULL
, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE
},
382 { LOPT_NO_NAMES
, ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL
},
383 { LOPT_OVERRIDE
, OPT_NO_OVERRIDE
, NULL
, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL
},
384 { LOPT_TFTP
, ARG_DUP
, "[=<intr>[,<intr>]]", gettext_noop("Enable integrated read-only TFTP server."), NULL
},
385 { LOPT_PREFIX
, ARG_DUP
, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL
},
386 { LOPT_APREF
, OPT_TFTP_APREF
, NULL
, gettext_noop("Add client IP address to tftp-root."), NULL
},
387 { LOPT_SECURE
, OPT_TFTP_SECURE
, NULL
, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL
},
388 { LOPT_TFTP_MAX
, ARG_ONE
, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
389 { LOPT_NOBLOCK
, OPT_TFTP_NOBLOCK
, NULL
, gettext_noop("Disable the TFTP blocksize extension."), NULL
},
390 { LOPT_TFTP_LC
, OPT_TFTP_LC
, NULL
, gettext_noop("Convert TFTP filenames to lowercase"), NULL
},
391 { LOPT_TFTPPORTS
, ARG_ONE
, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL
},
392 { LOPT_LOG_OPTS
, OPT_LOG_OPTS
, NULL
, gettext_noop("Extra logging for DHCP."), NULL
},
393 { LOPT_MAX_LOGS
, ARG_ONE
, "[=<integer>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL
},
394 { LOPT_REBIND
, OPT_NO_REBIND
, NULL
, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL
},
395 { LOPT_LOC_REBND
, OPT_LOCAL_REBIND
, NULL
, gettext_noop("Allow rebinding of 127.0.0.0/8, for RBL servers."), NULL
},
396 { LOPT_NO_REBIND
, ARG_DUP
, "/<domain>/", gettext_noop("Inhibit DNS-rebind protection on this domain."), NULL
},
397 { LOPT_NOLAST
, OPT_ALL_SERVERS
, NULL
, gettext_noop("Always perform DNS queries to all servers."), NULL
},
398 { LOPT_MATCH
, ARG_DUP
, "set:<tag>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL
},
399 { LOPT_ALTPORT
, ARG_ONE
, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL
},
400 { LOPT_NAPTR
, ARG_DUP
, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL
},
401 { LOPT_MINPORT
, ARG_ONE
, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL
},
402 { LOPT_DHCP_FQDN
, OPT_DHCP_FQDN
, NULL
, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL
},
403 { LOPT_GEN_NAMES
, ARG_DUP
, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL
},
404 { LOPT_PROXY
, ARG_DUP
, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL
},
405 { LOPT_RELAY
, ARG_DUP
, "<local-addr>,<server>[,<interface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL
},
406 { LOPT_CNAME
, ARG_DUP
, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL
},
407 { LOPT_PXE_PROMT
, ARG_DUP
, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL
},
408 { LOPT_PXE_SERV
, ARG_DUP
, "<service>", gettext_noop("Boot service for PXE menu."), NULL
},
409 { LOPT_TEST
, 0, NULL
, gettext_noop("Check configuration syntax."), NULL
},
410 { LOPT_ADD_MAC
, OPT_ADD_MAC
, NULL
, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL
},
411 { LOPT_DNSSEC
, OPT_DNSSEC
, NULL
, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL
},
412 { LOPT_INCR_ADDR
, OPT_CONSEC_ADDR
, NULL
, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL
},
413 { LOPT_CONNTRACK
, OPT_CONNTRACK
, NULL
, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL
},
414 { LOPT_FQDN
, OPT_FQDN_UPDATE
, NULL
, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL
},
415 { LOPT_RA
, OPT_RA
, NULL
, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL
},
416 { LOPT_FAST_RA
, OPT_FAST_RA
, NULL
, gettext_noop("Always send frequent router-advertisements"), NULL
},
417 { LOPT_DUID
, ARG_ONE
, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL
},
418 { LOPT_HOST_REC
, ARG_DUP
, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL
},
419 { LOPT_RR
, ARG_DUP
, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL
},
420 { LOPT_CLVERBIND
, OPT_CLEVERBIND
, NULL
, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL
},
421 { LOPT_AUTHSERV
, ARG_ONE
, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL
},
422 { LOPT_AUTHZONE
, ARG_DUP
, "<domain>,[<subnet>...]", gettext_noop("Domain to export to global DNS"), NULL
},
423 { LOPT_AUTHTTL
, ARG_ONE
, "<integer>", gettext_noop("Set TTL for authoritative replies"), NULL
},
424 { LOPT_AUTHSOA
, ARG_ONE
, "<serial>[,...]", gettext_noop("Set authoritive zone information"), NULL
},
425 { LOPT_AUTHSFS
, ARG_DUP
, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL
},
426 { LOPT_AUTHPEER
, ARG_DUP
, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL
},
427 { LOPT_IPSET
, ARG_DUP
, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL
},
428 { LOPT_SYNTH
, ARG_DUP
, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for sythesised names"), NULL
},
429 #ifdef OPTION6_PREFIX_CLASS
430 { LOPT_PREF_CLSS
, ARG_DUP
, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL
},
432 #ifdef HAVE_QUIET_DHCP //originally TOMATO option
433 { LOPT_QUIET_DHCP
, OPT_QUIET_DHCP
, NULL
, gettext_noop("Do not log DHCP packets."), NULL
},
434 { LOPT_QUIET_DHCP6
, OPT_QUIET_DHCP6
, NULL
, gettext_noop("Do not log DHCPv6 packets."), NULL
},
435 { LOPT_QUIET_RA
, OPT_QUIET_RA
, NULL
, gettext_noop("Do not log RA packets."), NULL
},
437 { 0, 0, NULL
, NULL
, NULL
}
440 /* We hide metacharaters in quoted strings by mapping them into the ASCII control
441 character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the
442 following sequence so that they map to themselves: it is therefore possible to call
443 unhide_metas repeatedly on string without breaking things.
444 The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a
445 couple of other places.
446 Note that space is included here so that
447 --dhcp-option=3, string
448 has five characters, whilst
449 --dhcp-option=3," string"
453 static const char meta
[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
455 static char hide_meta(char c
)
459 for (i
= 0; i
< (sizeof(meta
) - 1); i
++)
466 static char unhide_meta(char cr
)
470 if (c
< (sizeof(meta
) - 1))
476 static void unhide_metas(char *cp
)
480 *cp
= unhide_meta(*cp
);
483 static void *opt_malloc(size_t size
)
489 ret
= whine_malloc(size
);
494 ret
= safe_malloc(size
);
499 static char *opt_string_alloc(char *cp
)
503 if (cp
&& strlen(cp
) != 0)
505 ret
= opt_malloc(strlen(cp
)+1);
508 /* restore hidden metachars */
516 /* find next comma, split string with zero and eliminate spaces.
517 return start of string following comma */
519 static char *split_chr(char *s
, char c
)
523 if (!s
|| !(comma
= strchr(s
, c
)))
529 for (; *comma
== ' '; comma
++);
531 for (; (p
>= s
) && *p
== ' '; p
--)
537 static char *split(char *s
)
539 return split_chr(s
, ',');
542 static char *canonicalise_opt(char *s
)
551 if (!(ret
= canonicalise(s
, &nomem
)) && nomem
)
556 die(_("could not get memory"), NULL
, EC_NOMEM
);
562 static int atoi_check(char *a
, int *res
)
572 if (*p
< '0' || *p
> '9')
579 static int atoi_check16(char *a
, int *res
)
581 if (!(atoi_check(a
, res
)) ||
589 static void add_txt(char *name
, char *txt
)
591 size_t len
= strlen(txt
);
592 struct txt_record
*r
= opt_malloc(sizeof(struct txt_record
));
594 r
->name
= opt_string_alloc(name
);
595 r
->next
= daemon
->txt
;
598 r
->txt
= opt_malloc(len
+1);
601 memcpy((r
->txt
)+1, txt
, len
);
604 static void do_usage(void)
617 { '#', TFTP_MAX_CONNECTIONS
},
621 printf(_("Usage: dnsmasq [options]\n\n"));
622 #ifndef HAVE_GETOPT_LONG
623 printf(_("Use short options only on the command line.\n"));
625 printf(_("Valid options are:\n"));
627 for (i
= 0; usage
[i
].opt
!= 0; i
++)
629 char *desc
= usage
[i
].flagdesc
;
632 if (!desc
|| *desc
== '[')
638 for ( j
= 0; opts
[j
].name
; j
++)
639 if (opts
[j
].val
== usage
[i
].opt
)
641 if (usage
[i
].opt
< 256)
642 sprintf(buff
, "-%c, ", usage
[i
].opt
);
646 sprintf(buff
+4, "--%s%s%s", opts
[j
].name
, eq
, desc
);
647 printf("%-40.40s", buff
);
651 strcpy(buff
, usage
[i
].arg
);
652 for (j
= 0; tab
[j
].handle
; j
++)
653 if (tab
[j
].handle
== *(usage
[i
].arg
))
654 sprintf(buff
, "%d", tab
[j
].val
);
656 printf(_(usage
[i
].desc
), buff
);
661 #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
663 char *parse_server(char *arg
, union mysockaddr
*addr
, union mysockaddr
*source_addr
, char *interface
, int *flags
)
665 int source_port
= 0, serv_port
= NAMESERVER_PORT
;
666 char *portno
, *source
;
672 if ((source
= split_chr(arg
, '@')) && /* is there a source. */
673 (portno
= split_chr(source
, '#')) &&
674 !atoi_check16(portno
, &source_port
))
675 return _("bad port");
677 if ((portno
= split_chr(arg
, '#')) && /* is there a port no. */
678 !atoi_check16(portno
, &serv_port
))
679 return _("bad port");
682 scope_id
= split_chr(arg
, '%');
685 if (inet_pton(AF_INET
, arg
, &addr
->in
.sin_addr
) > 0)
687 addr
->in
.sin_port
= htons(serv_port
);
688 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET
;
689 #ifdef HAVE_SOCKADDR_SA_LEN
690 source_addr
->in
.sin_len
= addr
->in
.sin_len
= sizeof(struct sockaddr_in
);
692 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
693 source_addr
->in
.sin_port
= htons(daemon
->query_port
);
698 *flags
|= SERV_HAS_SOURCE
;
699 source_addr
->in
.sin_port
= htons(source_port
);
700 if (!(inet_pton(AF_INET
, source
, &source_addr
->in
.sin_addr
) > 0))
702 #if defined(SO_BINDTODEVICE)
703 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
704 strncpy(interface
, source
, IF_NAMESIZE
- 1);
706 return _("interface binding not supported");
712 else if (inet_pton(AF_INET6
, arg
, &addr
->in6
.sin6_addr
) > 0)
714 if (scope_id
&& (scope_index
= if_nametoindex(scope_id
)) == 0)
715 return _("bad interface name");
717 addr
->in6
.sin6_port
= htons(serv_port
);
718 addr
->in6
.sin6_scope_id
= scope_index
;
719 source_addr
->in6
.sin6_addr
= in6addr_any
;
720 source_addr
->in6
.sin6_port
= htons(daemon
->query_port
);
721 source_addr
->in6
.sin6_scope_id
= 0;
722 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET6
;
723 addr
->in6
.sin6_flowinfo
= source_addr
->in6
.sin6_flowinfo
= 0;
724 #ifdef HAVE_SOCKADDR_SA_LEN
725 addr
->in6
.sin6_len
= source_addr
->in6
.sin6_len
= sizeof(addr
->in6
);
730 *flags
|= SERV_HAS_SOURCE
;
731 source_addr
->in6
.sin6_port
= htons(source_port
);
732 if (inet_pton(AF_INET6
, source
, &source_addr
->in6
.sin6_addr
) == 0)
734 #if defined(SO_BINDTODEVICE)
735 source_addr
->in6
.sin6_addr
= in6addr_any
;
736 strncpy(interface
, source
, IF_NAMESIZE
- 1);
738 return _("interface binding not supported");
745 return _("bad address");
752 static int is_tag_prefix(char *arg
)
754 if (arg
&& (strstr(arg
, "net:") == arg
|| strstr(arg
, "tag:") == arg
))
760 static char *set_prefix(char *arg
)
762 if (strstr(arg
, "set:") == arg
)
768 /* This is too insanely large to keep in-line in the switch */
769 static int parse_dhcp_opt(char *errstr
, char *arg
, int flags
)
771 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
772 char lenchar
= 0, *cp
;
773 int addrs
, digs
, is_addr
, is_addr6
, is_hex
, is_dec
, is_string
, dots
;
775 struct dhcp_netid
*np
= NULL
;
790 for (cp
= arg
; *cp
; cp
++)
791 if (*cp
< '0' || *cp
> '9')
796 new->opt
= atoi(arg
);
802 if (strstr(arg
, "option:") == arg
)
804 if ((new->opt
= lookup_dhcp_opt(AF_INET
, arg
+7)) != -1)
806 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
807 /* option:<optname> must follow tag and vendor string. */
808 if (!(opt_len
& OT_INTERNAL
) || flags
== DHOPT_MATCH
)
814 else if (strstr(arg
, "option6:") == arg
)
816 for (cp
= arg
+8; *cp
; cp
++)
817 if (*cp
< '0' || *cp
> '9')
822 new->opt
= atoi(arg
+8);
828 if ((new->opt
= lookup_dhcp_opt(AF_INET6
, arg
+8)) != -1)
830 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
831 if (!(opt_len
& OT_INTERNAL
) || flags
== DHOPT_MATCH
)
835 /* option6:<opt>|<optname> must follow tag and vendor string. */
840 else if (strstr(arg
, "vendor:") == arg
)
842 new->u
.vendor_class
= (unsigned char *)opt_string_alloc(arg
+7);
843 new->flags
|= DHOPT_VENDOR
;
845 else if (strstr(arg
, "encap:") == arg
)
847 new->u
.encap
= atoi(arg
+6);
848 new->flags
|= DHOPT_ENCAPSULATE
;
850 else if (strstr(arg
, "vi-encap:") == arg
)
852 new->u
.encap
= atoi(arg
+9);
853 new->flags
|= DHOPT_RFC3925
;
854 if (flags
== DHOPT_MATCH
)
862 new->netid
= opt_malloc(sizeof (struct dhcp_netid
));
863 /* allow optional "net:" or "tag:" for consistency */
864 if (is_tag_prefix(arg
))
865 new->netid
->net
= opt_string_alloc(arg
+4);
867 new->netid
->net
= opt_string_alloc(set_prefix(arg
));
868 new->netid
->next
= np
;
878 if (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))
879 ret_err(_("unsupported encapsulation for IPv6 option"));
882 !(new->flags
& DHOPT_RFC3925
))
883 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
888 !(new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
| DHOPT_RFC3925
)))
889 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
891 /* option may be missing with rfc3925 match */
893 ret_err(_("bad dhcp-option"));
897 /* characterise the value */
900 is_addr
= is_addr6
= is_hex
= is_dec
= is_string
= 1;
903 for (cp
= comma
; (c
= *cp
); cp
++)
912 is_dec
= is_addr
= 0;
916 is_addr6
= is_dec
= is_hex
= 0;
917 if (cp
== comma
) /* leading / means a pathname */
922 is_addr6
= is_dec
= is_hex
= 0;
926 is_hex
= is_addr
= is_addr6
= 0;
929 else if (!(c
>='0' && c
<= '9'))
932 if (cp
[1] == 0 && is_dec
&&
933 (c
== 'b' || c
== 's' || c
== 'i'))
940 if (!((c
>='A' && c
<= 'F') ||
941 (c
>='a' && c
<= 'f') ||
942 (c
== '*' && (flags
& DHOPT_MATCH
))))
945 if (c
!= '[' && c
!= ']')
953 is_dec
= is_addr
= 0;
955 /* We know that some options take addresses */
956 if (opt_len
& OT_ADDR_LIST
)
958 is_string
= is_dec
= is_hex
= 0;
960 if (!is6
&& (!is_addr
|| dots
== 0))
961 ret_err(_("bad IP address"));
963 if (is6
&& !is_addr6
)
964 ret_err(_("bad IPv6 address"));
967 else if (opt_len
& (OT_NAME
| OT_RFC1035_NAME
| OT_CSTRING
))
968 is_addr6
= is_addr
= is_dec
= is_hex
= 0;
970 if (found_dig
&& (opt_len
& OT_TIME
) && strlen(comma
) > 0)
974 switch (comma
[strlen(comma
) - 1])
994 comma
[strlen(comma
) - 1] = 0;
998 new->val
= opt_malloc(4);
1000 *((int *)new->val
) = htonl(val
* fac
);
1002 else if (is_hex
&& digs
> 1)
1005 new->val
= opt_malloc(new->len
);
1006 parse_hex(comma
, new->val
, digs
, (flags
& DHOPT_MATCH
) ? &new->u
.wildcard_mask
: NULL
, NULL
);
1007 new->flags
|= DHOPT_HEX
;
1011 int i
, val
= atoi(comma
);
1012 /* assume numeric arg is 1 byte except for
1013 options where it is known otherwise.
1014 For vendor class option, we have to hack. */
1017 else if (val
& 0xffff0000)
1019 else if (val
& 0xff00)
1026 else if (lenchar
== 's')
1028 else if (lenchar
== 'i')
1031 new->val
= opt_malloc(new->len
);
1032 for (i
=0; i
<new->len
; i
++)
1033 new->val
[i
] = val
>>((new->len
- i
- 1)*8);
1035 else if (is_addr
&& !is6
)
1040 /* max length of address/subnet descriptor is five bytes,
1041 add one for the option 120 enc byte too */
1042 new->val
= op
= opt_malloc((5 * addrs
) + 1);
1043 new->flags
|= DHOPT_ADDR
;
1045 if (!(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)) &&
1046 new->opt
== OPTION_SIP_SERVER
)
1048 *(op
++) = 1; /* RFC 3361 "enc byte" */
1049 new->flags
&= ~DHOPT_ADDR
;
1055 slash
= split_chr(cp
, '/');
1056 inet_pton(AF_INET
, cp
, &in
);
1059 memcpy(op
, &in
, INADDRSZ
);
1064 unsigned char *p
= (unsigned char *)&in
;
1065 int netsize
= atoi(slash
);
1075 new->flags
&= ~DHOPT_ADDR
; /* cannot re-write descriptor format */
1078 new->len
= op
- new->val
;
1080 else if (is_addr6
&& is6
)
1083 new->val
= op
= opt_malloc(16 * addrs
);
1084 new->flags
|= DHOPT_ADDR6
;
1090 /* check for [1234::7] */
1093 if (strlen(cp
) > 1 && cp
[strlen(cp
)-1] == ']')
1094 cp
[strlen(cp
)-1] = 0;
1096 if (inet_pton(AF_INET6
, cp
, op
))
1102 ret_err(_("bad IPv6 address"));
1104 new->len
= op
- new->val
;
1109 if ((new->opt
== OPTION_DOMAIN_SEARCH
|| new->opt
== OPTION_SIP_SERVER
) &&
1110 !is6
&& !(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)))
1112 /* dns search, RFC 3397, or SIP, RFC 3361 */
1113 unsigned char *q
, *r
, *tail
;
1114 unsigned char *p
, *m
= NULL
, *newp
;
1115 size_t newlen
, len
= 0;
1116 int header_size
= (new->opt
== OPTION_DOMAIN_SEARCH
) ? 0 : 1;
1123 char *in
, *dom
= NULL
;
1125 /* Allow "." as an empty domain */
1126 if (strcmp (arg
, ".") != 0)
1128 if (!(dom
= canonicalise_opt(arg
)))
1129 ret_err(_("bad domain in dhcp-option"));
1131 domlen
= strlen(dom
) + 2;
1134 newp
= opt_malloc(len
+ domlen
+ header_size
);
1137 memcpy(newp
, m
, header_size
+ len
);
1141 p
= m
+ header_size
;
1144 /* add string on the end in RFC1035 format */
1145 for (in
= dom
; in
&& *in
;)
1147 unsigned char *cp
= q
++;
1149 for (j
= 0; *in
&& (*in
!= '.'); in
++, j
++)
1158 /* Now tail-compress using earlier names. */
1160 for (tail
= p
+ len
; *tail
; tail
+= (*tail
) + 1)
1161 for (r
= p
; r
- p
< (int)len
; r
+= (*r
) + 1)
1162 if (strcmp((char *)r
, (char *)tail
) == 0)
1164 PUTSHORT((r
- p
) | 0xc000, tail
);
1175 /* RFC 3361, enc byte is zero for names */
1176 if (new->opt
== OPTION_SIP_SERVER
)
1178 new->len
= (int) len
+ header_size
;
1182 else if (comma
&& (opt_len
& OT_CSTRING
))
1184 /* length fields are two bytes so need 16 bits for each string */
1186 unsigned char *p
, *newp
;
1188 for (i
= 0; comma
[i
]; i
++)
1189 if (comma
[i
] == ',')
1192 newp
= opt_malloc(strlen(comma
)+(2*commas
));
1199 u16 len
= strlen(arg
);
1202 memcpy(p
, arg
, len
);
1210 new->len
= p
- newp
;
1212 else if (comma
&& (opt_len
& OT_RFC1035_NAME
))
1214 unsigned char *p
= NULL
, *newp
, *end
;
1221 char *dom
= canonicalise_opt(arg
);
1223 ret_err(_("bad domain in dhcp-option"));
1225 newp
= opt_malloc(len
+ strlen(dom
) + 2);
1229 memcpy(newp
, p
, len
);
1234 end
= do_rfc1035_name(p
+ len
, dom
);
1249 new->len
= strlen(comma
);
1250 /* keep terminating zero on string */
1251 new->val
= (unsigned char *)opt_string_alloc(comma
);
1252 new->flags
|= DHOPT_STRING
;
1258 ((new->len
> 255) ||
1259 (new->len
> 253 && (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))) ||
1260 (new->len
> 250 && (new->flags
& DHOPT_RFC3925
))))
1261 ret_err(_("dhcp-option too long"));
1263 if (flags
== DHOPT_MATCH
)
1265 if ((new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
)) ||
1268 ret_err(_("illegal dhcp-match"));
1272 new->next
= daemon
->dhcp_match6
;
1273 daemon
->dhcp_match6
= new;
1277 new->next
= daemon
->dhcp_match
;
1278 daemon
->dhcp_match
= new;
1283 new->next
= daemon
->dhcp_opts6
;
1284 daemon
->dhcp_opts6
= new;
1288 new->next
= daemon
->dhcp_opts
;
1289 daemon
->dhcp_opts
= new;
1297 void set_option_bool(unsigned int opt
)
1300 daemon
->options
|= 1u << opt
;
1302 daemon
->options2
|= 1u << (opt
- 32);
1305 void reset_option_bool(unsigned int opt
)
1308 daemon
->options
&= ~(1u << opt
);
1310 daemon
->options2
&= ~(1u << (opt
- 32));
1313 static int one_opt(int option
, char *arg
, char *errstr
, char *gen_err
, int command_line
)
1321 for (i
=0; usage
[i
].opt
!= 0; i
++)
1322 if (usage
[i
].opt
== option
)
1324 int rept
= usage
[i
].rept
;
1329 if (rept
== ARG_USED_CL
)
1330 ret_err(_("illegal repeated flag"));
1331 if (rept
== ARG_ONE
)
1332 usage
[i
].rept
= ARG_USED_CL
;
1336 /* allow file to override command line */
1337 if (rept
== ARG_USED_FILE
)
1338 ret_err(_("illegal repeated keyword"));
1339 if (rept
== ARG_USED_CL
|| rept
== ARG_ONE
)
1340 usage
[i
].rept
= ARG_USED_FILE
;
1343 if (rept
!= ARG_DUP
&& rept
!= ARG_ONE
&& rept
!= ARG_USED_CL
)
1345 set_option_bool(rept
);
1354 case 'C': /* --conf-file */
1356 char *file
= opt_string_alloc(arg
);
1365 case '7': /* --conf-dir */
1369 char *directory
, *path
;
1373 } *ignore_suffix
= NULL
, *li
;
1376 if (!(directory
= opt_string_alloc(arg
)))
1379 for (arg
= comma
; arg
; arg
= comma
)
1382 li
= opt_malloc(sizeof(struct list
));
1383 li
->next
= ignore_suffix
;
1385 /* Have to copy: buffer is overwritten */
1386 li
->suffix
= opt_string_alloc(arg
);
1389 if (!(dir_stream
= opendir(directory
)))
1390 die(_("cannot access directory %s: %s"), directory
, EC_FILE
);
1392 while ((ent
= readdir(dir_stream
)))
1394 size_t len
= strlen(ent
->d_name
);
1397 /* ignore emacs backups and dotfiles */
1399 ent
->d_name
[len
- 1] == '~' ||
1400 (ent
->d_name
[0] == '#' && ent
->d_name
[len
- 1] == '#') ||
1401 ent
->d_name
[0] == '.')
1404 for (li
= ignore_suffix
; li
; li
= li
->next
)
1406 /* check for proscribed suffices */
1407 size_t ls
= strlen(li
->suffix
);
1409 strcmp(li
->suffix
, &ent
->d_name
[len
- ls
]) == 0)
1415 path
= opt_malloc(strlen(directory
) + len
+ 2);
1416 strcpy(path
, directory
);
1418 strcat(path
, ent
->d_name
);
1420 /* files must be readable */
1421 if (stat(path
, &buf
) == -1)
1422 die(_("cannot access %s: %s"), path
, EC_FILE
);
1424 /* only reg files allowed. */
1425 if (S_ISREG(buf
.st_mode
))
1431 closedir(dir_stream
);
1433 for(; ignore_suffix
; ignore_suffix
= li
)
1435 li
= ignore_suffix
->next
;
1436 free(ignore_suffix
->suffix
);
1437 free(ignore_suffix
);
1443 case '1': /* --enable-dbus */
1444 set_option_bool(OPT_DBUS
);
1446 daemon
->dbus_name
= opt_string_alloc(arg
);
1448 daemon
->dbus_name
= DNSMASQ_SERVICE
;
1451 case '8': /* --log-facility */
1452 /* may be a filename */
1453 if (strchr(arg
, '/') || strcmp (arg
, "-") == 0)
1454 daemon
->log_file
= opt_string_alloc(arg
);
1458 ret_err(_("setting log facility is not possible under Android"));
1460 for (i
= 0; facilitynames
[i
].c_name
; i
++)
1461 if (hostname_isequal((char *)facilitynames
[i
].c_name
, arg
))
1464 if (facilitynames
[i
].c_name
)
1465 daemon
->log_fac
= facilitynames
[i
].c_val
;
1467 ret_err(_("bad log facility"));
1472 case 'x': /* --pid-file */
1473 daemon
->runfile
= opt_string_alloc(arg
);
1476 case 'r': /* --resolv-file */
1478 char *name
= opt_string_alloc(arg
);
1479 struct resolvc
*new, *list
= daemon
->resolv_files
;
1481 if (list
&& list
->is_default
)
1483 /* replace default resolv file - possibly with nothing */
1486 list
->is_default
= 0;
1494 new = opt_malloc(sizeof(struct resolvc
));
1497 new->is_default
= 0;
1502 daemon
->resolv_files
= list
;
1506 case 'm': /* --mx-host */
1509 struct mx_srv_record
*new;
1510 char *name
, *target
= NULL
;
1512 if ((comma
= split(arg
)))
1515 if ((prefstr
= split(comma
)) && !atoi_check16(prefstr
, &pref
))
1516 ret_err(_("bad MX preference"));
1519 if (!(name
= canonicalise_opt(arg
)) ||
1520 (comma
&& !(target
= canonicalise_opt(comma
))))
1521 ret_err(_("bad MX name"));
1523 new = opt_malloc(sizeof(struct mx_srv_record
));
1524 new->next
= daemon
->mxnames
;
1525 daemon
->mxnames
= new;
1528 new->target
= target
; /* may be NULL */
1533 case 't': /* --mx-target */
1534 if (!(daemon
->mxtarget
= canonicalise_opt(arg
)))
1535 ret_err(_("bad MX target"));
1539 case 'l': /* --dhcp-leasefile */
1540 daemon
->lease_file
= opt_string_alloc(arg
);
1543 /* Sorry about the gross pre-processor abuse */
1544 case '6': /* --dhcp-script */
1545 case LOPT_LUASCRIPT
: /* --dhcp-luascript */
1546 # if defined(NO_FORK)
1547 ret_err(_("cannot run scripts under uClinux"));
1548 # elif !defined(HAVE_SCRIPT)
1549 ret_err(_("recompile with HAVE_SCRIPT defined to enable lease-change scripts"));
1551 if (option
== LOPT_LUASCRIPT
)
1552 # if !defined(HAVE_LUASCRIPT)
1553 ret_err(_("recompile with HAVE_LUASCRIPT defined to enable Lua scripts"));
1555 daemon
->luascript
= opt_string_alloc(arg
);
1558 daemon
->lease_change_command
= opt_string_alloc(arg
);
1561 #endif /* HAVE_DHCP */
1563 case LOPT_DHCP_HOST
: /* --dhcp-hostfile */
1564 case LOPT_DHCP_OPTS
: /* --dhcp-optsfile */
1565 case 'H': /* --addn-hosts */
1567 struct hostsfile
*new = opt_malloc(sizeof(struct hostsfile
));
1568 static int hosts_index
= 1;
1569 new->fname
= opt_string_alloc(arg
);
1570 new->index
= hosts_index
++;
1574 new->next
= daemon
->addn_hosts
;
1575 daemon
->addn_hosts
= new;
1577 else if (option
== LOPT_DHCP_HOST
)
1579 new->next
= daemon
->dhcp_hosts_file
;
1580 daemon
->dhcp_hosts_file
= new;
1582 else if (option
== LOPT_DHCP_OPTS
)
1584 new->next
= daemon
->dhcp_opts_file
;
1585 daemon
->dhcp_opts_file
= new;
1592 case LOPT_AUTHSERV
: /* --auth-server */
1593 if (!(comma
= split(arg
)))
1596 daemon
->authserver
= opt_string_alloc(arg
);
1599 struct iname
*new = opt_malloc(sizeof(struct iname
));
1603 if (inet_pton(AF_INET
, arg
, &new->addr
.in
.sin_addr
) > 0)
1604 new->addr
.sa
.sa_family
= AF_INET
;
1606 else if (inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
1607 new->addr
.sa
.sa_family
= AF_INET6
;
1610 new->name
= opt_string_alloc(arg
);
1612 new->next
= daemon
->authinterface
;
1613 daemon
->authinterface
= new;
1620 case LOPT_AUTHSFS
: /* --auth-sec-servers */
1622 struct name_list
*new;
1626 new = opt_malloc(sizeof(struct name_list
));
1627 new->name
= opt_string_alloc(arg
);
1628 new->next
= daemon
->secondary_forward_server
;
1629 daemon
->secondary_forward_server
= new;
1635 case LOPT_AUTHZONE
: /* --auth-zone */
1637 struct auth_zone
*new;
1641 new = opt_malloc(sizeof(struct auth_zone
));
1642 new->domain
= opt_string_alloc(arg
);
1644 new->next
= daemon
->auth_zones
;
1645 daemon
->auth_zones
= new;
1647 while ((arg
= comma
))
1651 struct subnet
*subnet
= opt_malloc(sizeof(struct subnet
));
1653 subnet
->next
= new->subnet
;
1654 new->subnet
= subnet
;
1657 prefix
= split_chr(arg
, '/');
1659 if (prefix
&& !atoi_check(prefix
, &prefixlen
))
1662 if (inet_pton(AF_INET
, arg
, &subnet
->addr4
))
1664 subnet
->prefixlen
= (prefixlen
== 0) ? 24 : prefixlen
;
1668 else if (inet_pton(AF_INET6
, arg
, &subnet
->addr6
))
1670 subnet
->prefixlen
= (prefixlen
== 0) ? 64 : prefixlen
;
1680 case LOPT_AUTHSOA
: /* --auth-soa */
1682 daemon
->soa_sn
= (u32
)atoi(arg
);
1688 daemon
->hostmaster
= opt_string_alloc(arg
);
1689 for (cp
= daemon
->hostmaster
; *cp
; cp
++)
1697 daemon
->soa_refresh
= (u32
)atoi(arg
);
1702 daemon
->soa_retry
= (u32
)atoi(arg
);
1707 daemon
->soa_expiry
= (u32
)atoi(arg
);
1716 case 's': /* --domain */
1717 case LOPT_SYNTH
: /* --synth-domain */
1718 if (strcmp (arg
, "#") == 0)
1719 set_option_bool(OPT_RESOLV_DOMAIN
);
1724 if (!(d
= canonicalise_opt(arg
)))
1730 struct cond_domain
*new = opt_malloc(sizeof(struct cond_domain
));
1735 unhide_metas(comma
);
1736 if ((netpart
= split_chr(comma
, '/')))
1740 arg
= split(netpart
);
1741 if (!atoi_check(netpart
, &msize
))
1743 else if (inet_pton(AF_INET
, comma
, &new->start
))
1745 int mask
= (1 << (32 - msize
)) - 1;
1747 new->start
.s_addr
= ntohl(htonl(new->start
.s_addr
) & ~mask
);
1748 new->end
.s_addr
= new->start
.s_addr
| htonl(mask
);
1753 if (!(new->prefix
= canonicalise_opt(arg
)) ||
1754 strlen(new->prefix
) > MAXLABEL
- INET_ADDRSTRLEN
)
1755 ret_err(_("bad prefix"));
1757 else if (strcmp(arg
, "local") != 0 ||
1758 (msize
!= 8 && msize
!= 16 && msize
!= 24))
1762 /* generate the equivalent of
1764 local=/xxx.yyy.zzz.in-addr.arpa/ */
1765 struct server
*serv
= opt_malloc(sizeof(struct server
));
1766 in_addr_t a
= ntohl(new->start
.s_addr
) >> 8;
1769 memset(serv
, 0, sizeof(struct server
));
1771 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1772 serv
->next
= daemon
->servers
;
1773 daemon
->servers
= serv
;
1775 serv
= opt_malloc(sizeof(struct server
));
1776 memset(serv
, 0, sizeof(struct server
));
1777 p
= serv
->domain
= opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */
1780 p
+= sprintf(p
, "%d.", a
& 0xff);
1783 p
+= sprintf(p
, "%d.", a
& 0xff);
1785 p
+= sprintf(p
, "%d.in-addr.arpa", a
& 0xff);
1787 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1788 serv
->next
= daemon
->servers
;
1789 daemon
->servers
= serv
;
1794 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1796 u64 mask
= (1LLU << (128 - msize
)) - 1LLU;
1797 u64 addrpart
= addr6part(&new->start6
);
1800 /* prefix==64 overflows the mask calculation above */
1804 new->end6
= new->start6
;
1805 setaddr6part(&new->start6
, addrpart
& ~mask
);
1806 setaddr6part(&new->end6
, addrpart
| mask
);
1814 if (!(new->prefix
= canonicalise_opt(arg
)) ||
1815 strlen(new->prefix
) > MAXLABEL
- INET6_ADDRSTRLEN
)
1816 ret_err(_("bad prefix"));
1818 else if (strcmp(arg
, "local") != 0 || ((msize
& 4) != 0))
1822 /* generate the equivalent of
1824 local=/xxx.yyy.zzz.ip6.arpa/ */
1825 struct server
*serv
= opt_malloc(sizeof(struct server
));
1828 memset(serv
, 0, sizeof(struct server
));
1830 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1831 serv
->next
= daemon
->servers
;
1832 daemon
->servers
= serv
;
1834 serv
= opt_malloc(sizeof(struct server
));
1835 memset(serv
, 0, sizeof(struct server
));
1836 p
= serv
->domain
= opt_malloc(73); /* strlen("32*<n.>ip6.arpa")+1 */
1838 for (i
= msize
-1; i
>= 0; i
-= 4)
1840 int dig
= ((unsigned char *)&new->start6
)[i
>>3];
1841 p
+= sprintf(p
, "%.1x.", (i
>>2) & 1 ? dig
& 15 : dig
>> 4);
1843 p
+= sprintf(p
, "ip6.arpa");
1845 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1846 serv
->next
= daemon
->servers
;
1847 daemon
->servers
= serv
;
1858 if (inet_pton(AF_INET
, comma
, &new->start
))
1862 new->end
.s_addr
= new->start
.s_addr
;
1863 else if (!inet_pton(AF_INET
, arg
, &new->end
))
1867 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1871 memcpy(&new->end6
, &new->start6
, IN6ADDRSZ
);
1872 else if (!inet_pton(AF_INET6
, arg
, &new->end6
))
1883 new->next
= daemon
->cond_domain
;
1884 daemon
->cond_domain
= new;
1888 new->next
= daemon
->synth_domains
;
1889 daemon
->synth_domains
= new;
1892 else if (option
== 's')
1893 daemon
->domain_suffix
= d
;
1900 case 'u': /* --user */
1901 daemon
->username
= opt_string_alloc(arg
);
1904 case 'g': /* --group */
1905 daemon
->groupname
= opt_string_alloc(arg
);
1906 daemon
->group_set
= 1;
1910 case LOPT_SCRIPTUSR
: /* --scriptuser */
1911 daemon
->scriptuser
= opt_string_alloc(arg
);
1915 case 'i': /* --interface */
1917 struct iname
*new = opt_malloc(sizeof(struct iname
));
1919 new->next
= daemon
->if_names
;
1920 daemon
->if_names
= new;
1921 /* new->name may be NULL if someone does
1922 "interface=" to disable all interfaces except loop. */
1923 new->name
= opt_string_alloc(arg
);
1929 case LOPT_TFTP
: /* --enable-tftp */
1930 set_option_bool(OPT_TFTP
);
1935 case 'I': /* --except-interface */
1936 case '2': /* --no-dhcp-interface */
1938 struct iname
*new = opt_malloc(sizeof(struct iname
));
1940 new->name
= opt_string_alloc(arg
);
1943 new->next
= daemon
->if_except
;
1944 daemon
->if_except
= new;
1946 else if (option
== LOPT_TFTP
)
1948 new->next
= daemon
->tftp_interfaces
;
1949 daemon
->tftp_interfaces
= new;
1953 new->next
= daemon
->dhcp_except
;
1954 daemon
->dhcp_except
= new;
1960 case 'B': /* --bogus-nxdomain */
1962 struct in_addr addr
;
1964 if (arg
&& (inet_pton(AF_INET
, arg
, &addr
) > 0))
1966 struct bogus_addr
*baddr
= opt_malloc(sizeof(struct bogus_addr
));
1967 baddr
->next
= daemon
->bogus_addr
;
1968 daemon
->bogus_addr
= baddr
;
1972 ret_err(gen_err
); /* error */
1976 case 'a': /* --listen-address */
1977 case LOPT_AUTHPEER
: /* --auth-peer */
1979 struct iname
*new = opt_malloc(sizeof(struct iname
));
1982 if (arg
&& (inet_pton(AF_INET
, arg
, &new->addr
.in
.sin_addr
) > 0))
1984 new->addr
.sa
.sa_family
= AF_INET
;
1985 new->addr
.in
.sin_port
= 0;
1986 #ifdef HAVE_SOCKADDR_SA_LEN
1987 new->addr
.in
.sin_len
= sizeof(new->addr
.in
);
1991 else if (arg
&& inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
1993 new->addr
.sa
.sa_family
= AF_INET6
;
1994 new->addr
.in6
.sin6_flowinfo
= 0;
1995 new->addr
.in6
.sin6_scope_id
= 0;
1996 new->addr
.in6
.sin6_port
= 0;
1997 #ifdef HAVE_SOCKADDR_SA_LEN
1998 new->addr
.in6
.sin6_len
= sizeof(new->addr
.in6
);
2008 new->next
= daemon
->if_addrs
;
2009 daemon
->if_addrs
= new;
2013 new->next
= daemon
->auth_peers
;
2014 daemon
->auth_peers
= new;
2020 case 'S': /* --server */
2021 case LOPT_LOCAL
: /* --local */
2022 case 'A': /* --address */
2023 case LOPT_NO_REBIND
: /* --rebind-domain-ok */
2025 struct server
*serv
, *newlist
= NULL
;
2029 if (arg
&& (*arg
== '/' || option
== LOPT_NO_REBIND
))
2031 int rebind
= !(*arg
== '/');
2035 while (rebind
|| (end
= split_chr(arg
, '/')))
2037 char *domain
= NULL
;
2038 /* elide leading dots - they are implied in the search algorithm */
2039 while (*arg
== '.') arg
++;
2040 /* # matches everything and becomes a zero length domain string */
2041 if (strcmp(arg
, "#") == 0)
2043 else if (strlen (arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
2045 serv
= opt_malloc(sizeof(struct server
));
2046 memset(serv
, 0, sizeof(struct server
));
2047 serv
->next
= newlist
;
2049 serv
->domain
= domain
;
2050 serv
->flags
= domain
? SERV_HAS_DOMAIN
: SERV_FOR_NODOTS
;
2060 newlist
= opt_malloc(sizeof(struct server
));
2061 memset(newlist
, 0, sizeof(struct server
));
2066 newlist
->flags
|= SERV_LITERAL_ADDRESS
;
2067 if (!(newlist
->flags
& SERV_TYPE
))
2070 else if (option
== LOPT_NO_REBIND
)
2071 newlist
->flags
|= SERV_NO_REBIND
;
2075 if (!(newlist
->flags
& SERV_NO_REBIND
))
2076 newlist
->flags
|= SERV_NO_ADDR
; /* no server */
2077 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
2081 else if (strcmp(arg
, "#") == 0)
2083 newlist
->flags
|= SERV_USE_RESOLV
; /* treat in ordinary way */
2084 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
2089 char *err
= parse_server(arg
, &newlist
->addr
, &newlist
->source_addr
, newlist
->interface
, &newlist
->flags
);
2097 serv
->next
->flags
= serv
->flags
;
2098 serv
->next
->addr
= serv
->addr
;
2099 serv
->next
->source_addr
= serv
->source_addr
;
2100 strcpy(serv
->next
->interface
, serv
->interface
);
2103 serv
->next
= daemon
->servers
;
2104 daemon
->servers
= newlist
;
2108 case LOPT_IPSET
: /* --ipset */
2110 ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
2114 struct ipsets ipsets_head
;
2115 struct ipsets
*ipsets
= &ipsets_head
;
2118 char **sets
, **sets_pos
;
2119 memset(ipsets
, 0, sizeof(struct ipsets
));
2121 if (arg
&& *arg
== '/')
2124 while ((end
= split_chr(arg
, '/')))
2126 char *domain
= NULL
;
2127 /* elide leading dots - they are implied in the search algorithm */
2130 /* # matches everything and becomes a zero length domain string */
2131 if (strcmp(arg
, "#") == 0 || !*arg
)
2133 else if (strlen(arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
2135 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2136 ipsets
= ipsets
->next
;
2137 memset(ipsets
, 0, sizeof(struct ipsets
));
2138 ipsets
->domain
= domain
;
2144 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2145 ipsets
= ipsets
->next
;
2146 memset(ipsets
, 0, sizeof(struct ipsets
));
2147 ipsets
->domain
= "";
2155 for (end
= arg
; *end
; ++end
)
2159 sets
= sets_pos
= opt_malloc(sizeof(char *) * size
);
2163 *sets_pos
++ = opt_string_alloc(arg
);
2167 for (ipsets
= &ipsets_head
; ipsets
->next
; ipsets
= ipsets
->next
)
2168 ipsets
->next
->sets
= sets
;
2169 ipsets
->next
= daemon
->ipsets
;
2170 daemon
->ipsets
= ipsets_head
.next
;
2176 case 'c': /* --cache-size */
2180 if (!atoi_check(arg
, &size
))
2184 /* zero is OK, and means no caching. */
2188 else if (size
> 10000)
2191 daemon
->cachesize
= size
;
2196 case 'p': /* --port */
2197 if (!atoi_check16(arg
, &daemon
->port
))
2201 case LOPT_MINPORT
: /* --min-port */
2202 if (!atoi_check16(arg
, &daemon
->min_port
))
2206 case '0': /* --dns-forward-max */
2207 if (!atoi_check(arg
, &daemon
->ftabsize
))
2211 case LOPT_MAX_LOGS
: /* --log-async */
2212 daemon
->max_logs
= LOG_MAX
; /* default */
2213 if (arg
&& !atoi_check(arg
, &daemon
->max_logs
))
2215 else if (daemon
->max_logs
> 100)
2216 daemon
->max_logs
= 100;
2219 case 'P': /* --edns-packet-max */
2222 if (!atoi_check(arg
, &i
))
2224 daemon
->edns_pktsz
= (unsigned short)i
;
2228 case 'Q': /* --query-port */
2229 if (!atoi_check16(arg
, &daemon
->query_port
))
2231 /* if explicitly set to zero, use single OS ephemeral port
2232 and disable random ports */
2233 if (daemon
->query_port
== 0)
2237 case 'T': /* --local-ttl */
2238 case LOPT_NEGTTL
: /* --neg-ttl */
2239 case LOPT_MAXTTL
: /* --max-ttl */
2240 case LOPT_MAXCTTL
: /* --max-cache-ttl */
2241 case LOPT_AUTHTTL
: /* --auth-ttl */
2244 if (!atoi_check(arg
, &ttl
))
2246 else if (option
== LOPT_NEGTTL
)
2247 daemon
->neg_ttl
= (unsigned long)ttl
;
2248 else if (option
== LOPT_MAXTTL
)
2249 daemon
->max_ttl
= (unsigned long)ttl
;
2250 else if (option
== LOPT_MAXCTTL
)
2251 daemon
->max_cache_ttl
= (unsigned long)ttl
;
2252 else if (option
== LOPT_AUTHTTL
)
2253 daemon
->auth_ttl
= (unsigned long)ttl
;
2255 daemon
->local_ttl
= (unsigned long)ttl
;
2260 case 'X': /* --dhcp-lease-max */
2261 if (!atoi_check(arg
, &daemon
->dhcp_max
))
2267 case LOPT_TFTP_MAX
: /* --tftp-max */
2268 if (!atoi_check(arg
, &daemon
->tftp_max
))
2272 case LOPT_PREFIX
: /* --tftp-prefix */
2276 struct tftp_prefix
*new = opt_malloc(sizeof(struct tftp_prefix
));
2277 new->interface
= opt_string_alloc(comma
);
2278 new->prefix
= opt_string_alloc(arg
);
2279 new->next
= daemon
->if_prefix
;
2280 daemon
->if_prefix
= new;
2283 daemon
->tftp_prefix
= opt_string_alloc(arg
);
2286 case LOPT_TFTPPORTS
: /* --tftp-port-range */
2287 if (!(comma
= split(arg
)) ||
2288 !atoi_check16(arg
, &daemon
->start_tftp_port
) ||
2289 !atoi_check16(comma
, &daemon
->end_tftp_port
))
2290 ret_err(_("bad port range"));
2292 if (daemon
->start_tftp_port
> daemon
->end_tftp_port
)
2294 int tmp
= daemon
->start_tftp_port
;
2295 daemon
->start_tftp_port
= daemon
->end_tftp_port
;
2296 daemon
->end_tftp_port
= tmp
;
2302 case LOPT_BRIDGE
: /* --bridge-interface */
2304 struct dhcp_bridge
*new = opt_malloc(sizeof(struct dhcp_bridge
));
2305 if (!(comma
= split(arg
)) || strlen(arg
) > IF_NAMESIZE
- 1 )
2306 ret_err(_("bad bridge-interface"));
2308 strcpy(new->iface
, arg
);
2310 new->next
= daemon
->bridges
;
2311 daemon
->bridges
= new;
2316 if (strlen(arg
) != 0 && strlen(arg
) <= IF_NAMESIZE
- 1)
2318 struct dhcp_bridge
*b
= opt_malloc(sizeof(struct dhcp_bridge
));
2319 b
->next
= new->alias
;
2321 strcpy(b
->iface
, arg
);
2329 case 'F': /* --dhcp-range */
2331 int k
, leasepos
= 2;
2332 char *cp
, *a
[8] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2333 struct dhcp_context
*new = opt_malloc(sizeof(struct dhcp_context
));
2335 memset (new, 0, sizeof(*new));
2336 new->lease_time
= DEFLEASE
;
2346 for (cp
= arg
; *cp
; cp
++)
2347 if (!(*cp
== ' ' || *cp
== '.' || *cp
== ':' ||
2348 (*cp
>= 'a' && *cp
<= 'f') || (*cp
>= 'A' && *cp
<= 'F') ||
2349 (*cp
>='0' && *cp
<= '9')))
2352 if (*cp
!= ',' && (comma
= split(arg
)))
2354 if (is_tag_prefix(arg
))
2356 struct dhcp_netid
*tt
= opt_malloc(sizeof (struct dhcp_netid
));
2357 tt
->net
= opt_string_alloc(arg
+4);
2358 tt
->next
= new->filter
;
2359 /* ignore empty tag */
2366 ret_err(_("only one tag allowed"));
2367 else if (strstr(arg
, "set:") == arg
)
2368 new->netid
.net
= opt_string_alloc(arg
+4);
2370 new->netid
.net
= opt_string_alloc(arg
);
2381 for (k
= 1; k
< 8; k
++)
2382 if (!(a
[k
] = split(a
[k
-1])))
2386 ret_err(_("bad dhcp-range"));
2388 if (inet_pton(AF_INET
, a
[0], &new->start
))
2390 new->next
= daemon
->dhcp
;
2392 new->end
= new->start
;
2393 if (strcmp(a
[1], "static") == 0)
2394 new->flags
|= CONTEXT_STATIC
;
2395 else if (strcmp(a
[1], "proxy") == 0)
2396 new->flags
|= CONTEXT_PROXY
;
2397 else if (!inet_pton(AF_INET
, a
[1], &new->end
))
2398 ret_err(_("bad dhcp-range"));
2400 if (ntohl(new->start
.s_addr
) > ntohl(new->end
.s_addr
))
2402 struct in_addr tmp
= new->start
;
2403 new->start
= new->end
;
2407 if (k
>= 3 && strchr(a
[2], '.') &&
2408 (inet_pton(AF_INET
, a
[2], &new->netmask
) > 0))
2410 new->flags
|= CONTEXT_NETMASK
;
2412 if (!is_same_net(new->start
, new->end
, new->netmask
))
2413 ret_err(_("inconsistent DHCP range"));
2416 if (k
>= 4 && strchr(a
[3], '.') &&
2417 (inet_pton(AF_INET
, a
[3], &new->broadcast
) > 0))
2419 new->flags
|= CONTEXT_BRDCAST
;
2424 else if (inet_pton(AF_INET6
, a
[0], &new->start6
))
2426 new->flags
|= CONTEXT_V6
;
2427 new->prefix
= 64; /* default */
2428 new->end6
= new->start6
;
2429 new->next
= daemon
->dhcp6
;
2430 daemon
->dhcp6
= new;
2432 for (leasepos
= 1; leasepos
< k
; leasepos
++)
2434 if (strcmp(a
[leasepos
], "static") == 0)
2435 new->flags
|= CONTEXT_STATIC
| CONTEXT_DHCP
;
2436 else if (strcmp(a
[leasepos
], "ra-only") == 0 || strcmp(a
[leasepos
], "slaac") == 0 )
2437 new->flags
|= CONTEXT_RA_ONLY
| CONTEXT_RA
;
2438 else if (strcmp(a
[leasepos
], "ra-names") == 0)
2439 new->flags
|= CONTEXT_RA_NAME
| CONTEXT_RA
;
2440 else if (strcmp(a
[leasepos
], "ra-stateless") == 0)
2441 new->flags
|= CONTEXT_RA_STATELESS
| CONTEXT_DHCP
| CONTEXT_RA
;
2442 else if (leasepos
== 1 && inet_pton(AF_INET6
, a
[leasepos
], &new->end6
))
2443 new->flags
|= CONTEXT_DHCP
;
2444 else if (strstr(a
[leasepos
], "constructor:") == a
[leasepos
])
2446 new->template_interface
= opt_string_alloc(a
[leasepos
] + 12);
2447 new->flags
|= CONTEXT_TEMPLATE
;
2449 else if (strstr(a
[leasepos
], "constructor-noauth:") == a
[leasepos
])
2451 new->template_interface
= opt_string_alloc(a
[leasepos
] + 19);
2452 new->flags
|= CONTEXT_TEMPLATE
| CONTEXT_NOAUTH
;
2458 /* bare integer < 128 is prefix value */
2462 for (cp
= a
[leasepos
]; *cp
; cp
++)
2463 if (!(*cp
>= '0' && *cp
<= '9'))
2465 if (!*cp
&& (pref
= atoi(a
[leasepos
])) <= 128)
2472 if (new->prefix
!= 64)
2474 if ((new->flags
& (CONTEXT_RA_ONLY
| CONTEXT_RA_NAME
| CONTEXT_RA_STATELESS
)))
2475 ret_err(_("prefix length must be exactly 64 for RA subnets"));
2476 else if (new->flags
& CONTEXT_TEMPLATE
)
2477 ret_err(_("prefix length must be exactly 64 for subnet constructors"));
2480 if (new->prefix
< 64)
2481 ret_err(_("prefix length must be at least 64"));
2483 if (!is_same_net6(&new->start6
, &new->end6
, new->prefix
))
2484 ret_err(_("inconsistent DHCPv6 range"));
2486 /* dhcp-range=:: enables DHCP stateless on any interface */
2487 if (IN6_IS_ADDR_UNSPECIFIED(&new->start6
) && !(new->flags
& CONTEXT_TEMPLATE
))
2490 if (new->flags
& CONTEXT_TEMPLATE
)
2492 struct in6_addr zero
;
2493 memset(&zero
, 0, sizeof(zero
));
2494 if (!is_same_net6(&zero
, &new->start6
, new->prefix
))
2495 ret_err(_("prefix must be zero with \"constructor:\" argument"));
2498 if (addr6part(&new->start6
) > addr6part(&new->end6
))
2500 struct in6_addr tmp
= new->start6
;
2501 new->start6
= new->end6
;
2507 ret_err(_("bad dhcp-range"));
2511 if (strcmp(a
[leasepos
], "infinite") == 0)
2512 new->lease_time
= 0xffffffff;
2513 else if (strcmp(a
[leasepos
], "deprecated") == 0)
2514 new->flags
|= CONTEXT_DEPRECATE
;
2518 if (strlen(a
[leasepos
]) > 0)
2520 switch (a
[leasepos
][strlen(a
[leasepos
]) - 1])
2540 a
[leasepos
][strlen(a
[leasepos
]) - 1] = 0;
2543 for (cp
= a
[leasepos
]; *cp
; cp
++)
2544 if (!(*cp
>= '0' && *cp
<= '9'))
2547 if (*cp
|| (leasepos
+1 < k
))
2548 ret_err(_("bad dhcp-range"));
2550 new->lease_time
= atoi(a
[leasepos
]) * fac
;
2551 /* Leases of a minute or less confuse
2552 some clients, notably Apple's */
2553 if (new->lease_time
< 120)
2554 new->lease_time
= 120;
2562 case 'G': /* --dhcp-host */
2565 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2566 struct dhcp_config
*new;
2569 new = opt_malloc(sizeof(struct dhcp_config
));
2571 new->next
= daemon
->dhcp_conf
;
2572 new->flags
= (option
== LOPT_BANK
) ? CONFIG_BANK
: 0;
2577 for (k
= 1; k
< 7; k
++)
2578 if (!(a
[k
] = split(a
[k
-1])))
2581 for (j
= 0; j
< k
; j
++)
2582 if (strchr(a
[j
], ':')) /* ethernet address, netid or binary CLID */
2586 if ((arg
[0] == 'i' || arg
[0] == 'I') &&
2587 (arg
[1] == 'd' || arg
[1] == 'D') &&
2591 new->flags
|= CONFIG_NOCLID
;
2595 arg
+= 3; /* dump id: */
2596 if (strchr(arg
, ':'))
2597 len
= parse_hex(arg
, (unsigned char *)arg
, -1, NULL
, NULL
);
2601 len
= (int) strlen(arg
);
2606 ret_err(_("bad hex constant"));
2607 else if ((new->clid
= opt_malloc(len
)))
2609 new->flags
|= CONFIG_CLID
;
2610 new->clid_len
= len
;
2611 memcpy(new->clid
, arg
, len
);
2615 /* dhcp-host has strange backwards-compat needs. */
2616 else if (strstr(arg
, "net:") == arg
|| strstr(arg
, "set:") == arg
)
2618 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2619 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2620 newtag
->net
= opt_malloc(strlen(arg
+ 4) + 1);
2621 newlist
->next
= new->netid
;
2622 new->netid
= newlist
;
2623 newlist
->list
= newtag
;
2624 strcpy(newtag
->net
, arg
+4);
2625 unhide_metas(newtag
->net
);
2627 else if (strstr(arg
, "tag:") == arg
)
2628 ret_err(_("cannot match tags in --dhcp-host"));
2630 else if (arg
[0] == '[' && arg
[strlen(arg
)-1] == ']')
2632 arg
[strlen(arg
)-1] = 0;
2635 if (!inet_pton(AF_INET6
, arg
, &new->addr6
))
2636 ret_err(_("bad IPv6 address"));
2638 for (i
= 0; i
< 8; i
++)
2639 if (new->addr6
.s6_addr
[i
] != 0)
2642 /* set WILDCARD if network part all zeros */
2644 new->flags
|= CONFIG_WILDCARD
;
2646 new->flags
|= CONFIG_ADDR6
;
2651 struct hwaddr_config
*newhw
= opt_malloc(sizeof(struct hwaddr_config
));
2652 if ((newhw
->hwaddr_len
= parse_hex(a
[j
], newhw
->hwaddr
, DHCP_CHADDR_MAX
,
2653 &newhw
->wildcard_mask
, &newhw
->hwaddr_type
)) == -1)
2654 ret_err(_("bad hex constant"));
2658 newhw
->next
= new->hwaddr
;
2659 new->hwaddr
= newhw
;
2663 else if (strchr(a
[j
], '.') && (inet_pton(AF_INET
, a
[j
], &in
) > 0))
2665 struct dhcp_config
*configs
;
2668 new->flags
|= CONFIG_ADDR
;
2670 /* If the same IP appears in more than one host config, then DISCOVER
2671 for one of the hosts will get the address, but REQUEST will be NAKed,
2672 since the address is reserved by the other one -> protocol loop. */
2673 for (configs
= daemon
->dhcp_conf
; configs
; configs
= configs
->next
)
2674 if ((configs
->flags
& CONFIG_ADDR
) && configs
->addr
.s_addr
== in
.s_addr
)
2676 sprintf(errstr
, _("duplicate dhcp-host IP address %s"), inet_ntoa(in
));
2682 char *cp
, *lastp
= NULL
, last
= 0;
2685 if (strlen(a
[j
]) > 1)
2687 lastp
= a
[j
] + strlen(a
[j
]) - 1;
2713 for (cp
= a
[j
]; *cp
; cp
++)
2714 if (!isdigit((unsigned char)*cp
) && *cp
!= ' ')
2721 if (strcmp(a
[j
], "infinite") == 0)
2723 new->lease_time
= 0xffffffff;
2724 new->flags
|= CONFIG_TIME
;
2726 else if (strcmp(a
[j
], "ignore") == 0)
2727 new->flags
|= CONFIG_DISABLE
;
2730 if (!(new->hostname
= canonicalise_opt(a
[j
])) ||
2731 !legal_hostname(new->hostname
))
2732 ret_err(_("bad DHCP host name"));
2734 new->flags
|= CONFIG_NAME
;
2735 new->domain
= strip_hostname(new->hostname
);
2740 new->lease_time
= atoi(a
[j
]) * fac
;
2741 /* Leases of a minute or less confuse
2742 some clients, notably Apple's */
2743 if (new->lease_time
< 120)
2744 new->lease_time
= 120;
2745 new->flags
|= CONFIG_TIME
;
2749 daemon
->dhcp_conf
= new;
2753 case LOPT_TAG_IF
: /* --tag-if */
2755 struct tag_if
*new = opt_malloc(sizeof(struct tag_if
));
2761 /* preserve order */
2762 if (!daemon
->tag_if
)
2763 daemon
->tag_if
= new;
2767 for (tmp
= daemon
->tag_if
; tmp
->next
; tmp
= tmp
->next
);
2785 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2786 newtag
->net
= opt_malloc(len
- 3);
2787 strcpy(newtag
->net
, arg
+4);
2788 unhide_metas(newtag
->net
);
2790 if (strstr(arg
, "set:") == arg
)
2792 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2793 newlist
->next
= new->set
;
2795 newlist
->list
= newtag
;
2797 else if (strstr(arg
, "tag:") == arg
)
2799 newtag
->next
= new->tag
;
2814 ret_err(_("bad tag-if"));
2820 case 'O': /* --dhcp-option */
2821 case LOPT_FORCE
: /* --dhcp-option-force */
2823 case LOPT_MATCH
: /* --dhcp-match */
2824 return parse_dhcp_opt(errstr
, arg
,
2825 option
== LOPT_FORCE
? DHOPT_FORCE
:
2826 (option
== LOPT_MATCH
? DHOPT_MATCH
:
2827 (option
== LOPT_OPTS
? DHOPT_BANK
: 0)));
2829 case 'M': /* --dhcp-boot */
2831 struct dhcp_netid
*id
= NULL
;
2832 while (is_tag_prefix(arg
))
2834 struct dhcp_netid
*newid
= opt_malloc(sizeof(struct dhcp_netid
));
2838 newid
->net
= opt_string_alloc(arg
+4);
2846 char *dhcp_file
, *dhcp_sname
= NULL
, *tftp_sname
= NULL
;
2847 struct in_addr dhcp_next_server
;
2848 struct dhcp_boot
*new;
2850 dhcp_file
= opt_string_alloc(arg
);
2851 dhcp_next_server
.s_addr
= 0;
2856 dhcp_sname
= opt_string_alloc(arg
);
2859 unhide_metas(comma
);
2860 if (!(inet_pton(AF_INET
, comma
, &dhcp_next_server
) > 0))
2863 * The user may have specified the tftp hostname here.
2864 * save it so that it can be resolved/looked up during
2865 * actual dhcp_reply().
2868 tftp_sname
= opt_string_alloc(comma
);
2869 dhcp_next_server
.s_addr
= 0;
2874 new = opt_malloc(sizeof(struct dhcp_boot
));
2875 new->file
= dhcp_file
;
2876 new->sname
= dhcp_sname
;
2877 new->tftp_sname
= tftp_sname
;
2878 new->next_server
= dhcp_next_server
;
2880 new->next
= daemon
->boot_config
;
2881 daemon
->boot_config
= new;
2887 case LOPT_PXE_PROMT
: /* --pxe-prompt */
2889 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
2893 new->opt
= 10; /* PXE_MENU_PROMPT */
2895 while (is_tag_prefix(arg
))
2897 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
2899 nn
->next
= new->netid
;
2901 nn
->net
= opt_string_alloc(arg
+4);
2911 new->len
= strlen(arg
) + 1;
2912 new->val
= opt_malloc(new->len
);
2913 memcpy(new->val
+ 1, arg
, new->len
- 1);
2915 new->u
.vendor_class
= (unsigned char *)"PXEClient";
2916 new->flags
= DHOPT_VENDOR
;
2918 if (comma
&& atoi_check(comma
, &timeout
))
2919 *(new->val
) = timeout
;
2923 new->next
= daemon
->dhcp_opts
;
2924 daemon
->dhcp_opts
= new;
2925 daemon
->enable_pxe
= 1;
2931 case LOPT_PXE_SERV
: /* --pxe-service */
2933 struct pxe_service
*new = opt_malloc(sizeof(struct pxe_service
));
2934 char *CSA
[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
2935 "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL
};
2936 static int boottype
= 32768;
2940 new->server
.s_addr
= 0;
2942 while (is_tag_prefix(arg
))
2944 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
2946 nn
->next
= new->netid
;
2948 nn
->net
= opt_string_alloc(arg
+4);
2952 if (arg
&& (comma
= split(arg
)))
2954 for (i
= 0; CSA
[i
]; i
++)
2955 if (strcasecmp(CSA
[i
], arg
) == 0)
2958 if (CSA
[i
] || atoi_check(arg
, &i
))
2964 new->menu
= opt_string_alloc(arg
);
2968 new->type
= 0; /* local boot */
2969 new->basename
= NULL
;
2975 if (atoi_check(arg
, &i
))
2978 new->basename
= NULL
;
2982 new->type
= boottype
++;
2983 new->basename
= opt_string_alloc(arg
);
2988 if (!inet_pton(AF_INET
, comma
, &new->server
))
2990 new->server
.s_addr
= 0;
2991 new->sname
= opt_string_alloc(comma
);
2999 if (!daemon
->pxe_services
)
3000 daemon
->pxe_services
= new;
3003 struct pxe_service
*s
;
3004 for (s
= daemon
->pxe_services
; s
->next
; s
= s
->next
);
3008 daemon
->enable_pxe
= 1;
3017 case '4': /* --dhcp-mac */
3019 if (!(comma
= split(arg
)))
3023 struct dhcp_mac
*new = opt_malloc(sizeof(struct dhcp_mac
));
3024 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
3025 unhide_metas(comma
);
3026 new->hwaddr_len
= parse_hex(comma
, new->hwaddr
, DHCP_CHADDR_MAX
, &new->mask
, &new->hwaddr_type
);
3027 if (new->hwaddr_len
== -1)
3031 new->next
= daemon
->dhcp_macs
;
3032 daemon
->dhcp_macs
= new;
3038 #ifdef OPTION6_PREFIX_CLASS
3039 case LOPT_PREF_CLSS
: /* --dhcp-prefix-class */
3041 struct prefix_class
*new = opt_malloc(sizeof(struct prefix_class
));
3043 if (!(comma
= split(arg
)) ||
3044 !atoi_check16(comma
, &new->class))
3047 new->tag
.net
= opt_string_alloc(set_prefix(arg
));
3048 new->next
= daemon
->prefix_classes
;
3049 daemon
->prefix_classes
= new;
3056 case 'U': /* --dhcp-vendorclass */
3057 case 'j': /* --dhcp-userclass */
3058 case LOPT_CIRCUIT
: /* --dhcp-circuitid */
3059 case LOPT_REMOTE
: /* --dhcp-remoteid */
3060 case LOPT_SUBSCR
: /* --dhcp-subscrid */
3064 struct dhcp_vendor
*new = opt_malloc(sizeof(struct dhcp_vendor
));
3066 if (!(comma
= split(arg
)))
3069 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
3070 /* check for hex string - must digits may include : must not have nothing else,
3071 only allowed for agent-options. */
3074 if ((comma
= split(arg
)))
3076 if (option
!= 'U' || strstr(arg
, "enterprise:") != arg
)
3079 new->enterprise
= atoi(arg
+11);
3084 for (p
= (unsigned char *)comma
; *p
; p
++)
3089 unhide_metas(comma
);
3090 if (option
== 'U' || option
== 'j' || *p
|| !dig
)
3092 new->len
= strlen(comma
);
3093 new->data
= opt_malloc(new->len
);
3094 memcpy(new->data
, comma
, new->len
);
3098 new->len
= parse_hex(comma
, (unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
3099 new->data
= opt_malloc(new->len
);
3100 memcpy(new->data
, comma
, new->len
);
3106 new->match_type
= MATCH_USER
;
3109 new->match_type
= MATCH_VENDOR
;
3112 new->match_type
= MATCH_CIRCUIT
;
3115 new->match_type
= MATCH_REMOTE
;
3118 new->match_type
= MATCH_SUBSCRIBER
;
3121 new->next
= daemon
->dhcp_vendors
;
3122 daemon
->dhcp_vendors
= new;
3127 case LOPT_ALTPORT
: /* --dhcp-alternate-port */
3130 daemon
->dhcp_server_port
= DHCP_SERVER_ALTPORT
;
3131 daemon
->dhcp_client_port
= DHCP_CLIENT_ALTPORT
;
3136 if (!atoi_check16(arg
, &daemon
->dhcp_server_port
) ||
3137 (comma
&& !atoi_check16(comma
, &daemon
->dhcp_client_port
)))
3138 ret_err(_("invalid port number"));
3140 daemon
->dhcp_client_port
= daemon
->dhcp_server_port
+1;
3144 case 'J': /* --dhcp-ignore */
3145 case LOPT_NO_NAMES
: /* --dhcp-ignore-names */
3146 case LOPT_BROADCAST
: /* --dhcp-broadcast */
3147 case '3': /* --bootp-dynamic */
3148 case LOPT_GEN_NAMES
: /* --dhcp-generate-names */
3150 struct dhcp_netid_list
*new = opt_malloc(sizeof(struct dhcp_netid_list
));
3151 struct dhcp_netid
*list
= NULL
;
3154 new->next
= daemon
->dhcp_ignore
;
3155 daemon
->dhcp_ignore
= new;
3157 else if (option
== LOPT_BROADCAST
)
3159 new->next
= daemon
->force_broadcast
;
3160 daemon
->force_broadcast
= new;
3162 else if (option
== '3')
3164 new->next
= daemon
->bootp_dynamic
;
3165 daemon
->bootp_dynamic
= new;
3167 else if (option
== LOPT_GEN_NAMES
)
3169 new->next
= daemon
->dhcp_gen_names
;
3170 daemon
->dhcp_gen_names
= new;
3174 new->next
= daemon
->dhcp_ignore_names
;
3175 daemon
->dhcp_ignore_names
= new;
3179 struct dhcp_netid
*member
= opt_malloc(sizeof(struct dhcp_netid
));
3181 member
->next
= list
;
3183 if (is_tag_prefix(arg
))
3184 member
->net
= opt_string_alloc(arg
+4);
3186 member
->net
= opt_string_alloc(arg
);
3194 case LOPT_PROXY
: /* --dhcp-proxy */
3195 daemon
->override
= 1;
3197 struct addr_list
*new = opt_malloc(sizeof(struct addr_list
));
3199 if (!(inet_pton(AF_INET
, arg
, &new->addr
) > 0))
3200 ret_err(_("bad dhcp-proxy address"));
3201 new->next
= daemon
->override_relays
;
3202 daemon
->override_relays
= new;
3207 case LOPT_RELAY
: /* --dhcp-relay */
3209 struct dhcp_relay
*new = opt_malloc(sizeof(struct dhcp_relay
));
3211 new->interface
= opt_string_alloc(split(comma
));
3212 new->iface_index
= 0;
3213 if (inet_pton(AF_INET
, arg
, &new->local
) && inet_pton(AF_INET
, comma
, &new->server
))
3215 new->next
= daemon
->relay4
;
3216 daemon
->relay4
= new;
3219 else if (inet_pton(AF_INET6
, arg
, &new->local
) && inet_pton(AF_INET6
, comma
, &new->server
))
3221 new->next
= daemon
->relay6
;
3222 daemon
->relay6
= new;
3226 ret_err(_("Bad dhcp-relay"));
3234 case LOPT_DUID
: /* --dhcp-duid */
3235 if (!(comma
= split(arg
)) || !atoi_check(arg
, (int *)&daemon
->duid_enterprise
))
3236 ret_err(_("bad DUID"));
3239 daemon
->duid_config_len
= parse_hex(comma
,(unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
3240 daemon
->duid_config
= opt_malloc(daemon
->duid_config_len
);
3241 memcpy(daemon
->duid_config
, comma
, daemon
->duid_config_len
);
3246 case 'V': /* --alias */
3248 char *dash
, *a
[3] = { NULL
, NULL
, NULL
};
3250 struct doctor
*new = opt_malloc(sizeof(struct doctor
));
3251 new->next
= daemon
->doctors
;
3252 daemon
->doctors
= new;
3253 new->mask
.s_addr
= 0xffffffff;
3254 new->end
.s_addr
= 0;
3257 for (k
= 1; k
< 3; k
++)
3259 if (!(a
[k
] = split(a
[k
-1])))
3264 dash
= split_chr(a
[0], '-');
3267 (!(inet_pton(AF_INET
, a
[0], &new->in
) > 0)) ||
3268 (!(inet_pton(AF_INET
, a
[1], &new->out
) > 0)))
3272 inet_pton(AF_INET
, a
[2], &new->mask
);
3275 (!(inet_pton(AF_INET
, dash
, &new->end
) > 0) ||
3276 !is_same_net(new->in
, new->end
, new->mask
) ||
3277 ntohl(new->in
.s_addr
) > ntohl(new->end
.s_addr
)))
3278 ret_err(_("invalid alias range"));
3283 case LOPT_INTNAME
: /* --interface-name */
3285 struct interface_name
*new, **up
;
3286 char *domain
= NULL
;
3290 if (!comma
|| !(domain
= canonicalise_opt(arg
)))
3291 ret_err(_("bad interface name"));
3293 new = opt_malloc(sizeof(struct interface_name
));
3299 /* Add to the end of the list, so that first name
3300 of an interface is used for PTR lookups. */
3301 for (up
= &daemon
->int_names
; *up
; up
= &((*up
)->next
));
3304 new->intr
= opt_string_alloc(comma
);
3308 case LOPT_CNAME
: /* --cname */
3314 if (!(comma
= split(arg
)))
3317 alias
= canonicalise_opt(arg
);
3318 target
= canonicalise_opt(comma
);
3320 if (!alias
|| !target
)
3321 ret_err(_("bad CNAME"));
3324 for (new = daemon
->cnames
; new; new = new->next
)
3325 if (hostname_isequal(new->alias
, arg
))
3326 ret_err(_("duplicate CNAME"));
3327 new = opt_malloc(sizeof(struct cname
));
3328 new->next
= daemon
->cnames
;
3329 daemon
->cnames
= new;
3331 new->target
= target
;
3337 case LOPT_PTR
: /* --ptr-record */
3339 struct ptr_record
*new;
3340 char *dom
, *target
= NULL
;
3344 if (!(dom
= canonicalise_opt(arg
)) ||
3345 (comma
&& !(target
= canonicalise_opt(comma
))))
3346 ret_err(_("bad PTR record"));
3349 new = opt_malloc(sizeof(struct ptr_record
));
3350 new->next
= daemon
->ptr
;
3358 case LOPT_NAPTR
: /* --naptr-record */
3360 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
3364 char *name
, *replace
= NULL
;
3367 for (k
= 1; k
< 7; k
++)
3368 if (!(a
[k
] = split(a
[k
-1])))
3373 !(name
= canonicalise_opt(a
[0])) ||
3374 !atoi_check16(a
[1], &order
) ||
3375 !atoi_check16(a
[2], &pref
) ||
3376 (k
== 7 && !(replace
= canonicalise_opt(a
[6]))))
3377 ret_err(_("bad NAPTR record"));
3380 new = opt_malloc(sizeof(struct naptr
));
3381 new->next
= daemon
->naptr
;
3382 daemon
->naptr
= new;
3384 new->flags
= opt_string_alloc(a
[3]);
3385 new->services
= opt_string_alloc(a
[4]);
3386 new->regexp
= opt_string_alloc(a
[5]);
3387 new->replace
= replace
;
3394 case LOPT_RR
: /* dns-rr */
3396 struct txt_record
*new;
3402 data
= split(comma
);
3404 new = opt_malloc(sizeof(struct txt_record
));
3405 new->next
= daemon
->rr
;
3408 if (!atoi_check(comma
, &val
) ||
3409 !(new->name
= canonicalise_opt(arg
)) ||
3410 (data
&& (len
= parse_hex(data
, (unsigned char *)data
, -1, NULL
, NULL
)) == -1U))
3411 ret_err(_("bad RR record"));
3418 new->txt
=opt_malloc(len
);
3420 memcpy(new->txt
, data
, len
);
3426 case 'Y': /* --txt-record */
3428 struct txt_record
*new;
3429 unsigned char *p
, *cnt
;
3434 new = opt_malloc(sizeof(struct txt_record
));
3435 new->next
= daemon
->txt
;
3439 if (!(new->name
= canonicalise_opt(arg
)))
3440 ret_err(_("bad TXT record"));
3442 len
= comma
? strlen(comma
) : 0;
3443 len
+= (len
/255) + 1; /* room for extra counts */
3444 new->txt
= p
= opt_malloc(len
);
3449 while (comma
&& *comma
)
3451 unsigned char c
= (unsigned char)*comma
++;
3453 if (c
== ',' || *cnt
== 255)
3462 *p
++ = unhide_meta(c
);
3467 new->len
= p
- new->txt
;
3472 case 'W': /* --srv-host */
3474 int port
= 1, priority
= 0, weight
= 0;
3475 char *name
, *target
= NULL
;
3476 struct mx_srv_record
*new;
3480 if (!(name
= canonicalise_opt(arg
)))
3481 ret_err(_("bad SRV record"));
3487 if (!(target
= canonicalise_opt(arg
)))
3488 ret_err(_("bad SRV target"));
3494 if (!atoi_check16(arg
, &port
))
3495 ret_err(_("invalid port number"));
3501 if (!atoi_check16(arg
, &priority
))
3502 ret_err(_("invalid priority"));
3508 if (!atoi_check16(arg
, &weight
))
3509 ret_err(_("invalid weight"));
3515 new = opt_malloc(sizeof(struct mx_srv_record
));
3516 new->next
= daemon
->mxnames
;
3517 daemon
->mxnames
= new;
3520 new->target
= target
;
3521 new->srvport
= port
;
3522 new->priority
= priority
;
3523 new->weight
= weight
;
3527 case LOPT_HOST_REC
: /* --host-record */
3529 struct host_record
*new = opt_malloc(sizeof(struct host_record
));
3530 memset(new, 0, sizeof(struct host_record
));
3532 if (!arg
|| !(comma
= split(arg
)))
3533 ret_err(_("Bad host-record"));
3537 struct all_addr addr
;
3538 if (inet_pton(AF_INET
, arg
, &addr
))
3539 new->addr
= addr
.addr
.addr4
;
3541 else if (inet_pton(AF_INET6
, arg
, &addr
))
3542 new->addr6
= addr
.addr
.addr6
;
3547 char *canon
= canonicalise(arg
, &nomem
);
3548 struct name_list
*nl
= opt_malloc(sizeof(struct name_list
));
3550 ret_err(_("Bad name in host-record"));
3553 /* keep order, so that PTR record goes to first name */
3559 struct name_list
*tmp
;
3560 for (tmp
= new->names
; tmp
->next
; tmp
= tmp
->next
);
3569 /* Keep list order */
3570 if (!daemon
->host_records_tail
)
3571 daemon
->host_records
= new;
3573 daemon
->host_records_tail
->next
= new;
3575 daemon
->host_records_tail
= new;
3580 ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DBus support)"));
3587 static void read_file(char *file
, FILE *f
, int hard_opt
)
3589 volatile int lineno
= 0;
3590 char *buff
= daemon
->namebuff
;
3592 while (fgets(buff
, MAXDNAME
, f
))
3594 int white
, i
, option
= hard_opt
;
3595 char *errmess
, *p
, *arg
= NULL
, *start
;
3598 /* Memory allocation failure longjmps here if mem_recover == 1 */
3601 if (setjmp(mem_jmp
))
3609 /* Implement quotes, inside quotes we allow \\ \" \n and \t
3610 metacharacters get hidden also strip comments */
3611 for (white
= 1, p
= buff
; *p
; p
++)
3615 memmove(p
, p
+1, strlen(p
+1)+1);
3617 for(; *p
&& *p
!= '"'; p
++)
3619 if (*p
== '\\' && strchr("\"tnebr\\", p
[1]))
3623 else if (p
[1] == 'n')
3625 else if (p
[1] == 'b')
3627 else if (p
[1] == 'r')
3629 else if (p
[1] == 'e') /* escape */
3631 memmove(p
, p
+1, strlen(p
+1)+1);
3638 errmess
= _("missing \"");
3642 memmove(p
, p
+1, strlen(p
+1)+1);
3652 if (white
&& *p
== '#')
3662 /* strip leading spaces */
3663 for (start
= buff
; *start
&& *start
== ' '; start
++);
3665 /* strip trailing spaces */
3666 for (len
= strlen(start
); (len
!= 0) && (start
[len
-1] == ' '); len
--);
3675 else if ((p
=strchr(start
, '=')))
3677 /* allow spaces around "=" */
3678 for (arg
= p
+1; *arg
== ' '; arg
++);
3679 for (; p
>= start
&& (*p
== ' ' || *p
== '='); p
--)
3687 for (option
= 0, i
= 0; opts
[i
].name
; i
++)
3688 if (strcmp(opts
[i
].name
, start
) == 0)
3690 option
= opts
[i
].val
;
3695 errmess
= _("bad option");
3696 else if (opts
[i
].has_arg
== 0 && arg
)
3697 errmess
= _("extraneous parameter");
3698 else if (opts
[i
].has_arg
== 1 && !arg
)
3699 errmess
= _("missing parameter");
3704 strcpy(daemon
->namebuff
, errmess
);
3706 if (errmess
|| !one_opt(option
, arg
, buff
, _("error"), 0))
3708 sprintf(daemon
->namebuff
+ strlen(daemon
->namebuff
), _(" at line %d of %s"), lineno
, file
);
3710 my_syslog(LOG_ERR
, "%s", daemon
->namebuff
);
3712 die("%s", daemon
->namebuff
, EC_BADCONF
);
3720 static int one_file(char *file
, int hard_opt
)
3724 static int read_stdin
= 0;
3725 static struct fileread
{
3728 struct fileread
*next
;
3729 } *filesread
= NULL
;
3731 if (hard_opt
== '7')
3733 /* default conf-file reading */
3738 if (hard_opt
== 0 && strcmp(file
, "-") == 0)
3740 if (read_stdin
== 1)
3748 /* ignore repeated files. */
3749 struct stat statbuf
;
3751 if (hard_opt
== 0 && stat(file
, &statbuf
) == 0)
3755 for (r
= filesread
; r
; r
= r
->next
)
3756 if (r
->dev
== statbuf
.st_dev
&& r
->ino
== statbuf
.st_ino
)
3759 r
= safe_malloc(sizeof(struct fileread
));
3760 r
->next
= filesread
;
3762 r
->dev
= statbuf
.st_dev
;
3763 r
->ino
= statbuf
.st_ino
;
3766 if (!(f
= fopen(file
, "r")))
3768 if (errno
== ENOENT
&& nofile_ok
)
3769 return 1; /* No conffile, all done. */
3772 char *str
= _("cannot read %s: %s");
3775 my_syslog(LOG_ERR
, str
, file
, strerror(errno
));
3779 die(str
, file
, EC_FILE
);
3784 read_file(file
, f
, hard_opt
);
3788 /* expand any name which is a directory */
3789 struct hostsfile
*expand_filelist(struct hostsfile
*list
)
3792 struct hostsfile
*ah
;
3794 for (i
= 0, ah
= list
; ah
; ah
= ah
->next
)
3799 if (ah
->flags
& AH_DIR
)
3800 ah
->flags
|= AH_INACTIVE
;
3802 ah
->flags
&= ~AH_INACTIVE
;
3805 for (ah
= list
; ah
; ah
= ah
->next
)
3806 if (!(ah
->flags
& AH_INACTIVE
))
3809 if (stat(ah
->fname
, &buf
) != -1 && S_ISDIR(buf
.st_mode
))
3814 /* don't read this as a file */
3815 ah
->flags
|= AH_INACTIVE
;
3817 if (!(dir_stream
= opendir(ah
->fname
)))
3818 my_syslog(LOG_ERR
, _("cannot access directory %s: %s"),
3819 ah
->fname
, strerror(errno
));
3822 while ((ent
= readdir(dir_stream
)))
3824 size_t lendir
= strlen(ah
->fname
);
3825 size_t lenfile
= strlen(ent
->d_name
);
3826 struct hostsfile
*ah1
;
3829 /* ignore emacs backups and dotfiles */
3831 ent
->d_name
[lenfile
- 1] == '~' ||
3832 (ent
->d_name
[0] == '#' && ent
->d_name
[lenfile
- 1] == '#') ||
3833 ent
->d_name
[0] == '.')
3836 /* see if we have an existing record.
3839 path to match is ah1->fname */
3841 for (ah1
= list
; ah1
; ah1
= ah1
->next
)
3843 if (lendir
< strlen(ah1
->fname
) &&
3844 strstr(ah1
->fname
, ah
->fname
) == ah1
->fname
&&
3845 ah1
->fname
[lendir
] == '/' &&
3846 strcmp(ah1
->fname
+ lendir
+ 1, ent
->d_name
) == 0)
3848 ah1
->flags
&= ~AH_INACTIVE
;
3853 /* make new record */
3856 if (!(ah1
= whine_malloc(sizeof(struct hostsfile
))))
3859 if (!(path
= whine_malloc(lendir
+ lenfile
+ 2)))
3865 strcpy(path
, ah
->fname
);
3867 strcat(path
, ent
->d_name
);
3870 ah1
->flags
= AH_DIR
;
3875 /* inactivate record if not regular file */
3876 if ((ah1
->flags
& AH_DIR
) && stat(ah1
->fname
, &buf
) != -1 && !S_ISREG(buf
.st_mode
))
3877 ah1
->flags
|= AH_INACTIVE
;
3880 closedir(dir_stream
);
3890 void reread_dhcp(void)
3892 struct hostsfile
*hf
;
3894 if (daemon
->dhcp_hosts_file
)
3896 struct dhcp_config
*configs
, *cp
, **up
;
3898 /* remove existing... */
3899 for (up
= &daemon
->dhcp_conf
, configs
= daemon
->dhcp_conf
; configs
; configs
= cp
)
3903 if (configs
->flags
& CONFIG_BANK
)
3905 struct hwaddr_config
*mac
, *tmp
;
3906 struct dhcp_netid_list
*list
, *tmplist
;
3908 for (mac
= configs
->hwaddr
; mac
; mac
= tmp
)
3914 if (configs
->flags
& CONFIG_CLID
)
3915 free(configs
->clid
);
3917 for (list
= configs
->netid
; list
; list
= tmplist
)
3920 tmplist
= list
->next
;
3924 if (configs
->flags
& CONFIG_NAME
)
3925 free(configs
->hostname
);
3927 *up
= configs
->next
;
3931 up
= &configs
->next
;
3934 daemon
->dhcp_hosts_file
= expand_filelist(daemon
->dhcp_hosts_file
);
3935 for (hf
= daemon
->dhcp_hosts_file
; hf
; hf
= hf
->next
)
3936 if (!(hf
->flags
& AH_INACTIVE
))
3938 if (one_file(hf
->fname
, LOPT_BANK
))
3939 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
3943 if (daemon
->dhcp_opts_file
)
3945 struct dhcp_opt
*opts
, *cp
, **up
;
3946 struct dhcp_netid
*id
, *next
;
3948 for (up
= &daemon
->dhcp_opts
, opts
= daemon
->dhcp_opts
; opts
; opts
= cp
)
3952 if (opts
->flags
& DHOPT_BANK
)
3954 if ((opts
->flags
& DHOPT_VENDOR
))
3955 free(opts
->u
.vendor_class
);
3957 for (id
= opts
->netid
; id
; id
= next
)
3970 daemon
->dhcp_opts_file
= expand_filelist(daemon
->dhcp_opts_file
);
3971 for (hf
= daemon
->dhcp_opts_file
; hf
; hf
= hf
->next
)
3972 if (!(hf
->flags
& AH_INACTIVE
))
3974 if (one_file(hf
->fname
, LOPT_OPTS
))
3975 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
3981 void read_opts(int argc
, char **argv
, char *compile_opts
)
3983 char *buff
= opt_malloc(MAXDNAME
);
3984 int option
, conffile_opt
= '7', testmode
= 0;
3985 char *arg
, *conffile
= CONFFILE
;
3989 daemon
= opt_malloc(sizeof(struct daemon
));
3990 memset(daemon
, 0, sizeof(struct daemon
));
3991 daemon
->namebuff
= buff
;
3993 /* Set defaults - everything else is zero or NULL */
3994 daemon
->cachesize
= CACHESIZ
;
3995 daemon
->ftabsize
= FTABSIZ
;
3996 daemon
->port
= NAMESERVER_PORT
;
3997 daemon
->dhcp_client_port
= DHCP_CLIENT_PORT
;
3998 daemon
->dhcp_server_port
= DHCP_SERVER_PORT
;
3999 daemon
->default_resolv
.is_default
= 1;
4000 daemon
->default_resolv
.name
= RESOLVFILE
;
4001 daemon
->resolv_files
= &daemon
->default_resolv
;
4002 daemon
->username
= CHUSER
;
4003 daemon
->runfile
= RUNFILE
;
4004 daemon
->dhcp_max
= MAXLEASES
;
4005 daemon
->tftp_max
= TFTP_MAX_CONNECTIONS
;
4006 daemon
->edns_pktsz
= EDNS_PKTSZ
;
4007 daemon
->log_fac
= -1;
4008 daemon
->auth_ttl
= AUTH_TTL
;
4009 daemon
->soa_refresh
= SOA_REFRESH
;
4010 daemon
->soa_retry
= SOA_RETRY
;
4011 daemon
->soa_expiry
= SOA_EXPIRY
;
4012 add_txt("version.bind", "dnsmasq-" VERSION
);
4013 add_txt("authors.bind", "Simon Kelley");
4014 add_txt("copyright.bind", COPYRIGHT
);
4018 #ifdef HAVE_GETOPT_LONG
4019 option
= getopt_long(argc
, argv
, OPTSTRING
, opts
, NULL
);
4021 option
= getopt(argc
, argv
, OPTSTRING
);
4026 for (; optind
< argc
; optind
++)
4028 unsigned char *c
= (unsigned char *)argv
[optind
];
4029 for (; *c
!= 0; c
++)
4031 die(_("junk found in command line"), NULL
, EC_BADCONF
);
4036 /* Copy optarg so that argv doesn't get changed */
4039 strncpy(buff
, optarg
, MAXDNAME
);
4040 buff
[MAXDNAME
-1] = 0;
4046 /* command-line only stuff */
4047 if (option
== LOPT_TEST
)
4049 else if (option
== 'w')
4052 if (argc
== 3 && strcmp(argv
[2], "dhcp") == 0)
4055 else if (argc
== 3 && strcmp(argv
[2], "dhcp6") == 0)
4064 else if (option
== 'v')
4066 printf(_("Dnsmasq version %s %s\n"), VERSION
, COPYRIGHT
);
4067 printf(_("Compile time options: %s\n\n"), compile_opts
);
4068 printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
4069 printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
4070 printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
4073 else if (option
== 'C')
4075 conffile_opt
= 0; /* file must exist */
4076 conffile
= opt_string_alloc(arg
);
4080 #ifdef HAVE_GETOPT_LONG
4081 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try --help"), 1))
4083 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try -w"), 1))
4085 die(_("bad command line options: %s"), daemon
->namebuff
, EC_BADCONF
);
4090 one_file(conffile
, conffile_opt
);
4092 /* port might not be known when the address is parsed - fill in here */
4093 if (daemon
->servers
)
4096 for (tmp
= daemon
->servers
; tmp
; tmp
= tmp
->next
)
4097 if (!(tmp
->flags
& SERV_HAS_SOURCE
))
4099 if (tmp
->source_addr
.sa
.sa_family
== AF_INET
)
4100 tmp
->source_addr
.in
.sin_port
= htons(daemon
->query_port
);
4102 else if (tmp
->source_addr
.sa
.sa_family
== AF_INET6
)
4103 tmp
->source_addr
.in6
.sin6_port
= htons(daemon
->query_port
);
4108 if (daemon
->if_addrs
)
4111 for(tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
4112 if (tmp
->addr
.sa
.sa_family
== AF_INET
)
4113 tmp
->addr
.in
.sin_port
= htons(daemon
->port
);
4115 else if (tmp
->addr
.sa
.sa_family
== AF_INET6
)
4116 tmp
->addr
.in6
.sin6_port
= htons(daemon
->port
);
4120 /* create default, if not specified */
4121 if (daemon
->authserver
&& !daemon
->hostmaster
)
4123 strcpy(buff
, "hostmaster.");
4124 strcat(buff
, daemon
->authserver
);
4125 daemon
->hostmaster
= opt_string_alloc(buff
);
4128 /* only one of these need be specified: the other defaults to the host-name */
4129 if (option_bool(OPT_LOCALMX
) || daemon
->mxnames
|| daemon
->mxtarget
)
4131 struct mx_srv_record
*mx
;
4133 if (gethostname(buff
, MAXDNAME
) == -1)
4134 die(_("cannot get host-name: %s"), NULL
, EC_MISC
);
4136 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
4137 if (!mx
->issrv
&& hostname_isequal(mx
->name
, buff
))
4140 if ((daemon
->mxtarget
|| option_bool(OPT_LOCALMX
)) && !mx
)
4142 mx
= opt_malloc(sizeof(struct mx_srv_record
));
4143 mx
->next
= daemon
->mxnames
;
4146 mx
->name
= opt_string_alloc(buff
);
4147 daemon
->mxnames
= mx
;
4150 if (!daemon
->mxtarget
)
4151 daemon
->mxtarget
= opt_string_alloc(buff
);
4153 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
4154 if (!mx
->issrv
&& !mx
->target
)
4155 mx
->target
= daemon
->mxtarget
;
4158 if (!option_bool(OPT_NO_RESOLV
) &&
4159 daemon
->resolv_files
&&
4160 daemon
->resolv_files
->next
&&
4161 option_bool(OPT_NO_POLL
))
4162 die(_("only one resolv.conf file allowed in no-poll mode."), NULL
, EC_BADCONF
);
4164 if (option_bool(OPT_RESOLV_DOMAIN
))
4169 if (option_bool(OPT_NO_RESOLV
) ||
4170 !daemon
->resolv_files
||
4171 (daemon
->resolv_files
)->next
)
4172 die(_("must have exactly one resolv.conf to read domain from."), NULL
, EC_BADCONF
);
4174 if (!(f
= fopen((daemon
->resolv_files
)->name
, "r")))
4175 die(_("failed to read %s: %s"), (daemon
->resolv_files
)->name
, EC_FILE
);
4177 while ((line
= fgets(buff
, MAXDNAME
, f
)))
4179 char *token
= strtok(line
, " \t\n\r");
4181 if (!token
|| strcmp(token
, "search") != 0)
4184 if ((token
= strtok(NULL
, " \t\n\r")) &&
4185 (daemon
->domain_suffix
= canonicalise_opt(token
)))
4191 if (!daemon
->domain_suffix
)
4192 die(_("no search directive found in %s"), (daemon
->resolv_files
)->name
, EC_MISC
);
4195 if (daemon
->domain_suffix
)
4197 /* add domain for any srv record without one. */
4198 struct mx_srv_record
*srv
;
4200 for (srv
= daemon
->mxnames
; srv
; srv
= srv
->next
)
4202 strchr(srv
->name
, '.') &&
4203 strchr(srv
->name
, '.') == strrchr(srv
->name
, '.'))
4205 strcpy(buff
, srv
->name
);
4207 strcat(buff
, daemon
->domain_suffix
);
4209 srv
->name
= opt_string_alloc(buff
);
4212 else if (option_bool(OPT_DHCP_FQDN
))
4213 die(_("there must be a default domain when --dhcp-fqdn is set"), NULL
, EC_BADCONF
);
4217 fprintf(stderr
, "dnsmasq: %s.\n", _("syntax check OK"));