]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/dnsmasq.c
Improve RFC-compliance when unable to supply addresses in DHCPv6
[people/ms/dnsmasq.git] / src / dnsmasq.c
CommitLineData
c47e3ba4 1/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
9e4abcb5
SK
2
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
824af85b
SK
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
9e4abcb5
SK
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.
824af85b 12
73a08a24
SK
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/>.
9e4abcb5
SK
15*/
16
c72daea8
SK
17/* Declare static char *compiler_opts in config.h */
18#define DNSMASQ_COMPILE_OPTS
19
9e4abcb5
SK
20#include "dnsmasq.h"
21
5aabfc78
SK
22struct daemon *daemon;
23
5aabfc78
SK
24static volatile pid_t pid = 0;
25static volatile int pipewrite;
9e4abcb5 26
5aabfc78
SK
27static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp);
28static void check_dns_listeners(fd_set *set, time_t now);
3be34541 29static void sig_handler(int sig);
5aabfc78 30static void async_event(int pipe, time_t now);
c72daea8
SK
31static void fatal_event(struct event_desc *ev, char *msg);
32static int read_event(int fd, struct event_desc *evp, char **msg);
47a95169 33static void poll_resolv(int force, int do_reload, time_t now);
9e4abcb5
SK
34
35int main (int argc, char **argv)
36{
de37951c 37 int bind_fallback = 0;
9009d746 38 time_t now;
9e4abcb5 39 struct sigaction sigact;
26128d27 40 struct iname *if_tmp;
1a6bca81
SK
41 int piperead, pipefd[2], err_pipe[2];
42 struct passwd *ent_pw = NULL;
c72daea8 43#if defined(HAVE_SCRIPT)
1a6bca81
SK
44 uid_t script_uid = 0;
45 gid_t script_gid = 0;
7622fc06
SK
46#endif
47 struct group *gp = NULL;
5aabfc78 48 long i, max_fd = sysconf(_SC_OPEN_MAX);
1a6bca81
SK
49 char *baduser = NULL;
50 int log_err;
51#if defined(HAVE_LINUX_NETWORK)
52 cap_user_header_t hdr = NULL;
53 cap_user_data_t data = NULL;
3b3f4411
SK
54 char *bound_device = NULL;
55 int did_bind = 0;
1a6bca81 56#endif
408c368f 57#if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
1f776932 58 struct dhcp_context *context;
ff7eea27 59 struct dhcp_relay *relay;
408c368f 60#endif
5aabfc78 61
824af85b 62#ifdef LOCALEDIR
b8187c80
SK
63 setlocale(LC_ALL, "");
64 bindtextdomain("dnsmasq", LOCALEDIR);
65 textdomain("dnsmasq");
66#endif
67
9e4abcb5
SK
68 sigact.sa_handler = sig_handler;
69 sigact.sa_flags = 0;
70 sigemptyset(&sigact.sa_mask);
71 sigaction(SIGUSR1, &sigact, NULL);
5aabfc78 72 sigaction(SIGUSR2, &sigact, NULL);
9e4abcb5
SK
73 sigaction(SIGHUP, &sigact, NULL);
74 sigaction(SIGTERM, &sigact, NULL);
44a2a316 75 sigaction(SIGALRM, &sigact, NULL);
feba5c1d
SK
76 sigaction(SIGCHLD, &sigact, NULL);
77
78 /* ignore SIGPIPE */
79 sigact.sa_handler = SIG_IGN;
80 sigaction(SIGPIPE, &sigact, NULL);
9e4abcb5 81
5aabfc78 82 umask(022); /* known umask, create leases and pid files as 0644 */
b5ea1cc2
SK
83
84 rand_init(); /* Must precede read_opts() */
85
5aabfc78 86 read_opts(argc, argv, compile_opts);
c3e0b9b6 87
3be34541 88 if (daemon->edns_pktsz < PACKETSZ)
60b68069
SK
89 daemon->edns_pktsz = PACKETSZ;
90#ifdef HAVE_DNSSEC
91 /* Enforce min packet big enough for DNSSEC */
92 if (option_bool(OPT_DNSSEC_VALID) && daemon->edns_pktsz < EDNS_PKTSZ)
93 daemon->edns_pktsz = EDNS_PKTSZ;
94#endif
3ddacb86 95
0a852541
SK
96 daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?
97 daemon->edns_pktsz : DNSMASQ_PACKETSZ;
98 daemon->packet = safe_malloc(daemon->packet_buff_sz);
3ddacb86 99
c72daea8 100 daemon->addrbuff = safe_malloc(ADDRSTRLEN);
3ddacb86
SK
101
102#ifdef HAVE_DNSSEC
103 if (option_bool(OPT_DNSSEC_VALID))
5107ace1
SK
104 {
105 daemon->keyname = safe_malloc(MAXDNAME);
106 daemon->workspacename = safe_malloc(MAXDNAME);
107 }
3ddacb86 108#endif
4f7b304f 109
7622fc06 110#ifdef HAVE_DHCP
3be34541 111 if (!daemon->lease_file)
9e4abcb5 112 {
52b92f4d 113 if (daemon->dhcp || daemon->dhcp6)
3be34541 114 daemon->lease_file = LEASEFILE;
9e4abcb5 115 }
7622fc06 116#endif
9e4abcb5 117
a2761754
SK
118 /* Close any file descriptors we inherited apart from std{in|out|err}
119
120 Ensure that at least stdin, stdout and stderr (fd 0, 1, 2) exist,
121 otherwise file descriptors we create can end up being 0, 1, or 2
122 and then get accidentally closed later when we make 0, 1, and 2
123 open to /dev/null. Normally we'll be started with 0, 1 and 2 open,
124 but it's not guaranteed. By opening /dev/null three times, we
125 ensure that we're not using those fds for real stuff. */
5aabfc78
SK
126 for (i = 0; i < max_fd; i++)
127 if (i != STDOUT_FILENO && i != STDERR_FILENO && i != STDIN_FILENO)
128 close(i);
a2761754
SK
129 else
130 open("/dev/null", O_RDWR);
5aabfc78 131
801ca9a7
SK
132#ifndef HAVE_LINUX_NETWORK
133# if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
28866e95 134 if (!option_bool(OPT_NOWILD))
de37951c
SK
135 {
136 bind_fallback = 1;
28866e95 137 set_option_bool(OPT_NOWILD);
de37951c 138 }
801ca9a7 139# endif
2b5bae9a
SK
140
141 /* -- bind-dynamic not supported on !Linux, fall back to --bind-interfaces */
54dd393f 142 if (option_bool(OPT_CLEVERBIND))
2b5bae9a
SK
143 {
144 bind_fallback = 1;
145 set_option_bool(OPT_NOWILD);
236e072c 146 reset_option_bool(OPT_CLEVERBIND);
2b5bae9a 147 }
309331f5 148#endif
2b5bae9a 149
0744ca66
SK
150 if (option_bool(OPT_DNSSEC_VALID))
151 {
3ddacb86 152#ifdef HAVE_DNSSEC
ee415867 153 if (!daemon->ds)
0744ca66
SK
154 die(_("No trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
155
156 if (daemon->cachesize < CACHESIZ)
157 die(_("Cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
158#else
159 die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
3ddacb86 160#endif
0744ca66 161 }
3ddacb86 162
832af0ba 163#ifndef HAVE_TFTP
9b40cbf5 164 if (option_bool(OPT_TFTP))
5aabfc78 165 die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
832af0ba
SK
166#endif
167
7de060b0
SK
168#ifdef HAVE_CONNTRACK
169 if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
170 die (_("Cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
171#else
172 if (option_bool(OPT_CONNTRACK))
173 die(_("Conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
174#endif
175
824af85b
SK
176#ifdef HAVE_SOLARIS_NETWORK
177 if (daemon->max_logs != 0)
178 die(_("asychronous logging is not available under Solaris"), NULL, EC_BADCONF);
179#endif
180
572b41eb
SK
181#ifdef __ANDROID__
182 if (daemon->max_logs != 0)
183 die(_("asychronous logging is not available under Android"), NULL, EC_BADCONF);
184#endif
185
4820dce9
SK
186#ifndef HAVE_AUTH
187 if (daemon->authserver)
188 die(_("authoritative DNS not available: set HAVE_AUTH in src/config.h"), NULL, EC_BADCONF);
189#endif
190
b5ea1cc2
SK
191#ifndef HAVE_LOOP
192 if (option_bool(OPT_LOOP_DETECT))
193 die(_("Loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
194#endif
1a6bca81 195
5aabfc78 196 now = dnsmasq_time();
4f7b304f 197
b0ff858e 198 /* Create a serial at startup if not configured. */
4f7b304f
SK
199 if (daemon->authinterface && daemon->soa_sn == 0)
200#ifdef HAVE_BROKEN_RTC
b0ff858e 201 die(_("zone serial must be configured in --auth-soa"), NULL, EC_BADCONF);
4f7b304f
SK
202#else
203 daemon->soa_sn = now;
204#endif
5aabfc78 205
ff7eea27
SK
206#ifdef HAVE_DHCP6
207 if (daemon->dhcp6)
208 {
209 daemon->doing_ra = option_bool(OPT_RA);
1f776932 210
ff7eea27 211 for (context = daemon->dhcp6; context; context = context->next)
1f776932 212 {
ff7eea27
SK
213 if (context->flags & CONTEXT_DHCP)
214 daemon->doing_dhcp6 = 1;
215 if (context->flags & CONTEXT_RA)
216 daemon->doing_ra = 1;
1ee9be4c 217#if !defined(HAVE_LINUX_NETWORK) && !defined(HAVE_BSD_NETWORK)
ff7eea27
SK
218 if (context->flags & CONTEXT_TEMPLATE)
219 die (_("dhcp-range constructor not available on this platform"), NULL, EC_BADCONF);
bb86e858 220#endif
1f776932 221 }
ff7eea27
SK
222 }
223#endif
224
225#ifdef HAVE_DHCP
226 /* Note that order matters here, we must call lease_init before
227 creating any file descriptors which shouldn't be leaked
228 to the lease-script init process. We need to call common_init
229 before lease_init to allocate buffers it uses.*/
230 if (daemon->dhcp || daemon->doing_dhcp6 || daemon->relay4 || daemon->relay6)
231 {
232 dhcp_common_init();
1f776932 233 if (daemon->dhcp || daemon->doing_dhcp6)
ff7eea27
SK
234 lease_init(now);
235 }
236
237 if (daemon->dhcp || daemon->relay4)
238 dhcp_init();
239
843c96b4 240# ifdef HAVE_DHCP6
89500e31 241 if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6)
ff7eea27
SK
242 ra_init(now);
243
244 if (daemon->doing_dhcp6 || daemon->relay6)
245 dhcp6_init();
801ca9a7
SK
246# endif
247
248#endif
249
13d86c73
JD
250#ifdef HAVE_IPSET
251 if (daemon->ipsets)
252 ipset_init();
253#endif
254
1ee9be4c 255#if defined(HAVE_LINUX_NETWORK)
801ca9a7 256 netlink_init();
1ee9be4c
SK
257#elif defined(HAVE_BSD_NETWORK)
258 route_init();
801ca9a7
SK
259#endif
260
1ee9be4c
SK
261 if (option_bool(OPT_NOWILD) && option_bool(OPT_CLEVERBIND))
262 die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF);
263
115ac3e4 264 if (!enumerate_interfaces(1) || !enumerate_interfaces(0))
5aabfc78 265 die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
843c96b4 266
54dd393f 267 if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
de37951c 268 {
74c95c25 269 create_bound_listeners(1);
54dd393f
SK
270
271 if (!option_bool(OPT_CLEVERBIND))
272 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
273 if (if_tmp->name && !if_tmp->used)
274 die(_("unknown interface %s"), if_tmp->name, EC_BADNET);
9380ba70
SK
275
276#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
277 /* after enumerate_interfaces() */
3b3f4411
SK
278 bound_device = whichdevice();
279
9380ba70
SK
280 if (daemon->dhcp)
281 {
3b3f4411
SK
282 if (!daemon->relay4 && bound_device)
283 {
284 bindtodevice(bound_device, daemon->dhcpfd);
285 did_bind = 1;
286 }
287 if (daemon->enable_pxe && bound_device)
288 {
289 bindtodevice(bound_device, daemon->pxefd);
290 did_bind = 1;
291 }
9380ba70
SK
292 }
293#endif
294
295#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
3b3f4411
SK
296 if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)
297 {
298 bindtodevice(bound_device, daemon->dhcp6fd);
299 did_bind = 1;
300 }
9380ba70 301#endif
de37951c 302 }
28866e95 303 else
74c95c25 304 create_wildcard_listeners();
5d162f20
SK
305
306#ifdef HAVE_DHCP6
307 /* after enumerate_interfaces() */
ff7eea27 308 if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
5d162f20 309 join_multicast(1);
3511a928
SK
310
311 /* After netlink_init() and before create_helper() */
312 lease_make_duid(now);
5d162f20 313#endif
de37951c 314
824af85b 315 if (daemon->port != 0)
82e3f45a
SK
316 {
317 cache_init();
318#ifdef HAVE_DNSSEC
319 blockdata_init();
320#endif
321 }
1a6bca81 322
28866e95 323 if (option_bool(OPT_DBUS))
3d8df260
SK
324#ifdef HAVE_DBUS
325 {
326 char *err;
327 daemon->dbus = NULL;
328 daemon->watches = NULL;
5aabfc78
SK
329 if ((err = dbus_init()))
330 die(_("DBus error: %s"), err, EC_MISC);
3d8df260
SK
331 }
332#else
5aabfc78 333 die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
3d8df260
SK
334#endif
335
824af85b
SK
336 if (daemon->port != 0)
337 pre_allocate_sfds();
1a6bca81 338
c72daea8 339#if defined(HAVE_SCRIPT)
1a6bca81 340 /* Note getpwnam returns static storage */
843c96b4
SK
341 if ((daemon->dhcp || daemon->dhcp6) &&
342 daemon->scriptuser &&
c72daea8 343 (daemon->lease_change_command || daemon->luascript))
1a6bca81
SK
344 {
345 if ((ent_pw = getpwnam(daemon->scriptuser)))
346 {
347 script_uid = ent_pw->pw_uid;
348 script_gid = ent_pw->pw_gid;
349 }
350 else
351 baduser = daemon->scriptuser;
352 }
7622fc06 353#endif
9e4abcb5 354
1a6bca81
SK
355 if (daemon->username && !(ent_pw = getpwnam(daemon->username)))
356 baduser = daemon->username;
357 else if (daemon->groupname && !(gp = getgrnam(daemon->groupname)))
358 baduser = daemon->groupname;
359
360 if (baduser)
361 die(_("unknown user or group: %s"), baduser, EC_BADCONF);
362
363 /* implement group defaults, "dip" if available, or group associated with uid */
364 if (!daemon->group_set && !gp)
365 {
366 if (!(gp = getgrnam(CHGRP)) && ent_pw)
367 gp = getgrgid(ent_pw->pw_gid);
368
369 /* for error message */
370 if (gp)
371 daemon->groupname = gp->gr_name;
372 }
373
374#if defined(HAVE_LINUX_NETWORK)
375 /* determine capability API version here, while we can still
376 call safe_malloc */
377 if (ent_pw && ent_pw->pw_uid != 0)
378 {
1a6bca81 379 int capsize = 1; /* for header version 1 */
3927da46
SK
380 hdr = safe_malloc(sizeof(*hdr));
381
1a6bca81
SK
382 /* find version supported by kernel */
383 memset(hdr, 0, sizeof(*hdr));
384 capget(hdr, NULL);
385
386 if (hdr->version != LINUX_CAPABILITY_VERSION_1)
387 {
388 /* if unknown version, use largest supported version (3) */
389 if (hdr->version != LINUX_CAPABILITY_VERSION_2)
390 hdr->version = LINUX_CAPABILITY_VERSION_3;
391 capsize = 2;
392 }
393
394 data = safe_malloc(sizeof(*data) * capsize);
395 memset(data, 0, sizeof(*data) * capsize);
396 }
397#endif
398
5aabfc78 399 /* Use a pipe to carry signals and other events back to the event loop
1a6bca81
SK
400 in a race-free manner and another to carry errors to daemon-invoking process */
401 safe_pipe(pipefd, 1);
5e9e0efb
SK
402
403 piperead = pipefd[0];
404 pipewrite = pipefd[1];
405 /* prime the pipe to load stuff first time. */
e98bd52e 406 send_event(pipewrite, EVENT_INIT, 0, NULL);
1a6bca81
SK
407
408 err_pipe[1] = -1;
1697269c 409
28866e95 410 if (!option_bool(OPT_DEBUG))
9e4abcb5 411 {
9e4abcb5
SK
412 /* The following code "daemonizes" the process.
413 See Stevens section 12.4 */
1a6bca81 414
9e038946
SK
415 if (chdir("/") != 0)
416 die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC);
417
1697269c 418#ifndef NO_FORK
28866e95 419 if (!option_bool(OPT_NO_FORK))
3be34541 420 {
5aabfc78 421 pid_t pid;
3be34541 422
1a6bca81
SK
423 /* pipe to carry errors back to original process.
424 When startup is complete we close this and the process terminates. */
425 safe_pipe(err_pipe, 0);
426
7622fc06
SK
427 if ((pid = fork()) == -1)
428 /* fd == -1 since we've not forked, never returns. */
c72daea8 429 send_event(-1, EVENT_FORK_ERR, errno, NULL);
9e038946 430
5aabfc78 431 if (pid != 0)
1a6bca81
SK
432 {
433 struct event_desc ev;
c72daea8
SK
434 char *msg;
435
1a6bca81
SK
436 /* close our copy of write-end */
437 close(err_pipe[1]);
438
439 /* check for errors after the fork */
c72daea8
SK
440 if (read_event(err_pipe[0], &ev, &msg))
441 fatal_event(&ev, msg);
1a6bca81
SK
442
443 _exit(EC_GOOD);
444 }
445
446 close(err_pipe[0]);
447
448 /* NO calls to die() from here on. */
3be34541 449
5aabfc78 450 setsid();
7622fc06
SK
451
452 if ((pid = fork()) == -1)
c72daea8 453 send_event(err_pipe[1], EVENT_FORK_ERR, errno, NULL);
7622fc06
SK
454
455 if (pid != 0)
7cebd20f 456 _exit(0);
3be34541 457 }
9e4abcb5 458#endif
9e038946 459
9e4abcb5 460 /* write pidfile _after_ forking ! */
1a6bca81
SK
461 if (daemon->runfile)
462 {
79cfefd8
SK
463 int fd, err = 0;
464
465 sprintf(daemon->namebuff, "%d\n", (int) getpid());
466
467 /* Explanation: Some installations of dnsmasq (eg Debian/Ubuntu) locate the pid-file
468 in a directory which is writable by the non-privileged user that dnsmasq runs as. This
469 allows the daemon to delete the file as part of its shutdown. This is a security hole to the
470 extent that an attacker running as the unprivileged user could replace the pidfile with a
471 symlink, and have the target of that symlink overwritten as root next time dnsmasq starts.
472
473 The folowing code first deletes any existing file, and then opens it with the O_EXCL flag,
474 ensuring that the open() fails should there be any existing file (because the unlink() failed,
475 or an attacker exploited the race between unlink() and open()). This ensures that no symlink
476 attack can succeed.
477
478 Any compromise of the non-privileged user still theoretically allows the pid-file to be
479 replaced whilst dnsmasq is running. The worst that could allow is that the usual
480 "shutdown dnsmasq" shell command could be tricked into stopping any other process.
481
482 Note that if dnsmasq is started as non-root (eg for testing) it silently ignores
483 failure to write the pid-file.
484 */
485
486 unlink(daemon->runfile);
1a6bca81 487
79cfefd8 488 if ((fd = open(daemon->runfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1)
1a6bca81 489 {
79cfefd8
SK
490 /* only complain if started as root */
491 if (getuid() == 0)
492 err = 1;
1a6bca81 493 }
79cfefd8
SK
494 else
495 {
496 if (!read_write(fd, (unsigned char *)daemon->namebuff, strlen(daemon->namebuff), 0))
497 err = 1;
498
499 while (!err && close(fd) == -1)
500 if (!retry_send())
501 err = 1;
502 }
503
504 if (err)
1a6bca81 505 {
c72daea8 506 send_event(err_pipe[1], EVENT_PIDFILE, errno, daemon->runfile);
1a6bca81
SK
507 _exit(0);
508 }
9e4abcb5 509 }
1697269c
SK
510 }
511
8ef5ada2
SK
512 log_err = log_start(ent_pw, err_pipe[1]);
513
28866e95 514 if (!option_bool(OPT_DEBUG))
8ef5ada2
SK
515 {
516 /* open stdout etc to /dev/null */
517 int nullfd = open("/dev/null", O_RDWR);
518 dup2(nullfd, STDOUT_FILENO);
519 dup2(nullfd, STDERR_FILENO);
520 dup2(nullfd, STDIN_FILENO);
521 close(nullfd);
522 }
1a6bca81
SK
523
524 /* if we are to run scripts, we need to fork a helper before dropping root. */
525 daemon->helperfd = -1;
c72daea8 526#ifdef HAVE_SCRIPT
52b92f4d 527 if ((daemon->dhcp || daemon->dhcp6) && (daemon->lease_change_command || daemon->luascript))
1a6bca81 528 daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
5aabfc78 529#endif
5aabfc78 530
28866e95 531 if (!option_bool(OPT_DEBUG) && getuid() == 0)
1697269c 532 {
1a6bca81
SK
533 int bad_capabilities = 0;
534 gid_t dummy;
535
536 /* remove all supplimentary groups */
537 if (gp &&
538 (setgroups(0, &dummy) == -1 ||
539 setgid(gp->gr_gid) == -1))
9e4abcb5 540 {
c72daea8 541 send_event(err_pipe[1], EVENT_GROUP_ERR, errno, daemon->groupname);
1a6bca81 542 _exit(0);
7cebd20f 543 }
1a6bca81 544
7cebd20f 545 if (ent_pw && ent_pw->pw_uid != 0)
1697269c 546 {
74c95c25 547#if defined(HAVE_LINUX_NETWORK)
1697269c 548 /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
74c95c25 549 CAP_NET_RAW (for icmp) if we're doing dhcp. If we have yet to bind
54dd393f
SK
550 ports because of DAD, or we're doing it dynamically,
551 we need CAP_NET_BIND_SERVICE too. */
552 if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
74c95c25
SK
553 data->effective = data->permitted = data->inheritable =
554 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) |
555 (1 << CAP_SETUID) | (1 << CAP_NET_BIND_SERVICE);
556 else
557 data->effective = data->permitted = data->inheritable =
558 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID);
5e9e0efb 559
1697269c 560 /* Tell kernel to not clear capabilities when dropping root */
572b41eb 561 if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
1697269c 562 bad_capabilities = errno;
1a6bca81 563
7622fc06 564#elif defined(HAVE_SOLARIS_NETWORK)
824af85b
SK
565 /* http://developers.sun.com/solaris/articles/program_privileges.html */
566 priv_set_t *priv_set;
567
568 if (!(priv_set = priv_str_to_set("basic", ",", NULL)) ||
569 priv_addset(priv_set, PRIV_NET_ICMPACCESS) == -1 ||
570 priv_addset(priv_set, PRIV_SYS_NET_CONFIG) == -1)
571 bad_capabilities = errno;
572
573 if (priv_set && bad_capabilities == 0)
574 {
575 priv_inverse(priv_set);
576
577 if (setppriv(PRIV_OFF, PRIV_LIMIT, priv_set) == -1)
578 bad_capabilities = errno;
579 }
580
581 if (priv_set)
582 priv_freeset(priv_set);
583
824af85b
SK
584#endif
585
1a6bca81 586 if (bad_capabilities != 0)
1697269c 587 {
c72daea8 588 send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities, NULL);
1a6bca81
SK
589 _exit(0);
590 }
591
592 /* finally drop root */
593 if (setuid(ent_pw->pw_uid) == -1)
594 {
c72daea8 595 send_event(err_pipe[1], EVENT_USER_ERR, errno, daemon->username);
1a6bca81
SK
596 _exit(0);
597 }
598
1697269c 599#ifdef HAVE_LINUX_NETWORK
54dd393f 600 if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
74c95c25
SK
601 data->effective = data->permitted =
602 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_NET_BIND_SERVICE);
603 else
604 data->effective = data->permitted =
605 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
1a6bca81
SK
606 data->inheritable = 0;
607
608 /* lose the setuid and setgid capbilities */
609 if (capset(hdr, data) == -1)
610 {
c72daea8 611 send_event(err_pipe[1], EVENT_CAP_ERR, errno, NULL);
1a6bca81 612 _exit(0);
1697269c 613 }
1a6bca81
SK
614#endif
615
9e4abcb5
SK
616 }
617 }
1697269c 618
1697269c 619#ifdef HAVE_LINUX_NETWORK
28866e95 620 if (option_bool(OPT_DEBUG))
572b41eb 621 prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
1697269c 622#endif
9e4abcb5 623
8b3ae2fd 624#ifdef HAVE_TFTP
8bc4cece 625 if (option_bool(OPT_TFTP))
8b3ae2fd
SK
626 {
627 DIR *dir;
628 struct tftp_prefix *p;
629
630 if (daemon->tftp_prefix)
631 {
632 if (!((dir = opendir(daemon->tftp_prefix))))
633 {
634 send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix);
635 _exit(0);
636 }
637 closedir(dir);
638 }
639
640 for (p = daemon->if_prefix; p; p = p->next)
641 {
642 if (!((dir = opendir(p->prefix))))
643 {
644 send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix);
645 _exit(0);
646 }
647 closedir(dir);
648 }
649 }
650#endif
651
824af85b
SK
652 if (daemon->port == 0)
653 my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
654 else if (daemon->cachesize != 0)
f2621c7f 655 my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
9e4abcb5 656 else
f2621c7f 657 my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
1697269c 658
f2621c7f 659 my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
1697269c 660
3d8df260 661#ifdef HAVE_DBUS
28866e95 662 if (option_bool(OPT_DBUS))
3d8df260
SK
663 {
664 if (daemon->dbus)
f2621c7f 665 my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
3d8df260 666 else
f2621c7f 667 my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
3d8df260
SK
668 }
669#endif
1a9a3489
SK
670
671 if (option_bool(OPT_LOCAL_SERVICE))
672 my_syslog(LOG_INFO, _("DNS service limited to local subnets"));
db737466 673
1d97ac4f 674#ifdef HAVE_DNSSEC
db737466 675 if (option_bool(OPT_DNSSEC_VALID))
e98bd52e
SK
676 {
677 my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
678 if (option_bool(OPT_DNSSEC_TIME))
679 my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
680 }
db737466 681#endif
3d8df260 682
1a6bca81
SK
683 if (log_err != 0)
684 my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
685 daemon->log_file, strerror(log_err));
db737466 686
de37951c 687 if (bind_fallback)
f2621c7f 688 my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
dc27e148 689
f7029f5c
SK
690 if (option_bool(OPT_NOWILD))
691 warn_bound_listeners();
692
693 warn_int_names();
de37951c 694
28866e95 695 if (!option_bool(OPT_NOWILD))
26128d27
SK
696 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
697 if (if_tmp->name && !if_tmp->used)
f2621c7f 698 my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
5e9e0efb 699
28866e95 700 if (daemon->port != 0 && option_bool(OPT_NO_RESOLV))
208b65c5
SK
701 {
702 if (daemon->resolv_files && !daemon->resolv_files->is_default)
f2621c7f 703 my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
208b65c5 704 daemon->resolv_files = NULL;
1b7ecd11 705 if (!daemon->servers)
f2621c7f 706 my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
208b65c5
SK
707 }
708
f2621c7f
SK
709 if (daemon->max_logs != 0)
710 my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
1f776932 711
f2621c7f 712
7622fc06 713#ifdef HAVE_DHCP
1f776932
SK
714 for (context = daemon->dhcp; context; context = context->next)
715 log_context(AF_INET, context);
52b92f4d 716
ff7eea27
SK
717 for (relay = daemon->relay4; relay; relay = relay->next)
718 log_relay(AF_INET, relay);
719
1f776932
SK
720# ifdef HAVE_DHCP6
721 for (context = daemon->dhcp6; context; context = context->next)
722 log_context(AF_INET6, context);
723
ff7eea27
SK
724 for (relay = daemon->relay6; relay; relay = relay->next)
725 log_relay(AF_INET6, relay);
726
1f776932
SK
727 if (daemon->doing_dhcp6 || daemon->doing_ra)
728 dhcp_construct_contexts(now);
729
730 if (option_bool(OPT_RA))
731 my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
732# endif
26128d27 733
3b3f4411
SK
734# ifdef HAVE_LINUX_NETWORK
735 if (did_bind)
736 my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
737# endif
738
8445f5d2
SK
739 /* after dhcp_contruct_contexts */
740 if (daemon->dhcp || daemon->doing_dhcp6)
741 lease_find_interfaces(now);
1f776932 742#endif
52b92f4d 743
832af0ba 744#ifdef HAVE_TFTP
8bc4cece 745 if (option_bool(OPT_TFTP))
832af0ba 746 {
832af0ba 747#ifdef FD_SETSIZE
5aabfc78 748 if (FD_SETSIZE < (unsigned)max_fd)
832af0ba
SK
749 max_fd = FD_SETSIZE;
750#endif
751
7622fc06 752 my_syslog(MS_TFTP | LOG_INFO, "TFTP %s%s %s",
f2621c7f
SK
753 daemon->tftp_prefix ? _("root is ") : _("enabled"),
754 daemon->tftp_prefix ? daemon->tftp_prefix: "",
28866e95 755 option_bool(OPT_TFTP_SECURE) ? _("secure mode") : "");
f2621c7f 756
832af0ba 757 /* This is a guess, it assumes that for small limits,
f2621c7f 758 disjoint files might be served, but for large limits,
832af0ba
SK
759 a single file will be sent to may clients (the file only needs
760 one fd). */
761
762 max_fd -= 30; /* use other than TFTP */
763
764 if (max_fd < 0)
765 max_fd = 5;
766 else if (max_fd < 100)
767 max_fd = max_fd/2;
768 else
769 max_fd = max_fd - 20;
824af85b
SK
770
771 /* if we have to use a limited range of ports,
772 that will limit the number of transfers */
773 if (daemon->start_tftp_port != 0 &&
774 daemon->end_tftp_port - daemon->start_tftp_port + 1 < max_fd)
775 max_fd = daemon->end_tftp_port - daemon->start_tftp_port + 1;
832af0ba
SK
776
777 if (daemon->tftp_max > max_fd)
778 {
779 daemon->tftp_max = max_fd;
7622fc06 780 my_syslog(MS_TFTP | LOG_WARNING,
f2621c7f
SK
781 _("restricting maximum simultaneous TFTP transfers to %d"),
782 daemon->tftp_max);
832af0ba
SK
783 }
784 }
785#endif
786
1a6bca81
SK
787 /* finished start-up - release original process */
788 if (err_pipe[1] != -1)
789 close(err_pipe[1]);
9e4abcb5 790
824af85b
SK
791 if (daemon->port != 0)
792 check_servers();
793
7cebd20f
SK
794 pid = getpid();
795
5e9e0efb 796 while (1)
9e4abcb5 797 {
1697269c 798 int maxfd = -1;
5e9e0efb 799 struct timeval t, *tp = NULL;
3d8df260 800 fd_set rset, wset, eset;
9e4abcb5
SK
801
802 FD_ZERO(&rset);
3d8df260
SK
803 FD_ZERO(&wset);
804 FD_ZERO(&eset);
9e4abcb5 805
1697269c
SK
806 /* if we are out of resources, find how long we have to wait
807 for some to come free, we'll loop around then and restart
808 listening for queries */
5aabfc78 809 if ((t.tv_sec = set_dns_listeners(now, &rset, &maxfd)) != 0)
1697269c
SK
810 {
811 t.tv_usec = 0;
812 tp = &t;
813 }
814
832af0ba
SK
815 /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
816 if (daemon->tftp_trans ||
28866e95 817 (option_bool(OPT_DBUS) && !daemon->dbus))
5e9e0efb 818 {
1697269c
SK
819 t.tv_sec = 0;
820 t.tv_usec = 250000;
5e9e0efb 821 tp = &t;
5e9e0efb 822 }
74c95c25
SK
823 /* Wake every second whilst waiting for DAD to complete */
824 else if (is_dad_listeners())
825 {
826 t.tv_sec = 1;
827 t.tv_usec = 0;
828 tp = &t;
829 }
44a2a316 830
832af0ba 831#ifdef HAVE_DBUS
5aabfc78 832 set_dbus_listeners(&maxfd, &rset, &wset, &eset);
5e9e0efb
SK
833#endif
834
7622fc06 835#ifdef HAVE_DHCP
ff7eea27 836 if (daemon->dhcp || daemon->relay4)
5e9e0efb
SK
837 {
838 FD_SET(daemon->dhcpfd, &rset);
1697269c 839 bump_maxfd(daemon->dhcpfd, &maxfd);
316e2730
SK
840 if (daemon->pxefd != -1)
841 {
842 FD_SET(daemon->pxefd, &rset);
843 bump_maxfd(daemon->pxefd, &maxfd);
844 }
5e9e0efb 845 }
7622fc06 846#endif
cdeda28f 847
52b92f4d 848#ifdef HAVE_DHCP6
ff7eea27 849 if (daemon->doing_dhcp6 || daemon->relay6)
52b92f4d
SK
850 {
851 FD_SET(daemon->dhcp6fd, &rset);
c5ad4e79 852 bump_maxfd(daemon->dhcp6fd, &maxfd);
5d71d834
SK
853 }
854
1f776932 855 if (daemon->doing_ra)
5d71d834
SK
856 {
857 FD_SET(daemon->icmp6fd, &rset);
858 bump_maxfd(daemon->icmp6fd, &maxfd);
52b92f4d
SK
859 }
860#endif
861
1ee9be4c 862#if defined(HAVE_LINUX_NETWORK)
5e9e0efb 863 FD_SET(daemon->netlinkfd, &rset);
1697269c 864 bump_maxfd(daemon->netlinkfd, &maxfd);
1ee9be4c
SK
865#elif defined(HAVE_BSD_NETWORK)
866 FD_SET(daemon->routefd, &rset);
867 bump_maxfd(daemon->routefd, &maxfd);
3d8df260 868#endif
1ee9be4c 869
5e9e0efb 870 FD_SET(piperead, &rset);
1697269c
SK
871 bump_maxfd(piperead, &maxfd);
872
7622fc06 873#ifdef HAVE_DHCP
1f15b81d 874# ifdef HAVE_SCRIPT
5aabfc78 875 while (helper_buf_empty() && do_script_run(now));
1697269c 876
a9530964
SK
877# ifdef HAVE_TFTP
878 while (helper_buf_empty() && do_tftp_script_run());
879# endif
880
1697269c
SK
881 if (!helper_buf_empty())
882 {
883 FD_SET(daemon->helperfd, &wset);
884 bump_maxfd(daemon->helperfd, &maxfd);
885 }
7622fc06 886# else
5aabfc78
SK
887 /* need this for other side-effects */
888 while (do_script_run(now));
a9530964
SK
889
890# ifdef HAVE_TFTP
891 while (do_tftp_script_run());
892# endif
893
7622fc06 894# endif
5aabfc78 895#endif
7622fc06 896
f2621c7f
SK
897 /* must do this just before select(), when we know no
898 more calls to my_syslog() can occur */
899 set_log_writer(&wset, &maxfd);
900
5e9e0efb
SK
901 if (select(maxfd+1, &rset, &wset, &eset, tp) < 0)
902 {
903 /* otherwise undefined after error */
904 FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset);
905 }
906
907 now = dnsmasq_time();
9e4abcb5 908
f2621c7f 909 check_log_writer(&wset);
115ac3e4
SK
910
911 /* prime. */
912 enumerate_interfaces(1);
913
74c95c25
SK
914 /* Check the interfaces to see if any have exited DAD state
915 and if so, bind the address. */
916 if (is_dad_listeners())
917 {
115ac3e4 918 enumerate_interfaces(0);
74c95c25
SK
919 /* NB, is_dad_listeners() == 1 --> we're binding interfaces */
920 create_bound_listeners(0);
dc27e148 921 warn_bound_listeners();
74c95c25 922 }
f2621c7f 923
1ee9be4c 924#if defined(HAVE_LINUX_NETWORK)
c52e1897 925 if (FD_ISSET(daemon->netlinkfd, &rset))
a0358e5d 926 netlink_multicast();
1ee9be4c
SK
927#elif defined(HAVE_BSD_NETWORK)
928 if (FD_ISSET(daemon->routefd, &rset))
a0358e5d 929 route_sock();
c52e1897
SK
930#endif
931
9e4abcb5 932 /* Check for changes to resolv files once per second max. */
3d8df260 933 /* Don't go silent for long periods if the clock goes backwards. */
9009d746
SK
934 if (daemon->last_resolv == 0 ||
935 difftime(now, daemon->last_resolv) > 1.0 ||
936 difftime(now, daemon->last_resolv) < -1.0)
9e4abcb5 937 {
8ef5ada2
SK
938 /* poll_resolv doesn't need to reload first time through, since
939 that's queued anyway. */
33820b7e 940
8ef5ada2
SK
941 poll_resolv(0, daemon->last_resolv != 0, now);
942 daemon->last_resolv = now;
9e4abcb5 943 }
5aabfc78 944
5e9e0efb 945 if (FD_ISSET(piperead, &rset))
5aabfc78 946 async_event(piperead, now);
7cebd20f 947
3d8df260
SK
948#ifdef HAVE_DBUS
949 /* if we didn't create a DBus connection, retry now. */
28866e95 950 if (option_bool(OPT_DBUS) && !daemon->dbus)
3d8df260
SK
951 {
952 char *err;
5aabfc78 953 if ((err = dbus_init()))
f2621c7f 954 my_syslog(LOG_WARNING, _("DBus error: %s"), err);
3d8df260 955 if (daemon->dbus)
f2621c7f 956 my_syslog(LOG_INFO, _("connected to system DBus"));
3d8df260 957 }
5aabfc78 958 check_dbus_listeners(&rset, &wset, &eset);
3d8df260 959#endif
824af85b 960
5aabfc78 961 check_dns_listeners(&rset, now);
832af0ba
SK
962
963#ifdef HAVE_TFTP
5aabfc78 964 check_tftp_listeners(&rset, now);
832af0ba
SK
965#endif
966
7622fc06 967#ifdef HAVE_DHCP
ff7eea27 968 if (daemon->dhcp || daemon->relay4)
316e2730
SK
969 {
970 if (FD_ISSET(daemon->dhcpfd, &rset))
971 dhcp_packet(now, 0);
972 if (daemon->pxefd != -1 && FD_ISSET(daemon->pxefd, &rset))
973 dhcp_packet(now, 1);
974 }
1697269c 975
52b92f4d 976#ifdef HAVE_DHCP6
ff7eea27 977 if ((daemon->doing_dhcp6 || daemon->relay6) && FD_ISSET(daemon->dhcp6fd, &rset))
18c63eff 978 dhcp6_packet(now);
c5ad4e79 979
1f776932
SK
980 if (daemon->doing_ra && FD_ISSET(daemon->icmp6fd, &rset))
981 icmp6_packet(now);
52b92f4d
SK
982#endif
983
1f15b81d 984# ifdef HAVE_SCRIPT
1697269c 985 if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset))
5aabfc78 986 helper_write();
7622fc06 987# endif
5aabfc78
SK
988#endif
989
9e4abcb5 990 }
9e4abcb5
SK
991}
992
3be34541
SK
993static void sig_handler(int sig)
994{
5e9e0efb 995 if (pid == 0)
3be34541 996 {
1697269c
SK
997 /* ignore anything other than TERM during startup
998 and in helper proc. (helper ignore TERM too) */
5e9e0efb 999 if (sig == SIGTERM)
5aabfc78 1000 exit(EC_MISC);
3be34541 1001 }
5aabfc78 1002 else if (pid != getpid())
5e9e0efb 1003 {
1697269c 1004 /* alarm is used to kill TCP children after a fixed time. */
5e9e0efb 1005 if (sig == SIGALRM)
7cebd20f 1006 _exit(0);
3be34541 1007 }
5aabfc78
SK
1008 else
1009 {
1010 /* master process */
1011 int event, errsave = errno;
1012
1013 if (sig == SIGHUP)
1014 event = EVENT_RELOAD;
1015 else if (sig == SIGCHLD)
1016 event = EVENT_CHILD;
1017 else if (sig == SIGALRM)
1018 event = EVENT_ALARM;
1019 else if (sig == SIGTERM)
1020 event = EVENT_TERM;
1021 else if (sig == SIGUSR1)
1022 event = EVENT_DUMP;
1023 else if (sig == SIGUSR2)
1024 event = EVENT_REOPEN;
1025 else
1026 return;
1027
c72daea8 1028 send_event(pipewrite, event, 0, NULL);
5aabfc78
SK
1029 errno = errsave;
1030 }
1031}
1032
353ae4d2
SK
1033/* now == 0 -> queue immediate callback */
1034void send_alarm(time_t event, time_t now)
741c2952 1035{
884a6dfe 1036 if (now == 0 || event != 0)
353ae4d2 1037 {
884a6dfe
SK
1038 /* alarm(0) or alarm(-ve) doesn't do what we want.... */
1039 if ((now == 0 || difftime(event, now) <= 0.0))
1040 send_event(pipewrite, EVENT_ALARM, 0, NULL);
1041 else
1042 alarm((unsigned)difftime(event, now));
353ae4d2 1043 }
741c2952
SK
1044}
1045
47a95169 1046void queue_event(int event)
a0358e5d 1047{
47a95169 1048 send_event(pipewrite, event, 0, NULL);
a0358e5d
SK
1049}
1050
c72daea8 1051void send_event(int fd, int event, int data, char *msg)
5aabfc78
SK
1052{
1053 struct event_desc ev;
c72daea8
SK
1054 struct iovec iov[2];
1055
5aabfc78
SK
1056 ev.event = event;
1057 ev.data = data;
c72daea8
SK
1058 ev.msg_sz = msg ? strlen(msg) : 0;
1059
1060 iov[0].iov_base = &ev;
1061 iov[0].iov_len = sizeof(ev);
1062 iov[1].iov_base = msg;
1063 iov[1].iov_len = ev.msg_sz;
1a6bca81
SK
1064
1065 /* error pipe, debug mode. */
1066 if (fd == -1)
c72daea8 1067 fatal_event(&ev, msg);
1a6bca81
SK
1068 else
1069 /* pipe is non-blocking and struct event_desc is smaller than
1070 PIPE_BUF, so this either fails or writes everything */
c72daea8 1071 while (writev(fd, iov, msg ? 2 : 1) == -1 && errno == EINTR);
5aabfc78
SK
1072}
1073
c72daea8
SK
1074/* NOTE: the memory used to return msg is leaked: use msgs in events only
1075 to describe fatal errors. */
1076static int read_event(int fd, struct event_desc *evp, char **msg)
1077{
1078 char *buf;
1079
1080 if (!read_write(fd, (unsigned char *)evp, sizeof(struct event_desc), 1))
1081 return 0;
1082
1083 *msg = NULL;
1084
1085 if (evp->msg_sz != 0 &&
1086 (buf = malloc(evp->msg_sz + 1)) &&
1087 read_write(fd, (unsigned char *)buf, evp->msg_sz, 1))
1088 {
1089 buf[evp->msg_sz] = 0;
1090 *msg = buf;
1091 }
1092
1093 return 1;
1094}
1095
1096static void fatal_event(struct event_desc *ev, char *msg)
1a6bca81
SK
1097{
1098 errno = ev->data;
1099
1100 switch (ev->event)
1101 {
1102 case EVENT_DIE:
1103 exit(0);
7622fc06
SK
1104
1105 case EVENT_FORK_ERR:
1106 die(_("cannot fork into background: %s"), NULL, EC_MISC);
1a6bca81
SK
1107
1108 case EVENT_PIPE_ERR:
1109 die(_("failed to create helper: %s"), NULL, EC_MISC);
1110
1111 case EVENT_CAP_ERR:
1112 die(_("setting capabilities failed: %s"), NULL, EC_MISC);
1113
1114 case EVENT_USER_ERR:
c72daea8 1115 die(_("failed to change user-id to %s: %s"), msg, EC_MISC);
1a6bca81
SK
1116
1117 case EVENT_GROUP_ERR:
c72daea8 1118 die(_("failed to change group-id to %s: %s"), msg, EC_MISC);
1a6bca81
SK
1119
1120 case EVENT_PIDFILE:
c72daea8 1121 die(_("failed to open pidfile %s: %s"), msg, EC_FILE);
1a6bca81
SK
1122
1123 case EVENT_LOG_ERR:
c72daea8
SK
1124 die(_("cannot open log %s: %s"), msg, EC_FILE);
1125
1126 case EVENT_LUA_ERR:
1127 die(_("failed to load Lua script: %s"), msg, EC_MISC);
8b3ae2fd
SK
1128
1129 case EVENT_TFTP_ERR:
1130 die(_("TFTP directory %s inaccessible: %s"), msg, EC_FILE);
1a6bca81
SK
1131 }
1132}
1133
5aabfc78
SK
1134static void async_event(int pipe, time_t now)
1135{
1136 pid_t p;
1137 struct event_desc ev;
7b1eae4f 1138 int i, check = 0;
c72daea8
SK
1139 char *msg;
1140
1141 /* NOTE: the memory used to return msg is leaked: use msgs in events only
1142 to describe fatal errors. */
1143
1144 if (read_event(pipe, &ev, &msg))
5aabfc78
SK
1145 switch (ev.event)
1146 {
1147 case EVENT_RELOAD:
e98bd52e
SK
1148#ifdef HAVE_DNSSEC
1149 if (option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
1150 {
1151 my_syslog(LOG_INFO, _("now checking DNSSEC signature timestamps"));
1152 reset_option_bool(OPT_DNSSEC_TIME);
1153 }
1154#endif
1155 /* fall through */
1156
1157 case EVENT_INIT:
5aabfc78 1158 clear_cache_and_reload(now);
e98bd52e 1159
7b1eae4f 1160 if (daemon->port != 0)
5aabfc78 1161 {
7b1eae4f
SK
1162 if (daemon->resolv_files && option_bool(OPT_NO_POLL))
1163 {
1164 reload_servers(daemon->resolv_files->name);
1165 check = 1;
1166 }
1167
1168 if (daemon->servers_file)
1169 {
1170 read_servers_file();
1171 check = 1;
1172 }
1173
1174 if (check)
1175 check_servers();
5aabfc78 1176 }
7b1eae4f 1177
7622fc06 1178#ifdef HAVE_DHCP
5aabfc78 1179 rerun_scripts();
7622fc06 1180#endif
5aabfc78
SK
1181 break;
1182
1183 case EVENT_DUMP:
824af85b
SK
1184 if (daemon->port != 0)
1185 dump_cache(now);
5aabfc78
SK
1186 break;
1187
1188 case EVENT_ALARM:
7622fc06 1189#ifdef HAVE_DHCP
1f776932 1190 if (daemon->dhcp || daemon->doing_dhcp6)
5aabfc78
SK
1191 {
1192 lease_prune(NULL, now);
1193 lease_update_file(now);
1194 }
843c96b4 1195#ifdef HAVE_DHCP6
1f776932 1196 else if (daemon->doing_ra)
353ae4d2
SK
1197 /* Not doing DHCP, so no lease system, manage alarms for ra only */
1198 send_alarm(periodic_ra(now), now);
843c96b4 1199#endif
7622fc06 1200#endif
5aabfc78
SK
1201 break;
1202
1203 case EVENT_CHILD:
1204 /* See Stevens 5.10 */
1205 while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
1206 if (p == -1)
1207 {
1208 if (errno != EINTR)
1209 break;
1210 }
1211 else
1212 for (i = 0 ; i < MAX_PROCS; i++)
1213 if (daemon->tcp_pids[i] == p)
1214 daemon->tcp_pids[i] = 0;
1215 break;
1216
1217 case EVENT_KILLED:
c72daea8 1218 my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data);
5aabfc78
SK
1219 break;
1220
1221 case EVENT_EXITED:
c72daea8 1222 my_syslog(LOG_WARNING, _("script process exited with status %d"), ev.data);
5aabfc78
SK
1223 break;
1224
1225 case EVENT_EXEC_ERR:
9e038946
SK
1226 my_syslog(LOG_ERR, _("failed to execute %s: %s"),
1227 daemon->lease_change_command, strerror(ev.data));
5aabfc78
SK
1228 break;
1229
1a6bca81 1230 /* necessary for fatal errors in helper */
c72daea8 1231 case EVENT_USER_ERR:
1a6bca81 1232 case EVENT_DIE:
c72daea8
SK
1233 case EVENT_LUA_ERR:
1234 fatal_event(&ev, msg);
9e038946
SK
1235 break;
1236
5aabfc78
SK
1237 case EVENT_REOPEN:
1238 /* Note: this may leave TCP-handling processes with the old file still open.
1239 Since any such process will die in CHILD_LIFETIME or probably much sooner,
1240 we leave them logging to the old file. */
1241 if (daemon->log_file != NULL)
1242 log_reopen(daemon->log_file);
1243 break;
a0358e5d
SK
1244
1245 case EVENT_NEWADDR:
1246 newaddress(now);
1247 break;
47a95169
SK
1248
1249 case EVENT_NEWROUTE:
1250 resend_query();
1251 /* Force re-reading resolv file right now, for luck. */
1252 poll_resolv(0, 1, now);
1253 break;
1254
5aabfc78
SK
1255 case EVENT_TERM:
1256 /* Knock all our children on the head. */
1257 for (i = 0; i < MAX_PROCS; i++)
1258 if (daemon->tcp_pids[i] != 0)
1259 kill(daemon->tcp_pids[i], SIGALRM);
1260
c72daea8 1261#if defined(HAVE_SCRIPT)
5aabfc78
SK
1262 /* handle pending lease transitions */
1263 if (daemon->helperfd != -1)
1264 {
1265 /* block in writes until all done */
1266 if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
1267 fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
1268 do {
1269 helper_write();
1270 } while (!helper_buf_empty() || do_script_run(now));
1271 close(daemon->helperfd);
1272 }
1273#endif
1274
1275 if (daemon->lease_stream)
1276 fclose(daemon->lease_stream);
73a08a24
SK
1277
1278 if (daemon->runfile)
1279 unlink(daemon->runfile);
5aabfc78
SK
1280
1281 my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
1282 flush_log();
1283 exit(EC_GOOD);
1284 }
3be34541
SK
1285}
1286
47a95169 1287static void poll_resolv(int force, int do_reload, time_t now)
5aabfc78
SK
1288{
1289 struct resolvc *res, *latest;
1290 struct stat statbuf;
1291 time_t last_change = 0;
1292 /* There may be more than one possible file.
1293 Go through and find the one which changed _last_.
1294 Warn of any which can't be read. */
8ef5ada2 1295
28866e95 1296 if (daemon->port == 0 || option_bool(OPT_NO_POLL))
8ef5ada2
SK
1297 return;
1298
5aabfc78
SK
1299 for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
1300 if (stat(res->name, &statbuf) == -1)
1301 {
8ef5ada2
SK
1302 if (force)
1303 {
1304 res->mtime = 0;
1305 continue;
1306 }
1307
5aabfc78
SK
1308 if (!res->logged)
1309 my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
1310 res->logged = 1;
8ef5ada2
SK
1311
1312 if (res->mtime != 0)
1313 {
1314 /* existing file evaporated, force selection of the latest
1315 file even if its mtime hasn't changed since we last looked */
1316 poll_resolv(1, do_reload, now);
1317 return;
1318 }
5aabfc78
SK
1319 }
1320 else
1321 {
1322 res->logged = 0;
8ef5ada2
SK
1323 if (force || (statbuf.st_mtime != res->mtime))
1324 {
1325 res->mtime = statbuf.st_mtime;
5aabfc78
SK
1326 if (difftime(statbuf.st_mtime, last_change) > 0.0)
1327 {
1328 last_change = statbuf.st_mtime;
1329 latest = res;
1330 }
1331 }
1332 }
1333
1334 if (latest)
1335 {
1336 static int warned = 0;
1337 if (reload_servers(latest->name))
1338 {
1339 my_syslog(LOG_INFO, _("reading %s"), latest->name);
1340 warned = 0;
1341 check_servers();
28866e95 1342 if (option_bool(OPT_RELOAD) && do_reload)
8ef5ada2 1343 clear_cache_and_reload(now);
5aabfc78
SK
1344 }
1345 else
1346 {
1347 latest->mtime = 0;
1348 if (!warned)
1349 {
1350 my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
1351 warned = 1;
1352 }
1353 }
1354 }
1355}
3d8df260 1356
5aabfc78 1357void clear_cache_and_reload(time_t now)
3d8df260 1358{
408c368f
VG
1359 (void)now;
1360
824af85b 1361 if (daemon->port != 0)
7622fc06 1362 cache_reload();
824af85b 1363
7622fc06 1364#ifdef HAVE_DHCP
1f776932 1365 if (daemon->dhcp || daemon->doing_dhcp6)
3d8df260 1366 {
28866e95 1367 if (option_bool(OPT_ETHERS))
5aabfc78 1368 dhcp_read_ethers();
824af85b 1369 reread_dhcp();
3d8df260 1370 dhcp_update_configs(daemon->dhcp_conf);
5aabfc78
SK
1371 lease_update_from_configs();
1372 lease_update_file(now);
353ae4d2 1373 lease_update_dns(1);
3d8df260 1374 }
843c96b4 1375#ifdef HAVE_DHCP6
1f776932 1376 else if (daemon->doing_ra)
2021c662
SK
1377 /* Not doing DHCP, so no lease system, manage
1378 alarms for ra only */
1379 send_alarm(periodic_ra(now), now);
843c96b4 1380#endif
7622fc06 1381#endif
3d8df260
SK
1382}
1383
5aabfc78 1384static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
3be34541
SK
1385{
1386 struct serverfd *serverfdp;
1387 struct listener *listener;
824af85b 1388 int wait = 0, i;
832af0ba
SK
1389
1390#ifdef HAVE_TFTP
1391 int tftp = 0;
1392 struct tftp_transfer *transfer;
1393 for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
1394 {
1395 tftp++;
1396 FD_SET(transfer->sockfd, set);
1397 bump_maxfd(transfer->sockfd, maxfdp);
1398 }
1399#endif
1400
1697269c 1401 /* will we be able to get memory? */
824af85b 1402 if (daemon->port != 0)
3a237152 1403 get_new_frec(now, &wait, 0);
1697269c 1404
3be34541
SK
1405 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
1406 {
1407 FD_SET(serverfdp->fd, set);
1697269c 1408 bump_maxfd(serverfdp->fd, maxfdp);
3be34541 1409 }
1a6bca81
SK
1410
1411 if (daemon->port != 0 && !daemon->osport)
1412 for (i = 0; i < RANDOM_SOCKS; i++)
1413 if (daemon->randomsocks[i].refcount != 0)
1414 {
1415 FD_SET(daemon->randomsocks[i].fd, set);
1416 bump_maxfd(daemon->randomsocks[i].fd, maxfdp);
1417 }
1418
3be34541
SK
1419 for (listener = daemon->listeners; listener; listener = listener->next)
1420 {
1697269c 1421 /* only listen for queries if we have resources */
824af85b 1422 if (listener->fd != -1 && wait == 0)
1697269c
SK
1423 {
1424 FD_SET(listener->fd, set);
1425 bump_maxfd(listener->fd, maxfdp);
1426 }
1427
1428 /* death of a child goes through the select loop, so
1429 we don't need to explicitly arrange to wake up here */
824af85b
SK
1430 if (listener->tcpfd != -1)
1431 for (i = 0; i < MAX_PROCS; i++)
1432 if (daemon->tcp_pids[i] == 0)
1433 {
1434 FD_SET(listener->tcpfd, set);
1435 bump_maxfd(listener->tcpfd, maxfdp);
1436 break;
1437 }
9e4abcb5 1438
832af0ba
SK
1439#ifdef HAVE_TFTP
1440 if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
1441 {
1442 FD_SET(listener->tftpfd, set);
1443 bump_maxfd(listener->tftpfd, maxfdp);
1444 }
1445#endif
1446
1447 }
1448
1697269c 1449 return wait;
3be34541 1450}
9e4abcb5 1451
5aabfc78 1452static void check_dns_listeners(fd_set *set, time_t now)
3be34541
SK
1453{
1454 struct serverfd *serverfdp;
1a6bca81
SK
1455 struct listener *listener;
1456 int i;
1457
832af0ba
SK
1458 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
1459 if (FD_ISSET(serverfdp->fd, set))
1a6bca81
SK
1460 reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
1461
1462 if (daemon->port != 0 && !daemon->osport)
1463 for (i = 0; i < RANDOM_SOCKS; i++)
1464 if (daemon->randomsocks[i].refcount != 0 &&
1465 FD_ISSET(daemon->randomsocks[i].fd, set))
1466 reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
832af0ba
SK
1467
1468 for (listener = daemon->listeners; listener; listener = listener->next)
1469 {
824af85b 1470 if (listener->fd != -1 && FD_ISSET(listener->fd, set))
5aabfc78 1471 receive_query(listener, now);
1a6bca81 1472
832af0ba
SK
1473#ifdef HAVE_TFTP
1474 if (listener->tftpfd != -1 && FD_ISSET(listener->tftpfd, set))
5aabfc78 1475 tftp_request(listener, now);
832af0ba 1476#endif
3be34541 1477
824af85b 1478 if (listener->tcpfd != -1 && FD_ISSET(listener->tcpfd, set))
832af0ba 1479 {
22ce550e 1480 int confd, client_ok = 1;
832af0ba
SK
1481 struct irec *iface = NULL;
1482 pid_t p;
52d4abf2
SK
1483 union mysockaddr tcp_addr;
1484 socklen_t tcp_len = sizeof(union mysockaddr);
1485
1486 while ((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
832af0ba 1487
46b06656 1488 if (confd == -1)
832af0ba 1489 continue;
76dd75de 1490
46b06656
SK
1491 if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
1492 {
1493 close(confd);
1494 continue;
1495 }
76dd75de
SK
1496
1497 /* Make sure that the interface list is up-to-date.
1498
1499 We do this here as we may need the results below, and
1500 the DNS code needs them for --interface-name stuff.
1501
1502 Multiple calls to enumerate_interfaces() per select loop are
1503 inhibited, so calls to it in the child process (which doesn't select())
1504 have no effect. This avoids two processes reading from the same
1505 netlink fd and screwing the pooch entirely.
1506 */
e25db1f2 1507
76dd75de
SK
1508 enumerate_interfaces(0);
1509
1510 if (option_bool(OPT_NOWILD))
1511 iface = listener->iface; /* May be NULL */
1512 else
1513 {
1514 int if_index;
1515 char intr_name[IF_NAMESIZE];
1516
1517 /* if we can find the arrival interface, check it's one that's allowed */
1518 if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&
1519 indextoname(listener->tcpfd, if_index, intr_name))
1520 {
1521 struct all_addr addr;
1522 addr.addr.addr4 = tcp_addr.in.sin_addr;
e25db1f2 1523#ifdef HAVE_IPV6
76dd75de
SK
1524 if (tcp_addr.sa.sa_family == AF_INET6)
1525 addr.addr.addr6 = tcp_addr.in6.sin6_addr;
e25db1f2 1526#endif
76dd75de
SK
1527
1528 for (iface = daemon->interfaces; iface; iface = iface->next)
1529 if (iface->index == if_index)
1530 break;
1531
1532 if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
1533 client_ok = 0;
1534 }
1535
1536 if (option_bool(OPT_CLEVERBIND))
1537 iface = listener->iface; /* May be NULL */
1538 else
1539 {
1540 /* Check for allowed interfaces when binding the wildcard address:
1541 we do this by looking for an interface with the same address as
1542 the local address of the TCP connection, then looking to see if that's
1543 an allowed interface. As a side effect, we get the netmask of the
1544 interface too, for localisation. */
1545
1546 for (iface = daemon->interfaces; iface; iface = iface->next)
1547 if (sockaddr_isequal(&iface->addr, &tcp_addr))
1548 break;
1549
1550 if (!iface)
1551 client_ok = 0;
1552 }
1553 }
1554
22ce550e 1555 if (!client_ok)
832af0ba
SK
1556 {
1557 shutdown(confd, SHUT_RDWR);
1558 close(confd);
1559 }
59353a6b 1560#ifndef NO_FORK
28866e95 1561 else if (!option_bool(OPT_DEBUG) && (p = fork()) != 0)
832af0ba
SK
1562 {
1563 if (p != -1)
1564 {
1565 int i;
1566 for (i = 0; i < MAX_PROCS; i++)
1567 if (daemon->tcp_pids[i] == 0)
1568 {
1569 daemon->tcp_pids[i] = p;
1570 break;
1571 }
1572 }
1573 close(confd);
1574 }
1575#endif
1576 else
1577 {
1578 unsigned char *buff;
1579 struct server *s;
1580 int flags;
52d4abf2 1581 struct in_addr netmask;
4f7b304f 1582 int auth_dns;
52d4abf2
SK
1583
1584 if (iface)
4f7b304f
SK
1585 {
1586 netmask = iface->netmask;
1587 auth_dns = iface->dns_auth;
1588 }
52d4abf2 1589 else
4f7b304f
SK
1590 {
1591 netmask.s_addr = 0;
1592 auth_dns = 0;
1593 }
52d4abf2 1594
8ef5ada2
SK
1595#ifndef NO_FORK
1596 /* Arrange for SIGALARM after CHILD_LIFETIME seconds to
1597 terminate the process. */
28866e95 1598 if (!option_bool(OPT_DEBUG))
832af0ba 1599 alarm(CHILD_LIFETIME);
8ef5ada2
SK
1600#endif
1601
832af0ba
SK
1602 /* start with no upstream connections. */
1603 for (s = daemon->servers; s; s = s->next)
7cebd20f 1604 s->tcpfd = -1;
832af0ba
SK
1605
1606 /* The connected socket inherits non-blocking
1607 attribute from the listening socket.
1608 Reset that here. */
1609 if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
1610 fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
1611
4f7b304f 1612 buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
7cebd20f 1613
832af0ba
SK
1614 shutdown(confd, SHUT_RDWR);
1615 close(confd);
1616
1617 if (buff)
1618 free(buff);
1619
1620 for (s = daemon->servers; s; s = s->next)
1621 if (s->tcpfd != -1)
1622 {
1623 shutdown(s->tcpfd, SHUT_RDWR);
1624 close(s->tcpfd);
1625 }
7cebd20f 1626#ifndef NO_FORK
28866e95 1627 if (!option_bool(OPT_DEBUG))
5aabfc78
SK
1628 {
1629 flush_log();
1630 _exit(0);
1631 }
59353a6b 1632#endif
832af0ba
SK
1633 }
1634 }
1635 }
3be34541
SK
1636}
1637
7622fc06 1638#ifdef HAVE_DHCP
5e9e0efb
SK
1639int make_icmp_sock(void)
1640{
7cebd20f 1641 int fd;
5e9e0efb
SK
1642 int zeroopt = 0;
1643
1644 if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
1645 {
7cebd20f 1646 if (!fix_fd(fd) ||
5e9e0efb
SK
1647 setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1)
1648 {
1649 close(fd);
1650 fd = -1;
1651 }
1652 }
1653
1654 return fd;
1655}
1656
5aabfc78 1657int icmp_ping(struct in_addr addr)
3be34541 1658{
5e9e0efb 1659 /* Try and get an ICMP echo from a machine. */
3be34541
SK
1660
1661 /* Note that whilst in the three second wait, we check for
832af0ba 1662 (and service) events on the DNS and TFTP sockets, (so doing that
3be34541
SK
1663 better not use any resources our caller has in use...)
1664 but we remain deaf to signals or further DHCP packets. */
1665
5e9e0efb 1666 int fd;
3be34541
SK
1667 struct sockaddr_in saddr;
1668 struct {
1669 struct ip ip;
1670 struct icmp icmp;
1671 } packet;
1672 unsigned short id = rand16();
1673 unsigned int i, j;
5e9e0efb 1674 int gotreply = 0;
3be34541 1675 time_t start, now;
5e9e0efb 1676
824af85b 1677#if defined(HAVE_LINUX_NETWORK) || defined (HAVE_SOLARIS_NETWORK)
5e9e0efb
SK
1678 if ((fd = make_icmp_sock()) == -1)
1679 return 0;
1680#else
1681 int opt = 2000;
1682 fd = daemon->dhcp_icmp_fd;
1683 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
1684#endif
1685
3be34541
SK
1686 saddr.sin_family = AF_INET;
1687 saddr.sin_port = 0;
1688 saddr.sin_addr = addr;
1689#ifdef HAVE_SOCKADDR_SA_LEN
1690 saddr.sin_len = sizeof(struct sockaddr_in);
1691#endif
1692
1693 memset(&packet.icmp, 0, sizeof(packet.icmp));
1694 packet.icmp.icmp_type = ICMP_ECHO;
1695 packet.icmp.icmp_id = id;
1696 for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++)
1697 j += ((u16 *)&packet.icmp)[i];
1698 while (j>>16)
1699 j = (j & 0xffff) + (j >> 16);
1700 packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
1701
5e9e0efb 1702 while (sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
fd9fa481
SK
1703 (struct sockaddr *)&saddr, sizeof(saddr)) == -1 &&
1704 retry_send());
1705
5e9e0efb
SK
1706 for (now = start = dnsmasq_time();
1707 difftime(now, start) < (float)PING_WAIT;)
fd9fa481
SK
1708 {
1709 struct timeval tv;
f2621c7f 1710 fd_set rset, wset;
fd9fa481 1711 struct sockaddr_in faddr;
1697269c 1712 int maxfd = fd;
3d8df260 1713 socklen_t len = sizeof(faddr);
fd9fa481
SK
1714
1715 tv.tv_usec = 250000;
1716 tv.tv_sec = 0;
1717
1718 FD_ZERO(&rset);
f2621c7f 1719 FD_ZERO(&wset);
5e9e0efb 1720 FD_SET(fd, &rset);
5aabfc78 1721 set_dns_listeners(now, &rset, &maxfd);
f2621c7f 1722 set_log_writer(&wset, &maxfd);
c5ad4e79
SK
1723
1724#ifdef HAVE_DHCP6
1f776932 1725 if (daemon->doing_ra)
c5ad4e79
SK
1726 {
1727 FD_SET(daemon->icmp6fd, &rset);
1728 bump_maxfd(daemon->icmp6fd, &maxfd);
1729 }
1730#endif
1731
f2621c7f
SK
1732 if (select(maxfd+1, &rset, &wset, NULL, &tv) < 0)
1733 {
1734 FD_ZERO(&rset);
1735 FD_ZERO(&wset);
1736 }
1737
5e9e0efb 1738 now = dnsmasq_time();
f2621c7f
SK
1739
1740 check_log_writer(&wset);
5aabfc78 1741 check_dns_listeners(&rset, now);
832af0ba 1742
c5ad4e79 1743#ifdef HAVE_DHCP6
1f776932
SK
1744 if (daemon->doing_ra && FD_ISSET(daemon->icmp6fd, &rset))
1745 icmp6_packet(now);
c5ad4e79
SK
1746#endif
1747
832af0ba 1748#ifdef HAVE_TFTP
5aabfc78 1749 check_tftp_listeners(&rset, now);
832af0ba
SK
1750#endif
1751
5e9e0efb
SK
1752 if (FD_ISSET(fd, &rset) &&
1753 recvfrom(fd, &packet, sizeof(packet), 0,
fd9fa481
SK
1754 (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
1755 saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
1756 packet.icmp.icmp_type == ICMP_ECHOREPLY &&
1757 packet.icmp.icmp_seq == 0 &&
1758 packet.icmp.icmp_id == id)
1759 {
1760 gotreply = 1;
1761 break;
1762 }
1763 }
1764
824af85b 1765#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
5e9e0efb
SK
1766 close(fd);
1767#else
3be34541 1768 opt = 1;
5e9e0efb
SK
1769 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
1770#endif
1771
3be34541
SK
1772 return gotreply;
1773}
7622fc06 1774#endif
0a852541
SK
1775
1776