]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/option.c
1 /* dnsmasq is Copyright (c) 2000-2012 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
125 #ifdef HAVE_GETOPT_LONG
126 static const struct option opts
[] =
128 static const struct myoption opts
[] =
131 { "version", 0, 0, 'v' },
132 { "no-hosts", 0, 0, 'h' },
133 { "no-poll", 0, 0, 'n' },
134 { "help", 0, 0, 'w' },
135 { "no-daemon", 0, 0, 'd' },
136 { "log-queries", 0, 0, 'q' },
137 { "user", 2, 0, 'u' },
138 { "group", 2, 0, 'g' },
139 { "resolv-file", 2, 0, 'r' },
140 { "mx-host", 1, 0, 'm' },
141 { "mx-target", 1, 0, 't' },
142 { "cache-size", 2, 0, 'c' },
143 { "port", 1, 0, 'p' },
144 { "dhcp-leasefile", 2, 0, 'l' },
145 { "dhcp-lease", 1, 0, 'l' },
146 { "dhcp-host", 1, 0, 'G' },
147 { "dhcp-range", 1, 0, 'F' },
148 { "dhcp-option", 1, 0, 'O' },
149 { "dhcp-boot", 1, 0, 'M' },
150 { "domain", 1, 0, 's' },
151 { "domain-suffix", 1, 0, 's' },
152 { "interface", 1, 0, 'i' },
153 { "listen-address", 1, 0, 'a' },
154 { "bogus-priv", 0, 0, 'b' },
155 { "bogus-nxdomain", 1, 0, 'B' },
156 { "selfmx", 0, 0, 'e' },
157 { "filterwin2k", 0, 0, 'f' },
158 { "pid-file", 2, 0, 'x' },
159 { "strict-order", 0, 0, 'o' },
160 { "server", 1, 0, 'S' },
161 { "local", 1, 0, LOPT_LOCAL
},
162 { "address", 1, 0, 'A' },
163 { "conf-file", 2, 0, 'C' },
164 { "no-resolv", 0, 0, 'R' },
165 { "expand-hosts", 0, 0, 'E' },
166 { "localmx", 0, 0, 'L' },
167 { "local-ttl", 1, 0, 'T' },
168 { "no-negcache", 0, 0, 'N' },
169 { "addn-hosts", 1, 0, 'H' },
170 { "query-port", 1, 0, 'Q' },
171 { "except-interface", 1, 0, 'I' },
172 { "no-dhcp-interface", 1, 0, '2' },
173 { "domain-needed", 0, 0, 'D' },
174 { "dhcp-lease-max", 1, 0, 'X' },
175 { "bind-interfaces", 0, 0, 'z' },
176 { "read-ethers", 0, 0, 'Z' },
177 { "alias", 1, 0, 'V' },
178 { "dhcp-vendorclass", 1, 0, 'U' },
179 { "dhcp-userclass", 1, 0, 'j' },
180 { "dhcp-ignore", 1, 0, 'J' },
181 { "edns-packet-max", 1, 0, 'P' },
182 { "keep-in-foreground", 0, 0, 'k' },
183 { "dhcp-authoritative", 0, 0, 'K' },
184 { "srv-host", 1, 0, 'W' },
185 { "localise-queries", 0, 0, 'y' },
186 { "txt-record", 1, 0, 'Y' },
187 { "dns-rr", 1, 0, LOPT_RR
},
188 { "enable-dbus", 2, 0, '1' },
189 { "bootp-dynamic", 2, 0, '3' },
190 { "dhcp-mac", 1, 0, '4' },
191 { "no-ping", 0, 0, '5' },
192 { "dhcp-script", 1, 0, '6' },
193 { "conf-dir", 1, 0, '7' },
194 { "log-facility", 1, 0 ,'8' },
195 { "leasefile-ro", 0, 0, '9' },
196 { "dns-forward-max", 1, 0, '0' },
197 { "clear-on-reload", 0, 0, LOPT_RELOAD
},
198 { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES
},
199 { "enable-tftp", 0, 0, LOPT_TFTP
},
200 { "tftp-secure", 0, 0, LOPT_SECURE
},
201 { "tftp-unique-root", 0, 0, LOPT_APREF
},
202 { "tftp-root", 1, 0, LOPT_PREFIX
},
203 { "tftp-max", 1, 0, LOPT_TFTP_MAX
},
204 { "tftp-lowercase", 0, 0, LOPT_TFTP_LC
},
205 { "ptr-record", 1, 0, LOPT_PTR
},
206 { "naptr-record", 1, 0, LOPT_NAPTR
},
207 { "bridge-interface", 1, 0 , LOPT_BRIDGE
},
208 { "dhcp-option-force", 1, 0, LOPT_FORCE
},
209 { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK
},
210 { "log-dhcp", 0, 0, LOPT_LOG_OPTS
},
211 { "log-async", 2, 0, LOPT_MAX_LOGS
},
212 { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT
},
213 { "dhcp-remoteid", 1, 0, LOPT_REMOTE
},
214 { "dhcp-subscrid", 1, 0, LOPT_SUBSCR
},
215 { "interface-name", 1, 0, LOPT_INTNAME
},
216 { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST
},
217 { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS
},
218 { "dhcp-no-override", 0, 0, LOPT_OVERRIDE
},
219 { "tftp-port-range", 1, 0, LOPT_TFTPPORTS
},
220 { "stop-dns-rebind", 0, 0, LOPT_REBIND
},
221 { "rebind-domain-ok", 1, 0, LOPT_NO_REBIND
},
222 { "all-servers", 0, 0, LOPT_NOLAST
},
223 { "dhcp-match", 1, 0, LOPT_MATCH
},
224 { "dhcp-broadcast", 2, 0, LOPT_BROADCAST
},
225 { "neg-ttl", 1, 0, LOPT_NEGTTL
},
226 { "max-ttl", 1, 0, LOPT_MAXTTL
},
227 { "max-cache-ttl", 1, 0, LOPT_MAXCTTL
},
228 { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT
},
229 { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR
},
230 { "min-port", 1, 0, LOPT_MINPORT
},
231 { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN
},
232 { "cname", 1, 0, LOPT_CNAME
},
233 { "pxe-prompt", 1, 0, LOPT_PXE_PROMT
},
234 { "pxe-service", 1, 0, LOPT_PXE_SERV
},
235 { "test", 0, 0, LOPT_TEST
},
236 { "tag-if", 1, 0, LOPT_TAG_IF
},
237 { "dhcp-proxy", 2, 0, LOPT_PROXY
},
238 { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES
},
239 { "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND
},
240 { "add-mac", 0, 0, LOPT_ADD_MAC
},
241 { "proxy-dnssec", 0, 0, LOPT_DNSSEC
},
242 { "dhcp-sequential-ip", 0, 0, LOPT_INCR_ADDR
},
243 { "conntrack", 0, 0, LOPT_CONNTRACK
},
244 { "dhcp-client-update", 0, 0, LOPT_FQDN
},
245 { "dhcp-luascript", 1, 0, LOPT_LUASCRIPT
},
246 { "enable-ra", 0, 0, LOPT_RA
},
247 { "dhcp-duid", 1, 0, LOPT_DUID
},
248 { "host-record", 1, 0, LOPT_HOST_REC
},
249 { "bind-dynamic", 0, 0, LOPT_CLVERBIND
},
254 #define ARG_DUP OPT_LAST
255 #define ARG_ONE OPT_LAST + 1
256 #define ARG_USED_CL OPT_LAST + 2
257 #define ARG_USED_FILE OPT_LAST + 3
262 char * const flagdesc
;
266 { 'a', ARG_DUP
, "<ipaddr>", gettext_noop("Specify local address(es) to listen on."), NULL
},
267 { 'A', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL
},
268 { 'b', OPT_BOGUSPRIV
, NULL
, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL
},
269 { 'B', ARG_DUP
, "<ipaddr>", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL
},
270 { 'c', ARG_ONE
, "<integer>", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
271 { 'C', ARG_DUP
, "<path>", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE
},
272 { 'd', OPT_DEBUG
, NULL
, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL
},
273 { 'D', OPT_NODOTS_LOCAL
, NULL
, gettext_noop("Do NOT forward queries with no domain part."), NULL
},
274 { 'e', OPT_SELFMX
, NULL
, gettext_noop("Return self-pointing MX records for local hosts."), NULL
},
275 { 'E', OPT_EXPAND
, NULL
, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL
},
276 { 'f', OPT_FILTER
, NULL
, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL
},
277 { 'F', ARG_DUP
, "<ipaddr>,...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL
},
278 { 'g', ARG_ONE
, "<groupname>", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP
},
279 { 'G', ARG_DUP
, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL
},
280 { LOPT_DHCP_HOST
, ARG_DUP
, "<path>", gettext_noop("Read DHCP host specs from file."), NULL
},
281 { LOPT_DHCP_OPTS
, ARG_DUP
, "<path>", gettext_noop("Read DHCP option specs from file."), NULL
},
282 { LOPT_TAG_IF
, ARG_DUP
, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL
},
283 { 'h', OPT_NO_HOSTS
, NULL
, gettext_noop("Do NOT load %s file."), HOSTSFILE
},
284 { 'H', ARG_DUP
, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE
},
285 { 'i', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL
},
286 { 'I', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL
},
287 { 'j', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL
},
288 { LOPT_CIRCUIT
, ARG_DUP
, "set:<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL
},
289 { LOPT_REMOTE
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL
},
290 { LOPT_SUBSCR
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL
},
291 { 'J', ARG_DUP
, "tag:<tag>...", gettext_noop("Don't do DHCP for hosts with tag set."), NULL
},
292 { LOPT_BROADCAST
, ARG_DUP
, "[=tag:<tag>...]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL
},
293 { 'k', OPT_NO_FORK
, NULL
, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL
},
294 { 'K', OPT_AUTHORITATIVE
, NULL
, gettext_noop("Assume we are the only DHCP server on the local network."), NULL
},
295 { 'l', ARG_ONE
, "<path>", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE
},
296 { 'L', OPT_LOCALMX
, NULL
, gettext_noop("Return MX records for local hosts."), NULL
},
297 { 'm', ARG_DUP
, "<host_name>,<target>,<pref>", gettext_noop("Specify an MX record."), NULL
},
298 { 'M', ARG_DUP
, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL
},
299 { 'n', OPT_NO_POLL
, NULL
, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE
},
300 { 'N', OPT_NO_NEG
, NULL
, gettext_noop("Do NOT cache failed search results."), NULL
},
301 { 'o', OPT_ORDER
, NULL
, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE
},
302 { 'O', ARG_DUP
, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL
},
303 { LOPT_FORCE
, ARG_DUP
, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL
},
304 { 'p', ARG_ONE
, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL
},
305 { 'P', ARG_ONE
, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
306 { 'q', OPT_LOG
, NULL
, gettext_noop("Log DNS queries."), NULL
},
307 { 'Q', ARG_ONE
, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL
},
308 { 'R', OPT_NO_RESOLV
, NULL
, gettext_noop("Do NOT read resolv.conf."), NULL
},
309 { 'r', ARG_DUP
, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE
},
310 { 'S', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL
},
311 { LOPT_LOCAL
, ARG_DUP
, "/<domain>/", gettext_noop("Never forward queries to specified domains."), NULL
},
312 { 's', ARG_DUP
, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL
},
313 { 't', ARG_ONE
, "<host_name>", gettext_noop("Specify default target in an MX record."), NULL
},
314 { 'T', ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL
},
315 { LOPT_NEGTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL
},
316 { LOPT_MAXTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL
},
317 { 'u', ARG_ONE
, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER
},
318 { 'U', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL
},
319 { 'v', 0, NULL
, gettext_noop("Display dnsmasq version and copyright information."), NULL
},
320 { 'V', ARG_DUP
, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL
},
321 { 'W', ARG_DUP
, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL
},
322 { 'w', 0, NULL
, gettext_noop("Display this message. Use --help dhcp for known DHCP options."), NULL
},
323 { 'x', ARG_ONE
, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE
},
324 { 'X', ARG_ONE
, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
325 { 'y', OPT_LOCALISE
, NULL
, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL
},
326 { 'Y', ARG_DUP
, "<name>,<txt>[,<txt]", gettext_noop("Specify TXT DNS record."), NULL
},
327 { LOPT_PTR
, ARG_DUP
, "<name>,<target>", gettext_noop("Specify PTR DNS record."), NULL
},
328 { LOPT_INTNAME
, ARG_DUP
, "<name>,<interface>", gettext_noop("Give DNS name to IPv4 address of interface."), NULL
},
329 { 'z', OPT_NOWILD
, NULL
, gettext_noop("Bind only to interfaces in use."), NULL
},
330 { 'Z', OPT_ETHERS
, NULL
, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE
},
331 { '1', ARG_ONE
, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL
},
332 { '2', ARG_DUP
, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL
},
333 { '3', ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL
},
334 { '4', ARG_DUP
, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL
},
335 { LOPT_BRIDGE
, ARG_DUP
, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL
},
336 { '5', OPT_NO_PING
, NULL
, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL
},
337 { '6', ARG_ONE
, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL
},
338 { LOPT_LUASCRIPT
, ARG_DUP
, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL
},
339 { LOPT_SCRIPTUSR
, ARG_ONE
, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL
},
340 { '7', ARG_DUP
, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL
},
341 { '8', ARG_ONE
, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL
},
342 { '9', OPT_LEASE_RO
, NULL
, gettext_noop("Do not use leasefile."), NULL
},
343 { '0', ARG_ONE
, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
344 { LOPT_RELOAD
, OPT_RELOAD
, NULL
, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE
},
345 { LOPT_NO_NAMES
, ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL
},
346 { LOPT_OVERRIDE
, OPT_NO_OVERRIDE
, NULL
, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL
},
347 { LOPT_TFTP
, OPT_TFTP
, NULL
, gettext_noop("Enable integrated read-only TFTP server."), NULL
},
348 { LOPT_PREFIX
, ARG_DUP
, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL
},
349 { LOPT_APREF
, OPT_TFTP_APREF
, NULL
, gettext_noop("Add client IP address to tftp-root."), NULL
},
350 { LOPT_SECURE
, OPT_TFTP_SECURE
, NULL
, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL
},
351 { LOPT_TFTP_MAX
, ARG_ONE
, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
352 { LOPT_NOBLOCK
, OPT_TFTP_NOBLOCK
, NULL
, gettext_noop("Disable the TFTP blocksize extension."), NULL
},
353 { LOPT_TFTP_LC
, OPT_TFTP_LC
, NULL
, gettext_noop("Convert TFTP filenames to lowercase"), NULL
},
354 { LOPT_TFTPPORTS
, ARG_ONE
, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL
},
355 { LOPT_LOG_OPTS
, OPT_LOG_OPTS
, NULL
, gettext_noop("Extra logging for DHCP."), NULL
},
356 { LOPT_MAX_LOGS
, ARG_ONE
, "[=<integer>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL
},
357 { LOPT_REBIND
, OPT_NO_REBIND
, NULL
, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL
},
358 { LOPT_LOC_REBND
, OPT_LOCAL_REBIND
, NULL
, gettext_noop("Allow rebinding of 127.0.0.0/8, for RBL servers."), NULL
},
359 { LOPT_NO_REBIND
, ARG_DUP
, "/<domain>/", gettext_noop("Inhibit DNS-rebind protection on this domain."), NULL
},
360 { LOPT_NOLAST
, OPT_ALL_SERVERS
, NULL
, gettext_noop("Always perform DNS queries to all servers."), NULL
},
361 { LOPT_MATCH
, ARG_DUP
, "set:<tag>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL
},
362 { LOPT_ALTPORT
, ARG_ONE
, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL
},
363 { LOPT_NAPTR
, ARG_DUP
, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL
},
364 { LOPT_MINPORT
, ARG_ONE
, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL
},
365 { LOPT_DHCP_FQDN
, OPT_DHCP_FQDN
, NULL
, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL
},
366 { LOPT_GEN_NAMES
, ARG_DUP
, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL
},
367 { LOPT_PROXY
, ARG_DUP
, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL
},
368 { LOPT_CNAME
, ARG_DUP
, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL
},
369 { LOPT_PXE_PROMT
, ARG_DUP
, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL
},
370 { LOPT_PXE_SERV
, ARG_DUP
, "<service>", gettext_noop("Boot service for PXE menu."), NULL
},
371 { LOPT_TEST
, 0, NULL
, gettext_noop("Check configuration syntax."), NULL
},
372 { LOPT_ADD_MAC
, OPT_ADD_MAC
, NULL
, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL
},
373 { LOPT_DNSSEC
, OPT_DNSSEC
, NULL
, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL
},
374 { LOPT_INCR_ADDR
, OPT_CONSEC_ADDR
, NULL
, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL
},
375 { LOPT_CONNTRACK
, OPT_CONNTRACK
, NULL
, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL
},
376 { LOPT_FQDN
, OPT_FQDN_UPDATE
, NULL
, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL
},
377 { LOPT_RA
, OPT_RA
, NULL
, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL
},
378 { LOPT_DUID
, ARG_ONE
, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL
},
379 { LOPT_HOST_REC
, ARG_DUP
, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL
},
380 { LOPT_RR
, ARG_DUP
, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL
},
381 { LOPT_CLVERBIND
, OPT_CLEVERBIND
, NULL
, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL
},
382 { 0, 0, NULL
, NULL
, NULL
}
385 /* We hide metacharaters in quoted strings by mapping them into the ASCII control
386 character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the
387 following sequence so that they map to themselves: it is therefore possible to call
388 unhide_metas repeatedly on string without breaking things.
389 The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a
390 couple of other places.
391 Note that space is included here so that
392 --dhcp-option=3, string
393 has five characters, whilst
394 --dhcp-option=3," string"
398 static const char meta
[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
400 static char hide_meta(char c
)
404 for (i
= 0; i
< (sizeof(meta
) - 1); i
++)
411 static char unhide_meta(char cr
)
415 if (c
< (sizeof(meta
) - 1))
421 static void unhide_metas(char *cp
)
425 *cp
= unhide_meta(*cp
);
428 static void *opt_malloc(size_t size
)
434 ret
= whine_malloc(size
);
439 ret
= safe_malloc(size
);
444 static char *opt_string_alloc(char *cp
)
448 if (cp
&& strlen(cp
) != 0)
450 ret
= opt_malloc(strlen(cp
)+1);
453 /* restore hidden metachars */
461 /* find next comma, split string with zero and eliminate spaces.
462 return start of string following comma */
464 static char *split_chr(char *s
, char c
)
468 if (!s
|| !(comma
= strchr(s
, c
)))
474 for (; *comma
== ' '; comma
++);
476 for (; (p
>= s
) && *p
== ' '; p
--)
482 static char *split(char *s
)
484 return split_chr(s
, ',');
487 static char *canonicalise_opt(char *s
)
496 if (!(ret
= canonicalise(s
, &nomem
)) && nomem
)
501 die(_("could not get memory"), NULL
, EC_NOMEM
);
507 static int atoi_check(char *a
, int *res
)
517 if (*p
< '0' || *p
> '9')
524 static int atoi_check16(char *a
, int *res
)
526 if (!(atoi_check(a
, res
)) ||
534 static void add_txt(char *name
, char *txt
)
536 size_t len
= strlen(txt
);
537 struct txt_record
*r
= opt_malloc(sizeof(struct txt_record
));
539 r
->name
= opt_string_alloc(name
);
540 r
->next
= daemon
->txt
;
543 r
->txt
= opt_malloc(len
+1);
546 memcpy((r
->txt
)+1, txt
, len
);
549 static void do_usage(void)
562 { '#', TFTP_MAX_CONNECTIONS
},
566 printf(_("Usage: dnsmasq [options]\n\n"));
567 #ifndef HAVE_GETOPT_LONG
568 printf(_("Use short options only on the command line.\n"));
570 printf(_("Valid options are:\n"));
572 for (i
= 0; usage
[i
].opt
!= 0; i
++)
574 char *desc
= usage
[i
].flagdesc
;
577 if (!desc
|| *desc
== '[')
583 for ( j
= 0; opts
[j
].name
; j
++)
584 if (opts
[j
].val
== usage
[i
].opt
)
586 if (usage
[i
].opt
< 256)
587 sprintf(buff
, "-%c, ", usage
[i
].opt
);
591 sprintf(buff
+4, "--%s%s%s", opts
[j
].name
, eq
, desc
);
592 printf("%-40.40s", buff
);
596 strcpy(buff
, usage
[i
].arg
);
597 for (j
= 0; tab
[j
].handle
; j
++)
598 if (tab
[j
].handle
== *(usage
[i
].arg
))
599 sprintf(buff
, "%d", tab
[j
].val
);
601 printf(_(usage
[i
].desc
), buff
);
606 #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
610 static int is_tag_prefix(char *arg
)
612 if (arg
&& (strstr(arg
, "net:") == arg
|| strstr(arg
, "tag:") == arg
))
618 static char *set_prefix(char *arg
)
620 if (strstr(arg
, "set:") == arg
)
626 char *parse_server(char *arg
, union mysockaddr
*addr
, union mysockaddr
*source_addr
, char *interface
, int *flags
)
628 int source_port
= 0, serv_port
= NAMESERVER_PORT
;
629 char *portno
, *source
;
635 if ((source
= split_chr(arg
, '@')) && /* is there a source. */
636 (portno
= split_chr(source
, '#')) &&
637 !atoi_check16(portno
, &source_port
))
638 return _("bad port");
640 if ((portno
= split_chr(arg
, '#')) && /* is there a port no. */
641 !atoi_check16(portno
, &serv_port
))
642 return _("bad port");
645 scope_id
= split_chr(arg
, '%');
648 if ((addr
->in
.sin_addr
.s_addr
= inet_addr(arg
)) != (in_addr_t
) -1)
650 addr
->in
.sin_port
= htons(serv_port
);
651 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET
;
652 #ifdef HAVE_SOCKADDR_SA_LEN
653 source_addr
->in
.sin_len
= addr
->in
.sin_len
= sizeof(struct sockaddr_in
);
655 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
656 source_addr
->in
.sin_port
= htons(daemon
->query_port
);
661 *flags
|= SERV_HAS_SOURCE
;
662 source_addr
->in
.sin_port
= htons(source_port
);
663 if ((source_addr
->in
.sin_addr
.s_addr
= inet_addr(source
)) == (in_addr_t
) -1)
665 #if defined(SO_BINDTODEVICE)
666 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
667 strncpy(interface
, source
, IF_NAMESIZE
- 1);
669 return _("interface binding not supported");
675 else if (inet_pton(AF_INET6
, arg
, &addr
->in6
.sin6_addr
) > 0)
677 if (scope_id
&& (scope_index
= if_nametoindex(scope_id
)) == 0)
678 return _("bad interface name");
680 addr
->in6
.sin6_port
= htons(serv_port
);
681 addr
->in6
.sin6_scope_id
= scope_index
;
682 source_addr
->in6
.sin6_addr
= in6addr_any
;
683 source_addr
->in6
.sin6_port
= htons(daemon
->query_port
);
684 source_addr
->in6
.sin6_scope_id
= 0;
685 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET6
;
686 addr
->in6
.sin6_flowinfo
= source_addr
->in6
.sin6_flowinfo
= 0;
687 #ifdef HAVE_SOCKADDR_SA_LEN
688 addr
->in6
.sin6_len
= source_addr
->in6
.sin6_len
= sizeof(addr
->in6
);
693 *flags
|= SERV_HAS_SOURCE
;
694 source_addr
->in6
.sin6_port
= htons(source_port
);
695 if (inet_pton(AF_INET6
, source
, &source_addr
->in6
.sin6_addr
) == 0)
697 #if defined(SO_BINDTODEVICE)
698 source_addr
->in6
.sin6_addr
= in6addr_any
;
699 strncpy(interface
, source
, IF_NAMESIZE
- 1);
701 return _("interface binding not supported");
708 return _("bad address");
713 /* This is too insanely large to keep in-line in the switch */
714 static int parse_dhcp_opt(char *errstr
, char *arg
, int flags
)
716 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
717 char lenchar
= 0, *cp
;
718 int addrs
, digs
, is_addr
, is_addr6
, is_hex
, is_dec
, is_string
, dots
;
720 struct dhcp_netid
*np
= NULL
;
734 for (cp
= arg
; *cp
; cp
++)
735 if (*cp
< '0' || *cp
> '9')
740 new->opt
= atoi(arg
);
745 if (strstr(arg
, "option:") == arg
)
747 new->opt
= lookup_dhcp_opt(AF_INET
, arg
+7);
748 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
749 /* option:<optname> must follow tag and vendor string. */
753 else if (strstr(arg
, "option6:") == arg
)
755 for (cp
= arg
+8; *cp
; cp
++)
756 if (*cp
< '0' || *cp
> '9')
761 new->opt
= atoi(arg
+8);
766 new->opt
= lookup_dhcp_opt(AF_INET6
, arg
+8);
767 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
769 /* option6:<opt>|<optname> must follow tag and vendor string. */
774 else if (strstr(arg
, "vendor:") == arg
)
776 new->u
.vendor_class
= (unsigned char *)opt_string_alloc(arg
+7);
777 new->flags
|= DHOPT_VENDOR
;
779 else if (strstr(arg
, "encap:") == arg
)
781 new->u
.encap
= atoi(arg
+6);
782 new->flags
|= DHOPT_ENCAPSULATE
;
784 else if (strstr(arg
, "vi-encap:") == arg
)
786 new->u
.encap
= atoi(arg
+9);
787 new->flags
|= DHOPT_RFC3925
;
788 if (flags
== DHOPT_MATCH
)
790 new->opt
= 1; /* avoid error below */
796 new->netid
= opt_malloc(sizeof (struct dhcp_netid
));
797 /* allow optional "net:" or "tag:" for consistency */
798 if (is_tag_prefix(arg
))
799 new->netid
->net
= opt_string_alloc(arg
+4);
801 new->netid
->net
= opt_string_alloc(set_prefix(arg
));
802 new->netid
->next
= np
;
812 if (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))
813 ret_err(_("unsupported encapsulation for IPv6 option"));
816 !(new->flags
& DHOPT_RFC3925
))
817 opt_len
= lookup_dhcp_len(AF_INET6
,new->opt
);
822 !(new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
| DHOPT_RFC3925
)))
823 opt_len
= lookup_dhcp_len(AF_INET
,new->opt
);
825 /* option may be missing with rfc3925 match */
827 ret_err(_("bad dhcp-option"));
831 /* characterise the value */
834 is_addr
= is_addr6
= is_hex
= is_dec
= is_string
= 1;
837 for (cp
= comma
; (c
= *cp
); cp
++)
846 is_dec
= is_addr
= 0;
850 is_addr6
= is_dec
= is_hex
= 0;
851 if (cp
== comma
) /* leading / means a pathname */
856 is_addr6
= is_dec
= is_hex
= 0;
860 is_hex
= is_addr
= is_addr6
= 0;
863 else if (!(c
>='0' && c
<= '9'))
866 if (cp
[1] == 0 && is_dec
&&
867 (c
== 'b' || c
== 's' || c
== 'i'))
874 if (!((c
>='A' && c
<= 'F') ||
875 (c
>='a' && c
<= 'f') ||
876 (c
== '*' && (flags
& DHOPT_MATCH
))))
879 if (c
!= '[' && c
!= ']')
887 is_dec
= is_addr
= 0;
889 /* We know that some options take addresses */
890 if (opt_len
& OT_ADDR_LIST
)
892 is_string
= is_dec
= is_hex
= 0;
894 if (!is6
&& (!is_addr
|| dots
== 0))
895 ret_err(_("bad IP address"));
897 if (is6
&& !is_addr6
)
898 ret_err(_("bad IPv6 address"));
901 else if (opt_len
& (OT_NAME
| OT_RFC1035_NAME
| OT_CSTRING
))
902 is_addr6
= is_addr
= is_dec
= is_hex
= 0;
904 if (found_dig
&& (opt_len
& OT_TIME
) && strlen(comma
) > 0)
908 switch (comma
[strlen(comma
) - 1])
928 comma
[strlen(comma
) - 1] = 0;
932 new->val
= opt_malloc(4);
934 *((int *)new->val
) = htonl(val
* fac
);
936 else if (is_hex
&& digs
> 1)
939 new->val
= opt_malloc(new->len
);
940 parse_hex(comma
, new->val
, digs
, (flags
& DHOPT_MATCH
) ? &new->u
.wildcard_mask
: NULL
, NULL
);
941 new->flags
|= DHOPT_HEX
;
945 int i
, val
= atoi(comma
);
946 /* assume numeric arg is 1 byte except for
947 options where it is known otherwise.
948 For vendor class option, we have to hack. */
951 else if (val
& 0xffff0000)
953 else if (val
& 0xff00)
960 else if (lenchar
== 's')
962 else if (lenchar
== 'i')
965 new->val
= opt_malloc(new->len
);
966 for (i
=0; i
<new->len
; i
++)
967 new->val
[i
] = val
>>((new->len
- i
- 1)*8);
969 else if (is_addr
&& !is6
)
974 /* max length of address/subnet descriptor is five bytes,
975 add one for the option 120 enc byte too */
976 new->val
= op
= opt_malloc((5 * addrs
) + 1);
977 new->flags
|= DHOPT_ADDR
;
979 if (!(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)) &&
980 new->opt
== OPTION_SIP_SERVER
)
982 *(op
++) = 1; /* RFC 3361 "enc byte" */
983 new->flags
&= ~DHOPT_ADDR
;
989 slash
= split_chr(cp
, '/');
990 in
.s_addr
= inet_addr(cp
);
993 memcpy(op
, &in
, INADDRSZ
);
998 unsigned char *p
= (unsigned char *)&in
;
999 int netsize
= atoi(slash
);
1009 new->flags
&= ~DHOPT_ADDR
; /* cannot re-write descriptor format */
1012 new->len
= op
- new->val
;
1014 else if (is_addr6
&& is6
)
1017 new->val
= op
= opt_malloc(16 * addrs
);
1018 new->flags
|= DHOPT_ADDR6
;
1024 /* check for [1234::7] */
1027 if (strlen(cp
) > 1 && cp
[strlen(cp
)-1] == ']')
1028 cp
[strlen(cp
)-1] = 0;
1030 if (inet_pton(AF_INET6
, cp
, op
))
1036 ret_err(_("bad IPv6 address"));
1038 new->len
= op
- new->val
;
1043 if ((new->opt
== OPTION_DOMAIN_SEARCH
|| new->opt
== OPTION_SIP_SERVER
) &&
1044 !is6
&& !(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)))
1046 /* dns search, RFC 3397, or SIP, RFC 3361 */
1047 unsigned char *q
, *r
, *tail
;
1048 unsigned char *p
, *m
= NULL
, *newp
;
1049 size_t newlen
, len
= 0;
1050 int header_size
= (new->opt
== OPTION_DOMAIN_SEARCH
) ? 0 : 1;
1057 char *in
, *dom
= NULL
;
1059 /* Allow "." as an empty domain */
1060 if (strcmp (arg
, ".") != 0)
1062 if (!(dom
= canonicalise_opt(arg
)))
1063 ret_err(_("bad domain in dhcp-option"));
1065 domlen
= strlen(dom
) + 2;
1068 newp
= opt_malloc(len
+ domlen
+ header_size
);
1071 memcpy(newp
, m
, header_size
+ len
);
1075 p
= m
+ header_size
;
1078 /* add string on the end in RFC1035 format */
1079 for (in
= dom
; in
&& *in
;)
1081 unsigned char *cp
= q
++;
1083 for (j
= 0; *in
&& (*in
!= '.'); in
++, j
++)
1092 /* Now tail-compress using earlier names. */
1094 for (tail
= p
+ len
; *tail
; tail
+= (*tail
) + 1)
1095 for (r
= p
; r
- p
< (int)len
; r
+= (*r
) + 1)
1096 if (strcmp((char *)r
, (char *)tail
) == 0)
1098 PUTSHORT((r
- p
) | 0xc000, tail
);
1109 /* RFC 3361, enc byte is zero for names */
1110 if (new->opt
== OPTION_SIP_SERVER
)
1112 new->len
= (int) len
+ header_size
;
1116 else if (comma
&& (opt_len
& OT_CSTRING
))
1118 /* length fields are two bytes so need 16 bits for each string */
1120 unsigned char *p
, *newp
;
1122 for (i
= 0; comma
[i
]; i
++)
1123 if (comma
[i
] == ',')
1126 newp
= opt_malloc(strlen(comma
)+(2*commas
));
1133 u16 len
= strlen(arg
);
1136 memcpy(p
, arg
, len
);
1144 new->len
= p
- newp
;
1146 else if (comma
&& (opt_len
& OT_RFC1035_NAME
))
1148 unsigned char *p
= NULL
, *newp
, *end
;
1155 char *dom
= canonicalise_opt(arg
);
1157 ret_err(_("bad domain in dhcp-option"));
1159 newp
= opt_malloc(len
+ strlen(dom
) + 2);
1163 memcpy(newp
, p
, len
);
1168 end
= do_rfc1035_name(p
+ len
, dom
);
1183 new->len
= strlen(comma
);
1184 /* keep terminating zero on string */
1185 new->val
= (unsigned char *)opt_string_alloc(comma
);
1186 new->flags
|= DHOPT_STRING
;
1192 ((new->len
> 255) ||
1193 (new->len
> 253 && (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))) ||
1194 (new->len
> 250 && (new->flags
& DHOPT_RFC3925
))))
1195 ret_err(_("dhcp-option too long"));
1197 if (flags
== DHOPT_MATCH
)
1199 if ((new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
)) ||
1202 ret_err(_("illegal dhcp-match"));
1206 new->next
= daemon
->dhcp_match6
;
1207 daemon
->dhcp_match6
= new;
1211 new->next
= daemon
->dhcp_match
;
1212 daemon
->dhcp_match
= new;
1217 new->next
= daemon
->dhcp_opts6
;
1218 daemon
->dhcp_opts6
= new;
1222 new->next
= daemon
->dhcp_opts
;
1223 daemon
->dhcp_opts
= new;
1231 void set_option_bool(unsigned int opt
)
1234 daemon
->options
|= 1u << opt
;
1236 daemon
->options2
|= 1u << (opt
- 32);
1239 void reset_option_bool(unsigned int opt
)
1242 daemon
->options
&= ~(1u << opt
);
1244 daemon
->options2
&= ~(1u << (opt
- 32));
1247 static int one_opt(int option
, char *arg
, char *errstr
, char *gen_err
, int command_line
)
1255 for (i
=0; usage
[i
].opt
!= 0; i
++)
1256 if (usage
[i
].opt
== option
)
1258 int rept
= usage
[i
].rept
;
1263 if (rept
== ARG_USED_CL
)
1264 ret_err(_("illegal repeated flag"));
1265 if (rept
== ARG_ONE
)
1266 usage
[i
].rept
= ARG_USED_CL
;
1270 /* allow file to override command line */
1271 if (rept
== ARG_USED_FILE
)
1272 ret_err(_("illegal repeated keyword"));
1273 if (rept
== ARG_USED_CL
|| rept
== ARG_ONE
)
1274 usage
[i
].rept
= ARG_USED_FILE
;
1277 if (rept
!= ARG_DUP
&& rept
!= ARG_ONE
&& rept
!= ARG_USED_CL
)
1279 set_option_bool(rept
);
1288 case 'C': /* --conf-file */
1290 char *file
= opt_string_alloc(arg
);
1299 case '7': /* --conf-dir */
1303 char *directory
, *path
;
1307 } *ignore_suffix
= NULL
, *li
;
1310 if (!(directory
= opt_string_alloc(arg
)))
1313 for (arg
= comma
; arg
; arg
= comma
)
1316 li
= opt_malloc(sizeof(struct list
));
1317 li
->next
= ignore_suffix
;
1319 /* Have to copy: buffer is overwritten */
1320 li
->suffix
= opt_string_alloc(arg
);
1323 if (!(dir_stream
= opendir(directory
)))
1324 die(_("cannot access directory %s: %s"), directory
, EC_FILE
);
1326 while ((ent
= readdir(dir_stream
)))
1328 size_t len
= strlen(ent
->d_name
);
1331 /* ignore emacs backups and dotfiles */
1333 ent
->d_name
[len
- 1] == '~' ||
1334 (ent
->d_name
[0] == '#' && ent
->d_name
[len
- 1] == '#') ||
1335 ent
->d_name
[0] == '.')
1338 for (li
= ignore_suffix
; li
; li
= li
->next
)
1340 /* check for proscribed suffices */
1341 size_t ls
= strlen(li
->suffix
);
1343 strcmp(li
->suffix
, &ent
->d_name
[len
- ls
]) == 0)
1349 path
= opt_malloc(strlen(directory
) + len
+ 2);
1350 strcpy(path
, directory
);
1352 strcat(path
, ent
->d_name
);
1354 if (stat(path
, &buf
) == -1)
1355 die(_("cannot access %s: %s"), path
, EC_FILE
);
1356 /* only reg files allowed. */
1357 if (!S_ISREG(buf
.st_mode
))
1360 /* files must be readable */
1365 closedir(dir_stream
);
1367 for(; ignore_suffix
; ignore_suffix
= li
)
1369 li
= ignore_suffix
->next
;
1370 free(ignore_suffix
->suffix
);
1371 free(ignore_suffix
);
1377 case '1': /* --enable-dbus */
1378 set_option_bool(OPT_DBUS
);
1380 daemon
->dbus_name
= opt_string_alloc(arg
);
1382 daemon
->dbus_name
= DNSMASQ_SERVICE
;
1385 case '8': /* --log-facility */
1386 /* may be a filename */
1387 if (strchr(arg
, '/') || strcmp (arg
, "-") == 0)
1388 daemon
->log_file
= opt_string_alloc(arg
);
1392 ret_err(_("setting log facility is not possible under Android"));
1394 for (i
= 0; facilitynames
[i
].c_name
; i
++)
1395 if (hostname_isequal((char *)facilitynames
[i
].c_name
, arg
))
1398 if (facilitynames
[i
].c_name
)
1399 daemon
->log_fac
= facilitynames
[i
].c_val
;
1401 ret_err(_("bad log facility"));
1406 case 'x': /* --pid-file */
1407 daemon
->runfile
= opt_string_alloc(arg
);
1410 case 'r': /* --resolv-file */
1412 char *name
= opt_string_alloc(arg
);
1413 struct resolvc
*new, *list
= daemon
->resolv_files
;
1415 if (list
&& list
->is_default
)
1417 /* replace default resolv file - possibly with nothing */
1420 list
->is_default
= 0;
1428 new = opt_malloc(sizeof(struct resolvc
));
1431 new->is_default
= 0;
1436 daemon
->resolv_files
= list
;
1440 case 'm': /* --mx-host */
1443 struct mx_srv_record
*new;
1444 char *name
, *target
= NULL
;
1446 if ((comma
= split(arg
)))
1449 if ((prefstr
= split(comma
)) && !atoi_check16(prefstr
, &pref
))
1450 ret_err(_("bad MX preference"));
1453 if (!(name
= canonicalise_opt(arg
)) ||
1454 (comma
&& !(target
= canonicalise_opt(comma
))))
1455 ret_err(_("bad MX name"));
1457 new = opt_malloc(sizeof(struct mx_srv_record
));
1458 new->next
= daemon
->mxnames
;
1459 daemon
->mxnames
= new;
1462 new->target
= target
; /* may be NULL */
1467 case 't': /* --mx-target */
1468 if (!(daemon
->mxtarget
= canonicalise_opt(arg
)))
1469 ret_err(_("bad MX target"));
1473 case 'l': /* --dhcp-leasefile */
1474 daemon
->lease_file
= opt_string_alloc(arg
);
1477 /* Sorry about the gross pre-processor abuse */
1478 case '6': /* --dhcp-script */
1479 case LOPT_LUASCRIPT
: /* --dhcp-luascript */
1480 # if defined(NO_FORK)
1481 ret_err(_("cannot run scripts under uClinux"));
1482 # elif !defined(HAVE_SCRIPT)
1483 ret_err(_("recompile with HAVE_SCRIPT defined to enable lease-change scripts"));
1485 if (option
== LOPT_LUASCRIPT
)
1486 # if !defined(HAVE_LUASCRIPT)
1487 ret_err(_("recompile with HAVE_LUASCRIPT defined to enable Lua scripts"));
1489 daemon
->luascript
= opt_string_alloc(arg
);
1492 daemon
->lease_change_command
= opt_string_alloc(arg
);
1495 #endif /* HAVE_DHCP */
1497 case LOPT_DHCP_HOST
: /* --dhcp-hostfile */
1498 case LOPT_DHCP_OPTS
: /* --dhcp-optsfile */
1499 case 'H': /* --addn-hosts */
1501 struct hostsfile
*new = opt_malloc(sizeof(struct hostsfile
));
1502 static int hosts_index
= 1;
1503 new->fname
= opt_string_alloc(arg
);
1504 new->index
= hosts_index
++;
1508 new->next
= daemon
->addn_hosts
;
1509 daemon
->addn_hosts
= new;
1511 else if (option
== LOPT_DHCP_HOST
)
1513 new->next
= daemon
->dhcp_hosts_file
;
1514 daemon
->dhcp_hosts_file
= new;
1516 else if (option
== LOPT_DHCP_OPTS
)
1518 new->next
= daemon
->dhcp_opts_file
;
1519 daemon
->dhcp_opts_file
= new;
1524 case 's': /* --domain */
1525 if (strcmp (arg
, "#") == 0)
1526 set_option_bool(OPT_RESOLV_DOMAIN
);
1531 if (!(d
= canonicalise_opt(arg
)))
1537 struct cond_domain
*new = safe_malloc(sizeof(struct cond_domain
));
1540 unhide_metas(comma
);
1541 if ((netpart
= split_chr(comma
, '/')))
1545 arg
= split(netpart
);
1546 if (!atoi_check(netpart
, &msize
))
1548 else if (inet_pton(AF_INET
, comma
, &new->start
))
1550 int mask
= (1 << (32 - msize
)) - 1;
1552 new->start
.s_addr
= ntohl(htonl(new->start
.s_addr
) & ~mask
);
1553 new->end
.s_addr
= new->start
.s_addr
| htonl(mask
);
1556 /* generate the equivalent of
1558 local=/xxx.yyy.zzz.in-addr.arpa/ */
1560 if (strcmp(arg
, "local") != 0 ||
1561 (msize
!= 8 && msize
!= 16 && msize
!= 24))
1565 struct server
*serv
= opt_malloc(sizeof(struct server
));
1566 in_addr_t a
= ntohl(new->start
.s_addr
) >> 8;
1569 memset(serv
, 0, sizeof(struct server
));
1571 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1572 serv
->next
= daemon
->servers
;
1573 daemon
->servers
= serv
;
1575 serv
= opt_malloc(sizeof(struct server
));
1576 memset(serv
, 0, sizeof(struct server
));
1577 p
= serv
->domain
= opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */
1580 p
+= sprintf(p
, "%d.", a
& 0xff);
1583 p
+= sprintf(p
, "%d.", a
& 0xff);
1585 p
+= sprintf(p
, "%d.in-addr.arpa", a
& 0xff);
1587 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1588 serv
->next
= daemon
->servers
;
1589 daemon
->servers
= serv
;
1594 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1596 u64 mask
= (1LLU << (128 - msize
)) - 1LLU;
1597 u64 addrpart
= addr6part(&new->start6
);
1600 /* prefix==64 overflows the mask calculation above */
1604 new->end6
= new->start6
;
1605 setaddr6part(&new->start6
, addrpart
& ~mask
);
1606 setaddr6part(&new->end6
, addrpart
| mask
);
1612 /* generate the equivalent of
1614 local=/xxx.yyy.zzz.ip6.arpa/ */
1616 if (strcmp(arg
, "local") != 0 || ((msize
& 4) != 0))
1620 struct server
*serv
= opt_malloc(sizeof(struct server
));
1623 memset(serv
, 0, sizeof(struct server
));
1625 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1626 serv
->next
= daemon
->servers
;
1627 daemon
->servers
= serv
;
1629 serv
= opt_malloc(sizeof(struct server
));
1630 memset(serv
, 0, sizeof(struct server
));
1631 p
= serv
->domain
= opt_malloc(73); /* strlen("32*<n.>ip6.arpa")+1 */
1633 for (i
= msize
-1; i
>= 0; i
-= 4)
1635 int dig
= ((unsigned char *)&new->start6
)[i
>>3];
1636 p
+= sprintf(p
, "%.1x.", (i
>>2) & 1 ? dig
& 15 : dig
>> 4);
1638 p
+= sprintf(p
, "ip6.arpa");
1640 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1641 serv
->next
= daemon
->servers
;
1642 daemon
->servers
= serv
;
1653 if (inet_pton(AF_INET
, comma
, &new->start
))
1657 new->end
.s_addr
= new->start
.s_addr
;
1658 else if (!inet_pton(AF_INET
, arg
, &new->end
))
1662 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1666 memcpy(&new->end6
, &new->start6
, IN6ADDRSZ
);
1667 else if (!inet_pton(AF_INET6
, arg
, &new->end6
))
1676 new->next
= daemon
->cond_domain
;
1677 daemon
->cond_domain
= new;
1680 daemon
->domain_suffix
= d
;
1685 case 'u': /* --user */
1686 daemon
->username
= opt_string_alloc(arg
);
1689 case 'g': /* --group */
1690 daemon
->groupname
= opt_string_alloc(arg
);
1691 daemon
->group_set
= 1;
1695 case LOPT_SCRIPTUSR
: /* --scriptuser */
1696 daemon
->scriptuser
= opt_string_alloc(arg
);
1700 case 'i': /* --interface */
1702 struct iname
*new = opt_malloc(sizeof(struct iname
));
1704 new->next
= daemon
->if_names
;
1705 daemon
->if_names
= new;
1706 /* new->name may be NULL if someone does
1707 "interface=" to disable all interfaces except loop. */
1708 new->name
= opt_string_alloc(arg
);
1714 case 'I': /* --except-interface */
1715 case '2': /* --no-dhcp-interface */
1717 struct iname
*new = opt_malloc(sizeof(struct iname
));
1719 new->name
= opt_string_alloc(arg
);
1722 new->next
= daemon
->if_except
;
1723 daemon
->if_except
= new;
1727 new->next
= daemon
->dhcp_except
;
1728 daemon
->dhcp_except
= new;
1734 case 'B': /* --bogus-nxdomain */
1736 struct in_addr addr
;
1738 if (arg
&& (addr
.s_addr
= inet_addr(arg
)) != (in_addr_t
)-1)
1740 struct bogus_addr
*baddr
= opt_malloc(sizeof(struct bogus_addr
));
1741 baddr
->next
= daemon
->bogus_addr
;
1742 daemon
->bogus_addr
= baddr
;
1746 ret_err(gen_err
); /* error */
1750 case 'a': /* --listen-address */
1752 struct iname
*new = opt_malloc(sizeof(struct iname
));
1755 new->next
= daemon
->if_addrs
;
1756 if (arg
&& (new->addr
.in
.sin_addr
.s_addr
= inet_addr(arg
)) != (in_addr_t
)-1)
1758 new->addr
.sa
.sa_family
= AF_INET
;
1759 #ifdef HAVE_SOCKADDR_SA_LEN
1760 new->addr
.in
.sin_len
= sizeof(new->addr
.in
);
1764 else if (arg
&& inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
1766 new->addr
.sa
.sa_family
= AF_INET6
;
1767 new->addr
.in6
.sin6_flowinfo
= 0;
1768 new->addr
.in6
.sin6_scope_id
= 0;
1769 #ifdef HAVE_SOCKADDR_SA_LEN
1770 new->addr
.in6
.sin6_len
= sizeof(new->addr
.in6
);
1778 daemon
->if_addrs
= new;
1783 case 'S': /* --server */
1784 case LOPT_LOCAL
: /* --local */
1785 case 'A': /* --address */
1786 case LOPT_NO_REBIND
: /* --rebind-domain-ok */
1788 struct server
*serv
, *newlist
= NULL
;
1792 if (arg
&& (*arg
== '/' || option
== LOPT_NO_REBIND
))
1794 int rebind
= !(*arg
== '/');
1798 while (rebind
|| (end
= split_chr(arg
, '/')))
1800 char *domain
= NULL
;
1801 /* elide leading dots - they are implied in the search algorithm */
1802 while (*arg
== '.') arg
++;
1803 /* # matches everything and becomes a zero length domain string */
1804 if (strcmp(arg
, "#") == 0)
1806 else if (strlen (arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
1808 serv
= opt_malloc(sizeof(struct server
));
1809 memset(serv
, 0, sizeof(struct server
));
1810 serv
->next
= newlist
;
1812 serv
->domain
= domain
;
1813 serv
->flags
= domain
? SERV_HAS_DOMAIN
: SERV_FOR_NODOTS
;
1823 newlist
= opt_malloc(sizeof(struct server
));
1824 memset(newlist
, 0, sizeof(struct server
));
1829 newlist
->flags
|= SERV_LITERAL_ADDRESS
;
1830 if (!(newlist
->flags
& SERV_TYPE
))
1833 else if (option
== LOPT_NO_REBIND
)
1834 newlist
->flags
|= SERV_NO_REBIND
;
1838 if (!(newlist
->flags
& SERV_NO_REBIND
))
1839 newlist
->flags
|= SERV_NO_ADDR
; /* no server */
1840 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
1844 else if (strcmp(arg
, "#") == 0)
1846 newlist
->flags
|= SERV_USE_RESOLV
; /* treat in ordinary way */
1847 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
1852 char *err
= parse_server(arg
, &newlist
->addr
, &newlist
->source_addr
, newlist
->interface
, &newlist
->flags
);
1860 serv
->next
->flags
= serv
->flags
;
1861 serv
->next
->addr
= serv
->addr
;
1862 serv
->next
->source_addr
= serv
->source_addr
;
1863 strcpy(serv
->next
->interface
, serv
->interface
);
1866 serv
->next
= daemon
->servers
;
1867 daemon
->servers
= newlist
;
1871 case 'c': /* --cache-size */
1875 if (!atoi_check(arg
, &size
))
1879 /* zero is OK, and means no caching. */
1883 else if (size
> 10000)
1886 daemon
->cachesize
= size
;
1891 case 'p': /* --port */
1892 if (!atoi_check16(arg
, &daemon
->port
))
1896 case LOPT_MINPORT
: /* --min-port */
1897 if (!atoi_check16(arg
, &daemon
->min_port
))
1901 case '0': /* --dns-forward-max */
1902 if (!atoi_check(arg
, &daemon
->ftabsize
))
1906 case LOPT_MAX_LOGS
: /* --log-async */
1907 daemon
->max_logs
= LOG_MAX
; /* default */
1908 if (arg
&& !atoi_check(arg
, &daemon
->max_logs
))
1910 else if (daemon
->max_logs
> 100)
1911 daemon
->max_logs
= 100;
1914 case 'P': /* --edns-packet-max */
1917 if (!atoi_check(arg
, &i
))
1919 daemon
->edns_pktsz
= (unsigned short)i
;
1923 case 'Q': /* --query-port */
1924 if (!atoi_check16(arg
, &daemon
->query_port
))
1926 /* if explicitly set to zero, use single OS ephemeral port
1927 and disable random ports */
1928 if (daemon
->query_port
== 0)
1932 case 'T': /* --local-ttl */
1933 case LOPT_NEGTTL
: /* --neg-ttl */
1934 case LOPT_MAXTTL
: /* --max-ttl */
1935 case LOPT_MAXCTTL
: /* --max-cache-ttl */
1938 if (!atoi_check(arg
, &ttl
))
1940 else if (option
== LOPT_NEGTTL
)
1941 daemon
->neg_ttl
= (unsigned long)ttl
;
1942 else if (option
== LOPT_MAXTTL
)
1943 daemon
->max_ttl
= (unsigned long)ttl
;
1944 else if (option
== LOPT_MAXCTTL
)
1945 daemon
->max_cache_ttl
= (unsigned long)ttl
;
1947 daemon
->local_ttl
= (unsigned long)ttl
;
1952 case 'X': /* --dhcp-lease-max */
1953 if (!atoi_check(arg
, &daemon
->dhcp_max
))
1959 case LOPT_TFTP_MAX
: /* --tftp-max */
1960 if (!atoi_check(arg
, &daemon
->tftp_max
))
1964 case LOPT_PREFIX
: /* --tftp-prefix */
1968 struct tftp_prefix
*new = opt_malloc(sizeof(struct tftp_prefix
));
1969 new->interface
= opt_string_alloc(comma
);
1970 new->prefix
= opt_string_alloc(arg
);
1971 new->next
= daemon
->if_prefix
;
1972 daemon
->if_prefix
= new;
1975 daemon
->tftp_prefix
= opt_string_alloc(arg
);
1978 case LOPT_TFTPPORTS
: /* --tftp-port-range */
1979 if (!(comma
= split(arg
)) ||
1980 !atoi_check16(arg
, &daemon
->start_tftp_port
) ||
1981 !atoi_check16(comma
, &daemon
->end_tftp_port
))
1982 ret_err(_("bad port range"));
1984 if (daemon
->start_tftp_port
> daemon
->end_tftp_port
)
1986 int tmp
= daemon
->start_tftp_port
;
1987 daemon
->start_tftp_port
= daemon
->end_tftp_port
;
1988 daemon
->end_tftp_port
= tmp
;
1994 case LOPT_BRIDGE
: /* --bridge-interface */
1996 struct dhcp_bridge
*new = opt_malloc(sizeof(struct dhcp_bridge
));
1997 if (!(comma
= split(arg
)) || strlen(arg
) > IF_NAMESIZE
- 1 )
1998 ret_err(_("bad bridge-interface"));
2000 strcpy(new->iface
, arg
);
2002 new->next
= daemon
->bridges
;
2003 daemon
->bridges
= new;
2008 if (strlen(arg
) != 0 && strlen(arg
) <= IF_NAMESIZE
- 1)
2010 struct dhcp_bridge
*b
= opt_malloc(sizeof(struct dhcp_bridge
));
2011 b
->next
= new->alias
;
2013 strcpy(b
->iface
, arg
);
2021 case 'F': /* --dhcp-range */
2023 int k
, leasepos
= 2;
2024 char *cp
, *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2025 struct dhcp_context
*new = opt_malloc(sizeof(struct dhcp_context
));
2027 memset (new, 0, sizeof(*new));
2028 new->lease_time
= DEFLEASE
;
2038 for (cp
= arg
; *cp
; cp
++)
2039 if (!(*cp
== ' ' || *cp
== '.' || *cp
== ':' ||
2040 (*cp
>= 'a' && *cp
<= 'f') || (*cp
>= 'A' && *cp
<= 'F') ||
2041 (*cp
>='0' && *cp
<= '9')))
2044 if (*cp
!= ',' && (comma
= split(arg
)))
2046 if (is_tag_prefix(arg
))
2048 struct dhcp_netid
*tt
= opt_malloc(sizeof (struct dhcp_netid
));
2049 tt
->net
= opt_string_alloc(arg
+4);
2050 tt
->next
= new->filter
;
2056 ret_err(_("only one tag allowed"));
2057 else if (strstr(arg
, "set:") == arg
)
2058 new->netid
.net
= opt_string_alloc(arg
+4);
2060 new->netid
.net
= opt_string_alloc(arg
);
2071 for (k
= 1; k
< 7; k
++)
2072 if (!(a
[k
] = split(a
[k
-1])))
2076 ret_err(_("bad dhcp-range"));
2078 if (inet_pton(AF_INET
, a
[0], &new->start
))
2080 new->next
= daemon
->dhcp
;
2082 new->end
= new->start
;
2083 if (strcmp(a
[1], "static") == 0)
2084 new->flags
|= CONTEXT_STATIC
;
2085 else if (strcmp(a
[1], "proxy") == 0)
2086 new->flags
|= CONTEXT_PROXY
;
2087 else if (!inet_pton(AF_INET
, a
[1], &new->end
))
2088 ret_err(_("bad dhcp-range"));
2090 if (ntohl(new->start
.s_addr
) > ntohl(new->end
.s_addr
))
2092 struct in_addr tmp
= new->start
;
2093 new->start
= new->end
;
2097 if (k
>= 3 && strchr(a
[2], '.') &&
2098 ((new->netmask
.s_addr
= inet_addr(a
[2])) != (in_addr_t
)-1))
2100 new->flags
|= CONTEXT_NETMASK
;
2102 if (!is_same_net(new->start
, new->end
, new->netmask
))
2103 ret_err(_("inconsistent DHCP range"));
2106 if (k
>= 4 && strchr(a
[3], '.') &&
2107 ((new->broadcast
.s_addr
= inet_addr(a
[3])) != (in_addr_t
)-1))
2109 new->flags
|= CONTEXT_BRDCAST
;
2114 else if (inet_pton(AF_INET6
, a
[0], &new->start6
))
2116 new->prefix
= 64; /* default */
2117 new->end6
= new->start6
;
2119 for (leasepos
= 1; leasepos
< k
; leasepos
++)
2121 if (strcmp(a
[leasepos
], "static") == 0)
2122 new->flags
|= CONTEXT_STATIC
| CONTEXT_DHCP
;
2123 else if (strcmp(a
[leasepos
], "ra-only") == 0 || strcmp(a
[leasepos
], "slaac") == 0 )
2124 new->flags
|= CONTEXT_RA_ONLY
;
2125 else if (strcmp(a
[leasepos
], "ra-names") == 0)
2126 new->flags
|= CONTEXT_RA_NAME
;
2127 else if (strcmp(a
[leasepos
], "ra-stateless") == 0)
2128 new->flags
|= CONTEXT_RA_STATELESS
| CONTEXT_DHCP
;
2129 else if (leasepos
== 1 && inet_pton(AF_INET6
, a
[leasepos
], &new->end6
))
2130 new->flags
|= CONTEXT_DHCP
;
2135 if (new->flags
& CONTEXT_DHCP
)
2137 new->next
= daemon
->dhcp6
;
2138 daemon
->dhcp6
= new;
2142 new->next
= daemon
->ra_contexts
;
2143 daemon
->ra_contexts
= new;
2146 /* bare integer < 128 is prefix value */
2150 for (cp
= a
[leasepos
]; *cp
; cp
++)
2151 if (!(*cp
>= '0' && *cp
<= '9'))
2153 if (!*cp
&& (pref
= atoi(a
[leasepos
])) <= 128)
2157 if ((new->flags
& (CONTEXT_RA_ONLY
| CONTEXT_RA_NAME
| CONTEXT_RA_STATELESS
)) &&
2159 ret_err(_("prefix must be exactly 64 for RA subnets"));
2160 else if (new->prefix
< 64)
2161 ret_err(_("prefix must be at least 64"));
2165 if (!is_same_net6(&new->start6
, &new->end6
, new->prefix
))
2166 ret_err(_("inconsistent DHCPv6 range"));
2167 if (addr6part(&new->start6
) > addr6part(&new->end6
))
2169 struct in6_addr tmp
= new->start6
;
2170 new->start6
= new->end6
;
2178 if (strcmp(a
[leasepos
], "infinite") == 0)
2179 new->lease_time
= 0xffffffff;
2180 else if (strcmp(a
[leasepos
], "deprecated") == 0)
2181 new->flags
|= CONTEXT_DEPRECATE
;
2185 if (strlen(a
[leasepos
]) > 0)
2187 switch (a
[leasepos
][strlen(a
[leasepos
]) - 1])
2207 a
[leasepos
][strlen(a
[leasepos
]) - 1] = 0;
2210 new->lease_time
= atoi(a
[leasepos
]) * fac
;
2211 /* Leases of a minute or less confuse
2212 some clients, notably Apple's */
2213 if (new->lease_time
< 120)
2214 new->lease_time
= 120;
2222 case 'G': /* --dhcp-host */
2225 char *a
[6] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2226 struct dhcp_config
*new;
2229 new = opt_malloc(sizeof(struct dhcp_config
));
2231 new->next
= daemon
->dhcp_conf
;
2232 new->flags
= (option
== LOPT_BANK
) ? CONFIG_BANK
: 0;
2237 for (k
= 1; k
< 6; k
++)
2238 if (!(a
[k
] = split(a
[k
-1])))
2241 for (j
= 0; j
< k
; j
++)
2242 if (strchr(a
[j
], ':')) /* ethernet address, netid or binary CLID */
2246 if ((arg
[0] == 'i' || arg
[0] == 'I') &&
2247 (arg
[1] == 'd' || arg
[1] == 'D') &&
2251 new->flags
|= CONFIG_NOCLID
;
2255 arg
+= 3; /* dump id: */
2256 if (strchr(arg
, ':'))
2257 len
= parse_hex(arg
, (unsigned char *)arg
, -1, NULL
, NULL
);
2261 len
= (int) strlen(arg
);
2266 ret_err(_("bad hex constant"));
2267 else if ((new->clid
= opt_malloc(len
)))
2269 new->flags
|= CONFIG_CLID
;
2270 new->clid_len
= len
;
2271 memcpy(new->clid
, arg
, len
);
2275 /* dhcp-host has strange backwards-compat needs. */
2276 else if (strstr(arg
, "net:") == arg
|| strstr(arg
, "set:") == arg
)
2278 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2279 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2280 newtag
->net
= opt_malloc(strlen(arg
+ 4) + 1);
2281 newlist
->next
= new->netid
;
2282 new->netid
= newlist
;
2283 newlist
->list
= newtag
;
2284 strcpy(newtag
->net
, arg
+4);
2285 unhide_metas(newtag
->net
);
2287 else if (strstr(arg
, "tag:") == arg
)
2288 ret_err(_("cannot match tags in --dhcp-host"));
2290 else if (arg
[0] == '[' && arg
[strlen(arg
)-1] == ']')
2292 arg
[strlen(arg
)-1] = 0;
2295 if (!inet_pton(AF_INET6
, arg
, &new->addr6
))
2296 ret_err(_("bad IPv6 address"));
2298 new->flags
|= CONFIG_ADDR6
;
2303 struct hwaddr_config
*newhw
= opt_malloc(sizeof(struct hwaddr_config
));
2304 if ((newhw
->hwaddr_len
= parse_hex(a
[j
], newhw
->hwaddr
, DHCP_CHADDR_MAX
,
2305 &newhw
->wildcard_mask
, &newhw
->hwaddr_type
)) == -1)
2306 ret_err(_("bad hex constant"));
2310 newhw
->next
= new->hwaddr
;
2311 new->hwaddr
= newhw
;
2315 else if (strchr(a
[j
], '.') && (in
.s_addr
= inet_addr(a
[j
])) != (in_addr_t
)-1)
2317 struct dhcp_config
*configs
;
2320 new->flags
|= CONFIG_ADDR
;
2322 /* If the same IP appears in more than one host config, then DISCOVER
2323 for one of the hosts will get the address, but REQUEST will be NAKed,
2324 since the address is reserved by the other one -> protocol loop. */
2325 for (configs
= daemon
->dhcp_conf
; configs
; configs
= configs
->next
)
2326 if ((configs
->flags
& CONFIG_ADDR
) && configs
->addr
.s_addr
== in
.s_addr
)
2328 sprintf(errstr
, _("duplicate dhcp-host IP address %s"), inet_ntoa(in
));
2334 char *cp
, *lastp
= NULL
, last
= 0;
2337 if (strlen(a
[j
]) > 1)
2339 lastp
= a
[j
] + strlen(a
[j
]) - 1;
2365 for (cp
= a
[j
]; *cp
; cp
++)
2366 if (!isdigit((unsigned char)*cp
) && *cp
!= ' ')
2373 if (strcmp(a
[j
], "infinite") == 0)
2375 new->lease_time
= 0xffffffff;
2376 new->flags
|= CONFIG_TIME
;
2378 else if (strcmp(a
[j
], "ignore") == 0)
2379 new->flags
|= CONFIG_DISABLE
;
2382 if (!(new->hostname
= canonicalise_opt(a
[j
])) ||
2383 !legal_hostname(new->hostname
))
2384 ret_err(_("bad DHCP host name"));
2386 new->flags
|= CONFIG_NAME
;
2387 new->domain
= strip_hostname(new->hostname
);
2392 new->lease_time
= atoi(a
[j
]) * fac
;
2393 /* Leases of a minute or less confuse
2394 some clients, notably Apple's */
2395 if (new->lease_time
< 120)
2396 new->lease_time
= 120;
2397 new->flags
|= CONFIG_TIME
;
2401 daemon
->dhcp_conf
= new;
2405 case LOPT_TAG_IF
: /* --tag-if */
2407 struct tag_if
*new = opt_malloc(sizeof(struct tag_if
));
2413 /* preserve order */
2414 if (!daemon
->tag_if
)
2415 daemon
->tag_if
= new;
2419 for (tmp
= daemon
->tag_if
; tmp
->next
; tmp
= tmp
->next
);
2437 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2438 newtag
->net
= opt_malloc(len
- 3);
2439 strcpy(newtag
->net
, arg
+4);
2440 unhide_metas(newtag
->net
);
2442 if (strstr(arg
, "set:") == arg
)
2444 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2445 newlist
->next
= new->set
;
2447 newlist
->list
= newtag
;
2449 else if (strstr(arg
, "tag:") == arg
)
2451 newtag
->next
= new->tag
;
2465 ret_err(_("bad tag-if"));
2471 case 'O': /* --dhcp-option */
2472 case LOPT_FORCE
: /* --dhcp-option-force */
2474 case LOPT_MATCH
: /* --dhcp-match */
2475 return parse_dhcp_opt(errstr
, arg
,
2476 option
== LOPT_FORCE
? DHOPT_FORCE
:
2477 (option
== LOPT_MATCH
? DHOPT_MATCH
:
2478 (option
== LOPT_OPTS
? DHOPT_BANK
: 0)));
2480 case 'M': /* --dhcp-boot */
2482 struct dhcp_netid
*id
= NULL
;
2483 while (is_tag_prefix(arg
))
2485 struct dhcp_netid
*newid
= opt_malloc(sizeof(struct dhcp_netid
));
2489 newid
->net
= opt_string_alloc(arg
+4);
2497 char *dhcp_file
, *dhcp_sname
= NULL
, *tftp_sname
= NULL
;
2498 struct in_addr dhcp_next_server
;
2499 struct dhcp_boot
*new;
2501 dhcp_file
= opt_string_alloc(arg
);
2502 dhcp_next_server
.s_addr
= 0;
2507 dhcp_sname
= opt_string_alloc(arg
);
2510 unhide_metas(comma
);
2511 if ((dhcp_next_server
.s_addr
= inet_addr(comma
)) == (in_addr_t
)-1) {
2514 * The user may have specified the tftp hostname here.
2515 * save it so that it can be resolved/looked up during
2516 * actual dhcp_reply().
2519 tftp_sname
= opt_string_alloc(comma
);
2520 dhcp_next_server
.s_addr
= 0;
2525 new = opt_malloc(sizeof(struct dhcp_boot
));
2526 new->file
= dhcp_file
;
2527 new->sname
= dhcp_sname
;
2528 new->tftp_sname
= tftp_sname
;
2529 new->next_server
= dhcp_next_server
;
2531 new->next
= daemon
->boot_config
;
2532 daemon
->boot_config
= new;
2538 case LOPT_PXE_PROMT
: /* --pxe-prompt */
2540 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
2544 new->opt
= 10; /* PXE_MENU_PROMPT */
2546 while (is_tag_prefix(arg
))
2548 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
2550 nn
->next
= new->netid
;
2552 nn
->net
= opt_string_alloc(arg
+4);
2562 new->len
= strlen(arg
) + 1;
2563 new->val
= opt_malloc(new->len
);
2564 memcpy(new->val
+ 1, arg
, new->len
- 1);
2566 new->u
.vendor_class
= (unsigned char *)"PXEClient";
2567 new->flags
= DHOPT_VENDOR
;
2569 if (comma
&& atoi_check(comma
, &timeout
))
2570 *(new->val
) = timeout
;
2574 new->next
= daemon
->dhcp_opts
;
2575 daemon
->dhcp_opts
= new;
2576 daemon
->enable_pxe
= 1;
2582 case LOPT_PXE_SERV
: /* --pxe-service */
2584 struct pxe_service
*new = opt_malloc(sizeof(struct pxe_service
));
2585 char *CSA
[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
2586 "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL
};
2587 static int boottype
= 32768;
2591 new->server
.s_addr
= 0;
2593 while (is_tag_prefix(arg
))
2595 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
2597 nn
->next
= new->netid
;
2599 nn
->net
= opt_string_alloc(arg
+4);
2603 if (arg
&& (comma
= split(arg
)))
2605 for (i
= 0; CSA
[i
]; i
++)
2606 if (strcasecmp(CSA
[i
], arg
) == 0)
2609 if (CSA
[i
] || atoi_check(arg
, &i
))
2615 new->menu
= opt_string_alloc(arg
);
2619 new->type
= 0; /* local boot */
2620 new->basename
= NULL
;
2626 if (atoi_check(arg
, &i
))
2629 new->basename
= NULL
;
2633 new->type
= boottype
++;
2634 new->basename
= opt_string_alloc(arg
);
2639 if (!inet_pton(AF_INET
, comma
, &new->server
))
2641 new->server
.s_addr
= 0;
2642 new->sname
= opt_string_alloc(comma
);
2650 if (!daemon
->pxe_services
)
2651 daemon
->pxe_services
= new;
2654 struct pxe_service
*s
;
2655 for (s
= daemon
->pxe_services
; s
->next
; s
= s
->next
);
2659 daemon
->enable_pxe
= 1;
2668 case '4': /* --dhcp-mac */
2670 if (!(comma
= split(arg
)))
2674 struct dhcp_mac
*new = opt_malloc(sizeof(struct dhcp_mac
));
2675 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
2676 unhide_metas(comma
);
2677 new->hwaddr_len
= parse_hex(comma
, new->hwaddr
, DHCP_CHADDR_MAX
, &new->mask
, &new->hwaddr_type
);
2678 if (new->hwaddr_len
== -1)
2682 new->next
= daemon
->dhcp_macs
;
2683 daemon
->dhcp_macs
= new;
2689 case 'U': /* --dhcp-vendorclass */
2690 case 'j': /* --dhcp-userclass */
2691 case LOPT_CIRCUIT
: /* --dhcp-circuitid */
2692 case LOPT_REMOTE
: /* --dhcp-remoteid */
2693 case LOPT_SUBSCR
: /* --dhcp-subscrid */
2697 struct dhcp_vendor
*new = opt_malloc(sizeof(struct dhcp_vendor
));
2699 if (!(comma
= split(arg
)))
2702 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
2703 /* check for hex string - must digits may include : must not have nothing else,
2704 only allowed for agent-options. */
2707 if ((comma
= split(arg
)))
2709 if (option
!= 'U' || strstr(arg
, "enterprise:") != arg
)
2712 new->enterprise
= atoi(arg
+11);
2717 for (p
= (unsigned char *)comma
; *p
; p
++)
2722 unhide_metas(comma
);
2723 if (option
== 'U' || option
== 'j' || *p
|| !dig
)
2725 new->len
= strlen(comma
);
2726 new->data
= opt_malloc(new->len
);
2727 memcpy(new->data
, comma
, new->len
);
2731 new->len
= parse_hex(comma
, (unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
2732 new->data
= opt_malloc(new->len
);
2733 memcpy(new->data
, comma
, new->len
);
2739 new->match_type
= MATCH_USER
;
2742 new->match_type
= MATCH_VENDOR
;
2745 new->match_type
= MATCH_CIRCUIT
;
2748 new->match_type
= MATCH_REMOTE
;
2751 new->match_type
= MATCH_SUBSCRIBER
;
2754 new->next
= daemon
->dhcp_vendors
;
2755 daemon
->dhcp_vendors
= new;
2760 case LOPT_ALTPORT
: /* --dhcp-alternate-port */
2763 daemon
->dhcp_server_port
= DHCP_SERVER_ALTPORT
;
2764 daemon
->dhcp_client_port
= DHCP_CLIENT_ALTPORT
;
2769 if (!atoi_check16(arg
, &daemon
->dhcp_server_port
) ||
2770 (comma
&& !atoi_check16(comma
, &daemon
->dhcp_client_port
)))
2771 ret_err(_("invalid port number"));
2773 daemon
->dhcp_client_port
= daemon
->dhcp_server_port
+1;
2777 case 'J': /* --dhcp-ignore */
2778 case LOPT_NO_NAMES
: /* --dhcp-ignore-names */
2779 case LOPT_BROADCAST
: /* --dhcp-broadcast */
2780 case '3': /* --bootp-dynamic */
2781 case LOPT_GEN_NAMES
: /* --dhcp-generate-names */
2783 struct dhcp_netid_list
*new = opt_malloc(sizeof(struct dhcp_netid_list
));
2784 struct dhcp_netid
*list
= NULL
;
2787 new->next
= daemon
->dhcp_ignore
;
2788 daemon
->dhcp_ignore
= new;
2790 else if (option
== LOPT_BROADCAST
)
2792 new->next
= daemon
->force_broadcast
;
2793 daemon
->force_broadcast
= new;
2795 else if (option
== '3')
2797 new->next
= daemon
->bootp_dynamic
;
2798 daemon
->bootp_dynamic
= new;
2800 else if (option
== LOPT_GEN_NAMES
)
2802 new->next
= daemon
->dhcp_gen_names
;
2803 daemon
->dhcp_gen_names
= new;
2807 new->next
= daemon
->dhcp_ignore_names
;
2808 daemon
->dhcp_ignore_names
= new;
2812 struct dhcp_netid
*member
= opt_malloc(sizeof(struct dhcp_netid
));
2814 member
->next
= list
;
2816 if (is_tag_prefix(arg
))
2817 member
->net
= opt_string_alloc(arg
+4);
2819 member
->net
= opt_string_alloc(arg
);
2827 case LOPT_PROXY
: /* --dhcp-proxy */
2828 daemon
->override
= 1;
2830 struct addr_list
*new = opt_malloc(sizeof(struct addr_list
));
2832 if ((new->addr
.s_addr
= inet_addr(arg
)) == (in_addr_t
)-1)
2833 ret_err(_("bad dhcp-proxy address"));
2834 new->next
= daemon
->override_relays
;
2835 daemon
->override_relays
= new;
2842 case LOPT_DUID
: /* --dhcp-duid */
2843 if (!(comma
= split(arg
)) || !atoi_check(arg
, (int *)&daemon
->duid_enterprise
))
2844 ret_err(_("bad DUID"));
2847 daemon
->duid_config_len
= parse_hex(comma
,(unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
2848 daemon
->duid_config
= opt_malloc(daemon
->duid_config_len
);
2849 memcpy(daemon
->duid_config
, comma
, daemon
->duid_config_len
);
2854 case 'V': /* --alias */
2856 char *dash
, *a
[3] = { NULL
, NULL
, NULL
};
2858 struct doctor
*new = opt_malloc(sizeof(struct doctor
));
2859 new->next
= daemon
->doctors
;
2860 daemon
->doctors
= new;
2861 new->mask
.s_addr
= 0xffffffff;
2862 new->end
.s_addr
= 0;
2865 for (k
= 1; k
< 3; k
++)
2867 if (!(a
[k
] = split(a
[k
-1])))
2872 dash
= split_chr(a
[0], '-');
2875 ((new->in
.s_addr
= inet_addr(a
[0])) == (in_addr_t
)-1) ||
2876 ((new->out
.s_addr
= inet_addr(a
[1])) == (in_addr_t
)-1))
2880 new->mask
.s_addr
= inet_addr(a
[2]);
2883 ((new->end
.s_addr
= inet_addr(dash
)) == (in_addr_t
)-1 ||
2884 !is_same_net(new->in
, new->end
, new->mask
) ||
2885 ntohl(new->in
.s_addr
) > ntohl(new->end
.s_addr
)))
2886 ret_err(_("invalid alias range"));
2891 case LOPT_INTNAME
: /* --interface-name */
2893 struct interface_name
*new, **up
;
2894 char *domain
= NULL
;
2898 if (!comma
|| !(domain
= canonicalise_opt(arg
)))
2899 ret_err(_("bad interface name"));
2901 new = opt_malloc(sizeof(struct interface_name
));
2903 /* Add to the end of the list, so that first name
2904 of an interface is used for PTR lookups. */
2905 for (up
= &daemon
->int_names
; *up
; up
= &((*up
)->next
));
2908 new->intr
= opt_string_alloc(comma
);
2912 case LOPT_CNAME
: /* --cname */
2918 if (!(comma
= split(arg
)))
2921 alias
= canonicalise_opt(arg
);
2922 target
= canonicalise_opt(comma
);
2924 if (!alias
|| !target
)
2925 ret_err(_("bad CNAME"));
2928 for (new = daemon
->cnames
; new; new = new->next
)
2929 if (hostname_isequal(new->alias
, arg
))
2930 ret_err(_("duplicate CNAME"));
2931 new = opt_malloc(sizeof(struct cname
));
2932 new->next
= daemon
->cnames
;
2933 daemon
->cnames
= new;
2935 new->target
= target
;
2941 case LOPT_PTR
: /* --ptr-record */
2943 struct ptr_record
*new;
2944 char *dom
, *target
= NULL
;
2948 if (!(dom
= canonicalise_opt(arg
)) ||
2949 (comma
&& !(target
= canonicalise_opt(comma
))))
2950 ret_err(_("bad PTR record"));
2953 new = opt_malloc(sizeof(struct ptr_record
));
2954 new->next
= daemon
->ptr
;
2962 case LOPT_NAPTR
: /* --naptr-record */
2964 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2968 char *name
, *replace
= NULL
;
2971 for (k
= 1; k
< 7; k
++)
2972 if (!(a
[k
] = split(a
[k
-1])))
2977 !(name
= canonicalise_opt(a
[0])) ||
2978 !atoi_check16(a
[1], &order
) ||
2979 !atoi_check16(a
[2], &pref
) ||
2980 (k
== 7 && !(replace
= canonicalise_opt(a
[6]))))
2981 ret_err(_("bad NAPTR record"));
2984 new = opt_malloc(sizeof(struct naptr
));
2985 new->next
= daemon
->naptr
;
2986 daemon
->naptr
= new;
2988 new->flags
= opt_string_alloc(a
[3]);
2989 new->services
= opt_string_alloc(a
[4]);
2990 new->regexp
= opt_string_alloc(a
[5]);
2991 new->replace
= replace
;
2998 case LOPT_RR
: /* dns-rr */
3000 struct txt_record
*new;
3006 data
= split(comma
);
3008 new = opt_malloc(sizeof(struct txt_record
));
3009 new->next
= daemon
->rr
;
3012 if (!atoi_check(comma
, &val
) ||
3013 !(new->name
= canonicalise_opt(arg
)) ||
3014 (data
&& (len
= parse_hex(data
, (unsigned char *)data
, -1, NULL
, NULL
)) == -1U))
3015 ret_err(_("bad RR record"));
3022 new->txt
=opt_malloc(len
);
3024 memcpy(new->txt
, data
, len
);
3030 case 'Y': /* --txt-record */
3032 struct txt_record
*new;
3033 unsigned char *p
, *cnt
;
3038 new = opt_malloc(sizeof(struct txt_record
));
3039 new->next
= daemon
->txt
;
3043 if (!(new->name
= canonicalise_opt(arg
)))
3044 ret_err(_("bad TXT record"));
3046 len
= comma
? strlen(comma
) : 0;
3047 len
+= (len
/255) + 1; /* room for extra counts */
3048 new->txt
= p
= opt_malloc(len
);
3053 while (comma
&& *comma
)
3055 unsigned char c
= (unsigned char)*comma
++;
3057 if (c
== ',' || *cnt
== 255)
3066 *p
++ = unhide_meta(c
);
3071 new->len
= p
- new->txt
;
3076 case 'W': /* --srv-host */
3078 int port
= 1, priority
= 0, weight
= 0;
3079 char *name
, *target
= NULL
;
3080 struct mx_srv_record
*new;
3084 if (!(name
= canonicalise_opt(arg
)))
3085 ret_err(_("bad SRV record"));
3091 if (!(target
= canonicalise_opt(arg
)))
3092 ret_err(_("bad SRV target"));
3098 if (!atoi_check16(arg
, &port
))
3099 ret_err(_("invalid port number"));
3105 if (!atoi_check16(arg
, &priority
))
3106 ret_err(_("invalid priority"));
3112 if (!atoi_check16(arg
, &weight
))
3113 ret_err(_("invalid weight"));
3119 new = opt_malloc(sizeof(struct mx_srv_record
));
3120 new->next
= daemon
->mxnames
;
3121 daemon
->mxnames
= new;
3124 new->target
= target
;
3125 new->srvport
= port
;
3126 new->priority
= priority
;
3127 new->weight
= weight
;
3131 case LOPT_HOST_REC
: /* --host-record */
3133 struct host_record
*new = opt_malloc(sizeof(struct host_record
));
3134 memset(new, 0, sizeof(struct host_record
));
3136 if (!arg
|| !(comma
= split(arg
)))
3137 ret_err(_("Bad host-record"));
3141 struct all_addr addr
;
3142 if (inet_pton(AF_INET
, arg
, &addr
))
3143 new->addr
= addr
.addr
.addr4
;
3145 else if (inet_pton(AF_INET6
, arg
, &addr
))
3146 new->addr6
= addr
.addr
.addr6
;
3151 char *canon
= canonicalise(arg
, &nomem
);
3152 struct name_list
*nl
= opt_malloc(sizeof(struct name_list
));
3154 ret_err(_("Bad name in host-record"));
3157 /* keep order, so that PTR record goes to first name */
3163 struct name_list
*tmp
;
3164 for (tmp
= new->names
; tmp
->next
; tmp
= tmp
->next
);
3173 /* Keep list order */
3174 if (!daemon
->host_records_tail
)
3175 daemon
->host_records
= new;
3177 daemon
->host_records_tail
->next
= new;
3179 daemon
->host_records_tail
= new;
3184 ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DBus support)"));
3191 static void read_file(char *file
, FILE *f
, int hard_opt
)
3193 volatile int lineno
= 0;
3194 char *buff
= daemon
->namebuff
;
3196 while (fgets(buff
, MAXDNAME
, f
))
3198 int white
, i
, option
= hard_opt
;
3199 char *errmess
, *p
, *arg
= NULL
, *start
;
3202 /* Memory allocation failure longjmps here if mem_recover == 1 */
3205 if (setjmp(mem_jmp
))
3213 /* Implement quotes, inside quotes we allow \\ \" \n and \t
3214 metacharacters get hidden also strip comments */
3215 for (white
= 1, p
= buff
; *p
; p
++)
3219 memmove(p
, p
+1, strlen(p
+1)+1);
3221 for(; *p
&& *p
!= '"'; p
++)
3223 if (*p
== '\\' && strchr("\"tnebr\\", p
[1]))
3227 else if (p
[1] == 'n')
3229 else if (p
[1] == 'b')
3231 else if (p
[1] == 'r')
3233 else if (p
[1] == 'e') /* escape */
3235 memmove(p
, p
+1, strlen(p
+1)+1);
3242 errmess
= _("missing \"");
3246 memmove(p
, p
+1, strlen(p
+1)+1);
3256 if (white
&& *p
== '#')
3266 /* strip leading spaces */
3267 for (start
= buff
; *start
&& *start
== ' '; start
++);
3269 /* strip trailing spaces */
3270 for (len
= strlen(start
); (len
!= 0) && (start
[len
-1] == ' '); len
--);
3279 else if ((p
=strchr(start
, '=')))
3281 /* allow spaces around "=" */
3282 for (arg
= p
+1; *arg
== ' '; arg
++);
3283 for (; p
>= start
&& (*p
== ' ' || *p
== '='); p
--)
3291 for (option
= 0, i
= 0; opts
[i
].name
; i
++)
3292 if (strcmp(opts
[i
].name
, start
) == 0)
3294 option
= opts
[i
].val
;
3299 errmess
= _("bad option");
3300 else if (opts
[i
].has_arg
== 0 && arg
)
3301 errmess
= _("extraneous parameter");
3302 else if (opts
[i
].has_arg
== 1 && !arg
)
3303 errmess
= _("missing parameter");
3308 strcpy(daemon
->namebuff
, errmess
);
3310 if (errmess
|| !one_opt(option
, arg
, buff
, _("error"), 0))
3312 sprintf(daemon
->namebuff
+ strlen(daemon
->namebuff
), _(" at line %d of %s"), lineno
, file
);
3314 my_syslog(LOG_ERR
, "%s", daemon
->namebuff
);
3316 die("%s", daemon
->namebuff
, EC_BADCONF
);
3324 static int one_file(char *file
, int hard_opt
)
3328 static int read_stdin
= 0;
3329 static struct fileread
{
3332 struct fileread
*next
;
3333 } *filesread
= NULL
;
3335 if (hard_opt
== '7')
3337 /* default conf-file reading */
3342 if (hard_opt
== 0 && strcmp(file
, "-") == 0)
3344 if (read_stdin
== 1)
3352 /* ignore repeated files. */
3353 struct stat statbuf
;
3355 if (hard_opt
== 0 && stat(file
, &statbuf
) == 0)
3359 for (r
= filesread
; r
; r
= r
->next
)
3360 if (r
->dev
== statbuf
.st_dev
&& r
->ino
== statbuf
.st_ino
)
3363 r
= safe_malloc(sizeof(struct fileread
));
3364 r
->next
= filesread
;
3366 r
->dev
= statbuf
.st_dev
;
3367 r
->ino
= statbuf
.st_ino
;
3370 if (!(f
= fopen(file
, "r")))
3372 if (errno
== ENOENT
&& nofile_ok
)
3373 return 1; /* No conffile, all done. */
3376 char *str
= _("cannot read %s: %s");
3379 my_syslog(LOG_ERR
, str
, file
, strerror(errno
));
3383 die(str
, file
, EC_FILE
);
3388 read_file(file
, f
, hard_opt
);
3392 /* expand any name which is a directory */
3393 struct hostsfile
*expand_filelist(struct hostsfile
*list
)
3396 struct hostsfile
*ah
;
3398 for (i
= 0, ah
= list
; ah
; ah
= ah
->next
)
3403 if (ah
->flags
& AH_DIR
)
3404 ah
->flags
|= AH_INACTIVE
;
3406 ah
->flags
&= ~AH_INACTIVE
;
3409 for (ah
= list
; ah
; ah
= ah
->next
)
3410 if (!(ah
->flags
& AH_INACTIVE
))
3413 if (stat(ah
->fname
, &buf
) != -1 && S_ISDIR(buf
.st_mode
))
3418 /* don't read this as a file */
3419 ah
->flags
|= AH_INACTIVE
;
3421 if (!(dir_stream
= opendir(ah
->fname
)))
3422 my_syslog(LOG_ERR
, _("cannot access directory %s: %s"),
3423 ah
->fname
, strerror(errno
));
3426 while ((ent
= readdir(dir_stream
)))
3428 size_t lendir
= strlen(ah
->fname
);
3429 size_t lenfile
= strlen(ent
->d_name
);
3430 struct hostsfile
*ah1
;
3433 /* ignore emacs backups and dotfiles */
3435 ent
->d_name
[lenfile
- 1] == '~' ||
3436 (ent
->d_name
[0] == '#' && ent
->d_name
[lenfile
- 1] == '#') ||
3437 ent
->d_name
[0] == '.')
3440 /* see if we have an existing record.
3443 path to match is ah1->fname */
3445 for (ah1
= list
; ah1
; ah1
= ah1
->next
)
3447 if (lendir
< strlen(ah1
->fname
) &&
3448 strstr(ah1
->fname
, ah
->fname
) == ah1
->fname
&&
3449 ah1
->fname
[lendir
] == '/' &&
3450 strcmp(ah1
->fname
+ lendir
+ 1, ent
->d_name
) == 0)
3452 ah1
->flags
&= ~AH_INACTIVE
;
3457 /* make new record */
3460 if (!(ah1
= whine_malloc(sizeof(struct hostsfile
))))
3463 if (!(path
= whine_malloc(lendir
+ lenfile
+ 2)))
3469 strcpy(path
, ah
->fname
);
3471 strcat(path
, ent
->d_name
);
3474 ah1
->flags
= AH_DIR
;
3479 /* inactivate record if not regular file */
3480 if ((ah1
->flags
& AH_DIR
) && stat(ah1
->fname
, &buf
) != -1 && !S_ISREG(buf
.st_mode
))
3481 ah1
->flags
|= AH_INACTIVE
;
3484 closedir(dir_stream
);
3494 void reread_dhcp(void)
3496 struct hostsfile
*hf
;
3498 if (daemon
->dhcp_hosts_file
)
3500 struct dhcp_config
*configs
, *cp
, **up
;
3502 /* remove existing... */
3503 for (up
= &daemon
->dhcp_conf
, configs
= daemon
->dhcp_conf
; configs
; configs
= cp
)
3507 if (configs
->flags
& CONFIG_BANK
)
3509 struct hwaddr_config
*mac
, *tmp
;
3510 struct dhcp_netid_list
*list
, *tmplist
;
3512 for (mac
= configs
->hwaddr
; mac
; mac
= tmp
)
3518 if (configs
->flags
& CONFIG_CLID
)
3519 free(configs
->clid
);
3521 for (list
= configs
->netid
; list
; list
= tmplist
)
3524 tmplist
= list
->next
;
3528 if (configs
->flags
& CONFIG_NAME
)
3529 free(configs
->hostname
);
3531 *up
= configs
->next
;
3535 up
= &configs
->next
;
3538 daemon
->dhcp_hosts_file
= expand_filelist(daemon
->dhcp_hosts_file
);
3539 for (hf
= daemon
->dhcp_hosts_file
; hf
; hf
= hf
->next
)
3540 if (!(hf
->flags
& AH_INACTIVE
))
3542 if (one_file(hf
->fname
, LOPT_BANK
))
3543 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
3547 if (daemon
->dhcp_opts_file
)
3549 struct dhcp_opt
*opts
, *cp
, **up
;
3550 struct dhcp_netid
*id
, *next
;
3552 for (up
= &daemon
->dhcp_opts
, opts
= daemon
->dhcp_opts
; opts
; opts
= cp
)
3556 if (opts
->flags
& DHOPT_BANK
)
3558 if ((opts
->flags
& DHOPT_VENDOR
))
3559 free(opts
->u
.vendor_class
);
3561 for (id
= opts
->netid
; id
; id
= next
)
3574 daemon
->dhcp_opts_file
= expand_filelist(daemon
->dhcp_opts_file
);
3575 for (hf
= daemon
->dhcp_opts_file
; hf
; hf
= hf
->next
)
3576 if (!(hf
->flags
& AH_INACTIVE
))
3578 if (one_file(hf
->fname
, LOPT_OPTS
))
3579 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
3585 void read_opts(int argc
, char **argv
, char *compile_opts
)
3587 char *buff
= opt_malloc(MAXDNAME
);
3588 int option
, conffile_opt
= '7', testmode
= 0;
3589 char *arg
, *conffile
= CONFFILE
;
3593 daemon
= opt_malloc(sizeof(struct daemon
));
3594 memset(daemon
, 0, sizeof(struct daemon
));
3595 daemon
->namebuff
= buff
;
3597 /* Set defaults - everything else is zero or NULL */
3598 daemon
->cachesize
= CACHESIZ
;
3599 daemon
->ftabsize
= FTABSIZ
;
3600 daemon
->port
= NAMESERVER_PORT
;
3601 daemon
->dhcp_client_port
= DHCP_CLIENT_PORT
;
3602 daemon
->dhcp_server_port
= DHCP_SERVER_PORT
;
3603 daemon
->default_resolv
.is_default
= 1;
3604 daemon
->default_resolv
.name
= RESOLVFILE
;
3605 daemon
->resolv_files
= &daemon
->default_resolv
;
3606 daemon
->username
= CHUSER
;
3607 daemon
->runfile
= RUNFILE
;
3608 daemon
->dhcp_max
= MAXLEASES
;
3609 daemon
->tftp_max
= TFTP_MAX_CONNECTIONS
;
3610 daemon
->edns_pktsz
= EDNS_PKTSZ
;
3611 daemon
->log_fac
= -1;
3612 add_txt("version.bind", "dnsmasq-" VERSION
);
3613 add_txt("authors.bind", "Simon Kelley");
3614 add_txt("copyright.bind", COPYRIGHT
);
3618 #ifdef HAVE_GETOPT_LONG
3619 option
= getopt_long(argc
, argv
, OPTSTRING
, opts
, NULL
);
3621 option
= getopt(argc
, argv
, OPTSTRING
);
3626 for (; optind
< argc
; optind
++)
3628 unsigned char *c
= (unsigned char *)argv
[optind
];
3629 for (; *c
!= 0; c
++)
3631 die(_("junk found in command line"), NULL
, EC_BADCONF
);
3636 /* Copy optarg so that argv doesn't get changed */
3639 strncpy(buff
, optarg
, MAXDNAME
);
3640 buff
[MAXDNAME
-1] = 0;
3646 /* command-line only stuff */
3647 if (option
== LOPT_TEST
)
3649 else if (option
== 'w')
3652 if (argc
== 3 && strcmp(argv
[2], "dhcp") == 0)
3655 else if (argc
== 3 && strcmp(argv
[2], "dhcp6") == 0)
3664 else if (option
== 'v')
3666 printf(_("Dnsmasq version %s %s\n"), VERSION
, COPYRIGHT
);
3667 printf(_("Compile time options: %s\n\n"), compile_opts
);
3668 printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
3669 printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
3670 printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
3673 else if (option
== 'C')
3675 conffile_opt
= 0; /* file must exist */
3676 conffile
= opt_string_alloc(arg
);
3680 #ifdef HAVE_GETOPT_LONG
3681 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try --help"), 1))
3683 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try -w"), 1))
3685 die(_("bad command line options: %s"), daemon
->namebuff
, EC_BADCONF
);
3690 one_file(conffile
, conffile_opt
);
3692 /* port might not be known when the address is parsed - fill in here */
3693 if (daemon
->servers
)
3696 for (tmp
= daemon
->servers
; tmp
; tmp
= tmp
->next
)
3697 if (!(tmp
->flags
& SERV_HAS_SOURCE
))
3699 if (tmp
->source_addr
.sa
.sa_family
== AF_INET
)
3700 tmp
->source_addr
.in
.sin_port
= htons(daemon
->query_port
);
3702 else if (tmp
->source_addr
.sa
.sa_family
== AF_INET6
)
3703 tmp
->source_addr
.in6
.sin6_port
= htons(daemon
->query_port
);
3708 if (daemon
->if_addrs
)
3711 for(tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
3712 if (tmp
->addr
.sa
.sa_family
== AF_INET
)
3713 tmp
->addr
.in
.sin_port
= htons(daemon
->port
);
3715 else if (tmp
->addr
.sa
.sa_family
== AF_INET6
)
3716 tmp
->addr
.in6
.sin6_port
= htons(daemon
->port
);
3720 /* only one of these need be specified: the other defaults to the host-name */
3721 if (option_bool(OPT_LOCALMX
) || daemon
->mxnames
|| daemon
->mxtarget
)
3723 struct mx_srv_record
*mx
;
3725 if (gethostname(buff
, MAXDNAME
) == -1)
3726 die(_("cannot get host-name: %s"), NULL
, EC_MISC
);
3728 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
3729 if (!mx
->issrv
&& hostname_isequal(mx
->name
, buff
))
3732 if ((daemon
->mxtarget
|| option_bool(OPT_LOCALMX
)) && !mx
)
3734 mx
= opt_malloc(sizeof(struct mx_srv_record
));
3735 mx
->next
= daemon
->mxnames
;
3738 mx
->name
= opt_string_alloc(buff
);
3739 daemon
->mxnames
= mx
;
3742 if (!daemon
->mxtarget
)
3743 daemon
->mxtarget
= opt_string_alloc(buff
);
3745 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
3746 if (!mx
->issrv
&& !mx
->target
)
3747 mx
->target
= daemon
->mxtarget
;
3750 if (!option_bool(OPT_NO_RESOLV
) &&
3751 daemon
->resolv_files
&&
3752 daemon
->resolv_files
->next
&&
3753 option_bool(OPT_NO_POLL
))
3754 die(_("only one resolv.conf file allowed in no-poll mode."), NULL
, EC_BADCONF
);
3756 if (option_bool(OPT_RESOLV_DOMAIN
))
3761 if (option_bool(OPT_NO_RESOLV
) ||
3762 !daemon
->resolv_files
||
3763 (daemon
->resolv_files
)->next
)
3764 die(_("must have exactly one resolv.conf to read domain from."), NULL
, EC_BADCONF
);
3766 if (!(f
= fopen((daemon
->resolv_files
)->name
, "r")))
3767 die(_("failed to read %s: %s"), (daemon
->resolv_files
)->name
, EC_FILE
);
3769 while ((line
= fgets(buff
, MAXDNAME
, f
)))
3771 char *token
= strtok(line
, " \t\n\r");
3773 if (!token
|| strcmp(token
, "search") != 0)
3776 if ((token
= strtok(NULL
, " \t\n\r")) &&
3777 (daemon
->domain_suffix
= canonicalise_opt(token
)))
3783 if (!daemon
->domain_suffix
)
3784 die(_("no search directive found in %s"), (daemon
->resolv_files
)->name
, EC_MISC
);
3787 if (daemon
->domain_suffix
)
3789 /* add domain for any srv record without one. */
3790 struct mx_srv_record
*srv
;
3792 for (srv
= daemon
->mxnames
; srv
; srv
= srv
->next
)
3794 strchr(srv
->name
, '.') &&
3795 strchr(srv
->name
, '.') == strrchr(srv
->name
, '.'))
3797 strcpy(buff
, srv
->name
);
3799 strcat(buff
, daemon
->domain_suffix
);
3801 srv
->name
= opt_string_alloc(buff
);
3804 else if (option_bool(OPT_DHCP_FQDN
))
3805 die(_("there must be a default domain when --dhcp-fqdn is set"), NULL
, EC_BADCONF
);
3809 fprintf(stderr
, "dnsmasq: %s.\n", _("syntax check OK"));