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

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

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