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