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

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

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