Annotation of embedaddon/dnsmasq/src/network.c, revision 1.1.1.4

1.1.1.4 ! misho       1: /* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
1.1       misho       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: 
1.1.1.4 ! misho      32:   safe_strncpy(name, ifr.ifr_name, IF_NAMESIZE);
1.1       misho      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;
1.1.1.4 ! misho      85:       safe_strncpy(lifr.lifr_name, lifrp->lifr_name, IF_NAMESIZE);
1.1       misho      86:       if (ioctl(fd, SIOCGLIFINDEX, &lifr) < 0) 
                     87:        return 0;
                     88:       
                     89:       if (lifr.lifr_index == index) {
1.1.1.4 ! misho      90:        safe_strncpy(name, lifr.lifr_name, IF_NAMESIZE);
1.1       misho      91:        return 1;
                     92:       }
                     93:     }
                     94:   return 0;
                     95: }
                     96: 
                     97: 
                     98: #else
                     99: 
                    100: int indextoname(int fd, int index, char *name)
                    101: { 
1.1.1.2   misho     102:   (void)fd;
                    103: 
1.1       misho     104:   if (index == 0 || !if_indextoname(index, name))
                    105:     return 0;
                    106: 
                    107:   return 1;
                    108: }
                    109: 
                    110: #endif
                    111: 
1.1.1.4 ! misho     112: int iface_check(int family, union all_addr *addr, char *name, int *auth)
1.1       misho     113: {
                    114:   struct iname *tmp;
1.1.1.2   misho     115:   int ret = 1, match_addr = 0;
1.1       misho     116: 
                    117:   /* Note: have to check all and not bail out early, so that we set the
1.1.1.2   misho     118:      "used" flags.
                    119: 
                    120:      May be called with family == AF_LOCALto check interface by name only. */
1.1       misho     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 &&
1.1.1.4 ! misho     138:                  tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
1.1.1.2   misho     139:                ret = match_addr = tmp->used = 1;
1.1       misho     140:              else if (family == AF_INET6 &&
                    141:                       IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, 
1.1.1.4 ! misho     142:                                          &addr->addr6))
1.1.1.2   misho     143:                ret = match_addr = tmp->used = 1;
1.1       misho     144:            }          
                    145:     }
                    146:   
1.1.1.2   misho     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;
1.1       misho     151:     
                    152: 
                    153:   for (tmp = daemon->authinterface; tmp; tmp = tmp->next)
                    154:     if (tmp->name)
                    155:       {
1.1.1.2   misho     156:        if (strcmp(tmp->name, name) == 0 &&
                    157:            (tmp->addr.sa.sa_family == 0 || tmp->addr.sa.sa_family == family))
1.1       misho     158:          break;
                    159:       }
                    160:     else if (addr && tmp->addr.sa.sa_family == AF_INET && family == AF_INET &&
1.1.1.4 ! misho     161:             tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
1.1       misho     162:       break;
                    163:     else if (addr && tmp->addr.sa.sa_family == AF_INET6 && family == AF_INET6 &&
1.1.1.4 ! misho     164:             IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr6))
1.1       misho     165:       break;
                    166: 
                    167:   if (tmp && auth) 
                    168:     {
                    169:       *auth = 1;
                    170:       ret = 1;
                    171:     }
                    172: 
                    173:   return ret; 
                    174: }
                    175: 
                    176: 
1.1.1.4 ! misho     177: /* Fix for problem that the kernel sometimes reports the loopback interface as the
1.1       misho     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. */
1.1.1.4 ! misho     182: int loopback_exception(int fd, int family, union all_addr *addr, char *name)    
1.1       misho     183: {
                    184:   struct ifreq ifr;
                    185:   struct irec *iface;
                    186: 
1.1.1.4 ! misho     187:   safe_strncpy(ifr.ifr_name, name, IF_NAMESIZE);
1.1       misho     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:              {
1.1.1.4 ! misho     196:                if (iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
1.1       misho     197:                  return 1;
                    198:              }
1.1.1.4 ! misho     199:            else if (IN6_ARE_ADDR_EQUAL(&iface->addr.in6.sin6_addr, &addr->addr6))
1.1       misho     200:              return 1;
                    201:          }
                    202:     }
                    203:   return 0;
                    204: }
                    205: 
