]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/option.c
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
132 #ifdef HAVE_GETOPT_LONG
133 static const struct option opts
[] =
135 static const struct myoption opts
[] =
138 { "version", 0, 0, 'v' },
139 { "no-hosts", 0, 0, 'h' },
140 { "no-poll", 0, 0, 'n' },
141 { "help", 0, 0, 'w' },
142 { "no-daemon", 0, 0, 'd' },
143 { "log-queries", 0, 0, 'q' },
144 { "user", 2, 0, 'u' },
145 { "group", 2, 0, 'g' },
146 { "resolv-file", 2, 0, 'r' },
147 { "mx-host", 1, 0, 'm' },
148 { "mx-target", 1, 0, 't' },
149 { "cache-size", 2, 0, 'c' },
150 { "port", 1, 0, 'p' },
151 { "dhcp-leasefile", 2, 0, 'l' },
152 { "dhcp-lease", 1, 0, 'l' },
153 { "dhcp-host", 1, 0, 'G' },
154 { "dhcp-range", 1, 0, 'F' },
155 { "dhcp-option", 1, 0, 'O' },
156 { "dhcp-boot", 1, 0, 'M' },
157 { "domain", 1, 0, 's' },
158 { "domain-suffix", 1, 0, 's' },
159 { "interface", 1, 0, 'i' },
160 { "listen-address", 1, 0, 'a' },
161 { "bogus-priv", 0, 0, 'b' },
162 { "bogus-nxdomain", 1, 0, 'B' },
163 { "selfmx", 0, 0, 'e' },
164 { "filterwin2k", 0, 0, 'f' },
165 { "pid-file", 2, 0, 'x' },
166 { "strict-order", 0, 0, 'o' },
167 { "server", 1, 0, 'S' },
168 { "local", 1, 0, LOPT_LOCAL
},
169 { "address", 1, 0, 'A' },
170 { "conf-file", 2, 0, 'C' },
171 { "no-resolv", 0, 0, 'R' },
172 { "expand-hosts", 0, 0, 'E' },
173 { "localmx", 0, 0, 'L' },
174 { "local-ttl", 1, 0, 'T' },
175 { "no-negcache", 0, 0, 'N' },
176 { "addn-hosts", 1, 0, 'H' },
177 { "query-port", 1, 0, 'Q' },
178 { "except-interface", 1, 0, 'I' },
179 { "no-dhcp-interface", 1, 0, '2' },
180 { "domain-needed", 0, 0, 'D' },
181 { "dhcp-lease-max", 1, 0, 'X' },
182 { "bind-interfaces", 0, 0, 'z' },
183 { "read-ethers", 0, 0, 'Z' },
184 { "alias", 1, 0, 'V' },
185 { "dhcp-vendorclass", 1, 0, 'U' },
186 { "dhcp-userclass", 1, 0, 'j' },
187 { "dhcp-ignore", 1, 0, 'J' },
188 { "edns-packet-max", 1, 0, 'P' },
189 { "keep-in-foreground", 0, 0, 'k' },
190 { "dhcp-authoritative", 0, 0, 'K' },
191 { "srv-host", 1, 0, 'W' },
192 { "localise-queries", 0, 0, 'y' },
193 { "txt-record", 1, 0, 'Y' },
194 { "dns-rr", 1, 0, LOPT_RR
},
195 { "enable-dbus", 2, 0, '1' },
196 { "bootp-dynamic", 2, 0, '3' },
197 { "dhcp-mac", 1, 0, '4' },
198 { "no-ping", 0, 0, '5' },
199 { "dhcp-script", 1, 0, '6' },
200 { "conf-dir", 1, 0, '7' },
201 { "log-facility", 1, 0 ,'8' },
202 { "leasefile-ro", 0, 0, '9' },
203 { "dns-forward-max", 1, 0, '0' },
204 { "clear-on-reload", 0, 0, LOPT_RELOAD
},
205 { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES
},
206 { "enable-tftp", 0, 0, LOPT_TFTP
},
207 { "tftp-secure", 0, 0, LOPT_SECURE
},
208 { "tftp-unique-root", 0, 0, LOPT_APREF
},
209 { "tftp-root", 1, 0, LOPT_PREFIX
},
210 { "tftp-max", 1, 0, LOPT_TFTP_MAX
},
211 { "tftp-lowercase", 0, 0, LOPT_TFTP_LC
},
212 { "ptr-record", 1, 0, LOPT_PTR
},
213 { "naptr-record", 1, 0, LOPT_NAPTR
},
214 { "bridge-interface", 1, 0 , LOPT_BRIDGE
},
215 { "dhcp-option-force", 1, 0, LOPT_FORCE
},
216 { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK
},
217 { "log-dhcp", 0, 0, LOPT_LOG_OPTS
},
218 { "log-async", 2, 0, LOPT_MAX_LOGS
},
219 { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT
},
220 { "dhcp-remoteid", 1, 0, LOPT_REMOTE
},
221 { "dhcp-subscrid", 1, 0, LOPT_SUBSCR
},
222 { "interface-name", 1, 0, LOPT_INTNAME
},
223 { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST
},
224 { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS
},
225 { "dhcp-no-override", 0, 0, LOPT_OVERRIDE
},
226 { "tftp-port-range", 1, 0, LOPT_TFTPPORTS
},
227 { "stop-dns-rebind", 0, 0, LOPT_REBIND
},
228 { "rebind-domain-ok", 1, 0, LOPT_NO_REBIND
},
229 { "all-servers", 0, 0, LOPT_NOLAST
},
230 { "dhcp-match", 1, 0, LOPT_MATCH
},
231 { "dhcp-broadcast", 2, 0, LOPT_BROADCAST
},
232 { "neg-ttl", 1, 0, LOPT_NEGTTL
},
233 { "max-ttl", 1, 0, LOPT_MAXTTL
},
234 { "max-cache-ttl", 1, 0, LOPT_MAXCTTL
},
235 { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT
},
236 { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR
},
237 { "min-port", 1, 0, LOPT_MINPORT
},
238 { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN
},
239 { "cname", 1, 0, LOPT_CNAME
},
240 { "pxe-prompt", 1, 0, LOPT_PXE_PROMT
},
241 { "pxe-service", 1, 0, LOPT_PXE_SERV
},
242 { "test", 0, 0, LOPT_TEST
},
243 { "tag-if", 1, 0, LOPT_TAG_IF
},
244 { "dhcp-proxy", 2, 0, LOPT_PROXY
},
245 { "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES
},
246 { "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND
},
247 { "add-mac", 0, 0, LOPT_ADD_MAC
},
248 { "proxy-dnssec", 0, 0, LOPT_DNSSEC
},
249 { "dhcp-sequential-ip", 0, 0, LOPT_INCR_ADDR
},
250 { "conntrack", 0, 0, LOPT_CONNTRACK
},
251 { "dhcp-client-update", 0, 0, LOPT_FQDN
},
252 { "dhcp-luascript", 1, 0, LOPT_LUASCRIPT
},
253 { "enable-ra", 0, 0, LOPT_RA
},
254 { "dhcp-duid", 1, 0, LOPT_DUID
},
255 { "host-record", 1, 0, LOPT_HOST_REC
},
256 { "bind-dynamic", 0, 0, LOPT_CLVERBIND
},
257 { "auth-zone", 1, 0, LOPT_AUTHZONE
},
258 { "auth-server", 1, 0, LOPT_AUTHSERV
},
259 { "auth-ttl", 1, 0, LOPT_AUTHTTL
},
260 { "auth-soa", 1, 0, LOPT_AUTHSOA
},
261 { "auth-sec-servers", 1, 0, LOPT_AUTHSFS
},
262 { "auth-peer", 1, 0, LOPT_AUTHPEER
},
263 { "ipset", 1, 0, LOPT_IPSET
},
268 #define ARG_DUP OPT_LAST
269 #define ARG_ONE OPT_LAST + 1
270 #define ARG_USED_CL OPT_LAST + 2
271 #define ARG_USED_FILE OPT_LAST + 3
276 char * const flagdesc
;
280 { 'a', ARG_DUP
, "<ipaddr>", gettext_noop("Specify local address(es) to listen on."), NULL
},
281 { 'A', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL
},
282 { 'b', OPT_BOGUSPRIV
, NULL
, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL
},
283 { 'B', ARG_DUP
, "<ipaddr>", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL
},
284 { 'c', ARG_ONE
, "<integer>", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
285 { 'C', ARG_DUP
, "<path>", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE
},
286 { 'd', OPT_DEBUG
, NULL
, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL
},
287 { 'D', OPT_NODOTS_LOCAL
, NULL
, gettext_noop("Do NOT forward queries with no domain part."), NULL
},
288 { 'e', OPT_SELFMX
, NULL
, gettext_noop("Return self-pointing MX records for local hosts."), NULL
},
289 { 'E', OPT_EXPAND
, NULL
, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL
},
290 { 'f', OPT_FILTER
, NULL
, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL
},
291 { 'F', ARG_DUP
, "<ipaddr>,...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL
},
292 { 'g', ARG_ONE
, "<groupname>", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP
},
293 { 'G', ARG_DUP
, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL
},
294 { LOPT_DHCP_HOST
, ARG_DUP
, "<path>", gettext_noop("Read DHCP host specs from file."), NULL
},
295 { LOPT_DHCP_OPTS
, ARG_DUP
, "<path>", gettext_noop("Read DHCP option specs from file."), NULL
},
296 { LOPT_TAG_IF
, ARG_DUP
, "tag-expression", gettext_noop("Evaluate conditional tag expression."), NULL
},
297 { 'h', OPT_NO_HOSTS
, NULL
, gettext_noop("Do NOT load %s file."), HOSTSFILE
},
298 { 'H', ARG_DUP
, "<path>", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE
},
299 { 'i', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) to listen on."), NULL
},
300 { 'I', ARG_DUP
, "<interface>", gettext_noop("Specify interface(s) NOT to listen on.") , NULL
},
301 { 'j', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL
},
302 { LOPT_CIRCUIT
, ARG_DUP
, "set:<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL
},
303 { LOPT_REMOTE
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL
},
304 { LOPT_SUBSCR
, ARG_DUP
, "set:<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL
},
305 { 'J', ARG_DUP
, "tag:<tag>...", gettext_noop("Don't do DHCP for hosts with tag set."), NULL
},
306 { LOPT_BROADCAST
, ARG_DUP
, "[=tag:<tag>...]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL
},
307 { 'k', OPT_NO_FORK
, NULL
, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL
},
308 { 'K', OPT_AUTHORITATIVE
, NULL
, gettext_noop("Assume we are the only DHCP server on the local network."), NULL
},
309 { 'l', ARG_ONE
, "<path>", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE
},
310 { 'L', OPT_LOCALMX
, NULL
, gettext_noop("Return MX records for local hosts."), NULL
},
311 { 'm', ARG_DUP
, "<host_name>,<target>,<pref>", gettext_noop("Specify an MX record."), NULL
},
312 { 'M', ARG_DUP
, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL
},
313 { 'n', OPT_NO_POLL
, NULL
, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE
},
314 { 'N', OPT_NO_NEG
, NULL
, gettext_noop("Do NOT cache failed search results."), NULL
},
315 { 'o', OPT_ORDER
, NULL
, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE
},
316 { 'O', ARG_DUP
, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL
},
317 { LOPT_FORCE
, ARG_DUP
, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL
},
318 { 'p', ARG_ONE
, "<integer>", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL
},
319 { 'P', ARG_ONE
, "<integer>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
320 { 'q', OPT_LOG
, NULL
, gettext_noop("Log DNS queries."), NULL
},
321 { 'Q', ARG_ONE
, "<integer>", gettext_noop("Force the originating port for upstream DNS queries."), NULL
},
322 { 'R', OPT_NO_RESOLV
, NULL
, gettext_noop("Do NOT read resolv.conf."), NULL
},
323 { 'r', ARG_DUP
, "<path>", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE
},
324 { 'S', ARG_DUP
, "/<domain>/<ipaddr>", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL
},
325 { LOPT_LOCAL
, ARG_DUP
, "/<domain>/", gettext_noop("Never forward queries to specified domains."), NULL
},
326 { 's', ARG_DUP
, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL
},
327 { 't', ARG_ONE
, "<host_name>", gettext_noop("Specify default target in an MX record."), NULL
},
328 { 'T', ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL
},
329 { LOPT_NEGTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL
},
330 { LOPT_MAXTTL
, ARG_ONE
, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL
},
331 { 'u', ARG_ONE
, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER
},
332 { 'U', ARG_DUP
, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL
},
333 { 'v', 0, NULL
, gettext_noop("Display dnsmasq version and copyright information."), NULL
},
334 { 'V', ARG_DUP
, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL
},
335 { 'W', ARG_DUP
, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL
},
336 { 'w', 0, NULL
, gettext_noop("Display this message. Use --help dhcp for known DHCP options."), NULL
},
337 { 'x', ARG_ONE
, "<path>", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE
},
338 { 'X', ARG_ONE
, "<integer>", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
339 { 'y', OPT_LOCALISE
, NULL
, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL
},
340 { 'Y', ARG_DUP
, "<name>,<txt>[,<txt]", gettext_noop("Specify TXT DNS record."), NULL
},
341 { LOPT_PTR
, ARG_DUP
, "<name>,<target>", gettext_noop("Specify PTR DNS record."), NULL
},
342 { LOPT_INTNAME
, ARG_DUP
, "<name>,<interface>", gettext_noop("Give DNS name to IPv4 address of interface."), NULL
},
343 { 'z', OPT_NOWILD
, NULL
, gettext_noop("Bind only to interfaces in use."), NULL
},
344 { 'Z', OPT_ETHERS
, NULL
, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE
},
345 { '1', ARG_ONE
, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL
},
346 { '2', ARG_DUP
, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL
},
347 { '3', ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL
},
348 { '4', ARG_DUP
, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL
},
349 { LOPT_BRIDGE
, ARG_DUP
, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL
},
350 { '5', OPT_NO_PING
, NULL
, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL
},
351 { '6', ARG_ONE
, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL
},
352 { LOPT_LUASCRIPT
, ARG_DUP
, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL
},
353 { LOPT_SCRIPTUSR
, ARG_ONE
, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL
},
354 { '7', ARG_DUP
, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL
},
355 { '8', ARG_ONE
, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL
},
356 { '9', OPT_LEASE_RO
, NULL
, gettext_noop("Do not use leasefile."), NULL
},
357 { '0', ARG_ONE
, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
358 { LOPT_RELOAD
, OPT_RELOAD
, NULL
, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE
},
359 { LOPT_NO_NAMES
, ARG_DUP
, "[=tag:<tag>]...", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL
},
360 { LOPT_OVERRIDE
, OPT_NO_OVERRIDE
, NULL
, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL
},
361 { LOPT_TFTP
, OPT_TFTP
, NULL
, gettext_noop("Enable integrated read-only TFTP server."), NULL
},
362 { LOPT_PREFIX
, ARG_DUP
, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL
},
363 { LOPT_APREF
, OPT_TFTP_APREF
, NULL
, gettext_noop("Add client IP address to tftp-root."), NULL
},
364 { LOPT_SECURE
, OPT_TFTP_SECURE
, NULL
, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL
},
365 { LOPT_TFTP_MAX
, ARG_ONE
, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
366 { LOPT_NOBLOCK
, OPT_TFTP_NOBLOCK
, NULL
, gettext_noop("Disable the TFTP blocksize extension."), NULL
},
367 { LOPT_TFTP_LC
, OPT_TFTP_LC
, NULL
, gettext_noop("Convert TFTP filenames to lowercase"), NULL
},
368 { LOPT_TFTPPORTS
, ARG_ONE
, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL
},
369 { LOPT_LOG_OPTS
, OPT_LOG_OPTS
, NULL
, gettext_noop("Extra logging for DHCP."), NULL
},
370 { LOPT_MAX_LOGS
, ARG_ONE
, "[=<integer>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL
},
371 { LOPT_REBIND
, OPT_NO_REBIND
, NULL
, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL
},
372 { LOPT_LOC_REBND
, OPT_LOCAL_REBIND
, NULL
, gettext_noop("Allow rebinding of 127.0.0.0/8, for RBL servers."), NULL
},
373 { LOPT_NO_REBIND
, ARG_DUP
, "/<domain>/", gettext_noop("Inhibit DNS-rebind protection on this domain."), NULL
},
374 { LOPT_NOLAST
, OPT_ALL_SERVERS
, NULL
, gettext_noop("Always perform DNS queries to all servers."), NULL
},
375 { LOPT_MATCH
, ARG_DUP
, "set:<tag>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL
},
376 { LOPT_ALTPORT
, ARG_ONE
, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL
},
377 { LOPT_NAPTR
, ARG_DUP
, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL
},
378 { LOPT_MINPORT
, ARG_ONE
, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL
},
379 { LOPT_DHCP_FQDN
, OPT_DHCP_FQDN
, NULL
, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL
},
380 { LOPT_GEN_NAMES
, ARG_DUP
, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL
},
381 { LOPT_PROXY
, ARG_DUP
, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL
},
382 { LOPT_CNAME
, ARG_DUP
, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL
},
383 { LOPT_PXE_PROMT
, ARG_DUP
, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL
},
384 { LOPT_PXE_SERV
, ARG_DUP
, "<service>", gettext_noop("Boot service for PXE menu."), NULL
},
385 { LOPT_TEST
, 0, NULL
, gettext_noop("Check configuration syntax."), NULL
},
386 { LOPT_ADD_MAC
, OPT_ADD_MAC
, NULL
, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL
},
387 { LOPT_DNSSEC
, OPT_DNSSEC
, NULL
, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL
},
388 { LOPT_INCR_ADDR
, OPT_CONSEC_ADDR
, NULL
, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL
},
389 { LOPT_CONNTRACK
, OPT_CONNTRACK
, NULL
, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL
},
390 { LOPT_FQDN
, OPT_FQDN_UPDATE
, NULL
, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL
},
391 { LOPT_RA
, OPT_RA
, NULL
, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL
},
392 { LOPT_DUID
, ARG_ONE
, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL
},
393 { LOPT_HOST_REC
, ARG_DUP
, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL
},
394 { LOPT_RR
, ARG_DUP
, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL
},
395 { LOPT_CLVERBIND
, OPT_CLEVERBIND
, NULL
, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL
},
396 { LOPT_AUTHSERV
, ARG_ONE
, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL
},
397 { LOPT_AUTHZONE
, ARG_DUP
, "<domain>,[<subnet>...]", gettext_noop("Domain to export to global DNS"), NULL
},
398 { LOPT_AUTHTTL
, ARG_ONE
, "<integer>", gettext_noop("Set TTL for authoritative replies"), NULL
},
399 { LOPT_AUTHSOA
, ARG_ONE
, "<serial>[,...]", gettext_noop("Set authoritive zone information"), NULL
},
400 { LOPT_AUTHSFS
, ARG_DUP
, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL
},
401 { LOPT_AUTHPEER
, ARG_DUP
, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL
},
402 { LOPT_IPSET
, ARG_DUP
, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL
},
403 { 0, 0, NULL
, NULL
, NULL
}
406 /* We hide metacharaters in quoted strings by mapping them into the ASCII control
407 character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the
408 following sequence so that they map to themselves: it is therefore possible to call
409 unhide_metas repeatedly on string without breaking things.
410 The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a
411 couple of other places.
412 Note that space is included here so that
413 --dhcp-option=3, string
414 has five characters, whilst
415 --dhcp-option=3," string"
419 static const char meta
[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
421 static char hide_meta(char c
)
425 for (i
= 0; i
< (sizeof(meta
) - 1); i
++)
432 static char unhide_meta(char cr
)
436 if (c
< (sizeof(meta
) - 1))
442 static void unhide_metas(char *cp
)
446 *cp
= unhide_meta(*cp
);
449 static void *opt_malloc(size_t size
)
455 ret
= whine_malloc(size
);
460 ret
= safe_malloc(size
);
465 static char *opt_string_alloc(char *cp
)
469 if (cp
&& strlen(cp
) != 0)
471 ret
= opt_malloc(strlen(cp
)+1);
474 /* restore hidden metachars */
482 /* find next comma, split string with zero and eliminate spaces.
483 return start of string following comma */
485 static char *split_chr(char *s
, char c
)
489 if (!s
|| !(comma
= strchr(s
, c
)))
495 for (; *comma
== ' '; comma
++);
497 for (; (p
>= s
) && *p
== ' '; p
--)
503 static char *split(char *s
)
505 return split_chr(s
, ',');
508 static char *canonicalise_opt(char *s
)
517 if (!(ret
= canonicalise(s
, &nomem
)) && nomem
)
522 die(_("could not get memory"), NULL
, EC_NOMEM
);
528 static int atoi_check(char *a
, int *res
)
538 if (*p
< '0' || *p
> '9')
545 static int atoi_check16(char *a
, int *res
)
547 if (!(atoi_check(a
, res
)) ||
555 static void add_txt(char *name
, char *txt
)
557 size_t len
= strlen(txt
);
558 struct txt_record
*r
= opt_malloc(sizeof(struct txt_record
));
560 r
->name
= opt_string_alloc(name
);
561 r
->next
= daemon
->txt
;
564 r
->txt
= opt_malloc(len
+1);
567 memcpy((r
->txt
)+1, txt
, len
);
570 static void do_usage(void)
583 { '#', TFTP_MAX_CONNECTIONS
},
587 printf(_("Usage: dnsmasq [options]\n\n"));
588 #ifndef HAVE_GETOPT_LONG
589 printf(_("Use short options only on the command line.\n"));
591 printf(_("Valid options are:\n"));
593 for (i
= 0; usage
[i
].opt
!= 0; i
++)
595 char *desc
= usage
[i
].flagdesc
;
598 if (!desc
|| *desc
== '[')
604 for ( j
= 0; opts
[j
].name
; j
++)
605 if (opts
[j
].val
== usage
[i
].opt
)
607 if (usage
[i
].opt
< 256)
608 sprintf(buff
, "-%c, ", usage
[i
].opt
);
612 sprintf(buff
+4, "--%s%s%s", opts
[j
].name
, eq
, desc
);
613 printf("%-40.40s", buff
);
617 strcpy(buff
, usage
[i
].arg
);
618 for (j
= 0; tab
[j
].handle
; j
++)
619 if (tab
[j
].handle
== *(usage
[i
].arg
))
620 sprintf(buff
, "%d", tab
[j
].val
);
622 printf(_(usage
[i
].desc
), buff
);
627 #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
629 char *parse_server(char *arg
, union mysockaddr
*addr
, union mysockaddr
*source_addr
, char *interface
, int *flags
)
631 int source_port
= 0, serv_port
= NAMESERVER_PORT
;
632 char *portno
, *source
;
638 if ((source
= split_chr(arg
, '@')) && /* is there a source. */
639 (portno
= split_chr(source
, '#')) &&
640 !atoi_check16(portno
, &source_port
))
641 return _("bad port");
643 if ((portno
= split_chr(arg
, '#')) && /* is there a port no. */
644 !atoi_check16(portno
, &serv_port
))
645 return _("bad port");
648 scope_id
= split_chr(arg
, '%');
651 if ((addr
->in
.sin_addr
.s_addr
= inet_addr(arg
)) != (in_addr_t
) -1)
653 addr
->in
.sin_port
= htons(serv_port
);
654 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET
;
655 #ifdef HAVE_SOCKADDR_SA_LEN
656 source_addr
->in
.sin_len
= addr
->in
.sin_len
= sizeof(struct sockaddr_in
);
658 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
659 source_addr
->in
.sin_port
= htons(daemon
->query_port
);
664 *flags
|= SERV_HAS_SOURCE
;
665 source_addr
->in
.sin_port
= htons(source_port
);
666 if ((source_addr
->in
.sin_addr
.s_addr
= inet_addr(source
)) == (in_addr_t
) -1)
668 #if defined(SO_BINDTODEVICE)
669 source_addr
->in
.sin_addr
.s_addr
= INADDR_ANY
;
670 strncpy(interface
, source
, IF_NAMESIZE
- 1);
672 return _("interface binding not supported");
678 else if (inet_pton(AF_INET6
, arg
, &addr
->in6
.sin6_addr
) > 0)
680 if (scope_id
&& (scope_index
= if_nametoindex(scope_id
)) == 0)
681 return _("bad interface name");
683 addr
->in6
.sin6_port
= htons(serv_port
);
684 addr
->in6
.sin6_scope_id
= scope_index
;
685 source_addr
->in6
.sin6_addr
= in6addr_any
;
686 source_addr
->in6
.sin6_port
= htons(daemon
->query_port
);
687 source_addr
->in6
.sin6_scope_id
= 0;
688 addr
->sa
.sa_family
= source_addr
->sa
.sa_family
= AF_INET6
;
689 addr
->in6
.sin6_flowinfo
= source_addr
->in6
.sin6_flowinfo
= 0;
690 #ifdef HAVE_SOCKADDR_SA_LEN
691 addr
->in6
.sin6_len
= source_addr
->in6
.sin6_len
= sizeof(addr
->in6
);
696 *flags
|= SERV_HAS_SOURCE
;
697 source_addr
->in6
.sin6_port
= htons(source_port
);
698 if (inet_pton(AF_INET6
, source
, &source_addr
->in6
.sin6_addr
) == 0)
700 #if defined(SO_BINDTODEVICE)
701 source_addr
->in6
.sin6_addr
= in6addr_any
;
702 strncpy(interface
, source
, IF_NAMESIZE
- 1);
704 return _("interface binding not supported");
711 return _("bad address");
718 static int is_tag_prefix(char *arg
)
720 if (arg
&& (strstr(arg
, "net:") == arg
|| strstr(arg
, "tag:") == arg
))
726 static char *set_prefix(char *arg
)
728 if (strstr(arg
, "set:") == arg
)
734 /* This is too insanely large to keep in-line in the switch */
735 static int parse_dhcp_opt(char *errstr
, char *arg
, int flags
)
737 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
738 char lenchar
= 0, *cp
;
739 int addrs
, digs
, is_addr
, is_addr6
, is_hex
, is_dec
, is_string
, dots
;
741 struct dhcp_netid
*np
= NULL
;
755 for (cp
= arg
; *cp
; cp
++)
756 if (*cp
< '0' || *cp
> '9')
761 new->opt
= atoi(arg
);
766 if (strstr(arg
, "option:") == arg
)
768 new->opt
= lookup_dhcp_opt(AF_INET
, arg
+7);
769 opt_len
= lookup_dhcp_len(AF_INET
, new->opt
);
770 /* option:<optname> must follow tag and vendor string. */
774 else if (strstr(arg
, "option6:") == arg
)
776 for (cp
= arg
+8; *cp
; cp
++)
777 if (*cp
< '0' || *cp
> '9')
782 new->opt
= atoi(arg
+8);
787 new->opt
= lookup_dhcp_opt(AF_INET6
, arg
+8);
788 opt_len
= lookup_dhcp_len(AF_INET6
, new->opt
);
790 /* option6:<opt>|<optname> must follow tag and vendor string. */
795 else if (strstr(arg
, "vendor:") == arg
)
797 new->u
.vendor_class
= (unsigned char *)opt_string_alloc(arg
+7);
798 new->flags
|= DHOPT_VENDOR
;
800 else if (strstr(arg
, "encap:") == arg
)
802 new->u
.encap
= atoi(arg
+6);
803 new->flags
|= DHOPT_ENCAPSULATE
;
805 else if (strstr(arg
, "vi-encap:") == arg
)
807 new->u
.encap
= atoi(arg
+9);
808 new->flags
|= DHOPT_RFC3925
;
809 if (flags
== DHOPT_MATCH
)
811 new->opt
= 1; /* avoid error below */
817 new->netid
= opt_malloc(sizeof (struct dhcp_netid
));
818 /* allow optional "net:" or "tag:" for consistency */
819 if (is_tag_prefix(arg
))
820 new->netid
->net
= opt_string_alloc(arg
+4);
822 new->netid
->net
= opt_string_alloc(set_prefix(arg
));
823 new->netid
->next
= np
;
833 if (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))
834 ret_err(_("unsupported encapsulation for IPv6 option"));
837 !(new->flags
& DHOPT_RFC3925
))
838 opt_len
= lookup_dhcp_len(AF_INET6
,new->opt
);
843 !(new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
| DHOPT_RFC3925
)))
844 opt_len
= lookup_dhcp_len(AF_INET
,new->opt
);
846 /* option may be missing with rfc3925 match */
848 ret_err(_("bad dhcp-option"));
852 /* characterise the value */
855 is_addr
= is_addr6
= is_hex
= is_dec
= is_string
= 1;
858 for (cp
= comma
; (c
= *cp
); cp
++)
867 is_dec
= is_addr
= 0;
871 is_addr6
= is_dec
= is_hex
= 0;
872 if (cp
== comma
) /* leading / means a pathname */
877 is_addr6
= is_dec
= is_hex
= 0;
881 is_hex
= is_addr
= is_addr6
= 0;
884 else if (!(c
>='0' && c
<= '9'))
887 if (cp
[1] == 0 && is_dec
&&
888 (c
== 'b' || c
== 's' || c
== 'i'))
895 if (!((c
>='A' && c
<= 'F') ||
896 (c
>='a' && c
<= 'f') ||
897 (c
== '*' && (flags
& DHOPT_MATCH
))))
900 if (c
!= '[' && c
!= ']')
908 is_dec
= is_addr
= 0;
910 /* We know that some options take addresses */
911 if (opt_len
& OT_ADDR_LIST
)
913 is_string
= is_dec
= is_hex
= 0;
915 if (!is6
&& (!is_addr
|| dots
== 0))
916 ret_err(_("bad IP address"));
918 if (is6
&& !is_addr6
)
919 ret_err(_("bad IPv6 address"));
922 else if (opt_len
& (OT_NAME
| OT_RFC1035_NAME
| OT_CSTRING
))
923 is_addr6
= is_addr
= is_dec
= is_hex
= 0;
925 if (found_dig
&& (opt_len
& OT_TIME
) && strlen(comma
) > 0)
929 switch (comma
[strlen(comma
) - 1])
949 comma
[strlen(comma
) - 1] = 0;
953 new->val
= opt_malloc(4);
955 *((int *)new->val
) = htonl(val
* fac
);
957 else if (is_hex
&& digs
> 1)
960 new->val
= opt_malloc(new->len
);
961 parse_hex(comma
, new->val
, digs
, (flags
& DHOPT_MATCH
) ? &new->u
.wildcard_mask
: NULL
, NULL
);
962 new->flags
|= DHOPT_HEX
;
966 int i
, val
= atoi(comma
);
967 /* assume numeric arg is 1 byte except for
968 options where it is known otherwise.
969 For vendor class option, we have to hack. */
972 else if (val
& 0xffff0000)
974 else if (val
& 0xff00)
981 else if (lenchar
== 's')
983 else if (lenchar
== 'i')
986 new->val
= opt_malloc(new->len
);
987 for (i
=0; i
<new->len
; i
++)
988 new->val
[i
] = val
>>((new->len
- i
- 1)*8);
990 else if (is_addr
&& !is6
)
995 /* max length of address/subnet descriptor is five bytes,
996 add one for the option 120 enc byte too */
997 new->val
= op
= opt_malloc((5 * addrs
) + 1);
998 new->flags
|= DHOPT_ADDR
;
1000 if (!(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)) &&
1001 new->opt
== OPTION_SIP_SERVER
)
1003 *(op
++) = 1; /* RFC 3361 "enc byte" */
1004 new->flags
&= ~DHOPT_ADDR
;
1010 slash
= split_chr(cp
, '/');
1011 in
.s_addr
= inet_addr(cp
);
1014 memcpy(op
, &in
, INADDRSZ
);
1019 unsigned char *p
= (unsigned char *)&in
;
1020 int netsize
= atoi(slash
);
1030 new->flags
&= ~DHOPT_ADDR
; /* cannot re-write descriptor format */
1033 new->len
= op
- new->val
;
1035 else if (is_addr6
&& is6
)
1038 new->val
= op
= opt_malloc(16 * addrs
);
1039 new->flags
|= DHOPT_ADDR6
;
1045 /* check for [1234::7] */
1048 if (strlen(cp
) > 1 && cp
[strlen(cp
)-1] == ']')
1049 cp
[strlen(cp
)-1] = 0;
1051 if (inet_pton(AF_INET6
, cp
, op
))
1057 ret_err(_("bad IPv6 address"));
1059 new->len
= op
- new->val
;
1064 if ((new->opt
== OPTION_DOMAIN_SEARCH
|| new->opt
== OPTION_SIP_SERVER
) &&
1065 !is6
&& !(new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
| DHOPT_RFC3925
)))
1067 /* dns search, RFC 3397, or SIP, RFC 3361 */
1068 unsigned char *q
, *r
, *tail
;
1069 unsigned char *p
, *m
= NULL
, *newp
;
1070 size_t newlen
, len
= 0;
1071 int header_size
= (new->opt
== OPTION_DOMAIN_SEARCH
) ? 0 : 1;
1078 char *in
, *dom
= NULL
;
1080 /* Allow "." as an empty domain */
1081 if (strcmp (arg
, ".") != 0)
1083 if (!(dom
= canonicalise_opt(arg
)))
1084 ret_err(_("bad domain in dhcp-option"));
1086 domlen
= strlen(dom
) + 2;
1089 newp
= opt_malloc(len
+ domlen
+ header_size
);
1092 memcpy(newp
, m
, header_size
+ len
);
1096 p
= m
+ header_size
;
1099 /* add string on the end in RFC1035 format */
1100 for (in
= dom
; in
&& *in
;)
1102 unsigned char *cp
= q
++;
1104 for (j
= 0; *in
&& (*in
!= '.'); in
++, j
++)
1113 /* Now tail-compress using earlier names. */
1115 for (tail
= p
+ len
; *tail
; tail
+= (*tail
) + 1)
1116 for (r
= p
; r
- p
< (int)len
; r
+= (*r
) + 1)
1117 if (strcmp((char *)r
, (char *)tail
) == 0)
1119 PUTSHORT((r
- p
) | 0xc000, tail
);
1130 /* RFC 3361, enc byte is zero for names */
1131 if (new->opt
== OPTION_SIP_SERVER
)
1133 new->len
= (int) len
+ header_size
;
1137 else if (comma
&& (opt_len
& OT_CSTRING
))
1139 /* length fields are two bytes so need 16 bits for each string */
1141 unsigned char *p
, *newp
;
1143 for (i
= 0; comma
[i
]; i
++)
1144 if (comma
[i
] == ',')
1147 newp
= opt_malloc(strlen(comma
)+(2*commas
));
1154 u16 len
= strlen(arg
);
1157 memcpy(p
, arg
, len
);
1165 new->len
= p
- newp
;
1167 else if (comma
&& (opt_len
& OT_RFC1035_NAME
))
1169 unsigned char *p
= NULL
, *newp
, *end
;
1176 char *dom
= canonicalise_opt(arg
);
1178 ret_err(_("bad domain in dhcp-option"));
1180 newp
= opt_malloc(len
+ strlen(dom
) + 2);
1184 memcpy(newp
, p
, len
);
1189 end
= do_rfc1035_name(p
+ len
, dom
);
1204 new->len
= strlen(comma
);
1205 /* keep terminating zero on string */
1206 new->val
= (unsigned char *)opt_string_alloc(comma
);
1207 new->flags
|= DHOPT_STRING
;
1213 ((new->len
> 255) ||
1214 (new->len
> 253 && (new->flags
& (DHOPT_VENDOR
| DHOPT_ENCAPSULATE
))) ||
1215 (new->len
> 250 && (new->flags
& DHOPT_RFC3925
))))
1216 ret_err(_("dhcp-option too long"));
1218 if (flags
== DHOPT_MATCH
)
1220 if ((new->flags
& (DHOPT_ENCAPSULATE
| DHOPT_VENDOR
)) ||
1223 ret_err(_("illegal dhcp-match"));
1227 new->next
= daemon
->dhcp_match6
;
1228 daemon
->dhcp_match6
= new;
1232 new->next
= daemon
->dhcp_match
;
1233 daemon
->dhcp_match
= new;
1238 new->next
= daemon
->dhcp_opts6
;
1239 daemon
->dhcp_opts6
= new;
1243 new->next
= daemon
->dhcp_opts
;
1244 daemon
->dhcp_opts
= new;
1252 void set_option_bool(unsigned int opt
)
1255 daemon
->options
|= 1u << opt
;
1257 daemon
->options2
|= 1u << (opt
- 32);
1260 void reset_option_bool(unsigned int opt
)
1263 daemon
->options
&= ~(1u << opt
);
1265 daemon
->options2
&= ~(1u << (opt
- 32));
1268 static int one_opt(int option
, char *arg
, char *errstr
, char *gen_err
, int command_line
)
1276 for (i
=0; usage
[i
].opt
!= 0; i
++)
1277 if (usage
[i
].opt
== option
)
1279 int rept
= usage
[i
].rept
;
1284 if (rept
== ARG_USED_CL
)
1285 ret_err(_("illegal repeated flag"));
1286 if (rept
== ARG_ONE
)
1287 usage
[i
].rept
= ARG_USED_CL
;
1291 /* allow file to override command line */
1292 if (rept
== ARG_USED_FILE
)
1293 ret_err(_("illegal repeated keyword"));
1294 if (rept
== ARG_USED_CL
|| rept
== ARG_ONE
)
1295 usage
[i
].rept
= ARG_USED_FILE
;
1298 if (rept
!= ARG_DUP
&& rept
!= ARG_ONE
&& rept
!= ARG_USED_CL
)
1300 set_option_bool(rept
);
1309 case 'C': /* --conf-file */
1311 char *file
= opt_string_alloc(arg
);
1320 case '7': /* --conf-dir */
1324 char *directory
, *path
;
1328 } *ignore_suffix
= NULL
, *li
;
1331 if (!(directory
= opt_string_alloc(arg
)))
1334 for (arg
= comma
; arg
; arg
= comma
)
1337 li
= opt_malloc(sizeof(struct list
));
1338 li
->next
= ignore_suffix
;
1340 /* Have to copy: buffer is overwritten */
1341 li
->suffix
= opt_string_alloc(arg
);
1344 if (!(dir_stream
= opendir(directory
)))
1345 die(_("cannot access directory %s: %s"), directory
, EC_FILE
);
1347 while ((ent
= readdir(dir_stream
)))
1349 size_t len
= strlen(ent
->d_name
);
1352 /* ignore emacs backups and dotfiles */
1354 ent
->d_name
[len
- 1] == '~' ||
1355 (ent
->d_name
[0] == '#' && ent
->d_name
[len
- 1] == '#') ||
1356 ent
->d_name
[0] == '.')
1359 for (li
= ignore_suffix
; li
; li
= li
->next
)
1361 /* check for proscribed suffices */
1362 size_t ls
= strlen(li
->suffix
);
1364 strcmp(li
->suffix
, &ent
->d_name
[len
- ls
]) == 0)
1370 path
= opt_malloc(strlen(directory
) + len
+ 2);
1371 strcpy(path
, directory
);
1373 strcat(path
, ent
->d_name
);
1375 /* files must be readable */
1376 if (stat(path
, &buf
) == -1)
1377 die(_("cannot access %s: %s"), path
, EC_FILE
);
1379 /* only reg files allowed. */
1380 if (S_ISREG(buf
.st_mode
))
1386 closedir(dir_stream
);
1388 for(; ignore_suffix
; ignore_suffix
= li
)
1390 li
= ignore_suffix
->next
;
1391 free(ignore_suffix
->suffix
);
1392 free(ignore_suffix
);
1398 case '1': /* --enable-dbus */
1399 set_option_bool(OPT_DBUS
);
1401 daemon
->dbus_name
= opt_string_alloc(arg
);
1403 daemon
->dbus_name
= DNSMASQ_SERVICE
;
1406 case '8': /* --log-facility */
1407 /* may be a filename */
1408 if (strchr(arg
, '/') || strcmp (arg
, "-") == 0)
1409 daemon
->log_file
= opt_string_alloc(arg
);
1413 ret_err(_("setting log facility is not possible under Android"));
1415 for (i
= 0; facilitynames
[i
].c_name
; i
++)
1416 if (hostname_isequal((char *)facilitynames
[i
].c_name
, arg
))
1419 if (facilitynames
[i
].c_name
)
1420 daemon
->log_fac
= facilitynames
[i
].c_val
;
1422 ret_err(_("bad log facility"));
1427 case 'x': /* --pid-file */
1428 daemon
->runfile
= opt_string_alloc(arg
);
1431 case 'r': /* --resolv-file */
1433 char *name
= opt_string_alloc(arg
);
1434 struct resolvc
*new, *list
= daemon
->resolv_files
;
1436 if (list
&& list
->is_default
)
1438 /* replace default resolv file - possibly with nothing */
1441 list
->is_default
= 0;
1449 new = opt_malloc(sizeof(struct resolvc
));
1452 new->is_default
= 0;
1457 daemon
->resolv_files
= list
;
1461 case 'm': /* --mx-host */
1464 struct mx_srv_record
*new;
1465 char *name
, *target
= NULL
;
1467 if ((comma
= split(arg
)))
1470 if ((prefstr
= split(comma
)) && !atoi_check16(prefstr
, &pref
))
1471 ret_err(_("bad MX preference"));
1474 if (!(name
= canonicalise_opt(arg
)) ||
1475 (comma
&& !(target
= canonicalise_opt(comma
))))
1476 ret_err(_("bad MX name"));
1478 new = opt_malloc(sizeof(struct mx_srv_record
));
1479 new->next
= daemon
->mxnames
;
1480 daemon
->mxnames
= new;
1483 new->target
= target
; /* may be NULL */
1488 case 't': /* --mx-target */
1489 if (!(daemon
->mxtarget
= canonicalise_opt(arg
)))
1490 ret_err(_("bad MX target"));
1494 case 'l': /* --dhcp-leasefile */
1495 daemon
->lease_file
= opt_string_alloc(arg
);
1498 /* Sorry about the gross pre-processor abuse */
1499 case '6': /* --dhcp-script */
1500 case LOPT_LUASCRIPT
: /* --dhcp-luascript */
1501 # if defined(NO_FORK)
1502 ret_err(_("cannot run scripts under uClinux"));
1503 # elif !defined(HAVE_SCRIPT)
1504 ret_err(_("recompile with HAVE_SCRIPT defined to enable lease-change scripts"));
1506 if (option
== LOPT_LUASCRIPT
)
1507 # if !defined(HAVE_LUASCRIPT)
1508 ret_err(_("recompile with HAVE_LUASCRIPT defined to enable Lua scripts"));
1510 daemon
->luascript
= opt_string_alloc(arg
);
1513 daemon
->lease_change_command
= opt_string_alloc(arg
);
1516 #endif /* HAVE_DHCP */
1518 case LOPT_DHCP_HOST
: /* --dhcp-hostfile */
1519 case LOPT_DHCP_OPTS
: /* --dhcp-optsfile */
1520 case 'H': /* --addn-hosts */
1522 struct hostsfile
*new = opt_malloc(sizeof(struct hostsfile
));
1523 static int hosts_index
= 1;
1524 new->fname
= opt_string_alloc(arg
);
1525 new->index
= hosts_index
++;
1529 new->next
= daemon
->addn_hosts
;
1530 daemon
->addn_hosts
= new;
1532 else if (option
== LOPT_DHCP_HOST
)
1534 new->next
= daemon
->dhcp_hosts_file
;
1535 daemon
->dhcp_hosts_file
= new;
1537 else if (option
== LOPT_DHCP_OPTS
)
1539 new->next
= daemon
->dhcp_opts_file
;
1540 daemon
->dhcp_opts_file
= new;
1545 case LOPT_AUTHSERV
: /* --auth-server */
1546 if (!(comma
= split(arg
)))
1549 daemon
->authserver
= opt_string_alloc(arg
);
1552 struct iname
*new = opt_malloc(sizeof(struct iname
));
1556 if ((new->addr
.in
.sin_addr
.s_addr
= inet_addr(arg
)) != (in_addr_t
)-1)
1557 new->addr
.sa
.sa_family
= AF_INET
;
1559 else if (inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
1560 new->addr
.sa
.sa_family
= AF_INET6
;
1563 new->name
= opt_string_alloc(arg
);
1565 new->next
= daemon
->authinterface
;
1566 daemon
->authinterface
= new;
1573 case LOPT_AUTHSFS
: /* --auth-sec-servers */
1575 struct name_list
*new;
1579 new = opt_malloc(sizeof(struct name_list
));
1580 new->name
= opt_string_alloc(arg
);
1581 new->next
= daemon
->secondary_forward_server
;
1582 daemon
->secondary_forward_server
= new;
1588 case LOPT_AUTHZONE
: /* --auth-zone */
1590 struct auth_zone
*new;
1594 new = opt_malloc(sizeof(struct auth_zone
));
1595 new->domain
= opt_string_alloc(arg
);
1597 new->next
= daemon
->auth_zones
;
1598 daemon
->auth_zones
= new;
1600 while ((arg
= comma
))
1604 struct subnet
*subnet
= opt_malloc(sizeof(struct subnet
));
1606 subnet
->next
= new->subnet
;
1607 new->subnet
= subnet
;
1610 prefix
= split_chr(arg
, '/');
1612 if (prefix
&& !atoi_check(prefix
, &prefixlen
))
1615 if (inet_pton(AF_INET
, arg
, &subnet
->addr4
))
1617 if ((prefixlen
& 0x07) != 0 || prefixlen
> 24)
1618 ret_err(_("bad prefix"));
1619 subnet
->prefixlen
= (prefixlen
== 0) ? 24 : prefixlen
;
1623 else if (inet_pton(AF_INET6
, arg
, &subnet
->addr6
))
1625 subnet
->prefixlen
= (prefixlen
== 0) ? 64 : prefixlen
;
1635 case LOPT_AUTHSOA
: /* --auth-soa */
1637 atoi_check(arg
, (int *)&daemon
->soa_sn
);
1643 daemon
->hostmaster
= opt_string_alloc(arg
);
1644 for (cp
= daemon
->hostmaster
; *cp
; cp
++)
1652 atoi_check(arg
, (int *)&daemon
->soa_refresh
);
1657 atoi_check(arg
, (int *)&daemon
->soa_retry
);
1662 atoi_check(arg
, (int *)&daemon
->soa_expiry
);
1670 case 's': /* --domain */
1671 if (strcmp (arg
, "#") == 0)
1672 set_option_bool(OPT_RESOLV_DOMAIN
);
1677 if (!(d
= canonicalise_opt(arg
)))
1683 struct cond_domain
*new = opt_malloc(sizeof(struct cond_domain
));
1686 unhide_metas(comma
);
1687 if ((netpart
= split_chr(comma
, '/')))
1691 arg
= split(netpart
);
1692 if (!atoi_check(netpart
, &msize
))
1694 else if (inet_pton(AF_INET
, comma
, &new->start
))
1696 int mask
= (1 << (32 - msize
)) - 1;
1698 new->start
.s_addr
= ntohl(htonl(new->start
.s_addr
) & ~mask
);
1699 new->end
.s_addr
= new->start
.s_addr
| htonl(mask
);
1702 /* generate the equivalent of
1704 local=/xxx.yyy.zzz.in-addr.arpa/ */
1706 if (strcmp(arg
, "local") != 0 ||
1707 (msize
!= 8 && msize
!= 16 && msize
!= 24))
1711 struct server
*serv
= opt_malloc(sizeof(struct server
));
1712 in_addr_t a
= ntohl(new->start
.s_addr
) >> 8;
1715 memset(serv
, 0, sizeof(struct server
));
1717 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1718 serv
->next
= daemon
->servers
;
1719 daemon
->servers
= serv
;
1721 serv
= opt_malloc(sizeof(struct server
));
1722 memset(serv
, 0, sizeof(struct server
));
1723 p
= serv
->domain
= opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */
1726 p
+= sprintf(p
, "%d.", a
& 0xff);
1729 p
+= sprintf(p
, "%d.", a
& 0xff);
1731 p
+= sprintf(p
, "%d.in-addr.arpa", a
& 0xff);
1733 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1734 serv
->next
= daemon
->servers
;
1735 daemon
->servers
= serv
;
1740 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1742 u64 mask
= (1LLU << (128 - msize
)) - 1LLU;
1743 u64 addrpart
= addr6part(&new->start6
);
1746 /* prefix==64 overflows the mask calculation above */
1750 new->end6
= new->start6
;
1751 setaddr6part(&new->start6
, addrpart
& ~mask
);
1752 setaddr6part(&new->end6
, addrpart
| mask
);
1758 /* generate the equivalent of
1760 local=/xxx.yyy.zzz.ip6.arpa/ */
1762 if (strcmp(arg
, "local") != 0 || ((msize
& 4) != 0))
1766 struct server
*serv
= opt_malloc(sizeof(struct server
));
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(73); /* strlen("32*<n.>ip6.arpa")+1 */
1779 for (i
= msize
-1; i
>= 0; i
-= 4)
1781 int dig
= ((unsigned char *)&new->start6
)[i
>>3];
1782 p
+= sprintf(p
, "%.1x.", (i
>>2) & 1 ? dig
& 15 : dig
>> 4);
1784 p
+= sprintf(p
, "ip6.arpa");
1786 serv
->flags
= SERV_HAS_DOMAIN
| SERV_NO_ADDR
;
1787 serv
->next
= daemon
->servers
;
1788 daemon
->servers
= serv
;
1799 if (inet_pton(AF_INET
, comma
, &new->start
))
1803 new->end
.s_addr
= new->start
.s_addr
;
1804 else if (!inet_pton(AF_INET
, arg
, &new->end
))
1808 else if (inet_pton(AF_INET6
, comma
, &new->start6
))
1812 memcpy(&new->end6
, &new->start6
, IN6ADDRSZ
);
1813 else if (!inet_pton(AF_INET6
, arg
, &new->end6
))
1822 new->next
= daemon
->cond_domain
;
1823 daemon
->cond_domain
= new;
1826 daemon
->domain_suffix
= d
;
1831 case 'u': /* --user */
1832 daemon
->username
= opt_string_alloc(arg
);
1835 case 'g': /* --group */
1836 daemon
->groupname
= opt_string_alloc(arg
);
1837 daemon
->group_set
= 1;
1841 case LOPT_SCRIPTUSR
: /* --scriptuser */
1842 daemon
->scriptuser
= opt_string_alloc(arg
);
1846 case 'i': /* --interface */
1848 struct iname
*new = opt_malloc(sizeof(struct iname
));
1850 new->next
= daemon
->if_names
;
1851 daemon
->if_names
= new;
1852 /* new->name may be NULL if someone does
1853 "interface=" to disable all interfaces except loop. */
1854 new->name
= opt_string_alloc(arg
);
1860 case 'I': /* --except-interface */
1861 case '2': /* --no-dhcp-interface */
1863 struct iname
*new = opt_malloc(sizeof(struct iname
));
1865 new->name
= opt_string_alloc(arg
);
1868 new->next
= daemon
->if_except
;
1869 daemon
->if_except
= new;
1873 new->next
= daemon
->dhcp_except
;
1874 daemon
->dhcp_except
= new;
1880 case 'B': /* --bogus-nxdomain */
1882 struct in_addr addr
;
1884 if (arg
&& (addr
.s_addr
= inet_addr(arg
)) != (in_addr_t
)-1)
1886 struct bogus_addr
*baddr
= opt_malloc(sizeof(struct bogus_addr
));
1887 baddr
->next
= daemon
->bogus_addr
;
1888 daemon
->bogus_addr
= baddr
;
1892 ret_err(gen_err
); /* error */
1896 case 'a': /* --listen-address */
1897 case LOPT_AUTHPEER
: /* --auth-peer */
1899 struct iname
*new = opt_malloc(sizeof(struct iname
));
1902 if (arg
&& (new->addr
.in
.sin_addr
.s_addr
= inet_addr(arg
)) != (in_addr_t
)-1)
1904 new->addr
.sa
.sa_family
= AF_INET
;
1905 new->addr
.in
.sin_port
= 0;
1906 #ifdef HAVE_SOCKADDR_SA_LEN
1907 new->addr
.in
.sin_len
= sizeof(new->addr
.in
);
1911 else if (arg
&& inet_pton(AF_INET6
, arg
, &new->addr
.in6
.sin6_addr
) > 0)
1913 new->addr
.sa
.sa_family
= AF_INET6
;
1914 new->addr
.in6
.sin6_flowinfo
= 0;
1915 new->addr
.in6
.sin6_scope_id
= 0;
1916 new->addr
.in6
.sin6_port
= 0;
1917 #ifdef HAVE_SOCKADDR_SA_LEN
1918 new->addr
.in6
.sin6_len
= sizeof(new->addr
.in6
);
1928 new->next
= daemon
->if_addrs
;
1929 daemon
->if_addrs
= new;
1933 new->next
= daemon
->auth_peers
;
1934 daemon
->auth_peers
= new;
1940 case 'S': /* --server */
1941 case LOPT_LOCAL
: /* --local */
1942 case 'A': /* --address */
1943 case LOPT_NO_REBIND
: /* --rebind-domain-ok */
1945 struct server
*serv
, *newlist
= NULL
;
1949 if (arg
&& (*arg
== '/' || option
== LOPT_NO_REBIND
))
1951 int rebind
= !(*arg
== '/');
1955 while (rebind
|| (end
= split_chr(arg
, '/')))
1957 char *domain
= NULL
;
1958 /* elide leading dots - they are implied in the search algorithm */
1959 while (*arg
== '.') arg
++;
1960 /* # matches everything and becomes a zero length domain string */
1961 if (strcmp(arg
, "#") == 0)
1963 else if (strlen (arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
1965 serv
= opt_malloc(sizeof(struct server
));
1966 memset(serv
, 0, sizeof(struct server
));
1967 serv
->next
= newlist
;
1969 serv
->domain
= domain
;
1970 serv
->flags
= domain
? SERV_HAS_DOMAIN
: SERV_FOR_NODOTS
;
1980 newlist
= opt_malloc(sizeof(struct server
));
1981 memset(newlist
, 0, sizeof(struct server
));
1986 newlist
->flags
|= SERV_LITERAL_ADDRESS
;
1987 if (!(newlist
->flags
& SERV_TYPE
))
1990 else if (option
== LOPT_NO_REBIND
)
1991 newlist
->flags
|= SERV_NO_REBIND
;
1995 if (!(newlist
->flags
& SERV_NO_REBIND
))
1996 newlist
->flags
|= SERV_NO_ADDR
; /* no server */
1997 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
2001 else if (strcmp(arg
, "#") == 0)
2003 newlist
->flags
|= SERV_USE_RESOLV
; /* treat in ordinary way */
2004 if (newlist
->flags
& SERV_LITERAL_ADDRESS
)
2009 char *err
= parse_server(arg
, &newlist
->addr
, &newlist
->source_addr
, newlist
->interface
, &newlist
->flags
);
2017 serv
->next
->flags
= serv
->flags
;
2018 serv
->next
->addr
= serv
->addr
;
2019 serv
->next
->source_addr
= serv
->source_addr
;
2020 strcpy(serv
->next
->interface
, serv
->interface
);
2023 serv
->next
= daemon
->servers
;
2024 daemon
->servers
= newlist
;
2028 case LOPT_IPSET
: /* --ipset */
2030 ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
2034 struct ipsets ipsets_head
;
2035 struct ipsets
*ipsets
= &ipsets_head
;
2038 char **sets
, **sets_pos
;
2039 memset(ipsets
, 0, sizeof(struct ipsets
));
2041 if (arg
&& *arg
== '/')
2044 while ((end
= split_chr(arg
, '/')))
2046 char *domain
= NULL
;
2047 /* elide leading dots - they are implied in the search algorithm */
2050 /* # matches everything and becomes a zero length domain string */
2051 if (strcmp(arg
, "#") == 0 || !*arg
)
2053 else if (strlen(arg
) != 0 && !(domain
= canonicalise_opt(arg
)))
2055 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2056 ipsets
= ipsets
->next
;
2057 memset(ipsets
, 0, sizeof(struct ipsets
));
2058 ipsets
->domain
= domain
;
2064 ipsets
->next
= opt_malloc(sizeof(struct ipsets
));
2065 ipsets
= ipsets
->next
;
2066 memset(ipsets
, 0, sizeof(struct ipsets
));
2067 ipsets
->domain
= "";
2075 for (end
= arg
; *end
; ++end
)
2079 sets
= sets_pos
= opt_malloc(sizeof(char *) * size
);
2083 *sets_pos
++ = opt_string_alloc(arg
);
2087 for (ipsets
= &ipsets_head
; ipsets
->next
; ipsets
= ipsets
->next
)
2088 ipsets
->next
->sets
= sets
;
2089 ipsets
->next
= daemon
->ipsets
;
2090 daemon
->ipsets
= ipsets_head
.next
;
2096 case 'c': /* --cache-size */
2100 if (!atoi_check(arg
, &size
))
2104 /* zero is OK, and means no caching. */
2108 else if (size
> 10000)
2111 daemon
->cachesize
= size
;
2116 case 'p': /* --port */
2117 if (!atoi_check16(arg
, &daemon
->port
))
2121 case LOPT_MINPORT
: /* --min-port */
2122 if (!atoi_check16(arg
, &daemon
->min_port
))
2126 case '0': /* --dns-forward-max */
2127 if (!atoi_check(arg
, &daemon
->ftabsize
))
2131 case LOPT_MAX_LOGS
: /* --log-async */
2132 daemon
->max_logs
= LOG_MAX
; /* default */
2133 if (arg
&& !atoi_check(arg
, &daemon
->max_logs
))
2135 else if (daemon
->max_logs
> 100)
2136 daemon
->max_logs
= 100;
2139 case 'P': /* --edns-packet-max */
2142 if (!atoi_check(arg
, &i
))
2144 daemon
->edns_pktsz
= (unsigned short)i
;
2148 case 'Q': /* --query-port */
2149 if (!atoi_check16(arg
, &daemon
->query_port
))
2151 /* if explicitly set to zero, use single OS ephemeral port
2152 and disable random ports */
2153 if (daemon
->query_port
== 0)
2157 case 'T': /* --local-ttl */
2158 case LOPT_NEGTTL
: /* --neg-ttl */
2159 case LOPT_MAXTTL
: /* --max-ttl */
2160 case LOPT_MAXCTTL
: /* --max-cache-ttl */
2161 case LOPT_AUTHTTL
: /* --auth-ttl */
2164 if (!atoi_check(arg
, &ttl
))
2166 else if (option
== LOPT_NEGTTL
)
2167 daemon
->neg_ttl
= (unsigned long)ttl
;
2168 else if (option
== LOPT_MAXTTL
)
2169 daemon
->max_ttl
= (unsigned long)ttl
;
2170 else if (option
== LOPT_MAXCTTL
)
2171 daemon
->max_cache_ttl
= (unsigned long)ttl
;
2172 else if (option
== LOPT_AUTHTTL
)
2173 daemon
->auth_ttl
= (unsigned long)ttl
;
2175 daemon
->local_ttl
= (unsigned long)ttl
;
2180 case 'X': /* --dhcp-lease-max */
2181 if (!atoi_check(arg
, &daemon
->dhcp_max
))
2187 case LOPT_TFTP_MAX
: /* --tftp-max */
2188 if (!atoi_check(arg
, &daemon
->tftp_max
))
2192 case LOPT_PREFIX
: /* --tftp-prefix */
2196 struct tftp_prefix
*new = opt_malloc(sizeof(struct tftp_prefix
));
2197 new->interface
= opt_string_alloc(comma
);
2198 new->prefix
= opt_string_alloc(arg
);
2199 new->next
= daemon
->if_prefix
;
2200 daemon
->if_prefix
= new;
2203 daemon
->tftp_prefix
= opt_string_alloc(arg
);
2206 case LOPT_TFTPPORTS
: /* --tftp-port-range */
2207 if (!(comma
= split(arg
)) ||
2208 !atoi_check16(arg
, &daemon
->start_tftp_port
) ||
2209 !atoi_check16(comma
, &daemon
->end_tftp_port
))
2210 ret_err(_("bad port range"));
2212 if (daemon
->start_tftp_port
> daemon
->end_tftp_port
)
2214 int tmp
= daemon
->start_tftp_port
;
2215 daemon
->start_tftp_port
= daemon
->end_tftp_port
;
2216 daemon
->end_tftp_port
= tmp
;
2222 case LOPT_BRIDGE
: /* --bridge-interface */
2224 struct dhcp_bridge
*new = opt_malloc(sizeof(struct dhcp_bridge
));
2225 if (!(comma
= split(arg
)) || strlen(arg
) > IF_NAMESIZE
- 1 )
2226 ret_err(_("bad bridge-interface"));
2228 strcpy(new->iface
, arg
);
2230 new->next
= daemon
->bridges
;
2231 daemon
->bridges
= new;
2236 if (strlen(arg
) != 0 && strlen(arg
) <= IF_NAMESIZE
- 1)
2238 struct dhcp_bridge
*b
= opt_malloc(sizeof(struct dhcp_bridge
));
2239 b
->next
= new->alias
;
2241 strcpy(b
->iface
, arg
);
2249 case 'F': /* --dhcp-range */
2251 int k
, leasepos
= 2;
2252 char *cp
, *a
[8] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2253 struct dhcp_context
*new = opt_malloc(sizeof(struct dhcp_context
));
2255 memset (new, 0, sizeof(*new));
2256 new->lease_time
= DEFLEASE
;
2266 for (cp
= arg
; *cp
; cp
++)
2267 if (!(*cp
== ' ' || *cp
== '.' || *cp
== ':' ||
2268 (*cp
>= 'a' && *cp
<= 'f') || (*cp
>= 'A' && *cp
<= 'F') ||
2269 (*cp
>='0' && *cp
<= '9')))
2272 if (*cp
!= ',' && (comma
= split(arg
)))
2274 if (is_tag_prefix(arg
))
2276 struct dhcp_netid
*tt
= opt_malloc(sizeof (struct dhcp_netid
));
2277 tt
->net
= opt_string_alloc(arg
+4);
2278 tt
->next
= new->filter
;
2284 ret_err(_("only one tag allowed"));
2285 else if (strstr(arg
, "set:") == arg
)
2286 new->netid
.net
= opt_string_alloc(arg
+4);
2288 new->netid
.net
= opt_string_alloc(arg
);
2299 for (k
= 1; k
< 8; k
++)
2300 if (!(a
[k
] = split(a
[k
-1])))
2304 ret_err(_("bad dhcp-range"));
2306 if (inet_pton(AF_INET
, a
[0], &new->start
))
2308 new->next
= daemon
->dhcp
;
2310 new->end
= new->start
;
2311 if (strcmp(a
[1], "static") == 0)
2312 new->flags
|= CONTEXT_STATIC
;
2313 else if (strcmp(a
[1], "proxy") == 0)
2314 new->flags
|= CONTEXT_PROXY
;
2315 else if (!inet_pton(AF_INET
, a
[1], &new->end
))
2316 ret_err(_("bad dhcp-range"));
2318 if (ntohl(new->start
.s_addr
) > ntohl(new->end
.s_addr
))
2320 struct in_addr tmp
= new->start
;
2321 new->start
= new->end
;
2325 if (k
>= 3 && strchr(a
[2], '.') &&
2326 ((new->netmask
.s_addr
= inet_addr(a
[2])) != (in_addr_t
)-1))
2328 new->flags
|= CONTEXT_NETMASK
;
2330 if (!is_same_net(new->start
, new->end
, new->netmask
))
2331 ret_err(_("inconsistent DHCP range"));
2334 if (k
>= 4 && strchr(a
[3], '.') &&
2335 ((new->broadcast
.s_addr
= inet_addr(a
[3])) != (in_addr_t
)-1))
2337 new->flags
|= CONTEXT_BRDCAST
;
2342 else if (inet_pton(AF_INET6
, a
[0], &new->start6
))
2344 new->prefix
= 64; /* default */
2345 new->end6
= new->start6
;
2347 /* dhcp-range=:: enables DHCP stateless on any interface */
2348 if (IN6_IS_ADDR_UNSPECIFIED(&new->start6
))
2351 for (leasepos
= 1; leasepos
< k
; leasepos
++)
2353 if (strcmp(a
[leasepos
], "static") == 0)
2354 new->flags
|= CONTEXT_STATIC
| CONTEXT_DHCP
;
2355 else if (strcmp(a
[leasepos
], "ra-only") == 0 || strcmp(a
[leasepos
], "slaac") == 0 )
2356 new->flags
|= CONTEXT_RA_ONLY
| CONTEXT_RA
;
2357 else if (strcmp(a
[leasepos
], "ra-names") == 0)
2358 new->flags
|= CONTEXT_RA_NAME
| CONTEXT_RA
;
2359 else if (strcmp(a
[leasepos
], "ra-stateless") == 0)
2360 new->flags
|= CONTEXT_RA_STATELESS
| CONTEXT_DHCP
| CONTEXT_RA
;
2361 else if (leasepos
== 1 && inet_pton(AF_INET6
, a
[leasepos
], &new->end6
))
2362 new->flags
|= CONTEXT_DHCP
;
2363 else if (strstr(a
[leasepos
], "constructor:") == a
[leasepos
])
2365 if (a
[leasepos
][strlen(a
[leasepos
])-1] == '*')
2367 a
[leasepos
][strlen(a
[leasepos
])-1] = 0;
2368 new->flags
|= CONTEXT_WILDCARD
;
2370 new->template_interface
= opt_string_alloc(a
[leasepos
] + 12);
2371 new->flags
|= CONTEXT_TEMPLATE
;
2377 new->next
= daemon
->dhcp6
;
2378 daemon
->dhcp6
= new;
2380 /* bare integer < 128 is prefix value */
2384 for (cp
= a
[leasepos
]; *cp
; cp
++)
2385 if (!(*cp
>= '0' && *cp
<= '9'))
2387 if (!*cp
&& (pref
= atoi(a
[leasepos
])) <= 128)
2391 if (new->prefix
!= 64)
2393 if ((new->flags
& (CONTEXT_RA_ONLY
| CONTEXT_RA_NAME
| CONTEXT_RA_STATELESS
)))
2394 ret_err(_("prefix must be exactly 64 for RA subnets"));
2395 else if (new->template_interface
)
2396 ret_err(_("prefix must be exactly 64 for subnet constructors"));
2398 if (new->prefix
< 64)
2399 ret_err(_("prefix must be at least 64"));
2403 if (!is_same_net6(&new->start6
, &new->end6
, new->prefix
))
2404 ret_err(_("inconsistent DHCPv6 range"));
2405 if (addr6part(&new->start6
) > addr6part(&new->end6
))
2407 struct in6_addr tmp
= new->start6
;
2408 new->start6
= new->end6
;
2416 if (strcmp(a
[leasepos
], "infinite") == 0)
2417 new->lease_time
= 0xffffffff;
2418 else if (strcmp(a
[leasepos
], "deprecated") == 0)
2419 new->flags
|= CONTEXT_DEPRECATE
;
2423 if (strlen(a
[leasepos
]) > 0)
2425 switch (a
[leasepos
][strlen(a
[leasepos
]) - 1])
2445 a
[leasepos
][strlen(a
[leasepos
]) - 1] = 0;
2448 for (cp
= a
[leasepos
]; *cp
; cp
++)
2449 if (!(*cp
>= '0' && *cp
<= '9'))
2452 if (*cp
|| (leasepos
+1 < k
))
2453 ret_err(_("bad dhcp-range"));
2455 new->lease_time
= atoi(a
[leasepos
]) * fac
;
2456 /* Leases of a minute or less confuse
2457 some clients, notably Apple's */
2458 if (new->lease_time
< 120)
2459 new->lease_time
= 120;
2467 case 'G': /* --dhcp-host */
2470 char *a
[6] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2471 struct dhcp_config
*new;
2474 new = opt_malloc(sizeof(struct dhcp_config
));
2476 new->next
= daemon
->dhcp_conf
;
2477 new->flags
= (option
== LOPT_BANK
) ? CONFIG_BANK
: 0;
2482 for (k
= 1; k
< 6; k
++)
2483 if (!(a
[k
] = split(a
[k
-1])))
2486 for (j
= 0; j
< k
; j
++)
2487 if (strchr(a
[j
], ':')) /* ethernet address, netid or binary CLID */
2491 if ((arg
[0] == 'i' || arg
[0] == 'I') &&
2492 (arg
[1] == 'd' || arg
[1] == 'D') &&
2496 new->flags
|= CONFIG_NOCLID
;
2500 arg
+= 3; /* dump id: */
2501 if (strchr(arg
, ':'))
2502 len
= parse_hex(arg
, (unsigned char *)arg
, -1, NULL
, NULL
);
2506 len
= (int) strlen(arg
);
2511 ret_err(_("bad hex constant"));
2512 else if ((new->clid
= opt_malloc(len
)))
2514 new->flags
|= CONFIG_CLID
;
2515 new->clid_len
= len
;
2516 memcpy(new->clid
, arg
, len
);
2520 /* dhcp-host has strange backwards-compat needs. */
2521 else if (strstr(arg
, "net:") == arg
|| strstr(arg
, "set:") == arg
)
2523 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2524 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2525 newtag
->net
= opt_malloc(strlen(arg
+ 4) + 1);
2526 newlist
->next
= new->netid
;
2527 new->netid
= newlist
;
2528 newlist
->list
= newtag
;
2529 strcpy(newtag
->net
, arg
+4);
2530 unhide_metas(newtag
->net
);
2532 else if (strstr(arg
, "tag:") == arg
)
2533 ret_err(_("cannot match tags in --dhcp-host"));
2535 else if (arg
[0] == '[' && arg
[strlen(arg
)-1] == ']')
2537 arg
[strlen(arg
)-1] = 0;
2540 if (!inet_pton(AF_INET6
, arg
, &new->addr6
))
2541 ret_err(_("bad IPv6 address"));
2543 for (i
= 0; i
< 8; i
++)
2544 if (new->addr6
.s6_addr
[i
] != 0)
2547 /* set WILDCARD if network part all zeros */
2549 new->flags
|= CONFIG_WILDCARD
;
2551 new->flags
|= CONFIG_ADDR6
;
2556 struct hwaddr_config
*newhw
= opt_malloc(sizeof(struct hwaddr_config
));
2557 if ((newhw
->hwaddr_len
= parse_hex(a
[j
], newhw
->hwaddr
, DHCP_CHADDR_MAX
,
2558 &newhw
->wildcard_mask
, &newhw
->hwaddr_type
)) == -1)
2559 ret_err(_("bad hex constant"));
2563 newhw
->next
= new->hwaddr
;
2564 new->hwaddr
= newhw
;
2568 else if (strchr(a
[j
], '.') && (in
.s_addr
= inet_addr(a
[j
])) != (in_addr_t
)-1)
2570 struct dhcp_config
*configs
;
2573 new->flags
|= CONFIG_ADDR
;
2575 /* If the same IP appears in more than one host config, then DISCOVER
2576 for one of the hosts will get the address, but REQUEST will be NAKed,
2577 since the address is reserved by the other one -> protocol loop. */
2578 for (configs
= daemon
->dhcp_conf
; configs
; configs
= configs
->next
)
2579 if ((configs
->flags
& CONFIG_ADDR
) && configs
->addr
.s_addr
== in
.s_addr
)
2581 sprintf(errstr
, _("duplicate dhcp-host IP address %s"), inet_ntoa(in
));
2587 char *cp
, *lastp
= NULL
, last
= 0;
2590 if (strlen(a
[j
]) > 1)
2592 lastp
= a
[j
] + strlen(a
[j
]) - 1;
2618 for (cp
= a
[j
]; *cp
; cp
++)
2619 if (!isdigit((unsigned char)*cp
) && *cp
!= ' ')
2626 if (strcmp(a
[j
], "infinite") == 0)
2628 new->lease_time
= 0xffffffff;
2629 new->flags
|= CONFIG_TIME
;
2631 else if (strcmp(a
[j
], "ignore") == 0)
2632 new->flags
|= CONFIG_DISABLE
;
2635 if (!(new->hostname
= canonicalise_opt(a
[j
])) ||
2636 !legal_hostname(new->hostname
))
2637 ret_err(_("bad DHCP host name"));
2639 new->flags
|= CONFIG_NAME
;
2640 new->domain
= strip_hostname(new->hostname
);
2645 new->lease_time
= atoi(a
[j
]) * fac
;
2646 /* Leases of a minute or less confuse
2647 some clients, notably Apple's */
2648 if (new->lease_time
< 120)
2649 new->lease_time
= 120;
2650 new->flags
|= CONFIG_TIME
;
2654 daemon
->dhcp_conf
= new;
2658 case LOPT_TAG_IF
: /* --tag-if */
2660 struct tag_if
*new = opt_malloc(sizeof(struct tag_if
));
2666 /* preserve order */
2667 if (!daemon
->tag_if
)
2668 daemon
->tag_if
= new;
2672 for (tmp
= daemon
->tag_if
; tmp
->next
; tmp
= tmp
->next
);
2690 struct dhcp_netid
*newtag
= opt_malloc(sizeof(struct dhcp_netid
));
2691 newtag
->net
= opt_malloc(len
- 3);
2692 strcpy(newtag
->net
, arg
+4);
2693 unhide_metas(newtag
->net
);
2695 if (strstr(arg
, "set:") == arg
)
2697 struct dhcp_netid_list
*newlist
= opt_malloc(sizeof(struct dhcp_netid_list
));
2698 newlist
->next
= new->set
;
2700 newlist
->list
= newtag
;
2702 else if (strstr(arg
, "tag:") == arg
)
2704 newtag
->next
= new->tag
;
2719 ret_err(_("bad tag-if"));
2725 case 'O': /* --dhcp-option */
2726 case LOPT_FORCE
: /* --dhcp-option-force */
2728 case LOPT_MATCH
: /* --dhcp-match */
2729 return parse_dhcp_opt(errstr
, arg
,
2730 option
== LOPT_FORCE
? DHOPT_FORCE
:
2731 (option
== LOPT_MATCH
? DHOPT_MATCH
:
2732 (option
== LOPT_OPTS
? DHOPT_BANK
: 0)));
2734 case 'M': /* --dhcp-boot */
2736 struct dhcp_netid
*id
= NULL
;
2737 while (is_tag_prefix(arg
))
2739 struct dhcp_netid
*newid
= opt_malloc(sizeof(struct dhcp_netid
));
2743 newid
->net
= opt_string_alloc(arg
+4);
2751 char *dhcp_file
, *dhcp_sname
= NULL
, *tftp_sname
= NULL
;
2752 struct in_addr dhcp_next_server
;
2753 struct dhcp_boot
*new;
2755 dhcp_file
= opt_string_alloc(arg
);
2756 dhcp_next_server
.s_addr
= 0;
2761 dhcp_sname
= opt_string_alloc(arg
);
2764 unhide_metas(comma
);
2765 if ((dhcp_next_server
.s_addr
= inet_addr(comma
)) == (in_addr_t
)-1) {
2768 * The user may have specified the tftp hostname here.
2769 * save it so that it can be resolved/looked up during
2770 * actual dhcp_reply().
2773 tftp_sname
= opt_string_alloc(comma
);
2774 dhcp_next_server
.s_addr
= 0;
2779 new = opt_malloc(sizeof(struct dhcp_boot
));
2780 new->file
= dhcp_file
;
2781 new->sname
= dhcp_sname
;
2782 new->tftp_sname
= tftp_sname
;
2783 new->next_server
= dhcp_next_server
;
2785 new->next
= daemon
->boot_config
;
2786 daemon
->boot_config
= new;
2792 case LOPT_PXE_PROMT
: /* --pxe-prompt */
2794 struct dhcp_opt
*new = opt_malloc(sizeof(struct dhcp_opt
));
2798 new->opt
= 10; /* PXE_MENU_PROMPT */
2800 while (is_tag_prefix(arg
))
2802 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
2804 nn
->next
= new->netid
;
2806 nn
->net
= opt_string_alloc(arg
+4);
2816 new->len
= strlen(arg
) + 1;
2817 new->val
= opt_malloc(new->len
);
2818 memcpy(new->val
+ 1, arg
, new->len
- 1);
2820 new->u
.vendor_class
= (unsigned char *)"PXEClient";
2821 new->flags
= DHOPT_VENDOR
;
2823 if (comma
&& atoi_check(comma
, &timeout
))
2824 *(new->val
) = timeout
;
2828 new->next
= daemon
->dhcp_opts
;
2829 daemon
->dhcp_opts
= new;
2830 daemon
->enable_pxe
= 1;
2836 case LOPT_PXE_SERV
: /* --pxe-service */
2838 struct pxe_service
*new = opt_malloc(sizeof(struct pxe_service
));
2839 char *CSA
[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
2840 "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL
};
2841 static int boottype
= 32768;
2845 new->server
.s_addr
= 0;
2847 while (is_tag_prefix(arg
))
2849 struct dhcp_netid
*nn
= opt_malloc(sizeof (struct dhcp_netid
));
2851 nn
->next
= new->netid
;
2853 nn
->net
= opt_string_alloc(arg
+4);
2857 if (arg
&& (comma
= split(arg
)))
2859 for (i
= 0; CSA
[i
]; i
++)
2860 if (strcasecmp(CSA
[i
], arg
) == 0)
2863 if (CSA
[i
] || atoi_check(arg
, &i
))
2869 new->menu
= opt_string_alloc(arg
);
2873 new->type
= 0; /* local boot */
2874 new->basename
= NULL
;
2880 if (atoi_check(arg
, &i
))
2883 new->basename
= NULL
;
2887 new->type
= boottype
++;
2888 new->basename
= opt_string_alloc(arg
);
2893 if (!inet_pton(AF_INET
, comma
, &new->server
))
2895 new->server
.s_addr
= 0;
2896 new->sname
= opt_string_alloc(comma
);
2904 if (!daemon
->pxe_services
)
2905 daemon
->pxe_services
= new;
2908 struct pxe_service
*s
;
2909 for (s
= daemon
->pxe_services
; s
->next
; s
= s
->next
);
2913 daemon
->enable_pxe
= 1;
2922 case '4': /* --dhcp-mac */
2924 if (!(comma
= split(arg
)))
2928 struct dhcp_mac
*new = opt_malloc(sizeof(struct dhcp_mac
));
2929 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
2930 unhide_metas(comma
);
2931 new->hwaddr_len
= parse_hex(comma
, new->hwaddr
, DHCP_CHADDR_MAX
, &new->mask
, &new->hwaddr_type
);
2932 if (new->hwaddr_len
== -1)
2936 new->next
= daemon
->dhcp_macs
;
2937 daemon
->dhcp_macs
= new;
2943 case 'U': /* --dhcp-vendorclass */
2944 case 'j': /* --dhcp-userclass */
2945 case LOPT_CIRCUIT
: /* --dhcp-circuitid */
2946 case LOPT_REMOTE
: /* --dhcp-remoteid */
2947 case LOPT_SUBSCR
: /* --dhcp-subscrid */
2951 struct dhcp_vendor
*new = opt_malloc(sizeof(struct dhcp_vendor
));
2953 if (!(comma
= split(arg
)))
2956 new->netid
.net
= opt_string_alloc(set_prefix(arg
));
2957 /* check for hex string - must digits may include : must not have nothing else,
2958 only allowed for agent-options. */
2961 if ((comma
= split(arg
)))
2963 if (option
!= 'U' || strstr(arg
, "enterprise:") != arg
)
2966 new->enterprise
= atoi(arg
+11);
2971 for (p
= (unsigned char *)comma
; *p
; p
++)
2976 unhide_metas(comma
);
2977 if (option
== 'U' || option
== 'j' || *p
|| !dig
)
2979 new->len
= strlen(comma
);
2980 new->data
= opt_malloc(new->len
);
2981 memcpy(new->data
, comma
, new->len
);
2985 new->len
= parse_hex(comma
, (unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
2986 new->data
= opt_malloc(new->len
);
2987 memcpy(new->data
, comma
, new->len
);
2993 new->match_type
= MATCH_USER
;
2996 new->match_type
= MATCH_VENDOR
;
2999 new->match_type
= MATCH_CIRCUIT
;
3002 new->match_type
= MATCH_REMOTE
;
3005 new->match_type
= MATCH_SUBSCRIBER
;
3008 new->next
= daemon
->dhcp_vendors
;
3009 daemon
->dhcp_vendors
= new;
3014 case LOPT_ALTPORT
: /* --dhcp-alternate-port */
3017 daemon
->dhcp_server_port
= DHCP_SERVER_ALTPORT
;
3018 daemon
->dhcp_client_port
= DHCP_CLIENT_ALTPORT
;
3023 if (!atoi_check16(arg
, &daemon
->dhcp_server_port
) ||
3024 (comma
&& !atoi_check16(comma
, &daemon
->dhcp_client_port
)))
3025 ret_err(_("invalid port number"));
3027 daemon
->dhcp_client_port
= daemon
->dhcp_server_port
+1;
3031 case 'J': /* --dhcp-ignore */
3032 case LOPT_NO_NAMES
: /* --dhcp-ignore-names */
3033 case LOPT_BROADCAST
: /* --dhcp-broadcast */
3034 case '3': /* --bootp-dynamic */
3035 case LOPT_GEN_NAMES
: /* --dhcp-generate-names */
3037 struct dhcp_netid_list
*new = opt_malloc(sizeof(struct dhcp_netid_list
));
3038 struct dhcp_netid
*list
= NULL
;
3041 new->next
= daemon
->dhcp_ignore
;
3042 daemon
->dhcp_ignore
= new;
3044 else if (option
== LOPT_BROADCAST
)
3046 new->next
= daemon
->force_broadcast
;
3047 daemon
->force_broadcast
= new;
3049 else if (option
== '3')
3051 new->next
= daemon
->bootp_dynamic
;
3052 daemon
->bootp_dynamic
= new;
3054 else if (option
== LOPT_GEN_NAMES
)
3056 new->next
= daemon
->dhcp_gen_names
;
3057 daemon
->dhcp_gen_names
= new;
3061 new->next
= daemon
->dhcp_ignore_names
;
3062 daemon
->dhcp_ignore_names
= new;
3066 struct dhcp_netid
*member
= opt_malloc(sizeof(struct dhcp_netid
));
3068 member
->next
= list
;
3070 if (is_tag_prefix(arg
))
3071 member
->net
= opt_string_alloc(arg
+4);
3073 member
->net
= opt_string_alloc(arg
);
3081 case LOPT_PROXY
: /* --dhcp-proxy */
3082 daemon
->override
= 1;
3084 struct addr_list
*new = opt_malloc(sizeof(struct addr_list
));
3086 if ((new->addr
.s_addr
= inet_addr(arg
)) == (in_addr_t
)-1)
3087 ret_err(_("bad dhcp-proxy address"));
3088 new->next
= daemon
->override_relays
;
3089 daemon
->override_relays
= new;
3096 case LOPT_DUID
: /* --dhcp-duid */
3097 if (!(comma
= split(arg
)) || !atoi_check(arg
, (int *)&daemon
->duid_enterprise
))
3098 ret_err(_("bad DUID"));
3101 daemon
->duid_config_len
= parse_hex(comma
,(unsigned char *)comma
, strlen(comma
), NULL
, NULL
);
3102 daemon
->duid_config
= opt_malloc(daemon
->duid_config_len
);
3103 memcpy(daemon
->duid_config
, comma
, daemon
->duid_config_len
);
3108 case 'V': /* --alias */
3110 char *dash
, *a
[3] = { NULL
, NULL
, NULL
};
3112 struct doctor
*new = opt_malloc(sizeof(struct doctor
));
3113 new->next
= daemon
->doctors
;
3114 daemon
->doctors
= new;
3115 new->mask
.s_addr
= 0xffffffff;
3116 new->end
.s_addr
= 0;
3119 for (k
= 1; k
< 3; k
++)
3121 if (!(a
[k
] = split(a
[k
-1])))
3126 dash
= split_chr(a
[0], '-');
3129 ((new->in
.s_addr
= inet_addr(a
[0])) == (in_addr_t
)-1) ||
3130 ((new->out
.s_addr
= inet_addr(a
[1])) == (in_addr_t
)-1))
3134 new->mask
.s_addr
= inet_addr(a
[2]);
3137 ((new->end
.s_addr
= inet_addr(dash
)) == (in_addr_t
)-1 ||
3138 !is_same_net(new->in
, new->end
, new->mask
) ||
3139 ntohl(new->in
.s_addr
) > ntohl(new->end
.s_addr
)))
3140 ret_err(_("invalid alias range"));
3145 case LOPT_INTNAME
: /* --interface-name */
3147 struct interface_name
*new, **up
;
3148 char *domain
= NULL
;
3152 if (!comma
|| !(domain
= canonicalise_opt(arg
)))
3153 ret_err(_("bad interface name"));
3155 new = opt_malloc(sizeof(struct interface_name
));
3157 /* Add to the end of the list, so that first name
3158 of an interface is used for PTR lookups. */
3159 for (up
= &daemon
->int_names
; *up
; up
= &((*up
)->next
));
3162 new->intr
= opt_string_alloc(comma
);
3166 case LOPT_CNAME
: /* --cname */
3172 if (!(comma
= split(arg
)))
3175 alias
= canonicalise_opt(arg
);
3176 target
= canonicalise_opt(comma
);
3178 if (!alias
|| !target
)
3179 ret_err(_("bad CNAME"));
3182 for (new = daemon
->cnames
; new; new = new->next
)
3183 if (hostname_isequal(new->alias
, arg
))
3184 ret_err(_("duplicate CNAME"));
3185 new = opt_malloc(sizeof(struct cname
));
3186 new->next
= daemon
->cnames
;
3187 daemon
->cnames
= new;
3189 new->target
= target
;
3195 case LOPT_PTR
: /* --ptr-record */
3197 struct ptr_record
*new;
3198 char *dom
, *target
= NULL
;
3202 if (!(dom
= canonicalise_opt(arg
)) ||
3203 (comma
&& !(target
= canonicalise_opt(comma
))))
3204 ret_err(_("bad PTR record"));
3207 new = opt_malloc(sizeof(struct ptr_record
));
3208 new->next
= daemon
->ptr
;
3216 case LOPT_NAPTR
: /* --naptr-record */
3218 char *a
[7] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
3222 char *name
, *replace
= NULL
;
3225 for (k
= 1; k
< 7; k
++)
3226 if (!(a
[k
] = split(a
[k
-1])))
3231 !(name
= canonicalise_opt(a
[0])) ||
3232 !atoi_check16(a
[1], &order
) ||
3233 !atoi_check16(a
[2], &pref
) ||
3234 (k
== 7 && !(replace
= canonicalise_opt(a
[6]))))
3235 ret_err(_("bad NAPTR record"));
3238 new = opt_malloc(sizeof(struct naptr
));
3239 new->next
= daemon
->naptr
;
3240 daemon
->naptr
= new;
3242 new->flags
= opt_string_alloc(a
[3]);
3243 new->services
= opt_string_alloc(a
[4]);
3244 new->regexp
= opt_string_alloc(a
[5]);
3245 new->replace
= replace
;
3252 case LOPT_RR
: /* dns-rr */
3254 struct txt_record
*new;
3260 data
= split(comma
);
3262 new = opt_malloc(sizeof(struct txt_record
));
3263 new->next
= daemon
->rr
;
3266 if (!atoi_check(comma
, &val
) ||
3267 !(new->name
= canonicalise_opt(arg
)) ||
3268 (data
&& (len
= parse_hex(data
, (unsigned char *)data
, -1, NULL
, NULL
)) == -1U))
3269 ret_err(_("bad RR record"));
3276 new->txt
=opt_malloc(len
);
3278 memcpy(new->txt
, data
, len
);
3284 case 'Y': /* --txt-record */
3286 struct txt_record
*new;
3287 unsigned char *p
, *cnt
;
3292 new = opt_malloc(sizeof(struct txt_record
));
3293 new->next
= daemon
->txt
;
3297 if (!(new->name
= canonicalise_opt(arg
)))
3298 ret_err(_("bad TXT record"));
3300 len
= comma
? strlen(comma
) : 0;
3301 len
+= (len
/255) + 1; /* room for extra counts */
3302 new->txt
= p
= opt_malloc(len
);
3307 while (comma
&& *comma
)
3309 unsigned char c
= (unsigned char)*comma
++;
3311 if (c
== ',' || *cnt
== 255)
3320 *p
++ = unhide_meta(c
);
3325 new->len
= p
- new->txt
;
3330 case 'W': /* --srv-host */
3332 int port
= 1, priority
= 0, weight
= 0;
3333 char *name
, *target
= NULL
;
3334 struct mx_srv_record
*new;
3338 if (!(name
= canonicalise_opt(arg
)))
3339 ret_err(_("bad SRV record"));
3345 if (!(target
= canonicalise_opt(arg
)))
3346 ret_err(_("bad SRV target"));
3352 if (!atoi_check16(arg
, &port
))
3353 ret_err(_("invalid port number"));
3359 if (!atoi_check16(arg
, &priority
))
3360 ret_err(_("invalid priority"));
3366 if (!atoi_check16(arg
, &weight
))
3367 ret_err(_("invalid weight"));
3373 new = opt_malloc(sizeof(struct mx_srv_record
));
3374 new->next
= daemon
->mxnames
;
3375 daemon
->mxnames
= new;
3378 new->target
= target
;
3379 new->srvport
= port
;
3380 new->priority
= priority
;
3381 new->weight
= weight
;
3385 case LOPT_HOST_REC
: /* --host-record */
3387 struct host_record
*new = opt_malloc(sizeof(struct host_record
));
3388 memset(new, 0, sizeof(struct host_record
));
3390 if (!arg
|| !(comma
= split(arg
)))
3391 ret_err(_("Bad host-record"));
3395 struct all_addr addr
;
3396 if (inet_pton(AF_INET
, arg
, &addr
))
3397 new->addr
= addr
.addr
.addr4
;
3399 else if (inet_pton(AF_INET6
, arg
, &addr
))
3400 new->addr6
= addr
.addr
.addr6
;
3405 char *canon
= canonicalise(arg
, &nomem
);
3406 struct name_list
*nl
= opt_malloc(sizeof(struct name_list
));
3408 ret_err(_("Bad name in host-record"));
3411 /* keep order, so that PTR record goes to first name */
3417 struct name_list
*tmp
;
3418 for (tmp
= new->names
; tmp
->next
; tmp
= tmp
->next
);
3427 /* Keep list order */
3428 if (!daemon
->host_records_tail
)
3429 daemon
->host_records
= new;
3431 daemon
->host_records_tail
->next
= new;
3433 daemon
->host_records_tail
= new;
3438 ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DBus support)"));
3445 static void read_file(char *file
, FILE *f
, int hard_opt
)
3447 volatile int lineno
= 0;
3448 char *buff
= daemon
->namebuff
;
3450 while (fgets(buff
, MAXDNAME
, f
))
3452 int white
, i
, option
= hard_opt
;
3453 char *errmess
, *p
, *arg
= NULL
, *start
;
3456 /* Memory allocation failure longjmps here if mem_recover == 1 */
3459 if (setjmp(mem_jmp
))
3467 /* Implement quotes, inside quotes we allow \\ \" \n and \t
3468 metacharacters get hidden also strip comments */
3469 for (white
= 1, p
= buff
; *p
; p
++)
3473 memmove(p
, p
+1, strlen(p
+1)+1);
3475 for(; *p
&& *p
!= '"'; p
++)
3477 if (*p
== '\\' && strchr("\"tnebr\\", p
[1]))
3481 else if (p
[1] == 'n')
3483 else if (p
[1] == 'b')
3485 else if (p
[1] == 'r')
3487 else if (p
[1] == 'e') /* escape */
3489 memmove(p
, p
+1, strlen(p
+1)+1);
3496 errmess
= _("missing \"");
3500 memmove(p
, p
+1, strlen(p
+1)+1);
3510 if (white
&& *p
== '#')
3520 /* strip leading spaces */
3521 for (start
= buff
; *start
&& *start
== ' '; start
++);
3523 /* strip trailing spaces */
3524 for (len
= strlen(start
); (len
!= 0) && (start
[len
-1] == ' '); len
--);
3533 else if ((p
=strchr(start
, '=')))
3535 /* allow spaces around "=" */
3536 for (arg
= p
+1; *arg
== ' '; arg
++);
3537 for (; p
>= start
&& (*p
== ' ' || *p
== '='); p
--)
3545 for (option
= 0, i
= 0; opts
[i
].name
; i
++)
3546 if (strcmp(opts
[i
].name
, start
) == 0)
3548 option
= opts
[i
].val
;
3553 errmess
= _("bad option");
3554 else if (opts
[i
].has_arg
== 0 && arg
)
3555 errmess
= _("extraneous parameter");
3556 else if (opts
[i
].has_arg
== 1 && !arg
)
3557 errmess
= _("missing parameter");
3562 strcpy(daemon
->namebuff
, errmess
);
3564 if (errmess
|| !one_opt(option
, arg
, buff
, _("error"), 0))
3566 sprintf(daemon
->namebuff
+ strlen(daemon
->namebuff
), _(" at line %d of %s"), lineno
, file
);
3568 my_syslog(LOG_ERR
, "%s", daemon
->namebuff
);
3570 die("%s", daemon
->namebuff
, EC_BADCONF
);
3578 static int one_file(char *file
, int hard_opt
)
3582 static int read_stdin
= 0;
3583 static struct fileread
{
3586 struct fileread
*next
;
3587 } *filesread
= NULL
;
3589 if (hard_opt
== '7')
3591 /* default conf-file reading */
3596 if (hard_opt
== 0 && strcmp(file
, "-") == 0)
3598 if (read_stdin
== 1)
3606 /* ignore repeated files. */
3607 struct stat statbuf
;
3609 if (hard_opt
== 0 && stat(file
, &statbuf
) == 0)
3613 for (r
= filesread
; r
; r
= r
->next
)
3614 if (r
->dev
== statbuf
.st_dev
&& r
->ino
== statbuf
.st_ino
)
3617 r
= safe_malloc(sizeof(struct fileread
));
3618 r
->next
= filesread
;
3620 r
->dev
= statbuf
.st_dev
;
3621 r
->ino
= statbuf
.st_ino
;
3624 if (!(f
= fopen(file
, "r")))
3626 if (errno
== ENOENT
&& nofile_ok
)
3627 return 1; /* No conffile, all done. */
3630 char *str
= _("cannot read %s: %s");
3633 my_syslog(LOG_ERR
, str
, file
, strerror(errno
));
3637 die(str
, file
, EC_FILE
);
3642 read_file(file
, f
, hard_opt
);
3646 /* expand any name which is a directory */
3647 struct hostsfile
*expand_filelist(struct hostsfile
*list
)
3650 struct hostsfile
*ah
;
3652 for (i
= 0, ah
= list
; ah
; ah
= ah
->next
)
3657 if (ah
->flags
& AH_DIR
)
3658 ah
->flags
|= AH_INACTIVE
;
3660 ah
->flags
&= ~AH_INACTIVE
;
3663 for (ah
= list
; ah
; ah
= ah
->next
)
3664 if (!(ah
->flags
& AH_INACTIVE
))
3667 if (stat(ah
->fname
, &buf
) != -1 && S_ISDIR(buf
.st_mode
))
3672 /* don't read this as a file */
3673 ah
->flags
|= AH_INACTIVE
;
3675 if (!(dir_stream
= opendir(ah
->fname
)))
3676 my_syslog(LOG_ERR
, _("cannot access directory %s: %s"),
3677 ah
->fname
, strerror(errno
));
3680 while ((ent
= readdir(dir_stream
)))
3682 size_t lendir
= strlen(ah
->fname
);
3683 size_t lenfile
= strlen(ent
->d_name
);
3684 struct hostsfile
*ah1
;
3687 /* ignore emacs backups and dotfiles */
3689 ent
->d_name
[lenfile
- 1] == '~' ||
3690 (ent
->d_name
[0] == '#' && ent
->d_name
[lenfile
- 1] == '#') ||
3691 ent
->d_name
[0] == '.')
3694 /* see if we have an existing record.
3697 path to match is ah1->fname */
3699 for (ah1
= list
; ah1
; ah1
= ah1
->next
)
3701 if (lendir
< strlen(ah1
->fname
) &&
3702 strstr(ah1
->fname
, ah
->fname
) == ah1
->fname
&&
3703 ah1
->fname
[lendir
] == '/' &&
3704 strcmp(ah1
->fname
+ lendir
+ 1, ent
->d_name
) == 0)
3706 ah1
->flags
&= ~AH_INACTIVE
;
3711 /* make new record */
3714 if (!(ah1
= whine_malloc(sizeof(struct hostsfile
))))
3717 if (!(path
= whine_malloc(lendir
+ lenfile
+ 2)))
3723 strcpy(path
, ah
->fname
);
3725 strcat(path
, ent
->d_name
);
3728 ah1
->flags
= AH_DIR
;
3733 /* inactivate record if not regular file */
3734 if ((ah1
->flags
& AH_DIR
) && stat(ah1
->fname
, &buf
) != -1 && !S_ISREG(buf
.st_mode
))
3735 ah1
->flags
|= AH_INACTIVE
;
3738 closedir(dir_stream
);
3748 void reread_dhcp(void)
3750 struct hostsfile
*hf
;
3752 if (daemon
->dhcp_hosts_file
)
3754 struct dhcp_config
*configs
, *cp
, **up
;
3756 /* remove existing... */
3757 for (up
= &daemon
->dhcp_conf
, configs
= daemon
->dhcp_conf
; configs
; configs
= cp
)
3761 if (configs
->flags
& CONFIG_BANK
)
3763 struct hwaddr_config
*mac
, *tmp
;
3764 struct dhcp_netid_list
*list
, *tmplist
;
3766 for (mac
= configs
->hwaddr
; mac
; mac
= tmp
)
3772 if (configs
->flags
& CONFIG_CLID
)
3773 free(configs
->clid
);
3775 for (list
= configs
->netid
; list
; list
= tmplist
)
3778 tmplist
= list
->next
;
3782 if (configs
->flags
& CONFIG_NAME
)
3783 free(configs
->hostname
);
3785 *up
= configs
->next
;
3789 up
= &configs
->next
;
3792 daemon
->dhcp_hosts_file
= expand_filelist(daemon
->dhcp_hosts_file
);
3793 for (hf
= daemon
->dhcp_hosts_file
; hf
; hf
= hf
->next
)
3794 if (!(hf
->flags
& AH_INACTIVE
))
3796 if (one_file(hf
->fname
, LOPT_BANK
))
3797 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
3801 if (daemon
->dhcp_opts_file
)
3803 struct dhcp_opt
*opts
, *cp
, **up
;
3804 struct dhcp_netid
*id
, *next
;
3806 for (up
= &daemon
->dhcp_opts
, opts
= daemon
->dhcp_opts
; opts
; opts
= cp
)
3810 if (opts
->flags
& DHOPT_BANK
)
3812 if ((opts
->flags
& DHOPT_VENDOR
))
3813 free(opts
->u
.vendor_class
);
3815 for (id
= opts
->netid
; id
; id
= next
)
3828 daemon
->dhcp_opts_file
= expand_filelist(daemon
->dhcp_opts_file
);
3829 for (hf
= daemon
->dhcp_opts_file
; hf
; hf
= hf
->next
)
3830 if (!(hf
->flags
& AH_INACTIVE
))
3832 if (one_file(hf
->fname
, LOPT_OPTS
))
3833 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s"), hf
->fname
);
3839 void read_opts(int argc
, char **argv
, char *compile_opts
)
3841 char *buff
= opt_malloc(MAXDNAME
);
3842 int option
, conffile_opt
= '7', testmode
= 0;
3843 char *arg
, *conffile
= CONFFILE
;
3847 daemon
= opt_malloc(sizeof(struct daemon
));
3848 memset(daemon
, 0, sizeof(struct daemon
));
3849 daemon
->namebuff
= buff
;
3851 /* Set defaults - everything else is zero or NULL */
3852 daemon
->cachesize
= CACHESIZ
;
3853 daemon
->ftabsize
= FTABSIZ
;
3854 daemon
->port
= NAMESERVER_PORT
;
3855 daemon
->dhcp_client_port
= DHCP_CLIENT_PORT
;
3856 daemon
->dhcp_server_port
= DHCP_SERVER_PORT
;
3857 daemon
->default_resolv
.is_default
= 1;
3858 daemon
->default_resolv
.name
= RESOLVFILE
;
3859 daemon
->resolv_files
= &daemon
->default_resolv
;
3860 daemon
->username
= CHUSER
;
3861 daemon
->runfile
= RUNFILE
;
3862 daemon
->dhcp_max
= MAXLEASES
;
3863 daemon
->tftp_max
= TFTP_MAX_CONNECTIONS
;
3864 daemon
->edns_pktsz
= EDNS_PKTSZ
;
3865 daemon
->log_fac
= -1;
3866 daemon
->auth_ttl
= AUTH_TTL
;
3867 daemon
->soa_refresh
= SOA_REFRESH
;
3868 daemon
->soa_retry
= SOA_RETRY
;
3869 daemon
->soa_expiry
= SOA_EXPIRY
;
3870 add_txt("version.bind", "dnsmasq-" VERSION
);
3871 add_txt("authors.bind", "Simon Kelley");
3872 add_txt("copyright.bind", COPYRIGHT
);
3876 #ifdef HAVE_GETOPT_LONG
3877 option
= getopt_long(argc
, argv
, OPTSTRING
, opts
, NULL
);
3879 option
= getopt(argc
, argv
, OPTSTRING
);
3884 for (; optind
< argc
; optind
++)
3886 unsigned char *c
= (unsigned char *)argv
[optind
];
3887 for (; *c
!= 0; c
++)
3889 die(_("junk found in command line"), NULL
, EC_BADCONF
);
3894 /* Copy optarg so that argv doesn't get changed */
3897 strncpy(buff
, optarg
, MAXDNAME
);
3898 buff
[MAXDNAME
-1] = 0;
3904 /* command-line only stuff */
3905 if (option
== LOPT_TEST
)
3907 else if (option
== 'w')
3910 if (argc
== 3 && strcmp(argv
[2], "dhcp") == 0)
3913 else if (argc
== 3 && strcmp(argv
[2], "dhcp6") == 0)
3922 else if (option
== 'v')
3924 printf(_("Dnsmasq version %s %s\n"), VERSION
, COPYRIGHT
);
3925 printf(_("Compile time options: %s\n\n"), compile_opts
);
3926 printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
3927 printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
3928 printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
3931 else if (option
== 'C')
3933 conffile_opt
= 0; /* file must exist */
3934 conffile
= opt_string_alloc(arg
);
3938 #ifdef HAVE_GETOPT_LONG
3939 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try --help"), 1))
3941 if (!one_opt(option
, arg
, daemon
->namebuff
, _("try -w"), 1))
3943 die(_("bad command line options: %s"), daemon
->namebuff
, EC_BADCONF
);
3948 one_file(conffile
, conffile_opt
);
3950 /* port might not be known when the address is parsed - fill in here */
3951 if (daemon
->servers
)
3954 for (tmp
= daemon
->servers
; tmp
; tmp
= tmp
->next
)
3955 if (!(tmp
->flags
& SERV_HAS_SOURCE
))
3957 if (tmp
->source_addr
.sa
.sa_family
== AF_INET
)
3958 tmp
->source_addr
.in
.sin_port
= htons(daemon
->query_port
);
3960 else if (tmp
->source_addr
.sa
.sa_family
== AF_INET6
)
3961 tmp
->source_addr
.in6
.sin6_port
= htons(daemon
->query_port
);
3966 if (daemon
->if_addrs
)
3969 for(tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
3970 if (tmp
->addr
.sa
.sa_family
== AF_INET
)
3971 tmp
->addr
.in
.sin_port
= htons(daemon
->port
);
3973 else if (tmp
->addr
.sa
.sa_family
== AF_INET6
)
3974 tmp
->addr
.in6
.sin6_port
= htons(daemon
->port
);
3978 /* create default, if not specified */
3979 if (daemon
->authserver
&& !daemon
->hostmaster
)
3981 strcpy(buff
, "hostmaster.");
3982 strcat(buff
, daemon
->authserver
);
3983 daemon
->hostmaster
= opt_string_alloc(buff
);
3986 /* only one of these need be specified: the other defaults to the host-name */
3987 if (option_bool(OPT_LOCALMX
) || daemon
->mxnames
|| daemon
->mxtarget
)
3989 struct mx_srv_record
*mx
;
3991 if (gethostname(buff
, MAXDNAME
) == -1)
3992 die(_("cannot get host-name: %s"), NULL
, EC_MISC
);
3994 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
3995 if (!mx
->issrv
&& hostname_isequal(mx
->name
, buff
))
3998 if ((daemon
->mxtarget
|| option_bool(OPT_LOCALMX
)) && !mx
)
4000 mx
= opt_malloc(sizeof(struct mx_srv_record
));
4001 mx
->next
= daemon
->mxnames
;
4004 mx
->name
= opt_string_alloc(buff
);
4005 daemon
->mxnames
= mx
;
4008 if (!daemon
->mxtarget
)
4009 daemon
->mxtarget
= opt_string_alloc(buff
);
4011 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
4012 if (!mx
->issrv
&& !mx
->target
)
4013 mx
->target
= daemon
->mxtarget
;
4016 if (!option_bool(OPT_NO_RESOLV
) &&
4017 daemon
->resolv_files
&&
4018 daemon
->resolv_files
->next
&&
4019 option_bool(OPT_NO_POLL
))
4020 die(_("only one resolv.conf file allowed in no-poll mode."), NULL
, EC_BADCONF
);
4022 if (option_bool(OPT_RESOLV_DOMAIN
))
4027 if (option_bool(OPT_NO_RESOLV
) ||
4028 !daemon
->resolv_files
||
4029 (daemon
->resolv_files
)->next
)
4030 die(_("must have exactly one resolv.conf to read domain from."), NULL
, EC_BADCONF
);
4032 if (!(f
= fopen((daemon
->resolv_files
)->name
, "r")))
4033 die(_("failed to read %s: %s"), (daemon
->resolv_files
)->name
, EC_FILE
);
4035 while ((line
= fgets(buff
, MAXDNAME
, f
)))
4037 char *token
= strtok(line
, " \t\n\r");
4039 if (!token
|| strcmp(token
, "search") != 0)
4042 if ((token
= strtok(NULL
, " \t\n\r")) &&
4043 (daemon
->domain_suffix
= canonicalise_opt(token
)))
4049 if (!daemon
->domain_suffix
)
4050 die(_("no search directive found in %s"), (daemon
->resolv_files
)->name
, EC_MISC
);
4053 if (daemon
->domain_suffix
)
4055 /* add domain for any srv record without one. */
4056 struct mx_srv_record
*srv
;
4058 for (srv
= daemon
->mxnames
; srv
; srv
= srv
->next
)
4060 strchr(srv
->name
, '.') &&
4061 strchr(srv
->name
, '.') == strrchr(srv
->name
, '.'))
4063 strcpy(buff
, srv
->name
);
4065 strcat(buff
, daemon
->domain_suffix
);
4067 srv
->name
= opt_string_alloc(buff
);
4070 else if (option_bool(OPT_DHCP_FQDN
))
4071 die(_("there must be a default domain when --dhcp-fqdn is set"), NULL
, EC_BADCONF
);
4075 fprintf(stderr
, "dnsmasq: %s.\n", _("syntax check OK"));