Home | History | Annotate | Download | only in src
      1 /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
      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
      5    the Free Software Foundation; version 2 dated June, 1991, or
      6    (at your option) version 3 dated 29 June, 2007.
      7 
      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.
     12 
     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/>.
     15 */
     16 
     17 #include "dnsmasq.h"
     18 
     19 struct daemon *daemon;
     20 
     21 static char *compile_opts =
     22 #ifndef HAVE_IPV6
     23 "no-"
     24 #endif
     25 "IPv6 "
     26 #ifndef HAVE_GETOPT_LONG
     27 "no-"
     28 #endif
     29 "GNU-getopt "
     30 #ifdef HAVE_BROKEN_RTC
     31 "no-RTC "
     32 #endif
     33 #ifdef NO_FORK
     34 "no-MMU "
     35 #endif
     36 #ifndef HAVE_DBUS
     37 "no-"
     38 #endif
     39 "DBus "
     40 #ifndef LOCALEDIR
     41 "no-"
     42 #endif
     43 "I18N "
     44 #ifndef HAVE_DHCP
     45 "no-"
     46 #endif
     47 "DHCP "
     48 #if defined(HAVE_DHCP) && !defined(HAVE_SCRIPT)
     49 "no-scripts "
     50 #endif
     51 #ifndef HAVE_TFTP
     52 "no-"
     53 #endif
     54 "TFTP";
     55 
     56 
     57 
     58 static volatile pid_t pid = 0;
     59 static volatile int pipewrite;
     60 
     61 static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp);
     62 static void check_dns_listeners(fd_set *set, time_t now);
     63 static void sig_handler(int sig);
     64 static void async_event(int pipe, time_t now);
     65 static void fatal_event(struct event_desc *ev);
     66 static void poll_resolv(void);
     67 #ifdef __ANDROID__
     68 static int set_android_listeners(fd_set *set, int *maxfdp);
     69 static int check_android_listeners(fd_set *set);
     70 #endif
     71 
     72 int main (int argc, char **argv)
     73 {
     74   int bind_fallback = 0;
     75   time_t now;
     76   struct sigaction sigact;
     77   struct iname *if_tmp;
     78   int piperead, pipefd[2], err_pipe[2];
     79   struct passwd *ent_pw = NULL;
     80 #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
     81   uid_t script_uid = 0;
     82   gid_t script_gid = 0;
     83 #endif
     84   struct group *gp = NULL;
     85   long i, max_fd = sysconf(_SC_OPEN_MAX);
     86   char *baduser = NULL;
     87   int log_err;
     88 #if defined(HAVE_LINUX_NETWORK)
     89   cap_user_header_t hdr = NULL;
     90   cap_user_data_t data = NULL;
     91 #endif
     92 
     93 #ifdef LOCALEDIR
     94   setlocale(LC_ALL, "");
     95   bindtextdomain("dnsmasq", LOCALEDIR);
     96   textdomain("dnsmasq");
     97 #endif
     98 
     99   sigact.sa_handler = sig_handler;
    100   sigact.sa_flags = 0;
    101   sigemptyset(&sigact.sa_mask);
    102   sigaction(SIGUSR1, &sigact, NULL);
    103   sigaction(SIGUSR2, &sigact, NULL);
    104   sigaction(SIGHUP, &sigact, NULL);
    105   sigaction(SIGTERM, &sigact, NULL);
    106   sigaction(SIGALRM, &sigact, NULL);
    107   sigaction(SIGCHLD, &sigact, NULL);
    108 
    109   /* ignore SIGPIPE */
    110   sigact.sa_handler = SIG_IGN;
    111   sigaction(SIGPIPE, &sigact, NULL);
    112 
    113   umask(022); /* known umask, create leases and pid files as 0644 */
    114 
    115   read_opts(argc, argv, compile_opts);
    116 
    117   if (daemon->edns_pktsz < PACKETSZ)
    118     daemon->edns_pktsz = PACKETSZ;
    119   daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?
    120     daemon->edns_pktsz : DNSMASQ_PACKETSZ;
    121   daemon->packet = safe_malloc(daemon->packet_buff_sz);
    122 
    123 #ifdef HAVE_DHCP
    124   if (!daemon->lease_file)
    125     {
    126       if (daemon->dhcp)
    127 	daemon->lease_file = LEASEFILE;
    128     }
    129 #endif
    130 
    131   /* Close any file descriptors we inherited apart from std{in|out|err} */
    132   for (i = 0; i < max_fd; i++)
    133     if (i != STDOUT_FILENO && i != STDERR_FILENO && i != STDIN_FILENO)
    134       close(i);
    135 
    136 #ifdef HAVE_LINUX_NETWORK
    137   netlink_init();
    138 #elif !(defined(IP_RECVDSTADDR) && \
    139 	defined(IP_RECVIF) && \
    140 	defined(IP_SENDSRCADDR))
    141   if (!(daemon->options & OPT_NOWILD))
    142     {
    143       bind_fallback = 1;
    144       daemon->options |= OPT_NOWILD;
    145     }
    146 #endif
    147 
    148 #ifndef HAVE_TFTP
    149   if (daemon->options & OPT_TFTP)
    150     die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
    151 #endif
    152 
    153 #ifdef HAVE_SOLARIS_NETWORK
    154   if (daemon->max_logs != 0)
    155     die(_("asychronous logging is not available under Solaris"), NULL, EC_BADCONF);
    156 #endif
    157 
    158   rand_init();
    159 
    160   now = dnsmasq_time();
    161 
    162 #ifdef HAVE_DHCP
    163   if (daemon->dhcp)
    164     {
    165       /* Note that order matters here, we must call lease_init before
    166 	 creating any file descriptors which shouldn't be leaked
    167 	 to the lease-script init process. */
    168       lease_init(now);
    169       dhcp_init();
    170     }
    171 #endif
    172 
    173   if (!enumerate_interfaces())
    174     die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
    175 
    176   if (daemon->options & OPT_NOWILD)
    177     {
    178       daemon->listeners = create_bound_listeners();
    179 
    180       for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
    181 	if (if_tmp->name && !if_tmp->used)
    182 	  die(_("unknown interface %s"), if_tmp->name, EC_BADNET);
    183 
    184       for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
    185 	if (!if_tmp->used)
    186 	  {
    187 	    prettyprint_addr(&if_tmp->addr, daemon->namebuff);
    188 	    die(_("no interface with address %s"), daemon->namebuff, EC_BADNET);
    189 	  }
    190     }
    191   else if ((daemon->port != 0 || (daemon->options & OPT_TFTP)) &&
    192 	   !(daemon->listeners = create_wildcard_listeners()))
    193     die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
    194 
    195   if (daemon->port != 0)
    196     cache_init();
    197 
    198   if (daemon->options & OPT_DBUS)
    199 #ifdef HAVE_DBUS
    200     {
    201       char *err;
    202       daemon->dbus = NULL;
    203       daemon->watches = NULL;
    204       if ((err = dbus_init()))
    205 	die(_("DBus error: %s"), err, EC_MISC);
    206     }
    207 #else
    208   die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
    209 #endif
    210 
    211   if (daemon->port != 0)
    212     pre_allocate_sfds();
    213 
    214 #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
    215   /* Note getpwnam returns static storage */
    216   if (daemon->dhcp && daemon->lease_change_command && daemon->scriptuser)
    217     {
    218       if ((ent_pw = getpwnam(daemon->scriptuser)))
    219 	{
    220 	  script_uid = ent_pw->pw_uid;
    221 	  script_gid = ent_pw->pw_gid;
    222 	 }
    223       else
    224 	baduser = daemon->scriptuser;
    225     }
    226 #endif
    227 
    228   if (daemon->username && !(ent_pw = getpwnam(daemon->username)))
    229     baduser = daemon->username;
    230   else if (daemon->groupname && !(gp = getgrnam(daemon->groupname)))
    231     baduser = daemon->groupname;
    232 
    233   if (baduser)
    234     die(_("unknown user or group: %s"), baduser, EC_BADCONF);
    235 
    236   /* implement group defaults, "dip" if available, or group associated with uid */
    237   if (!daemon->group_set && !gp)
    238     {
    239       if (!(gp = getgrnam(CHGRP)) && ent_pw)
    240 	gp = getgrgid(ent_pw->pw_gid);
    241 
    242       /* for error message */
    243       if (gp)
    244 	daemon->groupname = gp->gr_name;
    245     }
    246 
    247 #if defined(HAVE_LINUX_NETWORK)
    248   /* determine capability API version here, while we can still
    249      call safe_malloc */
    250   if (ent_pw && ent_pw->pw_uid != 0)
    251     {
    252       int capsize = 1; /* for header version 1 */
    253       hdr = safe_malloc(sizeof(*hdr));
    254 
    255       /* find version supported by kernel */
    256       memset(hdr, 0, sizeof(*hdr));
    257       capget(hdr, NULL);
    258 
    259       if (hdr->version != LINUX_CAPABILITY_VERSION_1)
    260 	{
    261 	  /* if unknown version, use largest supported version (3) */
    262 	  if (hdr->version != LINUX_CAPABILITY_VERSION_2)
    263 	    hdr->version = LINUX_CAPABILITY_VERSION_3;
    264 	  capsize = 2;
    265 	}
    266 
    267       data = safe_malloc(sizeof(*data) * capsize);
    268       memset(data, 0, sizeof(*data) * capsize);
    269     }
    270 #endif
    271 
    272   /* Use a pipe to carry signals and other events back to the event loop
    273      in a race-free manner and another to carry errors to daemon-invoking process */
    274   safe_pipe(pipefd, 1);
    275 
    276   piperead = pipefd[0];
    277   pipewrite = pipefd[1];
    278   /* prime the pipe to load stuff first time. */
    279   send_event(pipewrite, EVENT_RELOAD, 0);
    280 
    281   err_pipe[1] = -1;
    282 
    283   if (!(daemon->options & OPT_DEBUG))
    284     {
    285 #ifndef __ANDROID__
    286       int nullfd;
    287 #endif
    288 
    289       /* The following code "daemonizes" the process.
    290 	 See Stevens section 12.4 */
    291 
    292       if (chdir("/") != 0)
    293 	die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC);
    294 
    295 #ifndef NO_FORK
    296       if (!(daemon->options & OPT_NO_FORK))
    297 	{
    298 	  pid_t pid;
    299 
    300 	  /* pipe to carry errors back to original process.
    301 	     When startup is complete we close this and the process terminates. */
    302 	  safe_pipe(err_pipe, 0);
    303 
    304 	  if ((pid = fork()) == -1)
    305 	    /* fd == -1 since we've not forked, never returns. */
    306 	    send_event(-1, EVENT_FORK_ERR, errno);
    307 
    308 	  if (pid != 0)
    309 	    {
    310 	      struct event_desc ev;
    311 
    312 	      /* close our copy of write-end */
    313 	      close(err_pipe[1]);
    314 
    315 	      /* check for errors after the fork */
    316 	      if (read_write(err_pipe[0], (unsigned char *)&ev, sizeof(ev), 1))
    317 		fatal_event(&ev);
    318 
    319 	      _exit(EC_GOOD);
    320 	    }
    321 
    322 	  close(err_pipe[0]);
    323 
    324 	  /* NO calls to die() from here on. */
    325 
    326 	  setsid();
    327 
    328 	  if ((pid = fork()) == -1)
    329 	    send_event(err_pipe[1], EVENT_FORK_ERR, errno);
    330 
    331 	  if (pid != 0)
    332 	    _exit(0);
    333 	}
    334 #endif
    335 
    336       /* write pidfile _after_ forking ! */
    337       if (daemon->runfile)
    338 	{
    339 	  FILE *pidfile;
    340 
    341 	  /* only complain if started as root */
    342 	  if ((pidfile = fopen(daemon->runfile, "w")))
    343 	    {
    344 	      fprintf(pidfile, "%d\n", (int) getpid());
    345 	      fclose(pidfile);
    346 	    }
    347 	  else if (getuid() == 0)
    348 	    {
    349 	      send_event(err_pipe[1], EVENT_PIDFILE, errno);
    350 	      _exit(0);
    351 	    }
    352 	}
    353 
    354 #ifndef __ANDROID__
    355       /* open  stdout etc to /dev/null */
    356       nullfd = open("/dev/null", O_RDWR);
    357       dup2(nullfd, STDOUT_FILENO);
    358       dup2(nullfd, STDERR_FILENO);
    359       dup2(nullfd, STDIN_FILENO);
    360       close(nullfd);
    361 #endif
    362     }
    363 
    364    log_err = log_start(ent_pw, err_pipe[1]);
    365 
    366    /* if we are to run scripts, we need to fork a helper before dropping root. */
    367   daemon->helperfd = -1;
    368 #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
    369   if (daemon->dhcp && daemon->lease_change_command)
    370     daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
    371 #endif
    372 
    373   if (!(daemon->options & OPT_DEBUG) && getuid() == 0)
    374     {
    375       int bad_capabilities = 0;
    376       gid_t dummy;
    377 
    378       /* remove all supplimentary groups */
    379       if (gp &&
    380 	  (setgroups(0, &dummy) == -1 ||
    381 	   setgid(gp->gr_gid) == -1))
    382 	{
    383 	  send_event(err_pipe[1], EVENT_GROUP_ERR, errno);
    384 	  _exit(0);
    385 	}
    386 
    387       if (ent_pw && ent_pw->pw_uid != 0)
    388 	{
    389 #if defined(HAVE_LINUX_NETWORK)
    390 	  /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
    391 	     CAP_NET_RAW (for icmp) if we're doing dhcp */
    392 	  data->effective = data->permitted = data->inheritable =
    393 	    (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID);
    394 
    395 	  /* Tell kernel to not clear capabilities when dropping root */
    396 	  if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
    397 	    bad_capabilities = errno;
    398 
    399 #elif defined(HAVE_SOLARIS_NETWORK)
    400 	  /* http://developers.sun.com/solaris/articles/program_privileges.html */
    401 	  priv_set_t *priv_set;
    402 
    403 	  if (!(priv_set = priv_str_to_set("basic", ",", NULL)) ||
    404 	      priv_addset(priv_set, PRIV_NET_ICMPACCESS) == -1 ||
    405 	      priv_addset(priv_set, PRIV_SYS_NET_CONFIG) == -1)
    406 	    bad_capabilities = errno;
    407 
    408 	  if (priv_set && bad_capabilities == 0)
    409 	    {
    410 	      priv_inverse(priv_set);
    411 
    412 	      if (setppriv(PRIV_OFF, PRIV_LIMIT, priv_set) == -1)
    413 		bad_capabilities = errno;
    414 	    }
    415 
    416 	  if (priv_set)
    417 	    priv_freeset(priv_set);
    418 
    419 #endif
    420 
    421 	  if (bad_capabilities != 0)
    422 	    {
    423 	      send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities);
    424 	      _exit(0);
    425 	    }
    426 
    427 	  /* finally drop root */
    428 	  if (setuid(ent_pw->pw_uid) == -1)
    429 	    {
    430 	      send_event(err_pipe[1], EVENT_USER_ERR, errno);
    431 	      _exit(0);
    432 	    }
    433 
    434 #ifdef HAVE_LINUX_NETWORK
    435 	  data->effective = data->permitted =
    436 	    (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
    437 	  data->inheritable = 0;
    438 
    439 	  /* lose the setuid and setgid capbilities */
    440 	  if (capset(hdr, data) == -1)
    441 	    {
    442 	      send_event(err_pipe[1], EVENT_CAP_ERR, errno);
    443 	      _exit(0);
    444 	    }
    445 #endif
    446 
    447 	}
    448     }
    449 
    450 #ifdef HAVE_LINUX_NETWORK
    451   if (daemon->options & OPT_DEBUG)
    452     prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
    453 #endif
    454 
    455   if (daemon->port == 0)
    456     my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
    457   else if (daemon->cachesize != 0)
    458     my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
    459   else
    460     my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
    461 
    462   my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
    463 
    464 #ifdef HAVE_DBUS
    465   if (daemon->options & OPT_DBUS)
    466     {
    467       if (daemon->dbus)
    468 	my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
    469       else
    470 	my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
    471     }
    472 #endif
    473 
    474   if (log_err != 0)
    475     my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
    476 	      daemon->log_file, strerror(log_err));
    477 
    478   if (bind_fallback)
    479     my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
    480 
    481   if (!(daemon->options & OPT_NOWILD))
    482     for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
    483       if (if_tmp->name && !if_tmp->used)
    484 	my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
    485 
    486   if (daemon->port != 0 && (daemon->options & OPT_NO_RESOLV))
    487     {
    488       if (daemon->resolv_files && !daemon->resolv_files->is_default)
    489 	my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
    490       daemon->resolv_files = NULL;
    491       if (!daemon->servers)
    492 	my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
    493     }
    494 
    495   if (daemon->max_logs != 0)
    496     my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
    497 
    498 #ifdef HAVE_DHCP
    499   if (daemon->dhcp)
    500     {
    501       struct dhcp_context *dhcp_tmp;
    502 
    503       for (dhcp_tmp = daemon->dhcp; dhcp_tmp; dhcp_tmp = dhcp_tmp->next)
    504 	{
    505 	  prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time);
    506 	  strcpy(daemon->dhcp_buff, inet_ntoa(dhcp_tmp->start));
    507 	  my_syslog(MS_DHCP | LOG_INFO,
    508 		    (dhcp_tmp->flags & CONTEXT_STATIC) ?
    509 		    _("DHCP, static leases only on %.0s%s, lease time %s") :
    510 		    (dhcp_tmp->flags & CONTEXT_PROXY) ?
    511 		    _("DHCP, proxy on subnet %.0s%s%.0s") :
    512 		    _("DHCP, IP range %s -- %s, lease time %s"),
    513 		    daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
    514 	}
    515     }
    516 #endif
    517 
    518 #ifdef HAVE_TFTP
    519   if (daemon->options & OPT_TFTP)
    520     {
    521 #ifdef FD_SETSIZE
    522       if (FD_SETSIZE < (unsigned)max_fd)
    523 	max_fd = FD_SETSIZE;
    524 #endif
    525 
    526       my_syslog(MS_TFTP | LOG_INFO, "TFTP %s%s %s",
    527 		daemon->tftp_prefix ? _("root is ") : _("enabled"),
    528 		daemon->tftp_prefix ? daemon->tftp_prefix: "",
    529 		daemon->options & OPT_TFTP_SECURE ? _("secure mode") : "");
    530 
    531       /* This is a guess, it assumes that for small limits,
    532 	 disjoint files might be served, but for large limits,
    533 	 a single file will be sent to may clients (the file only needs
    534 	 one fd). */
    535 
    536       max_fd -= 30; /* use other than TFTP */
    537 
    538       if (max_fd < 0)
    539 	max_fd = 5;
    540       else if (max_fd < 100)
    541 	max_fd = max_fd/2;
    542       else
    543 	max_fd = max_fd - 20;
    544 
    545       /* if we have to use a limited range of ports,
    546 	 that will limit the number of transfers */
    547       if (daemon->start_tftp_port != 0 &&
    548 	  daemon->end_tftp_port - daemon->start_tftp_port + 1 < max_fd)
    549 	max_fd = daemon->end_tftp_port - daemon->start_tftp_port + 1;
    550 
    551       if (daemon->tftp_max > max_fd)
    552 	{
    553 	  daemon->tftp_max = max_fd;
    554 	  my_syslog(MS_TFTP | LOG_WARNING,
    555 		    _("restricting maximum simultaneous TFTP transfers to %d"),
    556 		    daemon->tftp_max);
    557 	}
    558     }
    559 #endif
    560 
    561   /* finished start-up - release original process */
    562   if (err_pipe[1] != -1)
    563     close(err_pipe[1]);
    564 
    565   if (daemon->port != 0)
    566     check_servers();
    567 
    568   pid = getpid();
    569 
    570   while (1)
    571     {
    572       int maxfd = -1;
    573       struct timeval t, *tp = NULL;
    574       fd_set rset, wset, eset;
    575 
    576       FD_ZERO(&rset);
    577       FD_ZERO(&wset);
    578       FD_ZERO(&eset);
    579 
    580       /* if we are out of resources, find how long we have to wait
    581 	 for some to come free, we'll loop around then and restart
    582 	 listening for queries */
    583       if ((t.tv_sec = set_dns_listeners(now, &rset, &maxfd)) != 0)
    584 	{
    585 	  t.tv_usec = 0;
    586 	  tp = &t;
    587 	}
    588 #ifdef __ANDROID__
    589       set_android_listeners(&rset, &maxfd);
    590 #endif
    591 
    592       /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
    593       if (daemon->tftp_trans ||
    594 	  ((daemon->options & OPT_DBUS) && !daemon->dbus))
    595 	{
    596 	  t.tv_sec = 0;
    597 	  t.tv_usec = 250000;
    598 	  tp = &t;
    599 	}
    600 
    601 #ifdef HAVE_DBUS
    602       set_dbus_listeners(&maxfd, &rset, &wset, &eset);
    603 #endif
    604 
    605 #ifdef HAVE_DHCP
    606       if (daemon->dhcp)
    607 	{
    608 	  FD_SET(daemon->dhcpfd, &rset);
    609 	  bump_maxfd(daemon->dhcpfd, &maxfd);
    610 	}
    611 #endif
    612 
    613 #ifdef HAVE_LINUX_NETWORK
    614       FD_SET(daemon->netlinkfd, &rset);
    615       bump_maxfd(daemon->netlinkfd, &maxfd);
    616 #endif
    617 
    618       FD_SET(piperead, &rset);
    619       bump_maxfd(piperead, &maxfd);
    620 
    621 #ifdef HAVE_DHCP
    622 #  ifdef HAVE_SCRIPT
    623       while (helper_buf_empty() && do_script_run(now));
    624 
    625       if (!helper_buf_empty())
    626 	{
    627 	  FD_SET(daemon->helperfd, &wset);
    628 	  bump_maxfd(daemon->helperfd, &maxfd);
    629 	}
    630 #  else
    631       /* need this for other side-effects */
    632       while (do_script_run(now));
    633 #  endif
    634 #endif
    635 
    636       /* must do this just before select(), when we know no
    637 	 more calls to my_syslog() can occur */
    638       set_log_writer(&wset, &maxfd);
    639 
    640       if (select(maxfd+1, &rset, &wset, &eset, tp) < 0)
    641 	{
    642 	  /* otherwise undefined after error */
    643 	  FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset);
    644 	}
    645 
    646       now = dnsmasq_time();
    647 
    648       check_log_writer(&wset);
    649 
    650       /* Check for changes to resolv files once per second max. */
    651       /* Don't go silent for long periods if the clock goes backwards. */
    652       if (daemon->last_resolv == 0 ||
    653 	  difftime(now, daemon->last_resolv) > 1.0 ||
    654 	  difftime(now, daemon->last_resolv) < -1.0)
    655 	{
    656 	  daemon->last_resolv = now;
    657 
    658 	  if (daemon->port != 0 && !(daemon->options & OPT_NO_POLL))
    659 	    poll_resolv();
    660 	}
    661 
    662       if (FD_ISSET(piperead, &rset))
    663 	async_event(piperead, now);
    664 
    665 #ifdef HAVE_LINUX_NETWORK
    666       if (FD_ISSET(daemon->netlinkfd, &rset))
    667 	netlink_multicast();
    668 #endif
    669 
    670 #ifdef HAVE_DBUS
    671       /* if we didn't create a DBus connection, retry now. */
    672      if ((daemon->options & OPT_DBUS) && !daemon->dbus)
    673 	{
    674 	  char *err;
    675 	  if ((err = dbus_init()))
    676 	    my_syslog(LOG_WARNING, _("DBus error: %s"), err);
    677 	  if (daemon->dbus)
    678 	    my_syslog(LOG_INFO, _("connected to system DBus"));
    679 	}
    680       check_dbus_listeners(&rset, &wset, &eset);
    681 #endif
    682 
    683 #ifdef __ANDROID__
    684       check_android_listeners(&rset);
    685 #endif
    686 
    687       check_dns_listeners(&rset, now);
    688 
    689 #ifdef HAVE_TFTP
    690       check_tftp_listeners(&rset, now);
    691 #endif
    692 
    693 #ifdef HAVE_DHCP
    694       if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset))
    695 	dhcp_packet(now);
    696 
    697 #  ifdef HAVE_SCRIPT
    698       if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset))
    699 	helper_write();
    700 #  endif
    701 #endif
    702 
    703     }
    704 }
    705 
    706 static void sig_handler(int sig)
    707 {
    708   if (pid == 0)
    709     {
    710       /* ignore anything other than TERM during startup
    711 	 and in helper proc. (helper ignore TERM too) */
    712       if (sig == SIGTERM)
    713 	exit(EC_MISC);
    714     }
    715   else if (pid != getpid())
    716     {
    717       /* alarm is used to kill TCP children after a fixed time. */
    718       if (sig == SIGALRM)
    719 	_exit(0);
    720     }
    721   else
    722     {
    723       /* master process */
    724       int event, errsave = errno;
    725 
    726       if (sig == SIGHUP)
    727 	event = EVENT_RELOAD;
    728       else if (sig == SIGCHLD)
    729 	event = EVENT_CHILD;
    730       else if (sig == SIGALRM)
    731 	event = EVENT_ALARM;
    732       else if (sig == SIGTERM)
    733 	event = EVENT_TERM;
    734       else if (sig == SIGUSR1)
    735 	event = EVENT_DUMP;
    736       else if (sig == SIGUSR2)
    737 	event = EVENT_REOPEN;
    738       else
    739 	return;
    740 
    741       send_event(pipewrite, event, 0);
    742       errno = errsave;
    743     }
    744 }
    745 
    746 void send_event(int fd, int event, int data)
    747 {
    748   struct event_desc ev;
    749 
    750   ev.event = event;
    751   ev.data = data;
    752 
    753   /* error pipe, debug mode. */
    754   if (fd == -1)
    755     fatal_event(&ev);
    756   else
    757     /* pipe is non-blocking and struct event_desc is smaller than
    758        PIPE_BUF, so this either fails or writes everything */
    759     while (write(fd, &ev, sizeof(ev)) == -1 && errno == EINTR);
    760 }
    761 
    762 static void fatal_event(struct event_desc *ev)
    763 {
    764   errno = ev->data;
    765 
    766   switch (ev->event)
    767     {
    768     case EVENT_DIE:
    769       exit(0);
    770 
    771     case EVENT_FORK_ERR:
    772       die(_("cannot fork into background: %s"), NULL, EC_MISC);
    773 
    774     case EVENT_PIPE_ERR:
    775       die(_("failed to create helper: %s"), NULL, EC_MISC);
    776 
    777     case EVENT_CAP_ERR:
    778       die(_("setting capabilities failed: %s"), NULL, EC_MISC);
    779 
    780     case EVENT_USER_ERR:
    781     case EVENT_HUSER_ERR:
    782       die(_("failed to change user-id to %s: %s"),
    783 	  ev->event == EVENT_USER_ERR ? daemon->username : daemon->scriptuser,
    784 	  EC_MISC);
    785 
    786     case EVENT_GROUP_ERR:
    787       die(_("failed to change group-id to %s: %s"), daemon->groupname, EC_MISC);
    788 
    789     case EVENT_PIDFILE:
    790       die(_("failed to open pidfile %s: %s"), daemon->runfile, EC_FILE);
    791 
    792     case EVENT_LOG_ERR:
    793       die(_("cannot open %s: %s"), daemon->log_file ? daemon->log_file : "log", EC_FILE);
    794     }
    795 }
    796 
    797 static void async_event(int pipe, time_t now)
    798 {
    799   pid_t p;
    800   struct event_desc ev;
    801   int i;
    802 
    803   if (read_write(pipe, (unsigned char *)&ev, sizeof(ev), 1))
    804     switch (ev.event)
    805       {
    806       case EVENT_RELOAD:
    807 	clear_cache_and_reload(now);
    808 	if (daemon->port != 0 && daemon->resolv_files && (daemon->options & OPT_NO_POLL))
    809 	  {
    810 	    reload_servers(daemon->resolv_files->name);
    811 	    check_servers();
    812 	  }
    813 #ifdef HAVE_DHCP
    814 	rerun_scripts();
    815 #endif
    816 	break;
    817 
    818       case EVENT_DUMP:
    819 	if (daemon->port != 0)
    820 	  dump_cache(now);
    821 	break;
    822 
    823       case EVENT_ALARM:
    824 #ifdef HAVE_DHCP
    825 	if (daemon->dhcp)
    826 	  {
    827 	    lease_prune(NULL, now);
    828 	    lease_update_file(now);
    829 	  }
    830 #endif
    831 	break;
    832 
    833       case EVENT_CHILD:
    834 	/* See Stevens 5.10 */
    835 	while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
    836 	  if (p == -1)
    837 	    {
    838 	      if (errno != EINTR)
    839 		break;
    840 	    }
    841 	  else
    842 	    for (i = 0 ; i < MAX_PROCS; i++)
    843 	      if (daemon->tcp_pids[i] == p)
    844 		daemon->tcp_pids[i] = 0;
    845 	break;
    846 
    847       case EVENT_KILLED:
    848 	my_syslog(LOG_WARNING, _("child process killed by signal %d"), ev.data);
    849 	break;
    850 
    851       case EVENT_EXITED:
    852 	my_syslog(LOG_WARNING, _("child process exited with status %d"), ev.data);
    853 	break;
    854 
    855       case EVENT_EXEC_ERR:
    856 	my_syslog(LOG_ERR, _("failed to execute %s: %s"),
    857 		  daemon->lease_change_command, strerror(ev.data));
    858 	break;
    859 
    860 	/* necessary for fatal errors in helper */
    861       case EVENT_HUSER_ERR:
    862       case EVENT_DIE:
    863 	fatal_event(&ev);
    864 	break;
    865 
    866       case EVENT_REOPEN:
    867 	/* Note: this may leave TCP-handling processes with the old file still open.
    868 	   Since any such process will die in CHILD_LIFETIME or probably much sooner,
    869 	   we leave them logging to the old file. */
    870 	if (daemon->log_file != NULL)
    871 	  log_reopen(daemon->log_file);
    872 	break;
    873 
    874       case EVENT_TERM:
    875 	/* Knock all our children on the head. */
    876 	for (i = 0; i < MAX_PROCS; i++)
    877 	  if (daemon->tcp_pids[i] != 0)
    878 	    kill(daemon->tcp_pids[i], SIGALRM);
    879 
    880 #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
    881 	/* handle pending lease transitions */
    882 	if (daemon->helperfd != -1)
    883 	  {
    884 	    /* block in writes until all done */
    885 	    if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
    886 	      fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
    887 	    do {
    888 	      helper_write();
    889 	    } while (!helper_buf_empty() || do_script_run(now));
    890 	    close(daemon->helperfd);
    891 	  }
    892 #endif
    893 
    894 	if (daemon->lease_stream)
    895 	  fclose(daemon->lease_stream);
    896 
    897 	if (daemon->runfile)
    898 	  unlink(daemon->runfile);
    899 
    900 	my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
    901 	flush_log();
    902 	exit(EC_GOOD);
    903       }
    904 }
    905 
    906 static void poll_resolv()
    907 {
    908   struct resolvc *res, *latest;
    909   struct stat statbuf;
    910   time_t last_change = 0;
    911   /* There may be more than one possible file.
    912      Go through and find the one which changed _last_.
    913      Warn of any which can't be read. */
    914   for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
    915     if (stat(res->name, &statbuf) == -1)
    916       {
    917 	if (!res->logged)
    918 	  my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
    919 	res->logged = 1;
    920       }
    921     else
    922       {
    923 	res->logged = 0;
    924 	if (statbuf.st_mtime != res->mtime)
    925 	  {
    926 	    res->mtime = statbuf.st_mtime;
    927 	    if (difftime(statbuf.st_mtime, last_change) > 0.0)
    928 	      {
    929 		last_change = statbuf.st_mtime;
    930 		latest = res;
    931 	      }
    932 	  }
    933       }
    934 
    935   if (latest)
    936     {
    937       static int warned = 0;
    938       if (reload_servers(latest->name))
    939 	{
    940 	  my_syslog(LOG_INFO, _("reading %s"), latest->name);
    941 	  warned = 0;
    942 	  check_servers();
    943 	  if (daemon->options & OPT_RELOAD)
    944 	    cache_reload();
    945 	}
    946       else
    947 	{
    948 	  latest->mtime = 0;
    949 	  if (!warned)
    950 	    {
    951 	      my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
    952 	      warned = 1;
    953 	    }
    954 	}
    955     }
    956 }
    957 
    958 void clear_cache_and_reload(time_t now)
    959 {
    960   if (daemon->port != 0)
    961     cache_reload();
    962 
    963 #ifdef HAVE_DHCP
    964   if (daemon->dhcp)
    965     {
    966       if (daemon->options & OPT_ETHERS)
    967 	dhcp_read_ethers();
    968       reread_dhcp();
    969       dhcp_update_configs(daemon->dhcp_conf);
    970       check_dhcp_hosts(0);
    971       lease_update_from_configs();
    972       lease_update_file(now);
    973       lease_update_dns();
    974     }
    975 #endif
    976 }
    977 
    978 #ifdef __ANDROID__
    979 
    980 static int set_android_listeners(fd_set *set, int *maxfdp) {
    981     FD_SET(STDIN_FILENO, set);
    982     bump_maxfd(STDIN_FILENO, maxfdp);
    983     return 0;
    984 }
    985 
    986 static int check_android_listeners(fd_set *set) {
    987     if (FD_ISSET(STDIN_FILENO, set)) {
    988         char buffer[1024];
    989         int rc;
    990 
    991         if ((rc = read(STDIN_FILENO, buffer, sizeof(buffer) -1)) < 0) {
    992             my_syslog(LOG_ERR, _("Error reading from stdin (%s)"), strerror(errno));
    993             return -1;
    994         }
    995         buffer[rc] = '\0';
    996         char *next = buffer;
    997         char *cmd;
    998 
    999         if (!(cmd = strsep(&next, ":"))) {
   1000             my_syslog(LOG_ERR, _("Malformatted msg '%s'"), buffer);
   1001             return -1;
   1002         }
   1003 
   1004         if (!strcmp(buffer, "update_dns")) {
   1005             set_servers(&buffer[11]);
   1006             check_servers();
   1007         } else {
   1008             my_syslog(LOG_ERR, _("Unknown cmd '%s'"), cmd);
   1009             return -1;
   1010         }
   1011     }
   1012     return 0;
   1013 }
   1014 #endif
   1015 
   1016 static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
   1017 {
   1018   struct serverfd *serverfdp;
   1019   struct listener *listener;
   1020   int wait = 0, i;
   1021 
   1022 #ifdef HAVE_TFTP
   1023   int  tftp = 0;
   1024   struct tftp_transfer *transfer;
   1025   for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
   1026     {
   1027       tftp++;
   1028       FD_SET(transfer->sockfd, set);
   1029       bump_maxfd(transfer->sockfd, maxfdp);
   1030     }
   1031 #endif
   1032 
   1033   /* will we be able to get memory? */
   1034   if (daemon->port != 0)
   1035     get_new_frec(now, &wait);
   1036 
   1037   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
   1038     {
   1039       FD_SET(serverfdp->fd, set);
   1040       bump_maxfd(serverfdp->fd, maxfdp);
   1041     }
   1042 
   1043   if (daemon->port != 0 && !daemon->osport)
   1044     for (i = 0; i < RANDOM_SOCKS; i++)
   1045       if (daemon->randomsocks[i].refcount != 0)
   1046 	{
   1047 	  FD_SET(daemon->randomsocks[i].fd, set);
   1048 	  bump_maxfd(daemon->randomsocks[i].fd, maxfdp);
   1049 	}
   1050 
   1051   for (listener = daemon->listeners; listener; listener = listener->next)
   1052     {
   1053       /* only listen for queries if we have resources */
   1054       if (listener->fd != -1 && wait == 0)
   1055 	{
   1056 	  FD_SET(listener->fd, set);
   1057 	  bump_maxfd(listener->fd, maxfdp);
   1058 	}
   1059 
   1060       /* death of a child goes through the select loop, so
   1061 	 we don't need to explicitly arrange to wake up here */
   1062       if  (listener->tcpfd != -1)
   1063 	for (i = 0; i < MAX_PROCS; i++)
   1064 	  if (daemon->tcp_pids[i] == 0)
   1065 	    {
   1066 	      FD_SET(listener->tcpfd, set);
   1067 	      bump_maxfd(listener->tcpfd, maxfdp);
   1068 	      break;
   1069 	    }
   1070 
   1071 #ifdef HAVE_TFTP
   1072       if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
   1073 	{
   1074 	  FD_SET(listener->tftpfd, set);
   1075 	  bump_maxfd(listener->tftpfd, maxfdp);
   1076 	}
   1077 #endif
   1078 
   1079     }
   1080 
   1081   return wait;
   1082 }
   1083 
   1084 static void check_dns_listeners(fd_set *set, time_t now)
   1085 {
   1086   struct serverfd *serverfdp;
   1087   struct listener *listener;
   1088   int i;
   1089 
   1090   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
   1091     if (FD_ISSET(serverfdp->fd, set))
   1092       reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
   1093 
   1094   if (daemon->port != 0 && !daemon->osport)
   1095     for (i = 0; i < RANDOM_SOCKS; i++)
   1096       if (daemon->randomsocks[i].refcount != 0 &&
   1097 	  FD_ISSET(daemon->randomsocks[i].fd, set))
   1098 	reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
   1099 
   1100   for (listener = daemon->listeners; listener; listener = listener->next)
   1101     {
   1102       if (listener->fd != -1 && FD_ISSET(listener->fd, set))
   1103 	receive_query(listener, now);
   1104 
   1105 #ifdef HAVE_TFTP
   1106       if (listener->tftpfd != -1 && FD_ISSET(listener->tftpfd, set))
   1107 	tftp_request(listener, now);
   1108 #endif
   1109 
   1110       if (listener->tcpfd != -1 && FD_ISSET(listener->tcpfd, set))
   1111 	{
   1112 	  int confd;
   1113 	  struct irec *iface = NULL;
   1114 	  pid_t p;
   1115 
   1116 	  while((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
   1117 
   1118 	  if (confd == -1)
   1119 	    continue;
   1120 
   1121 	  if (daemon->options & OPT_NOWILD)
   1122 	    iface = listener->iface;
   1123 	  else
   1124 	    {
   1125 	      union mysockaddr tcp_addr;
   1126 	      socklen_t tcp_len = sizeof(union mysockaddr);
   1127 	      /* Check for allowed interfaces when binding the wildcard address:
   1128 		 we do this by looking for an interface with the same address as
   1129 		 the local address of the TCP connection, then looking to see if that's
   1130 		 an allowed interface. As a side effect, we get the netmask of the
   1131 		 interface too, for localisation. */
   1132 
   1133 	      /* interface may be new since startup */
   1134 	      if (enumerate_interfaces() &&
   1135 		  getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) != -1)
   1136 		for (iface = daemon->interfaces; iface; iface = iface->next)
   1137 		  if (sockaddr_isequal(&iface->addr, &tcp_addr))
   1138 		    break;
   1139 	    }
   1140 
   1141 	  if (!iface)
   1142 	    {
   1143 	      shutdown(confd, SHUT_RDWR);
   1144 	      close(confd);
   1145 	    }
   1146 #ifndef NO_FORK
   1147 	  else if (!(daemon->options & OPT_DEBUG) && (p = fork()) != 0)
   1148 	    {
   1149 	      if (p != -1)
   1150 		{
   1151 		  int i;
   1152 		  for (i = 0; i < MAX_PROCS; i++)
   1153 		    if (daemon->tcp_pids[i] == 0)
   1154 		      {
   1155 			daemon->tcp_pids[i] = p;
   1156 			break;
   1157 		      }
   1158 		}
   1159 	      close(confd);
   1160 	    }
   1161 #endif
   1162 	  else
   1163 	    {
   1164 	      unsigned char *buff;
   1165 	      struct server *s;
   1166 	      int flags;
   1167 	      struct in_addr dst_addr_4;
   1168 
   1169 	      dst_addr_4.s_addr = 0;
   1170 
   1171 	       /* Arrange for SIGALARM after CHILD_LIFETIME seconds to
   1172 		  terminate the process. */
   1173 	      if (!(daemon->options & OPT_DEBUG))
   1174 		alarm(CHILD_LIFETIME);
   1175 
   1176 	      /* start with no upstream connections. */
   1177 	      for (s = daemon->servers; s; s = s->next)
   1178 		 s->tcpfd = -1;
   1179 
   1180 	      /* The connected socket inherits non-blocking
   1181 		 attribute from the listening socket.
   1182 		 Reset that here. */
   1183 	      if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
   1184 		fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
   1185 
   1186 	      if (listener->family == AF_INET)
   1187 		dst_addr_4 = iface->addr.in.sin_addr;
   1188 
   1189 	      buff = tcp_request(confd, now, dst_addr_4, iface->netmask);
   1190 
   1191 	      shutdown(confd, SHUT_RDWR);
   1192 	      close(confd);
   1193 
   1194 	      if (buff)
   1195 		free(buff);
   1196 
   1197 	      for (s = daemon->servers; s; s = s->next)
   1198 		if (s->tcpfd != -1)
   1199 		  {
   1200 		    shutdown(s->tcpfd, SHUT_RDWR);
   1201 		    close(s->tcpfd);
   1202 		  }
   1203 #ifndef NO_FORK
   1204 	      if (!(daemon->options & OPT_DEBUG))
   1205 		{
   1206 		  flush_log();
   1207 		  _exit(0);
   1208 		}
   1209 #endif
   1210 	    }
   1211 	}
   1212     }
   1213 }
   1214 
   1215 #ifdef HAVE_DHCP
   1216 int make_icmp_sock(void)
   1217 {
   1218   int fd;
   1219   int zeroopt = 0;
   1220 
   1221   if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
   1222     {
   1223       if (!fix_fd(fd) ||
   1224 	  setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1)
   1225 	{
   1226 	  close(fd);
   1227 	  fd = -1;
   1228 	}
   1229     }
   1230 
   1231   return fd;
   1232 }
   1233 
   1234 int icmp_ping(struct in_addr addr)
   1235 {
   1236   /* Try and get an ICMP echo from a machine. */
   1237 
   1238   /* Note that whilst in the three second wait, we check for
   1239      (and service) events on the DNS and TFTP  sockets, (so doing that
   1240      better not use any resources our caller has in use...)
   1241      but we remain deaf to signals or further DHCP packets. */
   1242 
   1243   int fd;
   1244   struct sockaddr_in saddr;
   1245   struct {
   1246     struct ip ip;
   1247     struct icmp icmp;
   1248   } packet;
   1249   unsigned short id = rand16();
   1250   unsigned int i, j;
   1251   int gotreply = 0;
   1252   time_t start, now;
   1253 
   1254 #if defined(HAVE_LINUX_NETWORK) || defined (HAVE_SOLARIS_NETWORK)
   1255   if ((fd = make_icmp_sock()) == -1)
   1256     return 0;
   1257 #else
   1258   int opt = 2000;
   1259   fd = daemon->dhcp_icmp_fd;
   1260   setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
   1261 #endif
   1262 
   1263   saddr.sin_family = AF_INET;
   1264   saddr.sin_port = 0;
   1265   saddr.sin_addr = addr;
   1266 #ifdef HAVE_SOCKADDR_SA_LEN
   1267   saddr.sin_len = sizeof(struct sockaddr_in);
   1268 #endif
   1269 
   1270   memset(&packet.icmp, 0, sizeof(packet.icmp));
   1271   packet.icmp.icmp_type = ICMP_ECHO;
   1272   packet.icmp.icmp_id = id;
   1273   for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++)
   1274     j += ((u16 *)&packet.icmp)[i];
   1275   while (j>>16)
   1276     j = (j & 0xffff) + (j >> 16);
   1277   packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
   1278 
   1279   while (sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
   1280 		(struct sockaddr *)&saddr, sizeof(saddr)) == -1 &&
   1281 	 retry_send());
   1282 
   1283   for (now = start = dnsmasq_time();
   1284        difftime(now, start) < (float)PING_WAIT;)
   1285     {
   1286       struct timeval tv;
   1287       fd_set rset, wset;
   1288       struct sockaddr_in faddr;
   1289       int maxfd = fd;
   1290       socklen_t len = sizeof(faddr);
   1291 
   1292       tv.tv_usec = 250000;
   1293       tv.tv_sec = 0;
   1294 
   1295       FD_ZERO(&rset);
   1296       FD_ZERO(&wset);
   1297       FD_SET(fd, &rset);
   1298       set_dns_listeners(now, &rset, &maxfd);
   1299       set_log_writer(&wset, &maxfd);
   1300 
   1301       if (select(maxfd+1, &rset, &wset, NULL, &tv) < 0)
   1302 	{
   1303 	  FD_ZERO(&rset);
   1304 	  FD_ZERO(&wset);
   1305 	}
   1306 
   1307       now = dnsmasq_time();
   1308 
   1309       check_log_writer(&wset);
   1310       check_dns_listeners(&rset, now);
   1311 
   1312 #ifdef HAVE_TFTP
   1313       check_tftp_listeners(&rset, now);
   1314 #endif
   1315 
   1316       if (FD_ISSET(fd, &rset) &&
   1317 	  recvfrom(fd, &packet, sizeof(packet), 0,
   1318 		   (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
   1319 	  saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
   1320 	  packet.icmp.icmp_type == ICMP_ECHOREPLY &&
   1321 	  packet.icmp.icmp_seq == 0 &&
   1322 	  packet.icmp.icmp_id == id)
   1323 	{
   1324 	  gotreply = 1;
   1325 	  break;
   1326 	}
   1327     }
   1328 
   1329 #if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
   1330   close(fd);
   1331 #else
   1332   opt = 1;
   1333   setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
   1334 #endif
   1335 
   1336   return gotreply;
   1337 }
   1338 #endif
   1339 
   1340 
   1341