1.1.1.2   misho     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. */
1.1.1.4 ! misho     210: int label_exception(int index, int family, union all_addr *addr)
1.1       misho     211: {
                    212:   struct irec *iface;
1.1.1.2   misho     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 &&
1.1.1.4 ! misho     220:        iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
1.1.1.2   misho     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,
1.1.1.3   misho     232:                         union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags) 
1.1.1.2   misho     233: {
                    234:   struct irec *iface;
                    235:   int mtu = 0, loopback;
1.1       misho     236:   struct ifreq ifr;
                    237:   int tftp_ok = !!option_bool(OPT_TFTP);
                    238:   int dhcp_ok = 1;
                    239:   int auth_dns = 0;
1.1.1.4 ! misho     240:   int is_label = 0;
1.1.1.2   misho     241: #if defined(HAVE_DHCP) || defined(HAVE_TFTP)
1.1       misho     242:   struct iname *tmp;
                    243: #endif
                    244: 
1.1.1.2   misho     245:   (void)prefixlen;
1.1       misho     246: 
1.1.1.2   misho     247:   if (!indextoname(param->fd, if_index, ifr.ifr_name) ||
                    248:       ioctl(param->fd, SIOCGIFFLAGS, &ifr) == -1)
                    249:     return 0;
1.1       misho     250:    
                    251:   loopback = ifr.ifr_flags & IFF_LOOPBACK;
                    252:   
                    253:   if (loopback)
1.1.1.2   misho     254:     dhcp_ok = 0;
                    255:   
                    256:   if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
1.1       misho     257:     mtu = ifr.ifr_mtu;
                    258:   
1.1.1.2   misho     259:   if (!label)
                    260:     label = ifr.ifr_name;
1.1.1.4 ! misho     261:   else
        !           262:     is_label = strcmp(label, ifr.ifr_name);
1.1.1.2   misho     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:            {
1.1.1.4 ! misho     285:              al->addr.addr4 = addr->in.sin_addr;
1.1.1.2   misho     286:              al->flags = 0;
                    287:            }
                    288:          else
                    289:            {
1.1.1.4 ! misho     290:              al->addr.addr6 = addr->in6.sin6_addr;
1.1.1.2   misho     291:              al->flags = ADDRLIST_IPV6;
                    292:            } 
                    293:        }
                    294:     }
1.1       misho     295:   
1.1.1.2   misho     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;
1.1.1.4 ! misho     324:                      al->addr.addr4 = addr->in.sin_addr;
1.1.1.2   misho     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;
1.1.1.4 ! misho     344:                      al->addr.addr6 = addr->in6.sin6_addr;
1.1.1.2   misho     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:                  {
1.1.1.4 ! misho     372:                    al->addr.addr4 = addr->in.sin_addr;
1.1.1.2   misho     373:                    al->flags = 0;
                    374:                  }
                    375:                else
                    376:                 {
1.1.1.4 ! misho     377:                    al->addr.addr6 = addr->in6.sin6_addr;
1.1.1.2   misho     378:                    al->flags = ADDRLIST_IPV6;
1.1.1.3   misho     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;
1.1.1.2   misho     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) 
1.1.1.4 ! misho     391:     if (sockaddr_isequal(&iface->addr, addr) && iface->index == if_index)
1.1.1.2   misho     392:       {
1.1.1.3   misho     393:        iface->dad = !!(iface_flags & IFACE_TENTATIVE);
1.1.1.2   misho     394:        iface->found = 1; /* for garbage collection */
1.1.1.4 ! misho     395:        iface->netmask = netmask;
1.1.1.2   misho     396:        return 1;
                    397:       }
                    398: 
                    399:  /* If we are restricting the set of interfaces to use, make
1.1       misho     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 &&
1.1.1.4 ! misho     423:       !iface_check(AF_INET, (union all_addr *)&addr->in.sin_addr, label, &auth_dns))
1.1       misho     424:     return 1;
                    425: 
                    426:   if (addr->sa.sa_family == AF_INET6 &&
1.1.1.4 ! misho     427:       !iface_check(AF_INET6, (union all_addr *)&addr->in6.sin6_addr, label, &auth_dns))
1.1       misho     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:  
1.1.1.2   misho     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:   
1.1       misho     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;
1.1.1.3   misho     467:       iface->dad = !!(iface_flags & IFACE_TENTATIVE);
1.1.1.2   misho     468:       iface->found = 1;
                    469:       iface->done = iface->multicast_done = iface->warned = 0;
1.1       misho     470:       iface->index = if_index;
1.1.1.4 ! misho     471:       iface->label = is_label;
1.1       misho     472:       if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
                    473:        {
                    474:          strcpy(iface->name, ifr.ifr_name);
1.1.1.2   misho     475:          iface->next = daemon->interfaces;
                    476:          daemon->interfaces = iface;
1.1       misho     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);
1.1.1.2   misho     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;
1.1       misho     511:   
1.1.1.3   misho     512:   return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, flags);
1.1       misho     513: }
                    514: 
1.1.1.2   misho     515: static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
1.1       misho     516:                            struct in_addr netmask, struct in_addr broadcast, void *vparam)
                    517: {
                    518:   union mysockaddr addr;
1.1.1.2   misho     519:   int prefix, bit;
1.1.1.3   misho     520:  
                    521:   (void)broadcast; /* warning */
