File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / network.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:56:46 2021 UTC (3 years, 3 months ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_84, HEAD
dnsmasq 2.84

    1: /* dnsmasq is Copyright (c) 2000-2021 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: #ifdef HAVE_LINUX_NETWORK
   20: 
   21: int indextoname(int fd, int index, char *name)
   22: {
   23:   struct ifreq ifr;
   24:   
   25:   if (index == 0)
   26:     return 0;
   27: 
   28:   ifr.ifr_ifindex = index;
   29:   if (ioctl(fd, SIOCGIFNAME, &ifr) == -1)
   30:     return 0;
   31: 
   32:   safe_strncpy(name, ifr.ifr_name, IF_NAMESIZE);
   33: 
   34:   return 1;
   35: }
   36: 
   37: 
   38: #elif defined(HAVE_SOLARIS_NETWORK)
   39: 
   40: #include <zone.h>
   41: #include <alloca.h>
   42: #ifndef LIFC_UNDER_IPMP
   43: #  define LIFC_UNDER_IPMP 0
   44: #endif
   45: 
   46: int indextoname(int fd, int index, char *name)
   47: {
   48:   int64_t lifc_flags;
   49:   struct lifnum lifn;
   50:   int numifs, bufsize, i;
   51:   struct lifconf lifc;
   52:   struct lifreq *lifrp;
   53:   
   54:   if (index == 0)
   55:     return 0;
   56:   
   57:   if (getzoneid() == GLOBAL_ZONEID) 
   58:     {
   59:       if (!if_indextoname(index, name))
   60: 	return 0;
   61:       return 1;
   62:     }
   63:   
   64:   lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES | LIFC_UNDER_IPMP;
   65:   lifn.lifn_family = AF_UNSPEC;
   66:   lifn.lifn_flags = lifc_flags;
   67:   if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0) 
   68:     return 0;
   69:   
   70:   numifs = lifn.lifn_count;
   71:   bufsize = numifs * sizeof(struct lifreq);
   72:   
   73:   lifc.lifc_family = AF_UNSPEC;
   74:   lifc.lifc_flags = lifc_flags;
   75:   lifc.lifc_len = bufsize;
   76:   lifc.lifc_buf = alloca(bufsize);
   77:   
   78:   if (ioctl(fd, SIOCGLIFCONF, &lifc) < 0)  
   79:     return 0;
   80:   
   81:   lifrp = lifc.lifc_req;
   82:   for (i = lifc.lifc_len / sizeof(struct lifreq); i; i--, lifrp++) 
   83:     {
   84:       struct lifreq lifr;
   85:       safe_strncpy(lifr.lifr_name, lifrp->lifr_name, IF_NAMESIZE);
   86:       if (ioctl(fd, SIOCGLIFINDEX, &lifr) < 0) 
   87: 	return 0;
   88:       
   89:       if (lifr.lifr_index == index) {
   90: 	safe_strncpy(name, lifr.lifr_name, IF_NAMESIZE);
   91: 	return 1;
   92:       }
   93:     }
   94:   return 0;
   95: }
   96: 
   97: 
   98: #else
   99: 
  100: int indextoname(int fd, int index, char *name)
  101: { 
  102:   (void)fd;
  103: 
  104:   if (index == 0 || !if_indextoname(index, name))
  105:     return 0;
  106: 
  107:   return 1;
  108: }
  109: 
  110: #endif
  111: 
  112: int iface_check(int family, union all_addr *addr, char *name, int *auth)
  113: {
  114:   struct iname *tmp;
  115:   int ret = 1, match_addr = 0;
  116: 
  117:   /* Note: have to check all and not bail out early, so that we set the
  118:      "used" flags.
  119: 
  120:      May be called with family == AF_LOCALto check interface by name only. */
  121:   
  122:   if (auth)
  123:     *auth = 0;
  124:   
  125:   if (daemon->if_names || daemon->if_addrs)
  126:     {
  127:       ret = 0;
  128: 
  129:       for (tmp = daemon->if_names; tmp; tmp = tmp->next)
  130: 	if (tmp->name && wildcard_match(tmp->name, name))
  131: 	  ret = tmp->used = 1;
  132: 	        
  133:       if (addr)
  134: 	for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
  135: 	  if (tmp->addr.sa.sa_family == family)
  136: 	    {
  137: 	      if (family == AF_INET &&
  138: 		  tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
  139: 		ret = match_addr = tmp->used = 1;
  140: 	      else if (family == AF_INET6 &&
  141: 		       IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, 
  142: 					  &addr->addr6))
  143: 		ret = match_addr = tmp->used = 1;
  144: 	    }          
  145:     }
  146:   
  147:   if (!match_addr)
  148:     for (tmp = daemon->if_except; tmp; tmp = tmp->next)
  149:       if (tmp->name && wildcard_match(tmp->name, name))
  150: 	ret = 0;
  151:     
  152: 
  153:   for (tmp = daemon->authinterface; tmp; tmp = tmp->next)
  154:     if (tmp->name)
  155:       {
  156: 	if (strcmp(tmp->name, name) == 0 &&
  157: 	    (tmp->addr.sa.sa_family == 0 || tmp->addr.sa.sa_family == family))
  158: 	  break;
  159:       }
  160:     else if (addr && tmp->addr.sa.sa_family == AF_INET && family == AF_INET &&
  161: 	     tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
  162:       break;
  163:     else if (addr && tmp->addr.sa.sa_family == AF_INET6 && family == AF_INET6 &&
  164: 	     IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr6))
  165:       break;
  166: 
  167:   if (tmp && auth) 
  168:     {
  169:       *auth = 1;
  170:       ret = 1;
  171:     }
  172: 
  173:   return ret; 
  174: }
  175: 
  176: 
  177: /* Fix for problem that the kernel sometimes reports the loopback interface as the
  178:    arrival interface when a packet originates locally, even when sent to address of 
  179:    an interface other than the loopback. Accept packet if it arrived via a loopback 
  180:    interface, even when we're not accepting packets that way, as long as the destination
  181:    address is one we're believing. Interface list must be up-to-date before calling. */
  182: int loopback_exception(int fd, int family, union all_addr *addr, char *name)    
  183: {
  184:   struct ifreq ifr;
  185:   struct irec *iface;
  186: 
  187:   safe_strncpy(ifr.ifr_name, name, IF_NAMESIZE);
  188:   if (ioctl(fd, SIOCGIFFLAGS, &ifr) != -1 &&
  189:       ifr.ifr_flags & IFF_LOOPBACK)
  190:     {
  191:       for (iface = daemon->interfaces; iface; iface = iface->next)
  192: 	if (iface->addr.sa.sa_family == family)
  193: 	  {
  194: 	    if (family == AF_INET)
  195: 	      {
  196: 		if (iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
  197: 		  return 1;
  198: 	      }
  199: 	    else if (IN6_ARE_ADDR_EQUAL(&iface->addr.in6.sin6_addr, &addr->addr6))
  200: 	      return 1;
  201: 	  }
  202:     }
  203:   return 0;
  204: }
  205: 
  206: /* If we're configured with something like --interface=eth0:0 then we'll listen correctly
  207:    on the relevant address, but the name of the arrival interface, derived from the
  208:    index won't match the config. Check that we found an interface address for the arrival 
  209:    interface: daemon->interfaces must be up-to-date. */
  210: int label_exception(int index, int family, union all_addr *addr)
  211: {
  212:   struct irec *iface;
  213: 
  214:   /* labels only supported on IPv4 addresses. */
  215:   if (family != AF_INET)
  216:     return 0;
  217: 
  218:   for (iface = daemon->interfaces; iface; iface = iface->next)
  219:     if (iface->index == index && iface->addr.sa.sa_family == AF_INET &&
  220: 	iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
  221:       return 1;
  222: 
  223:   return 0;
  224: }
  225: 
  226: struct iface_param {
  227:   struct addrlist *spare;
  228:   int fd;
  229: };
  230: 
  231: static int iface_allowed(struct iface_param *param, int if_index, char *label,
  232: 			 union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags) 
  233: {
  234:   struct irec *iface;
  235:   int mtu = 0, loopback;
  236:   struct ifreq ifr;
  237:   int tftp_ok = !!option_bool(OPT_TFTP);
  238:   int dhcp_ok = 1;
  239:   int auth_dns = 0;
  240:   int is_label = 0;
  241: #if defined(HAVE_DHCP) || defined(HAVE_TFTP)
  242:   struct iname *tmp;
  243: #endif
  244: 
  245:   (void)prefixlen;
  246: 
  247:   if (!indextoname(param->fd, if_index, ifr.ifr_name) ||
  248:       ioctl(param->fd, SIOCGIFFLAGS, &ifr) == -1)
  249:     return 0;
  250:    
  251:   loopback = ifr.ifr_flags & IFF_LOOPBACK;
  252:   
  253:   if (loopback)
  254:     dhcp_ok = 0;
  255:   
  256:   if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
  257:     mtu = ifr.ifr_mtu;
  258:   
  259:   if (!label)
  260:     label = ifr.ifr_name;
  261:   else
  262:     is_label = strcmp(label, ifr.ifr_name);
  263:  
  264:   /* maintain a list of all addresses on all interfaces for --local-service option */
  265:   if (option_bool(OPT_LOCAL_SERVICE))
  266:     {
  267:       struct addrlist *al;
  268: 
  269:       if (param->spare)
  270: 	{
  271: 	  al = param->spare;
  272: 	  param->spare = al->next;
  273: 	}
  274:       else
  275: 	al = whine_malloc(sizeof(struct addrlist));
  276:       
  277:       if (al)
  278: 	{
  279: 	  al->next = daemon->interface_addrs;
  280: 	  daemon->interface_addrs = al;
  281: 	  al->prefixlen = prefixlen;
  282: 	  
  283: 	  if (addr->sa.sa_family == AF_INET)
  284: 	    {
  285: 	      al->addr.addr4 = addr->in.sin_addr;
  286: 	      al->flags = 0;
  287: 	    }
  288: 	  else
  289: 	    {
  290: 	      al->addr.addr6 = addr->in6.sin6_addr;
  291: 	      al->flags = ADDRLIST_IPV6;
  292: 	    } 
  293: 	}
  294:     }
  295:   
  296:   if (addr->sa.sa_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&addr->in6.sin6_addr))
  297:     {
  298:       struct interface_name *int_name;
  299:       struct addrlist *al;
  300: #ifdef HAVE_AUTH
  301:       struct auth_zone *zone;
  302:       struct auth_name_list *name;
  303: 
  304:       /* Find subnets in auth_zones */
  305:       for (zone = daemon->auth_zones; zone; zone = zone->next)
  306: 	for (name = zone->interface_names; name; name = name->next)
  307: 	  if (wildcard_match(name->name, label))
  308: 	    {
  309: 	      if (addr->sa.sa_family == AF_INET && (name->flags & AUTH4))
  310: 		{
  311: 		  if (param->spare)
  312: 		    {
  313: 		      al = param->spare;
  314: 		      param->spare = al->next;
  315: 		    }
  316: 		  else
  317: 		    al = whine_malloc(sizeof(struct addrlist));
  318: 		  
  319: 		  if (al)
  320: 		    {
  321: 		      al->next = zone->subnet;
  322: 		      zone->subnet = al;
  323: 		      al->prefixlen = prefixlen;
  324: 		      al->addr.addr4 = addr->in.sin_addr;
  325: 		      al->flags = 0;
  326: 		    }
  327: 		}
  328: 	      
  329: 	      if (addr->sa.sa_family == AF_INET6 && (name->flags & AUTH6))
  330: 		{
  331: 		  if (param->spare)
  332: 		    {
  333: 		      al = param->spare;
  334: 		      param->spare = al->next;
  335: 		    }
  336: 		  else
  337: 		    al = whine_malloc(sizeof(struct addrlist));
  338: 		  
  339: 		  if (al)
  340: 		    {
  341: 		      al->next = zone->subnet;
  342: 		      zone->subnet = al;
  343: 		      al->prefixlen = prefixlen;
  344: 		      al->addr.addr6 = addr->in6.sin6_addr;
  345: 		      al->flags = ADDRLIST_IPV6;
  346: 		    }
  347: 		} 
  348: 	    }
  349: #endif
  350:        
  351:       /* Update addresses from interface_names. These are a set independent
  352: 	 of the set we're listening on. */  
  353:       for (int_name = daemon->int_names; int_name; int_name = int_name->next)
  354: 	if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0 && 
  355: 	    (addr->sa.sa_family == int_name->family || int_name->family == 0))
  356: 	  {
  357: 	    if (param->spare)
  358: 	      {
  359: 		al = param->spare;
  360: 		param->spare = al->next;
  361: 	      }
  362: 	    else
  363: 	      al = whine_malloc(sizeof(struct addrlist));
  364: 	    
  365: 	    if (al)
  366: 	      {
  367: 		al->next = int_name->addr;
  368: 		int_name->addr = al;
  369: 		
  370: 		if (addr->sa.sa_family == AF_INET)
  371: 		  {
  372: 		    al->addr.addr4 = addr->in.sin_addr;
  373: 		    al->flags = 0;
  374: 		  }
  375: 		else
  376: 		 {
  377: 		    al->addr.addr6 = addr->in6.sin6_addr;
  378: 		    al->flags = ADDRLIST_IPV6;
  379: 		    /* Privacy addresses and addresses still undergoing DAD and deprecated addresses
  380: 		       don't appear in forward queries, but will in reverse ones. */
  381: 		    if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE_DEPRECATED | IFACE_TENTATIVE)))
  382: 		      al->flags |= ADDRLIST_REVONLY;
  383: 		 } 
  384: 	      }
  385: 	  }
  386:     }
  387:  
  388:   /* check whether the interface IP has been added already 
  389:      we call this routine multiple times. */
  390:   for (iface = daemon->interfaces; iface; iface = iface->next) 
  391:     if (sockaddr_isequal(&iface->addr, addr) && iface->index == if_index)
  392:       {
  393: 	iface->dad = !!(iface_flags & IFACE_TENTATIVE);
  394: 	iface->found = 1; /* for garbage collection */
  395: 	iface->netmask = netmask;
  396: 	return 1;
  397:       }
  398: 
  399:  /* If we are restricting the set of interfaces to use, make
  400:      sure that loopback interfaces are in that set. */
  401:   if (daemon->if_names && loopback)
  402:     {
  403:       struct iname *lo;
  404:       for (lo = daemon->if_names; lo; lo = lo->next)
  405: 	if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
  406: 	  break;
  407:       
  408:       if (!lo && (lo = whine_malloc(sizeof(struct iname)))) 
  409: 	{
  410: 	  if ((lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
  411: 	    {
  412: 	      strcpy(lo->name, ifr.ifr_name);
  413: 	      lo->used = 1;
  414: 	      lo->next = daemon->if_names;
  415: 	      daemon->if_names = lo;
  416: 	    }
  417: 	  else
  418: 	    free(lo);
  419: 	}
  420:     }
  421:   
  422:   if (addr->sa.sa_family == AF_INET &&
  423:       !iface_check(AF_INET, (union all_addr *)&addr->in.sin_addr, label, &auth_dns))
  424:     return 1;
  425: 
  426:   if (addr->sa.sa_family == AF_INET6 &&
  427:       !iface_check(AF_INET6, (union all_addr *)&addr->in6.sin6_addr, label, &auth_dns))
  428:     return 1;
  429:     
  430: #ifdef HAVE_DHCP
  431:   /* No DHCP where we're doing auth DNS. */
  432:   if (auth_dns)
  433:     {
  434:       tftp_ok = 0;
  435:       dhcp_ok = 0;
  436:     }
  437:   else
  438:     for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
  439:       if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
  440: 	{
  441: 	  tftp_ok = 0;
  442: 	  dhcp_ok = 0;
  443: 	}
  444: #endif
  445:  
  446:   
  447: #ifdef HAVE_TFTP
  448:   if (daemon->tftp_interfaces)
  449:     {
  450:       /* dedicated tftp interface list */
  451:       tftp_ok = 0;
  452:       for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
  453: 	if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
  454: 	  tftp_ok = 1;
  455:     }
  456: #endif
  457:   
  458:   /* add to list */
  459:   if ((iface = whine_malloc(sizeof(struct irec))))
  460:     {
  461:       iface->addr = *addr;
  462:       iface->netmask = netmask;
  463:       iface->tftp_ok = tftp_ok;
  464:       iface->dhcp_ok = dhcp_ok;
  465:       iface->dns_auth = auth_dns;
  466:       iface->mtu = mtu;
  467:       iface->dad = !!(iface_flags & IFACE_TENTATIVE);
  468:       iface->found = 1;
  469:       iface->done = iface->multicast_done = iface->warned = 0;
  470:       iface->index = if_index;
  471:       iface->label = is_label;
  472:       if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
  473: 	{
  474: 	  strcpy(iface->name, ifr.ifr_name);
  475: 	  iface->next = daemon->interfaces;
  476: 	  daemon->interfaces = iface;
  477: 	  return 1;
  478: 	}
  479:       free(iface);
  480: 
  481:     }
  482:   
  483:   errno = ENOMEM; 
  484:   return 0;
  485: }
  486: 
  487: static int iface_allowed_v6(struct in6_addr *local, int prefix, 
  488: 			    int scope, int if_index, int flags, 
  489: 			    int preferred, int valid, void *vparam)
  490: {
  491:   union mysockaddr addr;
  492:   struct in_addr netmask; /* dummy */
  493:   netmask.s_addr = 0;
  494: 
  495:   (void)scope; /* warning */
  496:   (void)preferred;
  497:   (void)valid;
  498:   
  499:   memset(&addr, 0, sizeof(addr));
  500: #ifdef HAVE_SOCKADDR_SA_LEN
  501:   addr.in6.sin6_len = sizeof(addr.in6);
  502: #endif
  503:   addr.in6.sin6_family = AF_INET6;
  504:   addr.in6.sin6_addr = *local;
  505:   addr.in6.sin6_port = htons(daemon->port);
  506:   /* FreeBSD insists this is zero for non-linklocal addresses */
  507:   if (IN6_IS_ADDR_LINKLOCAL(local))
  508:     addr.in6.sin6_scope_id = if_index;
  509:   else
  510:     addr.in6.sin6_scope_id = 0;
  511:   
  512:   return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, flags);
  513: }
  514: 
  515: static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
  516: 			    struct in_addr netmask, struct in_addr broadcast, void *vparam)
  517: {
  518:   union mysockaddr addr;
  519:   int prefix, bit;
  520:  
  521:   (void)broadcast; /* warning */
  522: 
  523:   memset(&addr, 0, sizeof(addr));
  524: #ifdef HAVE_SOCKADDR_SA_LEN
  525:   addr.in.sin_len = sizeof(addr.in);
  526: #endif
  527:   addr.in.sin_family = AF_INET;
  528:   addr.in.sin_addr = local;
  529:   addr.in.sin_port = htons(daemon->port);
  530: 
  531:   /* determine prefix length from netmask */
  532:   for (prefix = 32, bit = 1; (bit & ntohl(netmask.s_addr)) == 0 && prefix != 0; bit = bit << 1, prefix--);
  533: 
  534:   return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
  535: }
  536: 
  537: /*
  538:  * Clean old interfaces no longer found.
  539:  */
  540: static void clean_interfaces()
  541: {
  542:   struct irec *iface;
  543:   struct irec **up = &daemon->interfaces;
  544: 
  545:   for (iface = *up; iface; iface = *up)
  546:   {
  547:     if (!iface->found && !iface->done)
  548:       {
  549:         *up = iface->next;
  550:         free(iface->name);
  551:         free(iface);
  552:       }
  553:     else
  554:       {
  555:         up = &iface->next;
  556:       }
  557:   }
  558: }
  559: 
  560: /** Release listener if no other interface needs it.
  561:  *
  562:  * @return 1 if released, 0 if still required
  563:  */
  564: static int release_listener(struct listener *l)
  565: {
  566:   if (l->used > 1)
  567:     {
  568:       struct irec *iface;
  569:       for (iface = daemon->interfaces; iface; iface = iface->next)
  570: 	if (iface->done && sockaddr_isequal(&l->addr, &iface->addr))
  571: 	  {
  572: 	    if (iface->found)
  573: 	      {
  574: 		/* update listener to point to active interface instead */
  575: 		if (!l->iface->found)
  576: 		  l->iface = iface;
  577: 	      }
  578: 	    else
  579: 	      {
  580: 		l->used--;
  581: 		iface->done = 0;
  582: 	      }
  583: 	  }
  584: 
  585:       /* Someone is still using this listener, skip its deletion */
  586:       if (l->used > 0)
  587: 	return 0;
  588:     }
  589: 
  590:   if (l->iface->done)
  591:     {
  592:       int port;
  593: 
  594:       port = prettyprint_addr(&l->iface->addr, daemon->addrbuff);
  595:       my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s port %d"),
  596: 		l->iface->name, l->iface->index, daemon->addrbuff, port);
  597:       /* In case it ever returns */
  598:       l->iface->done = 0;
  599:     }
  600: 
  601:   if (l->fd != -1)
  602:     close(l->fd);
  603:   if (l->tcpfd != -1)
  604:     close(l->tcpfd);
  605:   if (l->tftpfd != -1)
  606:     close(l->tftpfd);
  607: 
  608:   free(l);
  609:   return 1;
  610: }
  611: 
  612: int enumerate_interfaces(int reset)
  613: {
  614:   static struct addrlist *spare = NULL;
  615:   static int done = 0;
  616:   struct iface_param param;
  617:   int errsave, ret = 1;
  618:   struct addrlist *addr, *tmp;
  619:   struct interface_name *intname;
  620:   struct irec *iface;
  621: #ifdef HAVE_AUTH
  622:   struct auth_zone *zone;
  623: #endif
  624: 
  625:   /* Do this max once per select cycle  - also inhibits netlink socket use
  626:    in TCP child processes. */
  627: 
  628:   if (reset)
  629:     {
  630:       done = 0;
  631:       return 1;
  632:     }
  633: 
  634:   if (done)
  635:     return 1;
  636: 
  637:   done = 1;
  638: 
  639:   if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
  640:     return 0;
  641:  
  642:   /* Mark interfaces for garbage collection */
  643:   for (iface = daemon->interfaces; iface; iface = iface->next) 
  644:     iface->found = 0;
  645: 
  646:   /* remove addresses stored against interface_names */
  647:   for (intname = daemon->int_names; intname; intname = intname->next)
  648:     {
  649:       for (addr = intname->addr; addr; addr = tmp)
  650: 	{
  651: 	  tmp = addr->next;
  652: 	  addr->next = spare;
  653: 	  spare = addr;
  654: 	}
  655:       
  656:       intname->addr = NULL;
  657:     }
  658: 
  659:   /* Remove list of addresses of local interfaces */
  660:   for (addr = daemon->interface_addrs; addr; addr = tmp)
  661:     {
  662:       tmp = addr->next;
  663:       addr->next = spare;
  664:       spare = addr;
  665:     }
  666:   daemon->interface_addrs = NULL;
  667:   
  668: #ifdef HAVE_AUTH
  669:   /* remove addresses stored against auth_zone subnets, but not 
  670:    ones configured as address literals */
  671:   for (zone = daemon->auth_zones; zone; zone = zone->next)
  672:     if (zone->interface_names)
  673:       {
  674: 	struct addrlist **up;
  675: 	for (up = &zone->subnet, addr = zone->subnet; addr; addr = tmp)
  676: 	  {
  677: 	    tmp = addr->next;
  678: 	    if (addr->flags & ADDRLIST_LITERAL)
  679: 	      up = &addr->next;
  680: 	    else
  681: 	      {
  682: 		*up = addr->next;
  683: 		addr->next = spare;
  684: 		spare = addr;
  685: 	      }
  686: 	  }
  687:       }
  688: #endif
  689: 
  690:   param.spare = spare;
  691:   
  692:   ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6);
  693: 
  694:   if (ret)
  695:     ret = iface_enumerate(AF_INET, &param, iface_allowed_v4); 
  696:  
  697:   errsave = errno;
  698:   close(param.fd);
  699:   
  700:   if (option_bool(OPT_CLEVERBIND))
  701:     { 
  702:       /* Garbage-collect listeners listening on addresses that no longer exist.
  703: 	 Does nothing when not binding interfaces or for listeners on localhost, 
  704: 	 since the ->iface field is NULL. Note that this needs the protections
  705: 	 against reentrancy, hence it's here.  It also means there's a possibility,
  706: 	 in OPT_CLEVERBIND mode, that at listener will just disappear after
  707: 	 a call to enumerate_interfaces, this is checked OK on all calls. */
  708:       struct listener *l, *tmp, **up;
  709:       int freed = 0;
  710:       
  711:       for (up = &daemon->listeners, l = daemon->listeners; l; l = tmp)
  712: 	{
  713: 	  tmp = l->next;
  714: 	  
  715: 	  if (!l->iface || l->iface->found)
  716: 	    up = &l->next;
  717: 	  else if (release_listener(l))
  718: 	    {
  719: 	      *up = tmp;
  720: 	      freed = 1;
  721: 	    }
  722: 	}
  723: 
  724:       if (freed)
  725: 	clean_interfaces();
  726:     }
  727: 
  728:   errno = errsave;
  729:   spare = param.spare;
  730:     
  731:   return ret;
  732: }
  733: 
  734: /* set NONBLOCK bit on fd: See Stevens 16.6 */
  735: int fix_fd(int fd)
  736: {
  737:   int flags;
  738: 
  739:   if ((flags = fcntl(fd, F_GETFL)) == -1 ||
  740:       fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
  741:     return 0;
  742:   
  743:   return 1;
  744: }
  745: 
  746: static int make_sock(union mysockaddr *addr, int type, int dienow)
  747: {
  748:   int family = addr->sa.sa_family;
  749:   int fd, rc, opt = 1;
  750:   
  751:   if ((fd = socket(family, type, 0)) == -1)
  752:     {
  753:       int port, errsave;
  754:       char *s;
  755: 
  756:       /* No error if the kernel just doesn't support this IP flavour */
  757:       if (errno == EPROTONOSUPPORT ||
  758: 	  errno == EAFNOSUPPORT ||
  759: 	  errno == EINVAL)
  760: 	return -1;
  761:       
  762:     err:
  763:       errsave = errno;
  764:       port = prettyprint_addr(addr, daemon->addrbuff);
  765:       if (!option_bool(OPT_NOWILD) && !option_bool(OPT_CLEVERBIND))
  766: 	sprintf(daemon->addrbuff, "port %d", port);
  767:       s = _("failed to create listening socket for %s: %s");
  768:       
  769:       if (fd != -1)
  770: 	close (fd);
  771: 	
  772:       errno = errsave;
  773: 
  774:       if (dienow)
  775: 	{
  776: 	  /* failure to bind addresses given by --listen-address at this point
  777: 	     is OK if we're doing bind-dynamic */
  778: 	  if (!option_bool(OPT_CLEVERBIND))
  779: 	    die(s, daemon->addrbuff, EC_BADNET);
  780: 	}
  781:       else
  782: 	my_syslog(LOG_WARNING, s, daemon->addrbuff, strerror(errno));
  783:       
  784:       return -1;
  785:     }	
  786:   
  787:   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd))
  788:     goto err;
  789:   
  790:   if (family == AF_INET6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
  791:     goto err;
  792:   
  793:   if ((rc = bind(fd, (struct sockaddr *)addr, sa_len(addr))) == -1)
  794:     goto err;
  795:   
  796:   if (type == SOCK_STREAM)
  797:     {
  798: #ifdef TCP_FASTOPEN
  799:       int qlen = 5;                           
  800:       setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
  801: #endif
  802:       
  803:       if (listen(fd, TCP_BACKLOG) == -1)
  804: 	goto err;
  805:     }
  806:   else if (family == AF_INET)
  807:     {
  808:       if (!option_bool(OPT_NOWILD))
  809: 	{
  810: #if defined(HAVE_LINUX_NETWORK) 
  811: 	  if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1)
  812: 	    goto err;
  813: #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
  814: 	  if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
  815: 	      setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1)
  816: 	    goto err;
  817: #endif
  818: 	}
  819:     }
  820:   else if (!set_ipv6pktinfo(fd))
  821:     goto err;
  822:   
  823:   return fd;
  824: }
  825: 
  826: int set_ipv6pktinfo(int fd)
  827: {
  828:   int opt = 1;
  829: 
  830:   /* The API changed around Linux 2.6.14 but the old ABI is still supported:
  831:      handle all combinations of headers and kernel.
  832:      OpenWrt note that this fixes the problem addressed by your very broken patch. */
  833:   daemon->v6pktinfo = IPV6_PKTINFO;
  834:   
  835: #ifdef IPV6_RECVPKTINFO
  836:   if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &opt, sizeof(opt)) != -1)
  837:     return 1;
  838: # ifdef IPV6_2292PKTINFO
  839:   else if (errno == ENOPROTOOPT && setsockopt(fd, IPPROTO_IPV6, IPV6_2292PKTINFO, &opt, sizeof(opt)) != -1)
  840:     {
  841:       daemon->v6pktinfo = IPV6_2292PKTINFO;
  842:       return 1;
  843:     }
  844: # endif 
  845: #else
  846:   if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &opt, sizeof(opt)) != -1)
  847:     return 1;
  848: #endif
  849: 
  850:   return 0;
  851: }
  852: 
  853: 
  854: /* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
  855: int tcp_interface(int fd, int af)
  856: { 
  857:   (void)fd; /* suppress potential unused warning */
  858:   (void)af; /* suppress potential unused warning */
  859:   int if_index = 0;
  860: 
  861: #ifdef HAVE_LINUX_NETWORK
  862:   int opt = 1;
  863:   struct cmsghdr *cmptr;
  864:   struct msghdr msg;
  865:   socklen_t len;
  866:   
  867:   /* use mshdr so that the CMSDG_* macros are available */
  868:   msg.msg_control = daemon->packet;
  869:   msg.msg_controllen = len = daemon->packet_buff_sz;
  870:   
  871:   /* we overwrote the buffer... */
  872:   daemon->srv_save = NULL;
  873:   
  874:   if (af == AF_INET)
  875:     {
  876:       if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) != -1 &&
  877: 	  getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, &len) != -1)
  878: 	{
  879: 	  msg.msg_controllen = len;
  880: 	  for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
  881: 	    if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
  882: 	      {
  883: 		union {
  884: 		  unsigned char *c;
  885: 		  struct in_pktinfo *p;
  886: 		} p;
  887: 		
  888: 		p.c = CMSG_DATA(cmptr);
  889: 		if_index = p.p->ipi_ifindex;
  890: 	      }
  891: 	}
  892:     }
  893:   else
  894:     {
  895:       /* Only the RFC-2292 API has the ability to find the interface for TCP connections,
  896: 	 it was removed in RFC-3542 !!!! 
  897: 
  898: 	 Fortunately, Linux kept the 2292 ABI when it moved to 3542. The following code always
  899: 	 uses the old ABI, and should work with pre- and post-3542 kernel headers */
  900: 
  901: #ifdef IPV6_2292PKTOPTIONS   
  902: #  define PKTOPTIONS IPV6_2292PKTOPTIONS
  903: #else
  904: #  define PKTOPTIONS IPV6_PKTOPTIONS
  905: #endif
  906: 
  907:       if (set_ipv6pktinfo(fd) &&
  908: 	  getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, &len) != -1)
  909: 	{
  910:           msg.msg_controllen = len;
  911: 	  for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
  912:             if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
  913:               {
  914:                 union {
  915:                   unsigned char *c;
  916:                   struct in6_pktinfo *p;
  917:                 } p;
  918:                 p.c = CMSG_DATA(cmptr);
  919: 		
  920: 		if_index = p.p->ipi6_ifindex;
  921:               }
  922: 	}
  923:     }
  924: #endif /* Linux */
  925:  
  926:   return if_index;
  927: }
  928:       
  929: static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
  930: {
  931:   struct listener *l = NULL;
  932:   int fd = -1, tcpfd = -1, tftpfd = -1;
  933: 
  934:   (void)do_tftp;
  935: 
  936:   if (daemon->port != 0)
  937:     {
  938:       fd = make_sock(addr, SOCK_DGRAM, dienow);
  939:       tcpfd = make_sock(addr, SOCK_STREAM, dienow);
  940:     }
  941:   
  942: #ifdef HAVE_TFTP
  943:   if (do_tftp)
  944:     {
  945:       if (addr->sa.sa_family == AF_INET)
  946: 	{
  947: 	  /* port must be restored to DNS port for TCP code */
  948: 	  short save = addr->in.sin_port;
  949: 	  addr->in.sin_port = htons(TFTP_PORT);
  950: 	  tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
  951: 	  addr->in.sin_port = save;
  952: 	}
  953:       else
  954: 	{
  955: 	  short save = addr->in6.sin6_port;
  956: 	  addr->in6.sin6_port = htons(TFTP_PORT);
  957: 	  tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
  958: 	  addr->in6.sin6_port = save;
  959: 	}  
  960:     }
  961: #endif
  962: 
  963:   if (fd != -1 || tcpfd != -1 || tftpfd != -1)
  964:     {
  965:       l = safe_malloc(sizeof(struct listener));
  966:       l->next = NULL;
  967:       l->fd = fd;
  968:       l->tcpfd = tcpfd;
  969:       l->tftpfd = tftpfd;
  970:       l->addr = *addr;
  971:       l->used = 1;
  972:       l->iface = NULL;
  973:     }
  974: 
  975:   return l;
  976: }
  977: 
  978: void create_wildcard_listeners(void)
  979: {
  980:   union mysockaddr addr;
  981:   struct listener *l, *l6;
  982: 
  983:   memset(&addr, 0, sizeof(addr));
  984: #ifdef HAVE_SOCKADDR_SA_LEN
  985:   addr.in.sin_len = sizeof(addr.in);
  986: #endif
  987:   addr.in.sin_family = AF_INET;
  988:   addr.in.sin_addr.s_addr = INADDR_ANY;
  989:   addr.in.sin_port = htons(daemon->port);
  990: 
  991:   l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
  992: 
  993:   memset(&addr, 0, sizeof(addr));
  994: #ifdef HAVE_SOCKADDR_SA_LEN
  995:   addr.in6.sin6_len = sizeof(addr.in6);
  996: #endif
  997:   addr.in6.sin6_family = AF_INET6;
  998:   addr.in6.sin6_addr = in6addr_any;
  999:   addr.in6.sin6_port = htons(daemon->port);
 1000:  
 1001:   l6 = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
 1002:   if (l) 
 1003:     l->next = l6;
 1004:   else 
 1005:     l = l6;
 1006: 
 1007:   daemon->listeners = l;
 1008: }
 1009: 
 1010: static struct listener *find_listener(union mysockaddr *addr)
 1011: {
 1012:   struct listener *l;
 1013:   for (l = daemon->listeners; l; l = l->next)
 1014:     if (sockaddr_isequal(&l->addr, addr))
 1015:       return l;
 1016:   return NULL;
 1017: }
 1018: 
 1019: void create_bound_listeners(int dienow)
 1020: {
 1021:   struct listener *new;
 1022:   struct irec *iface;
 1023:   struct iname *if_tmp;
 1024:   struct listener *existing;
 1025: 
 1026:   for (iface = daemon->interfaces; iface; iface = iface->next)
 1027:     if (!iface->done && !iface->dad && iface->found)
 1028:       {
 1029: 	existing = find_listener(&iface->addr);
 1030: 	if (existing)
 1031: 	  {
 1032: 	    iface->done = 1;
 1033: 	    existing->used++; /* increase usage counter */
 1034: 	  }
 1035: 	else if ((new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
 1036: 	  {
 1037: 	    new->iface = iface;
 1038: 	    new->next = daemon->listeners;
 1039: 	    daemon->listeners = new;
 1040: 	    iface->done = 1;
 1041: 
 1042: 	    /* Don't log the initial set of listen addresses created
 1043:                at startup, since this is happening before the logging
 1044:                system is initialised and the sign-on printed. */
 1045:             if (!dienow)
 1046:               {
 1047: 		int port = prettyprint_addr(&iface->addr, daemon->addrbuff);
 1048: 		my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s port %d"),
 1049: 			  iface->name, iface->index, daemon->addrbuff, port);
 1050: 	      }
 1051: 	  }
 1052:       }
 1053: 
 1054:   /* Check for --listen-address options that haven't been used because there's
 1055:      no interface with a matching address. These may be valid: eg it's possible
 1056:      to listen on 127.0.1.1 even if the loopback interface is 127.0.0.1
 1057: 
 1058:      If the address isn't valid the bind() will fail and we'll die() 
 1059:      (except in bind-dynamic mode, when we'll complain but keep trying.)
 1060: 
 1061:      The resulting listeners have the ->iface field NULL, and this has to be
 1062:      handled by the DNS and TFTP code. It disables --localise-queries processing
 1063:      (no netmask) and some MTU login the tftp code. */
 1064: 
 1065:   for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
 1066:     if (!if_tmp->used && 
 1067: 	(new = create_listeners(&if_tmp->addr, !!option_bool(OPT_TFTP), dienow)))
 1068:       {
 1069: 	new->next = daemon->listeners;
 1070: 	daemon->listeners = new;
 1071: 
 1072: 	if (!dienow)
 1073: 	  {
 1074: 	    int port = prettyprint_addr(&if_tmp->addr, daemon->addrbuff);
 1075: 	    my_syslog(LOG_DEBUG, _("listening on %s port %d"), daemon->addrbuff, port);
 1076: 	  }
 1077:       }
 1078: }
 1079: 
 1080: /* In --bind-interfaces, the only access control is the addresses we're listening on. 
 1081:    There's nothing to avoid a query to the address of an internal interface arriving via
 1082:    an external interface where we don't want to accept queries, except that in the usual 
 1083:    case the addresses of internal interfaces are RFC1918. When bind-interfaces in use, 
 1084:    and we listen on an address that looks like it's probably globally routeable, shout.
 1085: 
 1086:    The fix is to use --bind-dynamic, which actually checks the arrival interface too.
 1087:    Tough if your platform doesn't support this.
 1088: 
 1089:    Note that checking the arrival interface is supported in the standard IPv6 API and
 1090:    always done, so we don't warn about any IPv6 addresses here.
 1091: */
 1092: 
 1093: void warn_bound_listeners(void)
 1094: {
 1095:   struct irec *iface; 	
 1096:   int advice = 0;
 1097: 
 1098:   for (iface = daemon->interfaces; iface; iface = iface->next)
 1099:     if (!iface->dns_auth)
 1100:       {
 1101: 	if (iface->addr.sa.sa_family == AF_INET)
 1102: 	  {
 1103: 	    if (!private_net(iface->addr.in.sin_addr, 1))
 1104: 	      {
 1105: 		inet_ntop(AF_INET, &iface->addr.in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
 1106: 		iface->warned = advice = 1;
 1107: 		my_syslog(LOG_WARNING, 
 1108: 			  _("LOUD WARNING: listening on %s may accept requests via interfaces other than %s"),
 1109: 			  daemon->addrbuff, iface->name);
 1110: 	      }
 1111: 	  }
 1112:       }
 1113:   
 1114:   if (advice)
 1115:     my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)")); 
 1116: }
 1117: 
 1118: void warn_wild_labels(void)
 1119: {
 1120:   struct irec *iface;
 1121: 
 1122:   for (iface = daemon->interfaces; iface; iface = iface->next)
 1123:     if (iface->found && iface->name && iface->label)
 1124:       my_syslog(LOG_WARNING, _("warning: using interface %s instead"), iface->name);
 1125: }
 1126: 
 1127: void warn_int_names(void)
 1128: {
 1129:   struct interface_name *intname;
 1130:  
 1131:   for (intname = daemon->int_names; intname; intname = intname->next)
 1132:     if (!intname->addr)
 1133:       my_syslog(LOG_WARNING, _("warning: no addresses found for interface %s"), intname->intr);
 1134: }
 1135:  
 1136: int is_dad_listeners(void)
 1137: {
 1138:   struct irec *iface;
 1139:   
 1140:   if (option_bool(OPT_NOWILD))
 1141:     for (iface = daemon->interfaces; iface; iface = iface->next)
 1142:       if (iface->dad && !iface->done)
 1143: 	return 1;
 1144:   
 1145:   return 0;
 1146: }
 1147: 
 1148: #ifdef HAVE_DHCP6
 1149: void join_multicast(int dienow)      
 1150: {
 1151:   struct irec *iface, *tmp;
 1152: 
 1153:   for (iface = daemon->interfaces; iface; iface = iface->next)
 1154:     if (iface->addr.sa.sa_family == AF_INET6 && iface->dhcp_ok && !iface->multicast_done)
 1155:       {
 1156: 	/* There's an irec per address but we only want to join for multicast 
 1157: 	   once per interface. Weed out duplicates. */
 1158: 	for (tmp = daemon->interfaces; tmp; tmp = tmp->next)
 1159: 	  if (tmp->multicast_done && tmp->index == iface->index)
 1160: 	    break;
 1161: 	
 1162: 	iface->multicast_done = 1;
 1163: 	
 1164: 	if (!tmp)
 1165: 	  {
 1166: 	    struct ipv6_mreq mreq;
 1167: 	    int err = 0;
 1168: 
 1169: 	    mreq.ipv6mr_interface = iface->index;
 1170: 	    
 1171: 	    inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
 1172: 	    
 1173: 	    if ((daemon->doing_dhcp6 || daemon->relay6) &&
 1174: 		setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
 1175: 	      err = errno;
 1176: 	    
 1177: 	    inet_pton(AF_INET6, ALL_SERVERS, &mreq.ipv6mr_multiaddr);
 1178: 	    
 1179: 	    if (daemon->doing_dhcp6 && 
 1180: 		setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
 1181: 	      err = errno;
 1182: 	    
 1183: 	    inet_pton(AF_INET6, ALL_ROUTERS, &mreq.ipv6mr_multiaddr);
 1184: 	    
 1185: 	    if (daemon->doing_ra &&
 1186: 		setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
 1187: 	      err = errno;
 1188: 	    
 1189: 	    if (err)
 1190: 	      {
 1191: 		char *s = _("interface %s failed to join DHCPv6 multicast group: %s");
 1192: 		errno = err;
 1193: 
 1194: #ifdef HAVE_LINUX_NETWORK
 1195: 		if (errno == ENOMEM)
 1196: 		  my_syslog(LOG_ERR, _("try increasing /proc/sys/net/core/optmem_max"));
 1197: #endif
 1198: 
 1199: 		if (dienow)
 1200: 		  die(s, iface->name, EC_BADNET);
 1201: 		else
 1202: 		  my_syslog(LOG_ERR, s, iface->name, strerror(errno));
 1203: 	      }
 1204: 	  }
 1205:       }
 1206: }
 1207: #endif
 1208: 
 1209: /* return a UDP socket bound to a random port, have to cope with straying into
 1210:    occupied port nos and reserved ones. */
 1211: int random_sock(int family)
 1212: {
 1213:   int fd;
 1214: 
 1215:   if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
 1216:     {
 1217:       union mysockaddr addr;
 1218:       unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
 1219:       int tries = ports_avail < 30 ? 3 * ports_avail : 100;
 1220: 
 1221:       memset(&addr, 0, sizeof(addr));
 1222:       addr.sa.sa_family = family;
 1223: 
 1224:       /* don't loop forever if all ports in use. */
 1225: 
 1226:       if (fix_fd(fd))
 1227: 	while(tries--)
 1228: 	  {
 1229: 	    unsigned short port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
 1230: 	    
 1231: 	    if (family == AF_INET) 
 1232: 	      {
 1233: 		addr.in.sin_addr.s_addr = INADDR_ANY;
 1234: 		addr.in.sin_port = port;
 1235: #ifdef HAVE_SOCKADDR_SA_LEN
 1236: 		addr.in.sin_len = sizeof(struct sockaddr_in);
 1237: #endif
 1238: 	      }
 1239: 	    else
 1240: 	      {
 1241: 		addr.in6.sin6_addr = in6addr_any; 
 1242: 		addr.in6.sin6_port = port;
 1243: #ifdef HAVE_SOCKADDR_SA_LEN
 1244: 		addr.in6.sin6_len = sizeof(struct sockaddr_in6);
 1245: #endif
 1246: 	      }
 1247: 	    
 1248: 	    if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
 1249: 	      return fd;
 1250: 	    
 1251: 	    if (errno != EADDRINUSE && errno != EACCES)
 1252: 	      break;
 1253: 	  }
 1254: 
 1255:       close(fd);
 1256:     }
 1257: 
 1258:   return -1; 
 1259: }
 1260:   
 1261: 
 1262: int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp)
 1263: {
 1264:   union mysockaddr addr_copy = *addr;
 1265:   unsigned short port;
 1266:   int tries = 1, done = 0;
 1267:   unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
 1268:  
 1269:   if (addr_copy.sa.sa_family == AF_INET)
 1270:     port = addr_copy.in.sin_port;
 1271:   else
 1272:     port = addr_copy.in6.sin6_port;
 1273: 
 1274:   /* cannot set source _port_ for TCP connections. */
 1275:   if (is_tcp)
 1276:     port = 0;
 1277: 
 1278:   /* Bind a random port within the range given by min-port and max-port */
 1279:   if (port == 0)
 1280:     {
 1281:       tries = ports_avail < 30 ? 3 * ports_avail : 100;
 1282:       port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
 1283:     }
 1284:   
 1285:   while (tries--)
 1286:     {
 1287:       if (addr_copy.sa.sa_family == AF_INET)
 1288: 	addr_copy.in.sin_port = port;
 1289:       else
 1290: 	addr_copy.in6.sin6_port = port;
 1291: 
 1292:       if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) != -1)
 1293: 	{
 1294: 	  done = 1;
 1295: 	  break;
 1296: 	}
 1297:       
 1298:       if (errno != EADDRINUSE && errno != EACCES)
 1299: 	return 0;
 1300:       
 1301:       port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
 1302:     }
 1303: 
 1304:   if (!done)
 1305:     return 0;
 1306: 
 1307:   if (!is_tcp && ifindex > 0)
 1308:     {
 1309: #if defined(IP_UNICAST_IF)
 1310:       if (addr_copy.sa.sa_family == AF_INET)
 1311:         {
 1312:           uint32_t ifindex_opt = htonl(ifindex);
 1313:           return setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_opt, sizeof(ifindex_opt)) == 0;
 1314:         }
 1315: #endif
 1316: #if defined (IPV6_UNICAST_IF)
 1317:       if (addr_copy.sa.sa_family == AF_INET6)
 1318:         {
 1319:           uint32_t ifindex_opt = htonl(ifindex);
 1320:           return setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex_opt, sizeof(ifindex_opt)) == 0;
 1321:         }
 1322: #endif
 1323:     }
 1324: 
 1325:   (void)intname; /* suppress potential unused warning */
 1326: #if defined(SO_BINDTODEVICE)
 1327:   if (intname[0] != 0 &&
 1328:       setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
 1329:     return 0;
 1330: #endif
 1331: 
 1332:   return 1;
 1333: }
 1334: 
 1335: static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
 1336: {
 1337:   struct serverfd *sfd;
 1338:   unsigned int ifindex = 0;
 1339:   int errsave;
 1340:   int opt = 1;
 1341:   
 1342:   /* when using random ports, servers which would otherwise use
 1343:      the INADDR_ANY/port0 socket have sfd set to NULL */
 1344:   if (!daemon->osport && intname[0] == 0)
 1345:     {
 1346:       errno = 0;
 1347:       
 1348:       if (addr->sa.sa_family == AF_INET &&
 1349: 	  addr->in.sin_addr.s_addr == INADDR_ANY &&
 1350: 	  addr->in.sin_port == htons(0)) 
 1351: 	return NULL;
 1352: 
 1353:       if (addr->sa.sa_family == AF_INET6 &&
 1354: 	  memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
 1355: 	  addr->in6.sin6_port == htons(0)) 
 1356: 	return NULL;
 1357:     }
 1358: 
 1359:   if (intname && strlen(intname) != 0)
 1360:     ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
 1361:       
 1362:   /* may have a suitable one already */
 1363:   for (sfd = daemon->sfds; sfd; sfd = sfd->next )
 1364:     if (sockaddr_isequal(&sfd->source_addr, addr) &&
 1365: 	strcmp(intname, sfd->interface) == 0 &&
 1366: 	ifindex == sfd->ifindex) 
 1367:       return sfd;
 1368:   
 1369:   /* need to make a new one. */
 1370:   errno = ENOMEM; /* in case malloc fails. */
 1371:   if (!(sfd = whine_malloc(sizeof(struct serverfd))))
 1372:     return NULL;
 1373:   
 1374:   if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
 1375:     {
 1376:       free(sfd);
 1377:       return NULL;
 1378:     }
 1379: 
 1380:   if ((addr->sa.sa_family == AF_INET6 && setsockopt(sfd->fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1) ||
 1381:       !local_bind(sfd->fd, addr, intname, ifindex, 0) || !fix_fd(sfd->fd))
 1382:     { 
 1383:       errsave = errno; /* save error from bind/setsockopt. */
 1384:       close(sfd->fd);
 1385:       free(sfd);
 1386:       errno = errsave;
 1387:       return NULL;
 1388:     }
 1389: 
 1390:   safe_strncpy(sfd->interface, intname, sizeof(sfd->interface)); 
 1391:   sfd->source_addr = *addr;
 1392:   sfd->next = daemon->sfds;
 1393:   sfd->ifindex = ifindex;
 1394:   sfd->preallocated = 0;
 1395:   daemon->sfds = sfd;
 1396: 
 1397:   return sfd; 
 1398: }
 1399: 
 1400: /* create upstream sockets during startup, before root is dropped which may be needed
 1401:    this allows query_port to be a low port and interface binding */
 1402: void pre_allocate_sfds(void)
 1403: {
 1404:   struct server *srv;
 1405:   struct serverfd *sfd;
 1406:   
 1407:   if (daemon->query_port != 0)
 1408:     {
 1409:       union  mysockaddr addr;
 1410:       memset(&addr, 0, sizeof(addr));
 1411:       addr.in.sin_family = AF_INET;
 1412:       addr.in.sin_addr.s_addr = INADDR_ANY;
 1413:       addr.in.sin_port = htons(daemon->query_port);
 1414: #ifdef HAVE_SOCKADDR_SA_LEN
 1415:       addr.in.sin_len = sizeof(struct sockaddr_in);
 1416: #endif
 1417:       if ((sfd = allocate_sfd(&addr, "")))
 1418: 	sfd->preallocated = 1;
 1419: 
 1420:       memset(&addr, 0, sizeof(addr));
 1421:       addr.in6.sin6_family = AF_INET6;
 1422:       addr.in6.sin6_addr = in6addr_any;
 1423:       addr.in6.sin6_port = htons(daemon->query_port);
 1424: #ifdef HAVE_SOCKADDR_SA_LEN
 1425:       addr.in6.sin6_len = sizeof(struct sockaddr_in6);
 1426: #endif
 1427:       if ((sfd = allocate_sfd(&addr, "")))
 1428: 	sfd->preallocated = 1;
 1429:     }
 1430:   
 1431:   for (srv = daemon->servers; srv; srv = srv->next)
 1432:     if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
 1433: 	!allocate_sfd(&srv->source_addr, srv->interface) &&
 1434: 	errno != 0 &&
 1435: 	option_bool(OPT_NOWILD))
 1436:       {
 1437: 	(void)prettyprint_addr(&srv->source_addr, daemon->namebuff);
 1438: 	if (srv->interface[0] != 0)
 1439: 	  {
 1440: 	    strcat(daemon->namebuff, " ");
 1441: 	    strcat(daemon->namebuff, srv->interface);
 1442: 	  }
 1443: 	die(_("failed to bind server socket for %s: %s"),
 1444: 	    daemon->namebuff, EC_BADNET);
 1445:       }  
 1446: }
 1447: 
 1448: void mark_servers(int flag)
 1449: {
 1450:   struct server *serv;
 1451: 
 1452:   /* mark everything with argument flag */
 1453:   for (serv = daemon->servers; serv; serv = serv->next)
 1454:     {
 1455:       if (serv->flags & flag)
 1456: 	serv->flags |= SERV_MARK;
 1457: #ifdef HAVE_LOOP
 1458:       /* Give looped servers another chance */
 1459:       serv->flags &= ~SERV_LOOP;
 1460: #endif
 1461:     }
 1462: }
 1463: 
 1464: void cleanup_servers(void)
 1465: {
 1466:   struct server *serv, *tmp, **up;
 1467: 
 1468:   /* unlink and free anything still marked. */
 1469:   for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp) 
 1470:     {
 1471:       tmp = serv->next;
 1472:       if (serv->flags & SERV_MARK)
 1473:        {
 1474:          server_gone(serv);
 1475:          *up = serv->next;
 1476:          if (serv->domain)
 1477: 	   free(serv->domain);
 1478: 	 free(serv);
 1479:        }
 1480:       else 
 1481:        up = &serv->next;
 1482:     }
 1483: 
 1484: #ifdef HAVE_LOOP
 1485:   /* Now we have a new set of servers, test for loops. */
 1486:   loop_send_probes();
 1487: #endif
 1488: }
 1489: 
 1490: void add_update_server(int flags,
 1491: 		       union mysockaddr *addr,
 1492: 		       union mysockaddr *source_addr,
 1493: 		       const char *interface,
 1494: 		       const char *domain)
 1495: {
 1496:   struct server *serv, *next = NULL;
 1497:   char *domain_str = NULL;
 1498:   
 1499:   /* See if there is a suitable candidate, and unmark */
 1500:   for (serv = daemon->servers; serv; serv = serv->next)
 1501:     if (serv->flags & SERV_MARK)
 1502:       {
 1503: 	if (domain)
 1504: 	  {
 1505: 	    if (!(serv->flags & SERV_HAS_DOMAIN) || !hostname_isequal(domain, serv->domain))
 1506: 	      continue;
 1507: 	  }
 1508: 	else
 1509: 	  {
 1510: 	    if (serv->flags & SERV_HAS_DOMAIN)
 1511: 	      continue;
 1512: 	  }
 1513: 	
 1514:         break;
 1515:       }
 1516: 
 1517:   if (serv)
 1518:     {
 1519:       domain_str = serv->domain;
 1520:       next = serv->next;
 1521:     }
 1522:   else if ((serv = whine_malloc(sizeof (struct server))))
 1523:     {
 1524:       /* Not found, create a new one. */
 1525:       if (domain && !(domain_str = whine_malloc(strlen(domain)+1)))
 1526: 	{
 1527: 	  free(serv);
 1528:           serv = NULL;
 1529:         }
 1530:       else
 1531:         {
 1532: 	  struct server *s;
 1533: 	  /* Add to the end of the chain, for order */
 1534: 	  if (!daemon->servers)
 1535: 	    daemon->servers = serv;
 1536: 	  else
 1537: 	    {
 1538: 	      for (s = daemon->servers; s->next; s = s->next);
 1539: 	      s->next = serv;
 1540: 	    }
 1541: 	  if (domain)
 1542: 	    strcpy(domain_str, domain);
 1543: 	}
 1544:     }
 1545:   
 1546:   if (serv)
 1547:     {
 1548:       memset(serv, 0, sizeof(struct server));
 1549:       serv->flags = flags;
 1550:       serv->domain = domain_str;
 1551:       serv->next = next;
 1552:       serv->queries = serv->failed_queries = 0;
 1553: #ifdef HAVE_LOOP
 1554:       serv->uid = rand32();
 1555: #endif      
 1556: 
 1557:       if (domain)
 1558: 	serv->flags |= SERV_HAS_DOMAIN;
 1559:       
 1560:       if (interface)
 1561: 	safe_strncpy(serv->interface, interface, sizeof(serv->interface));
 1562:       if (addr)
 1563: 	serv->addr = *addr;
 1564:       if (source_addr)
 1565: 	serv->source_addr = *source_addr;
 1566:     }
 1567: }
 1568: 
 1569: void check_servers(void)
 1570: {
 1571:   struct irec *iface;
 1572:   struct server *serv;
 1573:   struct serverfd *sfd, *tmp, **up;
 1574:   int port = 0, count;
 1575:   int locals = 0;
 1576: 
 1577:   /* interface may be new since startup */
 1578:   if (!option_bool(OPT_NOWILD))
 1579:     enumerate_interfaces(0);
 1580: 
 1581:   /* don't garbage collect pre-allocated sfds. */
 1582:   for (sfd = daemon->sfds; sfd; sfd = sfd->next)
 1583:     sfd->used = sfd->preallocated;
 1584: 
 1585:   for (count = 0, serv = daemon->servers; serv; serv = serv->next)
 1586:     {
 1587:       if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
 1588: 	{
 1589: 	  /* Init edns_pktsz for newly created server records. */
 1590: 	  if (serv->edns_pktsz == 0)
 1591: 	    serv->edns_pktsz = daemon->edns_pktsz;
 1592: 	  
 1593: #ifdef HAVE_DNSSEC
 1594: 	  if (option_bool(OPT_DNSSEC_VALID))
 1595: 	    { 
 1596: 	      if (!(serv->flags & SERV_FOR_NODOTS))
 1597: 		serv->flags |= SERV_DO_DNSSEC;
 1598: 	      
 1599: 	      /* Disable DNSSEC validation when using server=/domain/.... servers
 1600: 		 unless there's a configured trust anchor. */
 1601: 	      if (serv->flags & SERV_HAS_DOMAIN)
 1602: 		{
 1603: 		  struct ds_config *ds;
 1604: 		  char *domain = serv->domain;
 1605: 		  
 1606: 		  /* .example.com is valid */
 1607: 		  while (*domain == '.')
 1608: 		    domain++;
 1609: 		  
 1610: 		  for (ds = daemon->ds; ds; ds = ds->next)
 1611: 		    if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
 1612: 		      break;
 1613: 		  
 1614: 		  if (!ds)
 1615: 		    serv->flags &= ~SERV_DO_DNSSEC;
 1616: 		}
 1617: 	    }
 1618: #endif
 1619: 
 1620: 	  port = prettyprint_addr(&serv->addr, daemon->namebuff);
 1621: 	  
 1622: 	  /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
 1623: 	  if (serv->addr.sa.sa_family == AF_INET &&
 1624: 	      serv->addr.in.sin_addr.s_addr == 0)
 1625: 	    {
 1626: 	      serv->flags |= SERV_MARK;
 1627: 	      continue;
 1628: 	    }
 1629: 
 1630: 	  for (iface = daemon->interfaces; iface; iface = iface->next)
 1631: 	    if (sockaddr_isequal(&serv->addr, &iface->addr))
 1632: 	      break;
 1633: 	  if (iface)
 1634: 	    {
 1635: 	      my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
 1636: 	      serv->flags |= SERV_MARK;
 1637: 	      continue;
 1638: 	    }
 1639: 	  
 1640: 	  /* Do we need a socket set? */
 1641: 	  if (!serv->sfd && 
 1642: 	      !(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface)) &&
 1643: 	      errno != 0)
 1644: 	    {
 1645: 	      my_syslog(LOG_WARNING, 
 1646: 			_("ignoring nameserver %s - cannot make/bind socket: %s"),
 1647: 			daemon->namebuff, strerror(errno));
 1648: 	      serv->flags |= SERV_MARK;
 1649: 	      continue;
 1650: 	    }
 1651: 	  
 1652: 	  if (serv->sfd)
 1653: 	    serv->sfd->used = 1;
 1654: 	}
 1655:       
 1656:       if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
 1657: 	{
 1658: 	  if (++count > SERVERS_LOGGED)
 1659: 	    continue;
 1660: 	  
 1661: 	  if (serv->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
 1662: 	    {
 1663: 	      char *s1, *s2, *s3 = "";
 1664: #ifdef HAVE_DNSSEC
 1665: 	      if (option_bool(OPT_DNSSEC_VALID) && !(serv->flags & SERV_DO_DNSSEC))
 1666: 		s3 = _("(no DNSSEC)");
 1667: #endif
 1668: 	      if (!(serv->flags & SERV_HAS_DOMAIN))
 1669: 		s1 = _("unqualified"), s2 = _("names");
 1670: 	      else if (strlen(serv->domain) == 0)
 1671: 		s1 = _("default"), s2 = "";
 1672: 	      else
 1673: 		s1 = _("domain"), s2 = serv->domain;
 1674: 	      
 1675: 	      if (serv->flags & SERV_NO_ADDR)
 1676: 		{
 1677: 		  count--;
 1678: 		  if (++locals <= LOCALS_LOGGED)
 1679: 			my_syslog(LOG_INFO, _("using only locally-known addresses for %s %s"), s1, s2);
 1680: 	        }
 1681: 	      else if (serv->flags & SERV_USE_RESOLV)
 1682: 		my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
 1683: 	      else 
 1684: 		my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s %s"), daemon->namebuff, port, s1, s2, s3);
 1685: 	    }
 1686: #ifdef HAVE_LOOP
 1687: 	  else if (serv->flags & SERV_LOOP)
 1688: 	    my_syslog(LOG_INFO, _("NOT using nameserver %s#%d - query loop detected"), daemon->namebuff, port); 
 1689: #endif
 1690: 	  else if (serv->interface[0] != 0)
 1691: 	    my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, serv->interface); 
 1692: 	  else
 1693: 	    my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port); 
 1694: 	}
 1695:     }
 1696:   
 1697:   if (locals > LOCALS_LOGGED)
 1698:     my_syslog(LOG_INFO, _("using %d more local addresses"), locals - LOCALS_LOGGED);
 1699:   if (count - 1 > SERVERS_LOGGED)
 1700:     my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
 1701: 
 1702:   /* Remove unused sfds */
 1703:   for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmp)
 1704:     {
 1705:        tmp = sfd->next;
 1706:        if (!sfd->used) 
 1707: 	{
 1708: 	  *up = sfd->next;
 1709: 	  close(sfd->fd);
 1710: 	  free(sfd);
 1711: 	} 
 1712:       else
 1713: 	up = &sfd->next;
 1714:     }
 1715:   
 1716:   cleanup_servers();
 1717: }
 1718: 
 1719: /* Return zero if no servers found, in that case we keep polling.
 1720:    This is a protection against an update-time/write race on resolv.conf */
 1721: int reload_servers(char *fname)
 1722: {
 1723:   FILE *f;
 1724:   char *line;
 1725:   int gotone = 0;
 1726: 
 1727:   /* buff happens to be MAXDNAME long... */
 1728:   if (!(f = fopen(fname, "r")))
 1729:     {
 1730:       my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
 1731:       return 0;
 1732:     }
 1733:    
 1734:   mark_servers(SERV_FROM_RESOLV);
 1735:     
 1736:   while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
 1737:     {
 1738:       union mysockaddr addr, source_addr;
 1739:       char *token = strtok(line, " \t\n\r");
 1740:       
 1741:       if (!token)
 1742: 	continue;
 1743:       if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
 1744: 	continue;
 1745:       if (!(token = strtok(NULL, " \t\n\r")))
 1746: 	continue;
 1747:       
 1748:       memset(&addr, 0, sizeof(addr));
 1749:       memset(&source_addr, 0, sizeof(source_addr));
 1750:       
 1751:       if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
 1752: 	{
 1753: #ifdef HAVE_SOCKADDR_SA_LEN
 1754: 	  source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
 1755: #endif
 1756: 	  source_addr.in.sin_family = addr.in.sin_family = AF_INET;
 1757: 	  addr.in.sin_port = htons(NAMESERVER_PORT);
 1758: 	  source_addr.in.sin_addr.s_addr = INADDR_ANY;
 1759: 	  source_addr.in.sin_port = htons(daemon->query_port);
 1760: 	}
 1761:       else 
 1762: 	{	
 1763: 	  int scope_index = 0;
 1764: 	  char *scope_id = strchr(token, '%');
 1765: 	  
 1766: 	  if (scope_id)
 1767: 	    {
 1768: 	      *(scope_id++) = 0;
 1769: 	      scope_index = if_nametoindex(scope_id);
 1770: 	    }
 1771: 	  
 1772: 	  if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
 1773: 	    {
 1774: #ifdef HAVE_SOCKADDR_SA_LEN
 1775: 	      source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
 1776: #endif
 1777: 	      source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
 1778: 	      source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0;
 1779: 	      addr.in6.sin6_port = htons(NAMESERVER_PORT);
 1780: 	      addr.in6.sin6_scope_id = scope_index;
 1781: 	      source_addr.in6.sin6_addr = in6addr_any;
 1782: 	      source_addr.in6.sin6_port = htons(daemon->query_port);
 1783: 	      source_addr.in6.sin6_scope_id = 0;
 1784: 	    }
 1785: 	  else
 1786: 	    continue;
 1787: 	}
 1788: 
 1789:       add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL);
 1790:       gotone = 1;
 1791:     }
 1792:   
 1793:   fclose(f);
 1794:   cleanup_servers();
 1795: 
 1796:   return gotone;
 1797: }
 1798: 
 1799: /* Called when addresses are added or deleted from an interface */
 1800: void newaddress(time_t now)
 1801: {
 1802:   (void)now;
 1803:   
 1804:   if (option_bool(OPT_CLEVERBIND) || option_bool(OPT_LOCAL_SERVICE) ||
 1805:       daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
 1806:     enumerate_interfaces(0);
 1807:   
 1808:   if (option_bool(OPT_CLEVERBIND))
 1809:     create_bound_listeners(0);
 1810:   
 1811: #ifdef HAVE_DHCP6
 1812:   if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
 1813:     join_multicast(0);
 1814:   
 1815:   if (daemon->doing_dhcp6 || daemon->doing_ra)
 1816:     dhcp_construct_contexts(now);
 1817:   
 1818:   if (daemon->doing_dhcp6)
 1819:     lease_find_interfaces(now);
 1820: #endif
 1821: }
 1822: 
 1823: 
 1824: 
 1825: 
 1826: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>