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