1.1       misho     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: 
1.1.1.2   misho     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);
1.1       misho     535: }
1.1.1.4 ! misho     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: 
1.1.1.2   misho     612: int enumerate_interfaces(int reset)
1.1       misho     613: {
1.1.1.2   misho     614:   static struct addrlist *spare = NULL;
1.1.1.3   misho     615:   static int done = 0;
1.1.1.2   misho     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: 
1.1.1.3   misho     634:   if (done)
1.1.1.2   misho     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);
1.1       misho     693: 
1.1.1.2   misho     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
1.1.1.4 ! misho     705:         against reentrancy, hence it's here.  It also means there's a possibility,
1.1.1.2   misho     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;
1.1.1.4 ! misho     709:       int freed = 0;
1.1.1.2   misho     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;
1.1.1.4 ! misho     717:          else if (release_listener(l))
1.1.1.2   misho     718:            {
1.1.1.4 ! misho     719:              *up = tmp;
        !           720:              freed = 1;
1.1.1.2   misho     721:            }
                    722:        }
1.1.1.4 ! misho     723: 
        !           724:       if (freed)
        !           725:        clean_interfaces();
1.1.1.2   misho     726:     }
1.1.1.4 ! misho     727: 
1.1.1.2   misho     728:   errno = errsave;
                    729:   spare = param.spare;
1.1.1.3   misho     730:     
1.1.1.2   misho     731:   return ret;
1.1       misho     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:     {
1.1.1.4 ! misho     753:       int port, errsave;
1.1       misho     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:
1.1.1.4 ! misho     763:       errsave = errno;
1.1       misho     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);
1.1.1.2   misho     771:        
1.1.1.4 ! misho     772:       errno = errsave;
1.1.1.2   misho     773: 
1.1       misho     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:     {
1.1.1.4 ! misho     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)
1.1       misho     804:        goto err;
                    805:     }
1.1.1.2   misho     806:   else if (family == AF_INET)
1.1       misho     807:     {
1.1.1.2   misho     808:       if (!option_bool(OPT_NOWILD))
1.1       misho     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:        }
1.1.1.2   misho     819:     }
                    820:   else if (!set_ipv6pktinfo(fd))
                    821:     goto err;
