• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; version 2 dated June, 1991, or
6    (at your option) version 3 dated 29 June, 2007.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program.  If not, see <http://www.gnu.org/licenses/>.
15 */
16 
17 #include "dnsmasq.h"
18 
19 #ifdef HAVE_LINUX_NETWORK
20 
indextoname(int fd,int index,char * name)21 int indextoname(int fd, int index, char *name)
22 {
23   struct ifreq ifr;
24 
25   if (index == 0)
26     return 0;
27 
28   ifr.ifr_ifindex = index;
29   if (ioctl(fd, SIOCGIFNAME, &ifr) == -1)
30     return 0;
31 
32   strncpy(name, ifr.ifr_name, IF_NAMESIZE);
33 
34   return 1;
35 }
36 
37 #else
38 
indextoname(int fd,int index,char * name)39 int indextoname(int fd, int index, char *name)
40 {
41   if (index == 0 || !if_indextoname(index, name))
42     return 0;
43 
44   return 1;
45 }
46 
47 #endif
48 
iface_check(int family,struct all_addr * addr,char * name,int * indexp)49 int iface_check(int family, struct all_addr *addr, char *name, int *indexp)
50 {
51   struct iname *tmp;
52   int ret = 1;
53 
54   /* Note: have to check all and not bail out early, so that we set the
55      "used" flags. */
56 
57   if (indexp)
58     {
59       /* One form of bridging on BSD has the property that packets
60 	 can be recieved on bridge interfaces which do not have an IP address.
61 	 We allow these to be treated as aliases of another interface which does have
62 	 an IP address with --dhcp-bridge=interface,alias,alias */
63       struct dhcp_bridge *bridge, *alias;
64       for (bridge = daemon->bridges; bridge; bridge = bridge->next)
65 	{
66 	  for (alias = bridge->alias; alias; alias = alias->next)
67 	    if (strncmp(name, alias->iface, IF_NAMESIZE) == 0)
68 	      {
69 		int newindex;
70 
71 		if (!(newindex = if_nametoindex(bridge->iface)))
72 		  {
73 		    my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), name);
74 		    return 0;
75 		  }
76 		else
77 		  {
78 		    *indexp = newindex;
79 		    strncpy(name,  bridge->iface, IF_NAMESIZE);
80 		    break;
81 		  }
82 	      }
83 	  if (alias)
84 	    break;
85 	}
86     }
87 
88   if (daemon->if_names || (addr && daemon->if_addrs))
89     {
90       ret = 0;
91 
92       for (tmp = daemon->if_names; tmp; tmp = tmp->next)
93 	if (tmp->name && (strcmp(tmp->name, name) == 0))
94 	  ret = tmp->used = 1;
95 
96       for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
97 	if (addr && tmp->addr.sa.sa_family == family)
98 	  {
99 	    if (family == AF_INET &&
100 		tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
101 	      ret = tmp->used = 1;
102 #ifdef HAVE_IPV6
103 	    else if (family == AF_INET6 &&
104 		     IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr,
105 					&addr->addr.addr6))
106 	      ret = tmp->used = 1;
107 #endif
108 	  }
109     }
110 
111   for (tmp = daemon->if_except; tmp; tmp = tmp->next)
112     if (tmp->name && (strcmp(tmp->name, name) == 0))
113       ret = 0;
114 
115   return ret;
116 }
117 
iface_allowed(struct irec ** irecp,int if_index,union mysockaddr * addr,struct in_addr netmask)118 static int iface_allowed(struct irec **irecp, int if_index,
119 			 union mysockaddr *addr, struct in_addr netmask)
120 {
121   struct irec *iface;
122   int fd, mtu = 0, loopback;
123   struct ifreq ifr;
124   int dhcp_ok = 1;
125   struct iname *tmp;
126 
127   /* check whether the interface IP has been added already
128      we call this routine multiple times. */
129   for (iface = *irecp; iface; iface = iface->next)
130     if (sockaddr_isequal(&iface->addr, addr))
131       return 1;
132 
133   if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 ||
134       !indextoname(fd, if_index, ifr.ifr_name) ||
135       ioctl(fd, SIOCGIFFLAGS, &ifr) == -1)
136     {
137       if (fd != -1)
138 	{
139 	  int errsave = errno;
140 	  close(fd);
141 	  errno = errsave;
142 	}
143       return 0;
144     }
145 
146   loopback = ifr.ifr_flags & IFF_LOOPBACK;
147 
148   if (ioctl(fd, SIOCGIFMTU, &ifr) != -1)
149     mtu = ifr.ifr_mtu;
150 
151   close(fd);
152 
153   /* If we are restricting the set of interfaces to use, make
154      sure that loopback interfaces are in that set. */
155   if (daemon->if_names && loopback)
156     {
157       struct iname *lo;
158       for (lo = daemon->if_names; lo; lo = lo->next)
159 	if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
160 	  {
161 	    lo->isloop = 1;
162 	    break;
163 	  }
164 
165       if (!lo &&
166 	  (lo = whine_malloc(sizeof(struct iname))) &&
167 	  (lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
168 	{
169 	  strcpy(lo->name, ifr.ifr_name);
170 	  lo->isloop = lo->used = 1;
171 	  lo->next = daemon->if_names;
172 	  daemon->if_names = lo;
173 	}
174     }
175 
176   if (addr->sa.sa_family == AF_INET &&
177       !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, ifr.ifr_name, NULL))
178     return 1;
179 
180   for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
181     if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
182       dhcp_ok = 0;
183 
184 #ifdef HAVE_IPV6
185   if (addr->sa.sa_family == AF_INET6 &&
186       !iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, ifr.ifr_name, NULL))
187     return 1;
188 #endif
189 
190   /* add to list */
191   if ((iface = whine_malloc(sizeof(struct irec))))
192     {
193       iface->addr = *addr;
194       iface->netmask = netmask;
195       iface->dhcp_ok = dhcp_ok;
196       iface->mtu = mtu;
197       iface->next = *irecp;
198       *irecp = iface;
199       return 1;
200     }
201 
202   errno = ENOMEM;
203   return 0;
204 }
205 
206 #ifdef HAVE_IPV6
iface_allowed_v6(struct in6_addr * local,int scope,int if_index,void * vparam)207 static int iface_allowed_v6(struct in6_addr *local,
208 			    int scope, int if_index, void *vparam)
209 {
210   union mysockaddr addr;
211   struct in_addr netmask; /* dummy */
212 
213   netmask.s_addr = 0;
214 
215   memset(&addr, 0, sizeof(addr));
216 #ifdef HAVE_SOCKADDR_SA_LEN
217   addr.in6.sin6_len = sizeof(addr.in6);
218 #endif
219   addr.in6.sin6_family = AF_INET6;
220   addr.in6.sin6_addr = *local;
221   addr.in6.sin6_port = htons(daemon->port);
222   addr.in6.sin6_scope_id = scope;
223 
224   return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
225 }
226 #endif
227 
iface_allowed_v4(struct in_addr local,int if_index,struct in_addr netmask,struct in_addr broadcast,void * vparam)228 static int iface_allowed_v4(struct in_addr local, int if_index,
229 			    struct in_addr netmask, struct in_addr broadcast, void *vparam)
230 {
231   union mysockaddr addr;
232 
233   memset(&addr, 0, sizeof(addr));
234 #ifdef HAVE_SOCKADDR_SA_LEN
235   addr.in.sin_len = sizeof(addr.in);
236 #endif
237   addr.in.sin_family = AF_INET;
238   addr.in.sin_addr = broadcast; /* warning */
239   addr.in.sin_addr = local;
240   addr.in.sin_port = htons(daemon->port);
241 
242   return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
243 }
244 
enumerate_interfaces(void)245 int enumerate_interfaces(void)
246 {
247 #ifdef HAVE_IPV6
248   return iface_enumerate(&daemon->interfaces, iface_allowed_v4, iface_allowed_v6);
249 #else
250   return iface_enumerate(&daemon->interfaces, iface_allowed_v4, NULL);
251 #endif
252 }
253 
254 /* set NONBLOCK bit on fd: See Stevens 16.6 */
fix_fd(int fd)255 int fix_fd(int fd)
256 {
257   int flags;
258 
259   if ((flags = fcntl(fd, F_GETFL)) == -1 ||
260       fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
261     return 0;
262 
263   return 1;
264 }
265 
266 #if defined(HAVE_IPV6)
create_ipv6_listener(struct listener ** link,int port)267 static int create_ipv6_listener(struct listener **link, int port)
268 {
269   union mysockaddr addr;
270   int tcpfd, fd;
271   struct listener *l;
272   int opt = 1;
273 
274   memset(&addr, 0, sizeof(addr));
275   addr.in6.sin6_family = AF_INET6;
276   addr.in6.sin6_addr = in6addr_any;
277   addr.in6.sin6_port = htons(port);
278 #ifdef HAVE_SOCKADDR_SA_LEN
279   addr.in6.sin6_len = sizeof(addr.in6);
280 #endif
281 
282   /* No error of the kernel doesn't support IPv6 */
283   if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
284     return (errno == EPROTONOSUPPORT ||
285 	    errno == EAFNOSUPPORT ||
286 	    errno == EINVAL);
287 
288   if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
289     return 0;
290 
291   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
292       setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
293       setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
294       setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
295       !fix_fd(fd) ||
296       !fix_fd(tcpfd) ||
297 #ifdef IPV6_RECVPKTINFO
298       setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
299 #else
300       setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
301 #endif
302       bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
303       listen(tcpfd, 5) == -1 ||
304       bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
305     return 0;
306 
307   l = safe_malloc(sizeof(struct listener));
308   l->fd = fd;
309   l->tcpfd = tcpfd;
310   l->tftpfd = -1;
311   l->family = AF_INET6;
312   l->next = NULL;
313   *link = l;
314 
315   return 1;
316 }
317 #endif
318 
create_wildcard_listeners(void)319 struct listener *create_wildcard_listeners(void)
320 {
321   union mysockaddr addr;
322   int opt = 1;
323   struct listener *l, *l6 = NULL;
324   int tcpfd = -1, fd = -1, tftpfd = -1;
325 
326   memset(&addr, 0, sizeof(addr));
327   addr.in.sin_family = AF_INET;
328   addr.in.sin_addr.s_addr = INADDR_ANY;
329   addr.in.sin_port = htons(daemon->port);
330 #ifdef HAVE_SOCKADDR_SA_LEN
331   addr.in.sin_len = sizeof(struct sockaddr_in);
332 #endif
333 
334   if (daemon->port != 0)
335     {
336 
337       if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
338 	  (tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
339 	return NULL;
340 
341       if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
342 	  bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
343 	  listen(tcpfd, 5) == -1 ||
344 	  !fix_fd(tcpfd) ||
345 #ifdef HAVE_IPV6
346 	  !create_ipv6_listener(&l6, daemon->port) ||
347 #endif
348 	  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
349 	  !fix_fd(fd) ||
350 #if defined(HAVE_LINUX_NETWORK)
351 	  setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
352 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
353 	  setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
354 	  setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
355 #endif
356 	  bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
357 	return NULL;
358     }
359 
360 #ifdef HAVE_TFTP
361   if (daemon->options & OPT_TFTP)
362     {
363       addr.in.sin_port = htons(TFTP_PORT);
364       if ((tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
365 	return NULL;
366 
367       if (!fix_fd(tftpfd) ||
368 #if defined(HAVE_LINUX_NETWORK)
369 	  setsockopt(tftpfd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
370 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
371 	  setsockopt(tftpfd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
372 	  setsockopt(tftpfd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
373 #endif
374 	  bind(tftpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
375 	return NULL;
376     }
377 #endif
378 
379   l = safe_malloc(sizeof(struct listener));
380   l->family = AF_INET;
381   l->fd = fd;
382   l->tcpfd = tcpfd;
383   l->tftpfd = tftpfd;
384   l->next = l6;
385 
386   return l;
387 }
388 
389 #ifdef __ANDROID__
390 /**
391  * for a single given irec (interface name and address) create
392  * a set of sockets listening.  This is a copy of the code inside the loop
393  * of create_bound_listeners below and is added here to allow us
394  * to create just a single new listener dynamically when our interface
395  * list is changed.
396  *
397  * iface - input of the new interface details to listen on
398  * listeners - output.  Creates a new struct listener and inserts at head of the list
399  *
400  * die's on errors, so don't pass bad data.
401  */
create_bound_listener(struct listener ** listeners,struct irec * iface)402 void create_bound_listener(struct listener **listeners, struct irec *iface)
403 {
404   int rc, opt = 1;
405 #ifdef HAVE_IPV6
406   static int dad_count = 0;
407 #endif
408 
409   struct listener *new = safe_malloc(sizeof(struct listener));
410   new->family = iface->addr.sa.sa_family;
411   new->iface = iface;
412   new->next = *listeners;
413   new->tftpfd = -1;
414   new->tcpfd = -1;
415   new->fd = -1;
416   *listeners = new;
417 
418   if (daemon->port != 0)
419   {
420     if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
421         (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
422         setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
423         setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
424         !fix_fd(new->tcpfd) ||
425         !fix_fd(new->fd))
426       die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
427 
428 #ifdef HAVE_IPV6
429     if (iface->addr.sa.sa_family == AF_INET6)
430     {
431       if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
432           setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
433         die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);\
434     }
435 #endif
436 
437     while(1)
438     {
439       if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
440         break;
441 
442 #ifdef HAVE_IPV6
443       /* An interface may have an IPv6 address which is still undergoing DAD.
444          If so, the bind will fail until the DAD completes, so we try over 20 seconds
445          before failing. */
446       if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) &&
447           dad_count++ < DAD_WAIT)
448       {
449         sleep(1);
450         continue;
451       }
452 #endif
453       break;
454     }
455 
456     if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
457     {
458       prettyprint_addr(&iface->addr, daemon->namebuff);
459       die(_("failed to bind listening socket for %s: %s"), daemon->namebuff, EC_BADNET);
460     }
461 
462     if (listen(new->tcpfd, 5) == -1)
463       die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
464   }
465 
466 #ifdef HAVE_TFTP
467   if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
468   {
469     short save = iface->addr.in.sin_port;
470     iface->addr.in.sin_port = htons(TFTP_PORT);
471     if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
472         setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
473         !fix_fd(new->tftpfd) ||
474         bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
475       die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
476     iface->addr.in.sin_port = save;
477   }
478 #endif
479 }
480 
481 /**
482  * If a listener has a struct irec pointer whose address matches the newly
483  * malloc()d struct irec's address, update its pointer to refer to this new
484  * struct irec instance.
485  *
486  * Otherwise, any listeners that are preserved across interface list changes
487  * will point at interface structures that are free()d at the end of
488  * set_interfaces(), and can get overwritten by subsequent memory allocations.
489  *
490  * See b/17475756 for further discussion.
491  */
fixup_possible_existing_listener(struct irec * new_iface)492 void fixup_possible_existing_listener(struct irec *new_iface) {
493   /* find the listener, if present */
494   struct listener *l;
495   for (l = daemon->listeners; l; l = l->next) {
496     struct irec *listener_iface = l->iface;
497     if (listener_iface) {
498       if (sockaddr_isequal(&listener_iface->addr, &new_iface->addr)) {
499         l->iface = new_iface;
500         return;
501       }
502     }
503   }
504 }
505 
506 /**
507  * Close the sockets listening on the given interface
508  *
509  * This new function is needed as we're dynamically changing the interfaces
510  * we listen on.  Before they'd be opened once in create_bound_listeners and stay
511  * until we exited.  Now, if an interface moves off the to-listen list we need to
512  * close out the listeners and keep trucking.
513  *
514  * interface - input of the interface details to listen on
515  */
close_bound_listener(struct irec * interface)516 int close_bound_listener(struct irec *interface)
517 {
518   /* find the listener */
519   struct listener **l, *listener;
520   for (l = &(daemon->listeners); *l; l = &((*l)->next)) {
521     struct irec *listener_iface = (*l)->iface;
522     if (listener_iface && interface) {
523       if (sockaddr_isequal(&listener_iface->addr, &interface->addr)) {
524         break;
525       }
526     } else {
527       if (interface == NULL && listener_iface == NULL) {
528         break;
529       }
530     }
531   }
532   listener = *l;
533   if (listener == NULL) return 0;
534 
535   if (listener->tftpfd != -1)
536   {
537     close(listener->tftpfd);
538     listener->tftpfd = -1;
539   }
540   if (listener->tcpfd != -1)
541   {
542     close(listener->tcpfd);
543     listener->tcpfd = -1;
544   }
545   if (listener->fd != -1)
546   {
547     close(listener->fd);
548     listener->fd = -1;
549   }
550   *l = listener->next;
551   free(listener);
552   return -1;
553 }
554 #endif /* __ANDROID__ */
555 
create_bound_listeners(void)556 struct listener *create_bound_listeners(void)
557 {
558   struct listener *listeners = NULL;
559   struct irec *iface;
560 #ifndef __ANDROID__
561   int rc, opt = 1;
562 #ifdef HAVE_IPV6
563   static int dad_count = 0;
564 #endif
565 #endif
566 
567   for (iface = daemon->interfaces; iface; iface = iface->next)
568     {
569 #ifdef __ANDROID__
570       create_bound_listener(&listeners, iface);
571 #else
572       struct listener *new = safe_malloc(sizeof(struct listener));
573       new->family = iface->addr.sa.sa_family;
574       new->iface = iface;
575       new->next = listeners;
576       new->tftpfd = -1;
577       new->tcpfd = -1;
578       new->fd = -1;
579       listeners = new;
580 
581       if (daemon->port != 0)
582 	{
583 	  if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
584 	      (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
585 	      setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
586 	      setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
587 	      !fix_fd(new->tcpfd) ||
588 	      !fix_fd(new->fd))
589 	    die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
590 
591 #ifdef HAVE_IPV6
592 	  if (iface->addr.sa.sa_family == AF_INET6)
593 	    {
594 	      if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
595 		  setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
596 		die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
597 	    }
598 #endif
599 
600 	  while(1)
601 	    {
602 	      if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
603 		break;
604 
605 #ifdef HAVE_IPV6
606 	      /* An interface may have an IPv6 address which is still undergoing DAD.
607 		 If so, the bind will fail until the DAD completes, so we try over 20 seconds
608 		 before failing. */
609 	      if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) &&
610 		  dad_count++ < DAD_WAIT)
611 		{
612 		  sleep(1);
613 		  continue;
614 		}
615 #endif
616 	      break;
617 	    }
618 
619 	  if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
620 	    {
621 	      prettyprint_addr(&iface->addr, daemon->namebuff);
622 	      die(_("failed to bind listening socket for %s: %s"),
623 		  daemon->namebuff, EC_BADNET);
624 	    }
625 
626 	  if (listen(new->tcpfd, 5) == -1)
627 	    die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
628 	}
629 
630 #ifdef HAVE_TFTP
631       if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
632 	{
633 	  short save = iface->addr.in.sin_port;
634 	  iface->addr.in.sin_port = htons(TFTP_PORT);
635 	  if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
636 	      setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
637 	      !fix_fd(new->tftpfd) ||
638 	      bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
639 	    die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
640 	  iface->addr.in.sin_port = save;
641 	}
642 #endif
643 #endif /* !__ANDROID */
644     }
645 
646   return listeners;
647 }
648 
649 
650 /* return a UDP socket bound to a random port, have to cope with straying into
651    occupied port nos and reserved ones. */
random_sock(int family)652 int random_sock(int family)
653 {
654   int fd;
655 
656   if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
657     {
658       union mysockaddr addr;
659       unsigned int ports_avail = 65536u - (unsigned short)daemon->min_port;
660       int tries = ports_avail < 30 ? 3 * ports_avail : 100;
661 
662       memset(&addr, 0, sizeof(addr));
663       addr.sa.sa_family = family;
664 
665       /* don't loop forever if all ports in use. */
666 
667       if (fix_fd(fd))
668 	while(tries--)
669 	  {
670 	    unsigned short port = rand16();
671 
672 	    if (daemon->min_port != 0)
673 	      port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
674 
675 	    if (family == AF_INET)
676 	      {
677 		addr.in.sin_addr.s_addr = INADDR_ANY;
678 		addr.in.sin_port = port;
679 #ifdef HAVE_SOCKADDR_SA_LEN
680 		addr.in.sin_len = sizeof(struct sockaddr_in);
681 #endif
682 	      }
683 #ifdef HAVE_IPV6
684 	    else
685 	      {
686 		addr.in6.sin6_addr = in6addr_any;
687 		addr.in6.sin6_port = port;
688 #ifdef HAVE_SOCKADDR_SA_LEN
689 		addr.in6.sin6_len = sizeof(struct sockaddr_in6);
690 #endif
691 	      }
692 #endif
693 
694 	    if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
695 	      return fd;
696 
697 	    if (errno != EADDRINUSE && errno != EACCES)
698 	      break;
699 	  }
700 
701       close(fd);
702     }
703 
704   return -1;
705 }
706 
707 
local_bind(int fd,union mysockaddr * addr,char * intname,uint32_t mark,int is_tcp)708 int local_bind(int fd, union mysockaddr *addr, char *intname, uint32_t mark, int is_tcp)
709 {
710   union mysockaddr addr_copy = *addr;
711 
712   /* cannot set source _port_ for TCP connections. */
713   if (is_tcp)
714     {
715       if (addr_copy.sa.sa_family == AF_INET)
716 	addr_copy.in.sin_port = 0;
717 #ifdef HAVE_IPV6
718       else
719 	addr_copy.in6.sin6_port = 0;
720 #endif
721     }
722 
723   if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
724     return 0;
725 
726 #if defined(SO_BINDTODEVICE)
727   if (intname[0] != 0 &&
728       setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, strlen(intname)) == -1)
729     return 0;
730 #endif
731 
732   if (mark != 0 && setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1)
733     return 0;
734 
735   return 1;
736 }
737 
allocate_sfd(union mysockaddr * addr,char * intname,uint32_t mark)738 static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname, uint32_t mark)
739 {
740   struct serverfd *sfd;
741   int errsave;
742 
743   /* when using random ports, servers which would otherwise use
744      the INADDR_ANY/port0 socket have sfd set to NULL */
745   if (!daemon->osport && intname[0] == 0)
746     {
747       errno = 0;
748 
749       if (addr->sa.sa_family == AF_INET &&
750 	  addr->in.sin_addr.s_addr == INADDR_ANY &&
751 	  addr->in.sin_port == htons(0))
752 	return NULL;
753 
754 #ifdef HAVE_IPV6
755       if (addr->sa.sa_family == AF_INET6 &&
756 	  memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
757 	  addr->in6.sin6_port == htons(0))
758 	return NULL;
759 #endif
760     }
761 
762   /* may have a suitable one already */
763   for (sfd = daemon->sfds; sfd; sfd = sfd->next )
764     if (sockaddr_isequal(&sfd->source_addr, addr) &&
765 	mark == sfd->mark &&
766 	strcmp(intname, sfd->interface) == 0)
767       return sfd;
768 
769   /* need to make a new one. */
770   errno = ENOMEM; /* in case malloc fails. */
771   if (!(sfd = whine_malloc(sizeof(struct serverfd))))
772     return NULL;
773 
774   if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
775     {
776       free(sfd);
777       return NULL;
778     }
779 
780   if (!local_bind(sfd->fd, addr, intname, mark, 0) || !fix_fd(sfd->fd))
781     {
782       errsave = errno; /* save error from bind. */
783       close(sfd->fd);
784       free(sfd);
785       errno = errsave;
786       return NULL;
787     }
788 
789   strcpy(sfd->interface, intname);
790   sfd->source_addr = *addr;
791   sfd->mark = mark;
792   sfd->next = daemon->sfds;
793   daemon->sfds = sfd;
794   return sfd;
795 }
796 
797 /* create upstream sockets during startup, before root is dropped which may be needed
798    this allows query_port to be a low port and interface binding */
pre_allocate_sfds(void)799 void pre_allocate_sfds(void)
800 {
801   struct server *srv;
802 
803   if (daemon->query_port != 0)
804     {
805       union  mysockaddr addr;
806       memset(&addr, 0, sizeof(addr));
807       addr.in.sin_family = AF_INET;
808       addr.in.sin_addr.s_addr = INADDR_ANY;
809       addr.in.sin_port = htons(daemon->query_port);
810 #ifdef HAVE_SOCKADDR_SA_LEN
811       addr.in.sin_len = sizeof(struct sockaddr_in);
812 #endif
813       allocate_sfd(&addr, "", 0);
814 #ifdef HAVE_IPV6
815       memset(&addr, 0, sizeof(addr));
816       addr.in6.sin6_family = AF_INET6;
817       addr.in6.sin6_addr = in6addr_any;
818       addr.in6.sin6_port = htons(daemon->query_port);
819 #ifdef HAVE_SOCKADDR_SA_LEN
820       addr.in6.sin6_len = sizeof(struct sockaddr_in6);
821 #endif
822       allocate_sfd(&addr, "", 0);
823 #endif
824     }
825 
826   for (srv = daemon->servers; srv; srv = srv->next)
827     if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
828 	!allocate_sfd(&srv->source_addr, srv->interface, srv->mark) &&
829 	errno != 0 &&
830 	(daemon->options & OPT_NOWILD))
831       {
832 	prettyprint_addr(&srv->addr, daemon->namebuff);
833 	if (srv->interface[0] != 0)
834 	  {
835 	    strcat(daemon->namebuff, " ");
836 	    strcat(daemon->namebuff, srv->interface);
837 	  }
838 	die(_("failed to bind server socket for %s: %s"),
839 	    daemon->namebuff, EC_BADNET);
840       }
841 }
842 
843 
check_servers(void)844 void check_servers(void)
845 {
846   struct irec *iface;
847   struct server *new, *tmp, *ret = NULL;
848   int port = 0;
849 
850   for (new = daemon->servers; new; new = tmp)
851     {
852       tmp = new->next;
853 
854       if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)))
855 	{
856 	  port = prettyprint_addr(&new->addr, daemon->namebuff);
857 
858 	  /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
859 	  if (new->addr.sa.sa_family == AF_INET &&
860 	      new->addr.in.sin_addr.s_addr == 0)
861 	    {
862 	      free(new);
863 	      continue;
864 	    }
865 
866 	  for (iface = daemon->interfaces; iface; iface = iface->next)
867 	    if (sockaddr_isequal(&new->addr, &iface->addr))
868 	      break;
869 	  if (iface)
870 	    {
871 	      my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
872 	      free(new);
873 	      continue;
874 	    }
875 
876 	  /* Do we need a socket set? */
877 	  if (!new->sfd &&
878 	      !(new->sfd = allocate_sfd(&new->source_addr, new->interface, new->mark)) &&
879 	      errno != 0)
880 	    {
881 	      my_syslog(LOG_WARNING,
882 			_("ignoring nameserver %s - cannot make/bind socket: %s"),
883 			daemon->namebuff, strerror(errno));
884 	      free(new);
885 	      continue;
886 	    }
887 	}
888 
889       /* reverse order - gets it right. */
890       new->next = ret;
891       ret = new;
892 
893       if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS))
894 	{
895 	  char *s1, *s2;
896 	  if (!(new->flags & SERV_HAS_DOMAIN))
897 	    s1 = _("unqualified"), s2 = _("names");
898 	  else if (strlen(new->domain) == 0)
899 	    s1 = _("default"), s2 = "";
900 	  else
901 	    s1 = _("domain"), s2 = new->domain;
902 
903 	  if (new->flags & SERV_NO_ADDR)
904 	    my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
905 	  else if (!(new->flags & SERV_LITERAL_ADDRESS))
906 	    my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
907 	}
908       else if (new->interface[0] != 0)
909 	my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface);
910       else
911 	my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
912     }
913 
914   daemon->servers = ret;
915 }
916 
917 #ifdef __ANDROID__
918 /* #define __ANDROID_DEBUG__ 1 */
919 /*
920  * Ingests a new list of interfaces and starts to listen on them, adding only the new
921  * and stopping to listen to any interfaces not on the new list.
922  *
923  * interfaces - input in the format "bt-pan:eth0:wlan0:..>" up to 1024 bytes long
924  */
set_interfaces(const char * interfaces)925 void set_interfaces(const char *interfaces)
926 {
927     struct iname *if_tmp;
928     struct iname *prev_if_names;
929     struct irec *old_iface, *new_iface, *prev_interfaces;
930     char s[1024];
931     char *next = s;
932     char *interface;
933     int was_wild = 0;
934 
935 #ifdef __ANDROID_DEBUG__
936     my_syslog(LOG_DEBUG, _("set_interfaces(%s)"), interfaces);
937 #endif
938     prev_if_names = daemon->if_names;
939     daemon->if_names = NULL;
940 
941     prev_interfaces = daemon->interfaces;
942     daemon->interfaces = NULL;
943 
944     if (strlen(interfaces) > sizeof(s)) {
945         die(_("interface string too long: %s"), NULL, EC_BADNET);
946     }
947     strncpy(s, interfaces, sizeof(s));
948     while((interface = strsep(&next, ":"))) {
949         if_tmp = safe_malloc(sizeof(struct iname));
950         memset(if_tmp, 0, sizeof(struct iname));
951         if ((if_tmp->name = strdup(interface)) == NULL) {
952             die(_("malloc failure in set_interfaces: %s"), NULL, EC_BADNET);
953         }
954         if_tmp->next = daemon->if_names;
955         daemon->if_names = if_tmp;
956     }
957 
958     if (!enumerate_interfaces()) {
959         die(_("enumerate interfaces error in set_interfaces: %s"), NULL, EC_BADNET);
960     }
961 
962     for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next) {
963         if (if_tmp->name && !if_tmp->used) {
964             die(_("unknown interface given %s in set_interfaces: %s"), if_tmp->name, EC_BADNET);
965         }
966     }
967     /* success! - setup to free the old */
968     /* check for any that have been removed */
969     for (old_iface = prev_interfaces; old_iface; old_iface=old_iface->next) {
970       int found = 0;
971       for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
972         if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
973             found = 1;
974             break;
975         }
976       }
977 
978       if (found) {
979         fixup_possible_existing_listener(new_iface);
980       } else {
981 #ifdef __ANDROID_DEBUG__
982         char debug_buff[MAXDNAME];
983         prettyprint_addr(&old_iface->addr, debug_buff);
984         my_syslog(LOG_DEBUG, _("closing listener for %s"), debug_buff);
985 #endif
986 
987         close_bound_listener(old_iface);
988       }
989     }
990 
991     /* remove wildchar listeners */
992     was_wild = close_bound_listener(NULL);
993     if (was_wild) daemon->options |= OPT_NOWILD;
994 
995     /* check for any that have been added */
996     for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
997       int found = 0;
998 
999       /* if the previous setup used a wildchar, then add any current interfaces */
1000       if (!was_wild) {
1001         for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
1002           if(sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
1003             found = -1;
1004             break;
1005           }
1006         }
1007       }
1008       if (!found) {
1009 #ifdef __ANDROID_DEBUG__
1010         char debug_buff[MAXDNAME];
1011         prettyprint_addr(&new_iface->addr, debug_buff);
1012         my_syslog(LOG_DEBUG, _("adding listener for %s"), debug_buff);
1013 #endif
1014         create_bound_listener(&(daemon->listeners), new_iface);
1015       }
1016     }
1017 
1018     while (prev_if_names) {
1019       if (prev_if_names->name) free(prev_if_names->name);
1020       if_tmp = prev_if_names->next;
1021       free(prev_if_names);
1022       prev_if_names = if_tmp;
1023     }
1024     while (prev_interfaces) {
1025       struct irec *tmp_irec = prev_interfaces->next;
1026       free(prev_interfaces);
1027       prev_interfaces = tmp_irec;
1028     }
1029 #ifdef __ANDROID_DEBUG__
1030     my_syslog(LOG_DEBUG, _("done with setInterfaces"));
1031 #endif
1032 }
1033 
1034 /*
1035  * Takes a string in the format "0x100b:1.2.3.4:1.2.3.4:..." - up to 1024 bytes in length
1036  *  - The first element is the socket mark to set on sockets that forward DNS queries.
1037  *  - The subsequent elements are the DNS servers to forward queries to.
1038  */
set_servers(const char * servers)1039 int set_servers(const char *servers)
1040 {
1041   char s[1024];
1042   struct server *old_servers = NULL;
1043   struct server *new_servers = NULL;
1044   struct server *serv;
1045   char *mark_string;
1046   uint32_t mark;
1047 
1048   strncpy(s, servers, sizeof(s));
1049 
1050   /* move old servers to free list - we can reuse the memory
1051      and not risk malloc if there are the same or fewer new servers.
1052      Servers which were specced on the command line go to the new list. */
1053   for (serv = daemon->servers; serv;)
1054     {
1055       struct server *tmp = serv->next;
1056       if (serv->flags & SERV_FROM_RESOLV)
1057 	{
1058 	  serv->next = old_servers;
1059 	  old_servers = serv;
1060 	  /* forward table rules reference servers, so have to blow them away */
1061 	  server_gone(serv);
1062 	}
1063       else
1064 	{
1065 	  serv->next = new_servers;
1066 	  new_servers = serv;
1067 	}
1068       serv = tmp;
1069     }
1070 
1071   char *next = s;
1072   char *saddr;
1073 
1074   /* Parse the mark. */
1075   mark_string = strsep(&next, ":");
1076   mark = strtoul(mark_string, NULL, 0);
1077 
1078   while ((saddr = strsep(&next, ":"))) {
1079       union mysockaddr addr, source_addr;
1080       memset(&addr, 0, sizeof(addr));
1081       memset(&source_addr, 0, sizeof(source_addr));
1082 
1083       if ((addr.in.sin_addr.s_addr = inet_addr(saddr)) != (in_addr_t) -1)
1084 	{
1085 #ifdef HAVE_SOCKADDR_SA_LEN
1086 	  source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
1087 #endif
1088 	  source_addr.in.sin_family = addr.in.sin_family = AF_INET;
1089 	  addr.in.sin_port = htons(NAMESERVER_PORT);
1090 	  source_addr.in.sin_addr.s_addr = INADDR_ANY;
1091 	  source_addr.in.sin_port = htons(daemon->query_port);
1092 	}
1093 #ifdef HAVE_IPV6
1094       else if (inet_pton(AF_INET6, saddr, &addr.in6.sin6_addr) > 0)
1095 	{
1096 #ifdef HAVE_SOCKADDR_SA_LEN
1097 	  source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
1098 #endif
1099 	  source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
1100 	  addr.in6.sin6_port = htons(NAMESERVER_PORT);
1101 	  source_addr.in6.sin6_addr = in6addr_any;
1102 	  source_addr.in6.sin6_port = htons(daemon->query_port);
1103 	}
1104 #endif /* IPV6 */
1105       else
1106 	continue;
1107 
1108       if (old_servers)
1109 	{
1110 	  serv = old_servers;
1111 	  old_servers = old_servers->next;
1112 	}
1113       else if (!(serv = whine_malloc(sizeof (struct server))))
1114 	continue;
1115 
1116       /* this list is reverse ordered:
1117 	 it gets reversed again in check_servers */
1118       serv->next = new_servers;
1119       new_servers = serv;
1120       serv->addr = addr;
1121       serv->source_addr = source_addr;
1122       serv->domain = NULL;
1123       serv->interface[0] = 0;
1124       serv->mark = mark;
1125       serv->sfd = NULL;
1126       serv->flags = SERV_FROM_RESOLV;
1127       serv->queries = serv->failed_queries = 0;
1128     }
1129 
1130   /* Free any memory not used. */
1131   while (old_servers)
1132     {
1133       struct server *tmp = old_servers->next;
1134       free(old_servers);
1135       old_servers = tmp;
1136     }
1137 
1138   daemon->servers = new_servers;
1139   return 0;
1140 }
1141 #endif
1142 
1143 /* Return zero if no servers found, in that case we keep polling.
1144    This is a protection against an update-time/write race on resolv.conf */
reload_servers(char * fname)1145 int reload_servers(char *fname)
1146 {
1147   FILE *f;
1148   char *line;
1149   struct server *old_servers = NULL;
1150   struct server *new_servers = NULL;
1151   struct server *serv;
1152   int gotone = 0;
1153 
1154   /* buff happens to be MAXDNAME long... */
1155   if (!(f = fopen(fname, "r")))
1156     {
1157       my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
1158       return 0;
1159     }
1160 
1161   /* move old servers to free list - we can reuse the memory
1162      and not risk malloc if there are the same or fewer new servers.
1163      Servers which were specced on the command line go to the new list. */
1164   for (serv = daemon->servers; serv;)
1165     {
1166       struct server *tmp = serv->next;
1167       if (serv->flags & SERV_FROM_RESOLV)
1168 	{
1169 	  serv->next = old_servers;
1170 	  old_servers = serv;
1171 	  /* forward table rules reference servers, so have to blow them away */
1172 	  server_gone(serv);
1173 	}
1174       else
1175 	{
1176 	  serv->next = new_servers;
1177 	  new_servers = serv;
1178 	}
1179       serv = tmp;
1180     }
1181 
1182   while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
1183     {
1184       union mysockaddr addr, source_addr;
1185       char *token = strtok(line, " \t\n\r");
1186 
1187       if (!token)
1188 	continue;
1189       if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
1190 	continue;
1191       if (!(token = strtok(NULL, " \t\n\r")))
1192 	continue;
1193 
1194       memset(&addr, 0, sizeof(addr));
1195       memset(&source_addr, 0, sizeof(source_addr));
1196 
1197       if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
1198 	{
1199 #ifdef HAVE_SOCKADDR_SA_LEN
1200 	  source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
1201 #endif
1202 	  source_addr.in.sin_family = addr.in.sin_family = AF_INET;
1203 	  addr.in.sin_port = htons(NAMESERVER_PORT);
1204 	  source_addr.in.sin_addr.s_addr = INADDR_ANY;
1205 	  source_addr.in.sin_port = htons(daemon->query_port);
1206 	}
1207 #ifdef HAVE_IPV6
1208       else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
1209 	{
1210 #ifdef HAVE_SOCKADDR_SA_LEN
1211 	  source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
1212 #endif
1213 	  source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
1214 	  addr.in6.sin6_port = htons(NAMESERVER_PORT);
1215 	  source_addr.in6.sin6_addr = in6addr_any;
1216 	  source_addr.in6.sin6_port = htons(daemon->query_port);
1217 	}
1218 #endif /* IPV6 */
1219       else
1220 	continue;
1221 
1222       if (old_servers)
1223 	{
1224 	  serv = old_servers;
1225 	  old_servers = old_servers->next;
1226 	}
1227       else if (!(serv = whine_malloc(sizeof (struct server))))
1228 	continue;
1229 
1230       /* this list is reverse ordered:
1231 	 it gets reversed again in check_servers */
1232       serv->next = new_servers;
1233       new_servers = serv;
1234       serv->addr = addr;
1235       serv->source_addr = source_addr;
1236       serv->domain = NULL;
1237       serv->interface[0] = 0;
1238       serv->mark = 0;
1239       serv->sfd = NULL;
1240       serv->flags = SERV_FROM_RESOLV;
1241       serv->queries = serv->failed_queries = 0;
1242       gotone = 1;
1243     }
1244 
1245   /* Free any memory not used. */
1246   while (old_servers)
1247     {
1248       struct server *tmp = old_servers->next;
1249       free(old_servers);
1250       old_servers = tmp;
1251     }
1252 
1253   daemon->servers = new_servers;
1254   fclose(f);
1255 
1256   return gotone;
1257 }
1258 
1259 
1260 /* Use an IPv4 listener socket for ioctling */
get_ifaddr(char * intr)1261 struct in_addr get_ifaddr(char *intr)
1262 {
1263   struct listener *l;
1264   struct ifreq ifr;
1265 
1266   for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
1267 
1268   strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
1269   ifr.ifr_addr.sa_family = AF_INET;
1270 
1271   if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
1272     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
1273 
1274   return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
1275 }
1276