File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / network.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:31:38 2014 UTC (10 years ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_71, HEAD
dnsmasq 2.71

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

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