1.1       misho     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: { 
1.1.1.4 ! misho     857:   (void)fd; /* suppress potential unused warning */
        !           858:   (void)af; /* suppress potential unused warning */
1.1       misho     859:   int if_index = 0;
                    860: 
                    861: #ifdef HAVE_LINUX_NETWORK
                    862:   int opt = 1;
                    863:   struct cmsghdr *cmptr;
                    864:   struct msghdr msg;
1.1.1.3   misho     865:   socklen_t len;
1.1       misho     866:   
1.1.1.3   misho     867:   /* use mshdr so that the CMSDG_* macros are available */
1.1       misho     868:   msg.msg_control = daemon->packet;
1.1.1.3   misho     869:   msg.msg_controllen = len = daemon->packet_buff_sz;
1.1       misho     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 &&
1.1.1.3   misho     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:        }
1.1       misho     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) &&
1.1.1.3   misho     908:          getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, &len) != -1)
1.1       misho     909:        {
1.1.1.3   misho     910:           msg.msg_controllen = len;
                    911:          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
1.1       misho     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: 
1.1.1.2   misho     934:   (void)do_tftp;
                    935: 
1.1       misho     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;
1.1.1.4 ! misho     969:       l->tftpfd = tftpfd;
        !           970:       l->addr = *addr;
        !           971:       l->used = 1;
1.1.1.2   misho     972:       l->iface = NULL;
1.1       misho     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));
1.1.1.4 ! misho     994: #ifdef HAVE_SOCKADDR_SA_LEN
1.1       misho     995:   addr.in6.sin6_len = sizeof(addr.in6);
1.1.1.4 ! misho     996: #endif
1.1       misho     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: 
1.1.1.4 ! misho    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: 
1.1       misho    1019: void create_bound_listeners(int dienow)
                   1020: {
                   1021:   struct listener *new;
                   1022:   struct irec *iface;
                   1023:   struct iname *if_tmp;
1.1.1.4 ! misho    1024:   struct listener *existing;
1.1       misho    1025: 
                   1026:   for (iface = daemon->interfaces; iface; iface = iface->next)
1.1.1.4 ! misho    1027:     if (!iface->done && !iface->dad && iface->found)
1.1       misho    1028:       {
1.1.1.4 ! misho    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:          }
1.1       misho    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;
1.1.1.4 ! misho    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:          }
1.1       misho    1077:       }
                   1078: }
                   1079: 
1.1.1.2   misho    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: 
1.1.1.4 ! misho    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: 
1.1.1.2   misho    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:  
1.1       misho    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:            
1.1.1.2   misho    1173:            if ((daemon->doing_dhcp6 || daemon->relay6) &&
1.1       misho    1174:                setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
1.1.1.3   misho    1175:              err = errno;
1.1       misho    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)
1.1.1.3   misho    1181:              err = errno;
1.1       misho    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)
1.1.1.3   misho    1187:              err = errno;
1.1       misho    1188:            
                   1189:            if (err)
                   1190:              {
                   1191:                char *s = _("interface %s failed to join DHCPv6 multicast group: %s");
1.1.1.3   misho    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: 
1.1       misho    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;
1.1.1.3   misho    1218:       unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
1.1       misho    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:          {
1.1.1.4 ! misho    1229:            unsigned short port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
1.1       misho    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: 
1.1.1.4 ! misho    1262: int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp)
1.1       misho    1263: {
                   1264:   union mysockaddr addr_copy = *addr;
1.1.1.4 ! misho    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;
1.1       misho    1273: 
                   1274:   /* cannot set source _port_ for TCP connections. */
                   1275:   if (is_tcp)
1.1.1.4 ! misho    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--)
1.1       misho    1286:     {
                   1287:       if (addr_copy.sa.sa_family == AF_INET)
1.1.1.4 ! misho    1288:        addr_copy.in.sin_port = port;
1.1       misho    1289:       else
1.1.1.4 ! misho    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)));
1.1       misho    1302:     }
1.1.1.4 ! misho    1303: 
        !          1304:   if (!done)
1.1       misho    1305:     return 0;
1.1.1.4 ! misho    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 */
1.1       misho    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;
1.1.1.4 ! misho    1338:   unsigned int ifindex = 0;
1.1       misho    1339:   int errsave;
1.1.1.4 ! misho    1340:   int opt = 1;
        !          1341:   
1.1       misho    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:     }
1.1.1.4 ! misho    1358: 
        !          1359:   if (intname && strlen(intname) != 0)
        !          1360:     ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
1.1       misho    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) &&
1.1.1.4 ! misho    1365:        strcmp(intname, sfd->interface) == 0 &&
        !          1366:        ifindex == sfd->ifindex) 
1.1       misho    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:     }
1.1.1.4 ! misho    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))
1.1       misho    1382:     { 
1.1.1.4 ! misho    1383:       errsave = errno; /* save error from bind/setsockopt. */
1.1       misho    1384:       close(sfd->fd);
                   1385:       free(sfd);
                   1386:       errno = errsave;
                   1387:       return NULL;
                   1388:     }
1.1.1.4 ! misho    1389: 
        !          1390:   safe_strncpy(sfd->interface, intname, sizeof(sfd->interface)); 
1.1       misho    1391:   sfd->source_addr = *addr;
                   1392:   sfd->next = daemon->sfds;
1.1.1.4 ! misho    1393:   sfd->ifindex = ifindex;
        !          1394:   sfd->preallocated = 0;
1.1       misho    1395:   daemon->sfds = sfd;
1.1.1.4 ! misho    1396: 
1.1       misho    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;
1.1.1.4 ! misho    1405:   struct serverfd *sfd;
1.1       misho    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
1.1.1.4 ! misho    1417:       if ((sfd = allocate_sfd(&addr, "")))
        !          1418:        sfd->preallocated = 1;
        !          1419: 
1.1       misho    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
1.1.1.4 ! misho    1427:       if ((sfd = allocate_sfd(&addr, "")))
        !          1428:        sfd->preallocated = 1;
1.1       misho    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:       {
1.1.1.4 ! misho    1437:        (void)prettyprint_addr(&srv->source_addr, daemon->namebuff);
1.1       misho    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: 
1.1.1.2   misho    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)
1.1.1.3   misho    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:     }
1.1.1.2   misho    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:     }
1.1.1.3   misho    1483: 
                   1484: #ifdef HAVE_LOOP
                   1485:   /* Now we have a new set of servers, test for loops. */
                   1486:   loop_send_probes();
                   1487: #endif
1.1.1.2   misho    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;
1.1.1.3   misho    1553: #ifdef HAVE_LOOP
                   1554:       serv->uid = rand32();
                   1555: #endif      
                   1556: 
1.1.1.2   misho    1557:       if (domain)
                   1558:        serv->flags |= SERV_HAS_DOMAIN;
                   1559:       
                   1560:       if (interface)
1.1.1.4 ! misho    1561:        safe_strncpy(serv->interface, interface, sizeof(serv->interface));
1.1.1.2   misho    1562:       if (addr)
                   1563:        serv->addr = *addr;
                   1564:       if (source_addr)
                   1565:        serv->source_addr = *source_addr;
                   1566:     }
                   1567: }
1.1       misho    1568: 
                   1569: void check_servers(void)
                   1570: {
                   1571:   struct irec *iface;
1.1.1.2   misho    1572:   struct server *serv;
1.1.1.4 ! misho    1573:   struct serverfd *sfd, *tmp, **up;
1.1.1.3   misho    1574:   int port = 0, count;
1.1.1.4 ! misho    1575:   int locals = 0;
1.1       misho    1576: 
                   1577:   /* interface may be new since startup */
                   1578:   if (!option_bool(OPT_NOWILD))
1.1.1.2   misho    1579:     enumerate_interfaces(0);
1.1.1.4 ! misho    1580: 
        !          1581:   /* don't garbage collect pre-allocated sfds. */
        !          1582:   for (sfd = daemon->sfds; sfd; sfd = sfd->next)
        !          1583:     sfd->used = sfd->preallocated;
1.1.1.3   misho    1584: 
                   1585:   for (count = 0, serv = daemon->servers; serv; serv = serv->next)
1.1       misho    1586:     {
1.1.1.3   misho    1587:       if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
1.1       misho    1588:        {
1.1.1.3   misho    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:            { 
1.1.1.4 ! misho    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. */
1.1.1.3   misho    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
1.1       misho    1619: 
1.1.1.3   misho    1620:          port = prettyprint_addr(&serv->addr, daemon->namebuff);
                   1621:          
1.1       misho    1622:          /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
1.1.1.2   misho    1623:          if (serv->addr.sa.sa_family == AF_INET &&
                   1624:              serv->addr.in.sin_addr.s_addr == 0)
1.1       misho    1625:            {
1.1.1.2   misho    1626:              serv->flags |= SERV_MARK;
1.1       misho    1627:              continue;
                   1628:            }
                   1629: 
                   1630:          for (iface = daemon->interfaces; iface; iface = iface->next)
1.1.1.2   misho    1631:            if (sockaddr_isequal(&serv->addr, &iface->addr))
1.1       misho    1632:              break;
                   1633:          if (iface)
                   1634:            {
                   1635:              my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
1.1.1.2   misho    1636:              serv->flags |= SERV_MARK;
1.1       misho    1637:              continue;
                   1638:            }
                   1639:          
                   1640:          /* Do we need a socket set? */
1.1.1.2   misho    1641:          if (!serv->sfd && 
                   1642:              !(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface)) &&
1.1       misho    1643:              errno != 0)
                   1644:            {
                   1645:              my_syslog(LOG_WARNING, 
                   1646:                        _("ignoring nameserver %s - cannot make/bind socket: %s"),
                   1647:                        daemon->namebuff, strerror(errno));
1.1.1.2   misho    1648:              serv->flags |= SERV_MARK;
1.1       misho    1649:              continue;
                   1650:            }
1.1.1.4 ! misho    1651:          
        !          1652:          if (serv->sfd)
        !          1653:            serv->sfd->used = 1;
1.1       misho    1654:        }
                   1655:       
1.1.1.3   misho    1656:       if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
1.1       misho    1657:        {
1.1.1.3   misho    1658:          if (++count > SERVERS_LOGGED)
                   1659:            continue;
                   1660:          
1.1.1.2   misho    1661:          if (serv->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
1.1       misho    1662:            {
1.1.1.3   misho    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
1.1.1.2   misho    1668:              if (!(serv->flags & SERV_HAS_DOMAIN))
1.1       misho    1669:                s1 = _("unqualified"), s2 = _("names");
1.1.1.2   misho    1670:              else if (strlen(serv->domain) == 0)
1.1       misho    1671:                s1 = _("default"), s2 = "";
                   1672:              else
1.1.1.2   misho    1673:                s1 = _("domain"), s2 = serv->domain;
1.1       misho    1674:              
1.1.1.2   misho    1675:              if (serv->flags & SERV_NO_ADDR)
1.1.1.4 ! misho    1676:                {
        !          1677:                  count--;
        !          1678:                  if (++locals <= LOCALS_LOGGED)
        !          1679:                        my_syslog(LOG_INFO, _("using only locally-known addresses for %s %s"), s1, s2);
        !          1680:                }
1.1.1.2   misho    1681:              else if (serv->flags & SERV_USE_RESOLV)
1.1       misho    1682:                my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
1.1.1.3   misho    1683:              else 
                   1684:                my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s %s"), daemon->namebuff, port, s1, s2, s3);
1.1       misho    1685:            }
1.1.1.3   misho    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
1.1.1.2   misho    1690:          else if (serv->interface[0] != 0)
                   1691:            my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, serv->interface); 
1.1       misho    1692:          else
                   1693:            my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port); 
                   1694:        }
                   1695:     }
1.1.1.3   misho    1696:   
1.1.1.4 ! misho    1697:   if (locals > LOCALS_LOGGED)
        !          1698:     my_syslog(LOG_INFO, _("using %d more local addresses"), locals - LOCALS_LOGGED);
1.1.1.3   misho    1699:   if (count - 1 > SERVERS_LOGGED)
                   1700:     my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
1.1.1.2   misho    1701: 
1.1.1.4 ! misho    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:   
1.1.1.2   misho    1716:   cleanup_servers();
1.1       misho    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:     }
1.1.1.2   misho    1733:    
                   1734:   mark_servers(SERV_FROM_RESOLV);
                   1735:     
1.1       misho    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: 
1.1.1.2   misho    1789:       add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL);
1.1       misho    1790:       gotone = 1;
                   1791:     }
                   1792:   
                   1793:   fclose(f);
1.1.1.2   misho    1794:   cleanup_servers();
1.1       misho    1795: 
                   1796:   return gotone;
                   1797: }
                   1798: 
1.1.1.2   misho    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);
1.1       misho    1807:   
1.1.1.2   misho    1808:   if (option_bool(OPT_CLEVERBIND))
                   1809:     create_bound_listeners(0);
1.1       misho    1810:   
1.1.1.2   misho    1811: #ifdef HAVE_DHCP6
                   1812:   if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
                   1813:     join_multicast(0);
1.1       misho    1814:   
1.1.1.2   misho    1815:   if (daemon->doing_dhcp6 || daemon->doing_ra)
                   1816:     dhcp_construct_contexts(now);
1.1       misho    1817:   
1.1.1.2   misho    1818:   if (daemon->doing_dhcp6)
                   1819:     lease_find_interfaces(now);
                   1820: #endif
1.1       misho    1821: }
                   1822: 
1.1.1.2   misho    1823: 
                   1824: 
1.1       misho    1825: 
                   1826: 

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