Tomato 1.28
[tomato.git] / release / src / router / dnsmasq / src / network.c
bloba144a7a21294b98b196ed4ced88490d821696aeb
1 /* dnsmasq is Copyright (c) 2000-2010 Simon Kelley
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.
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.
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/>.
17 #include "dnsmasq.h"
19 #ifdef HAVE_LINUX_NETWORK
21 int indextoname(int fd, int index, char *name)
23 struct ifreq ifr;
25 if (index == 0)
26 return 0;
28 ifr.ifr_ifindex = index;
29 if (ioctl(fd, SIOCGIFNAME, &ifr) == -1)
30 return 0;
32 strncpy(name, ifr.ifr_name, IF_NAMESIZE);
34 return 1;
37 #else
39 int indextoname(int fd, int index, char *name)
41 if (index == 0 || !if_indextoname(index, name))
42 return 0;
44 return 1;
47 #endif
49 int iface_check(int family, struct all_addr *addr, char *name, int *indexp)
51 struct iname *tmp;
52 int ret = 1;
54 /* Note: have to check all and not bail out early, so that we set the
55 "used" flags. */
57 if (daemon->if_names || (addr && daemon->if_addrs))
59 #ifdef HAVE_DHCP
60 struct dhcp_context *range;
61 #endif
63 ret = 0;
65 #ifdef HAVE_DHCP
66 for (range = daemon->dhcp; range; range = range->next)
67 if (range->interface && strcmp(range->interface, name) == 0)
68 ret = 1;
69 #endif
71 for (tmp = daemon->if_names; tmp; tmp = tmp->next)
72 if (tmp->name && (strcmp(tmp->name, name) == 0))
73 ret = tmp->used = 1;
75 for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
76 if (addr && tmp->addr.sa.sa_family == family)
78 if (family == AF_INET &&
79 tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
80 ret = tmp->used = 1;
81 #ifdef HAVE_IPV6
82 else if (family == AF_INET6 &&
83 IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr,
84 &addr->addr.addr6))
85 ret = tmp->used = 1;
86 #endif
90 for (tmp = daemon->if_except; tmp; tmp = tmp->next)
91 if (tmp->name && (strcmp(tmp->name, name) == 0))
92 ret = 0;
94 if (indexp)
96 /* One form of bridging on BSD has the property that packets
97 can be recieved on bridge interfaces which do not have an IP address.
98 We allow these to be treated as aliases of another interface which does have
99 an IP address with --dhcp-bridge=interface,alias,alias */
100 struct dhcp_bridge *bridge, *alias;
101 for (bridge = daemon->bridges; bridge; bridge = bridge->next)
103 for (alias = bridge->alias; alias; alias = alias->next)
104 if (strncmp(name, alias->iface, IF_NAMESIZE) == 0)
106 int newindex;
108 if (!(newindex = if_nametoindex(bridge->iface)))
110 my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), name);
111 return 0;
113 else
115 *indexp = newindex;
116 strncpy(name, bridge->iface, IF_NAMESIZE);
117 break;
120 if (alias)
121 break;
125 return ret;
128 static int iface_allowed(struct irec **irecp, int if_index,
129 union mysockaddr *addr, struct in_addr netmask)
131 struct irec *iface;
132 int fd, mtu = 0, loopback;
133 struct ifreq ifr;
134 int tftp_ok = daemon->tftp_unlimited;
135 #ifdef HAVE_DHCP
136 struct iname *tmp;
137 #endif
138 struct interface_list *ir = NULL;
140 /* check whether the interface IP has been added already
141 we call this routine multiple times. */
142 for (iface = *irecp; iface; iface = iface->next)
143 if (sockaddr_isequal(&iface->addr, addr))
144 return 1;
146 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 ||
147 !indextoname(fd, if_index, ifr.ifr_name) ||
148 ioctl(fd, SIOCGIFFLAGS, &ifr) == -1)
150 if (fd != -1)
152 int errsave = errno;
153 close(fd);
154 errno = errsave;
156 return 0;
159 loopback = ifr.ifr_flags & IFF_LOOPBACK;
161 if (ioctl(fd, SIOCGIFMTU, &ifr) != -1)
162 mtu = ifr.ifr_mtu;
164 close(fd);
166 /* If we are restricting the set of interfaces to use, make
167 sure that loopback interfaces are in that set. */
168 if (daemon->if_names && loopback)
170 struct iname *lo;
171 for (lo = daemon->if_names; lo; lo = lo->next)
172 if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
174 lo->isloop = 1;
175 break;
178 if (!lo &&
179 (lo = whine_malloc(sizeof(struct iname))) &&
180 (lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
182 strcpy(lo->name, ifr.ifr_name);
183 lo->isloop = lo->used = 1;
184 lo->next = daemon->if_names;
185 daemon->if_names = lo;
189 #ifdef HAVE_TFTP
190 /* implement wierd TFTP service rules */
191 if (addr->sa.sa_family == AF_INET)
192 for (ir = daemon->tftp_interfaces; ir; ir = ir->next)
193 if (strcmp(ir->interface, ifr.ifr_name) == 0)
195 tftp_ok = 1;
196 break;
198 #endif
200 if (!ir)
202 if (addr->sa.sa_family == AF_INET &&
203 !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, ifr.ifr_name, NULL))
204 return 1;
206 #ifdef HAVE_DHCP
207 for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
208 if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
209 tftp_ok = 0;
210 #endif
212 #ifdef HAVE_IPV6
213 if (addr->sa.sa_family == AF_INET6 &&
214 !iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, ifr.ifr_name, NULL))
215 return 1;
216 #endif
219 /* add to list */
220 if ((iface = whine_malloc(sizeof(struct irec))))
222 iface->addr = *addr;
223 iface->netmask = netmask;
224 iface->tftp_ok = tftp_ok;
225 iface->mtu = mtu;
226 if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
227 strcpy(iface->name, ifr.ifr_name);
228 iface->next = *irecp;
229 *irecp = iface;
230 return 1;
233 errno = ENOMEM;
234 return 0;
237 #ifdef HAVE_IPV6
238 static int iface_allowed_v6(struct in6_addr *local,
239 int scope, int if_index, void *vparam)
241 union mysockaddr addr;
242 struct in_addr netmask; /* dummy */
244 netmask.s_addr = 0;
246 memset(&addr, 0, sizeof(addr));
247 #ifdef HAVE_SOCKADDR_SA_LEN
248 addr.in6.sin6_len = sizeof(addr.in6);
249 #endif
250 addr.in6.sin6_family = AF_INET6;
251 addr.in6.sin6_addr = *local;
252 addr.in6.sin6_port = htons(daemon->port);
253 addr.in6.sin6_scope_id = scope;
255 return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
257 #endif
259 static int iface_allowed_v4(struct in_addr local, int if_index,
260 struct in_addr netmask, struct in_addr broadcast, void *vparam)
262 union mysockaddr addr;
264 memset(&addr, 0, sizeof(addr));
265 #ifdef HAVE_SOCKADDR_SA_LEN
266 addr.in.sin_len = sizeof(addr.in);
267 #endif
268 addr.in.sin_family = AF_INET;
269 addr.in.sin_addr = broadcast; /* warning */
270 addr.in.sin_addr = local;
271 addr.in.sin_port = htons(daemon->port);
273 return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
276 int enumerate_interfaces(void)
278 #ifdef HAVE_IPV6
279 return iface_enumerate(&daemon->interfaces, iface_allowed_v4, iface_allowed_v6);
280 #else
281 return iface_enumerate(&daemon->interfaces, iface_allowed_v4, NULL);
282 #endif
285 /* set NONBLOCK bit on fd: See Stevens 16.6 */
286 int fix_fd(int fd)
288 int flags;
290 if ((flags = fcntl(fd, F_GETFL)) == -1 ||
291 fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
292 return 0;
294 return 1;
297 #if defined(HAVE_IPV6)
298 static int create_ipv6_listener(struct listener **link, int port)
300 union mysockaddr addr;
301 int tcpfd, fd;
302 struct listener *l;
303 int opt = 1;
305 memset(&addr, 0, sizeof(addr));
306 addr.in6.sin6_family = AF_INET6;
307 addr.in6.sin6_addr = in6addr_any;
308 addr.in6.sin6_port = htons(port);
309 #ifdef HAVE_SOCKADDR_SA_LEN
310 addr.in6.sin6_len = sizeof(addr.in6);
311 #endif
313 /* No error of the kernel doesn't support IPv6 */
314 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
315 return (errno == EPROTONOSUPPORT ||
316 errno == EAFNOSUPPORT ||
317 errno == EINVAL);
319 if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
320 return 0;
322 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
323 setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
324 setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
325 setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
326 !fix_fd(fd) ||
327 !fix_fd(tcpfd) ||
328 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
329 listen(tcpfd, 5) == -1 ||
330 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
331 return 0;
333 /* The API changed around Linux 2.6.14 but the old ABI is still supported:
334 handle all combinations of headers and kernel.
335 OpenWrt note that this fixes the problem addressed by your very broken patch. */
337 daemon->v6pktinfo = IPV6_PKTINFO;
339 #ifdef IPV6_RECVPKTINFO
340 # ifdef IPV6_2292PKTINFO
341 if (setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1)
343 if (errno == ENOPROTOOPT && setsockopt(fd, IPV6_LEVEL, IPV6_2292PKTINFO, &opt, sizeof(opt)) != -1)
344 daemon->v6pktinfo = IPV6_2292PKTINFO;
345 else
346 return 0;
348 # else
349 if (setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1)
350 return 0;
351 # endif
352 #else
353 if (setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1)
354 return 0;
355 #endif
357 l = safe_malloc(sizeof(struct listener));
358 l->fd = fd;
359 l->tcpfd = tcpfd;
360 l->tftpfd = -1;
361 l->family = AF_INET6;
362 l->next = NULL;
363 *link = l;
365 return 1;
367 #endif
369 struct listener *create_wildcard_listeners(void)
371 union mysockaddr addr;
372 int opt = 1;
373 struct listener *l, *l6 = NULL;
374 int tcpfd = -1, fd = -1, tftpfd = -1;
376 memset(&addr, 0, sizeof(addr));
377 addr.in.sin_family = AF_INET;
378 addr.in.sin_addr.s_addr = INADDR_ANY;
379 addr.in.sin_port = htons(daemon->port);
380 #ifdef HAVE_SOCKADDR_SA_LEN
381 addr.in.sin_len = sizeof(struct sockaddr_in);
382 #endif
384 if (daemon->port != 0)
387 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
388 (tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
389 return NULL;
391 if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
392 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
393 listen(tcpfd, 5) == -1 ||
394 !fix_fd(tcpfd) ||
395 #ifdef HAVE_IPV6
396 !create_ipv6_listener(&l6, daemon->port) ||
397 #endif
398 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
399 !fix_fd(fd) ||
400 #if defined(HAVE_LINUX_NETWORK)
401 setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
402 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
403 setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
404 setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
405 #endif
406 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
407 return NULL;
410 #ifdef HAVE_TFTP
411 if (daemon->tftp_unlimited || daemon->tftp_interfaces)
413 addr.in.sin_port = htons(TFTP_PORT);
414 if ((tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
415 return NULL;
417 if (!fix_fd(tftpfd) ||
418 #if defined(HAVE_LINUX_NETWORK)
419 setsockopt(tftpfd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
420 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
421 setsockopt(tftpfd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
422 setsockopt(tftpfd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
423 #endif
424 bind(tftpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
425 return NULL;
427 #endif
429 l = safe_malloc(sizeof(struct listener));
430 l->family = AF_INET;
431 l->fd = fd;
432 l->tcpfd = tcpfd;
433 l->tftpfd = tftpfd;
434 l->next = l6;
436 return l;
439 struct listener *create_bound_listeners(void)
441 struct listener *listeners = NULL;
442 struct irec *iface;
443 int rc, opt = 1;
444 #ifdef HAVE_IPV6
445 static int dad_count = 0;
446 #endif
448 for (iface = daemon->interfaces; iface; iface = iface->next)
450 struct listener *new = safe_malloc(sizeof(struct listener));
451 new->family = iface->addr.sa.sa_family;
452 new->iface = iface;
453 new->next = listeners;
454 new->tftpfd = -1;
455 new->tcpfd = -1;
456 new->fd = -1;
457 listeners = new;
459 if (daemon->port != 0)
461 if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
462 (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
463 setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
464 setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
465 !fix_fd(new->tcpfd) ||
466 !fix_fd(new->fd))
467 die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
469 #ifdef HAVE_IPV6
470 if (iface->addr.sa.sa_family == AF_INET6)
472 if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
473 setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
474 die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
476 #endif
478 while(1)
480 if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
481 break;
483 #ifdef HAVE_IPV6
484 /* An interface may have an IPv6 address which is still undergoing DAD.
485 If so, the bind will fail until the DAD completes, so we try over 20 seconds
486 before failing. */
487 if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) &&
488 dad_count++ < DAD_WAIT)
490 sleep(1);
491 continue;
493 #endif
494 break;
497 if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
499 prettyprint_addr(&iface->addr, daemon->namebuff);
500 die(_("failed to bind listening socket for %s: %s"),
501 daemon->namebuff, EC_BADNET);
504 if (listen(new->tcpfd, 5) == -1)
505 die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
508 #ifdef HAVE_TFTP
509 if (iface->addr.sa.sa_family == AF_INET && iface->tftp_ok)
511 short save = iface->addr.in.sin_port;
512 iface->addr.in.sin_port = htons(TFTP_PORT);
513 if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
514 setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
515 !fix_fd(new->tftpfd) ||
516 bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
517 die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
518 iface->addr.in.sin_port = save;
520 #endif
524 return listeners;
528 /* return a UDP socket bound to a random port, have to cope with straying into
529 occupied port nos and reserved ones. */
530 int random_sock(int family)
532 int fd;
534 if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
536 union mysockaddr addr;
537 unsigned int ports_avail = 65536u - (unsigned short)daemon->min_port;
538 int tries = ports_avail < 30 ? 3 * ports_avail : 100;
540 memset(&addr, 0, sizeof(addr));
541 addr.sa.sa_family = family;
543 /* don't loop forever if all ports in use. */
545 if (fix_fd(fd))
546 while(tries--)
548 unsigned short port = rand16();
550 if (daemon->min_port != 0)
551 port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
553 if (family == AF_INET)
555 addr.in.sin_addr.s_addr = INADDR_ANY;
556 addr.in.sin_port = port;
557 #ifdef HAVE_SOCKADDR_SA_LEN
558 addr.in.sin_len = sizeof(struct sockaddr_in);
559 #endif
561 #ifdef HAVE_IPV6
562 else
564 addr.in6.sin6_addr = in6addr_any;
565 addr.in6.sin6_port = port;
566 #ifdef HAVE_SOCKADDR_SA_LEN
567 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
568 #endif
570 #endif
572 if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
573 return fd;
575 if (errno != EADDRINUSE && errno != EACCES)
576 break;
579 close(fd);
582 return -1;
586 int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
588 union mysockaddr addr_copy = *addr;
590 /* cannot set source _port_ for TCP connections. */
591 if (is_tcp)
593 if (addr_copy.sa.sa_family == AF_INET)
594 addr_copy.in.sin_port = 0;
595 #ifdef HAVE_IPV6
596 else
597 addr_copy.in6.sin6_port = 0;
598 #endif
601 if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
602 return 0;
604 #if defined(SO_BINDTODEVICE)
605 if (intname[0] != 0 &&
606 setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
607 return 0;
608 #endif
610 return 1;
613 static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
615 struct serverfd *sfd;
616 int errsave;
618 /* when using random ports, servers which would otherwise use
619 the INADDR_ANY/port0 socket have sfd set to NULL */
620 if (!daemon->osport && intname[0] == 0)
622 errno = 0;
624 if (addr->sa.sa_family == AF_INET &&
625 addr->in.sin_addr.s_addr == INADDR_ANY &&
626 addr->in.sin_port == htons(0))
627 return NULL;
629 #ifdef HAVE_IPV6
630 if (addr->sa.sa_family == AF_INET6 &&
631 memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
632 addr->in6.sin6_port == htons(0))
633 return NULL;
634 #endif
637 /* may have a suitable one already */
638 for (sfd = daemon->sfds; sfd; sfd = sfd->next )
639 if (sockaddr_isequal(&sfd->source_addr, addr) &&
640 strcmp(intname, sfd->interface) == 0)
641 return sfd;
643 /* need to make a new one. */
644 errno = ENOMEM; /* in case malloc fails. */
645 if (!(sfd = whine_malloc(sizeof(struct serverfd))))
646 return NULL;
648 if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
650 free(sfd);
651 return NULL;
654 if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd))
656 errsave = errno; /* save error from bind. */
657 close(sfd->fd);
658 free(sfd);
659 errno = errsave;
660 return NULL;
663 strcpy(sfd->interface, intname);
664 sfd->source_addr = *addr;
665 sfd->next = daemon->sfds;
666 daemon->sfds = sfd;
667 return sfd;
670 /* create upstream sockets during startup, before root is dropped which may be needed
671 this allows query_port to be a low port and interface binding */
672 void pre_allocate_sfds(void)
674 struct server *srv;
676 if (daemon->query_port != 0)
678 union mysockaddr addr;
679 memset(&addr, 0, sizeof(addr));
680 addr.in.sin_family = AF_INET;
681 addr.in.sin_addr.s_addr = INADDR_ANY;
682 addr.in.sin_port = htons(daemon->query_port);
683 #ifdef HAVE_SOCKADDR_SA_LEN
684 addr.in.sin_len = sizeof(struct sockaddr_in);
685 #endif
686 allocate_sfd(&addr, "");
687 #ifdef HAVE_IPV6
688 memset(&addr, 0, sizeof(addr));
689 addr.in6.sin6_family = AF_INET6;
690 addr.in6.sin6_addr = in6addr_any;
691 addr.in6.sin6_port = htons(daemon->query_port);
692 #ifdef HAVE_SOCKADDR_SA_LEN
693 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
694 #endif
695 allocate_sfd(&addr, "");
696 #endif
699 for (srv = daemon->servers; srv; srv = srv->next)
700 if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
701 !allocate_sfd(&srv->source_addr, srv->interface) &&
702 errno != 0 &&
703 (daemon->options & OPT_NOWILD))
705 prettyprint_addr(&srv->source_addr, daemon->namebuff);
706 if (srv->interface[0] != 0)
708 strcat(daemon->namebuff, " ");
709 strcat(daemon->namebuff, srv->interface);
711 die(_("failed to bind server socket for %s: %s"),
712 daemon->namebuff, EC_BADNET);
717 void check_servers(void)
719 struct irec *iface;
720 struct server *new, *tmp, *ret = NULL;
721 int port = 0;
723 /* interface may be new since startup */
724 if (!(daemon->options & OPT_NOWILD))
725 enumerate_interfaces();
727 for (new = daemon->servers; new; new = tmp)
729 tmp = new->next;
731 if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
733 port = prettyprint_addr(&new->addr, daemon->namebuff);
735 /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
736 if (new->addr.sa.sa_family == AF_INET &&
737 new->addr.in.sin_addr.s_addr == 0)
739 free(new);
740 continue;
743 for (iface = daemon->interfaces; iface; iface = iface->next)
744 if (sockaddr_isequal(&new->addr, &iface->addr))
745 break;
746 if (iface)
748 my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
749 free(new);
750 continue;
753 /* Do we need a socket set? */
754 if (!new->sfd &&
755 !(new->sfd = allocate_sfd(&new->source_addr, new->interface)) &&
756 errno != 0)
758 my_syslog(LOG_WARNING,
759 _("ignoring nameserver %s - cannot make/bind socket: %s"),
760 daemon->namebuff, strerror(errno));
761 free(new);
762 continue;
766 /* reverse order - gets it right. */
767 new->next = ret;
768 ret = new;
770 if (!(new->flags & SERV_NO_REBIND))
772 if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
774 char *s1, *s2;
775 if (!(new->flags & SERV_HAS_DOMAIN))
776 s1 = _("unqualified"), s2 = _("names");
777 else if (strlen(new->domain) == 0)
778 s1 = _("default"), s2 = "";
779 else
780 s1 = _("domain"), s2 = new->domain;
782 if (new->flags & SERV_NO_ADDR)
783 my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
784 else if (new->flags & SERV_USE_RESOLV)
785 my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
786 else if (!(new->flags & SERV_LITERAL_ADDRESS))
787 my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
789 else if (new->interface[0] != 0)
790 my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface);
791 else
792 my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
796 daemon->servers = ret;
799 /* Return zero if no servers found, in that case we keep polling.
800 This is a protection against an update-time/write race on resolv.conf */
801 int reload_servers(char *fname)
803 FILE *f;
804 char *line;
805 struct server *old_servers = NULL;
806 struct server *new_servers = NULL;
807 struct server *serv;
808 int gotone = 0;
810 /* buff happens to be MAXDNAME long... */
811 if (!(f = fopen(fname, "r")))
813 my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
814 return 0;
817 /* move old servers to free list - we can reuse the memory
818 and not risk malloc if there are the same or fewer new servers.
819 Servers which were specced on the command line go to the new list. */
820 for (serv = daemon->servers; serv;)
822 struct server *tmp = serv->next;
823 if (serv->flags & SERV_FROM_RESOLV)
825 serv->next = old_servers;
826 old_servers = serv;
827 /* forward table rules reference servers, so have to blow them away */
828 server_gone(serv);
830 else
832 serv->next = new_servers;
833 new_servers = serv;
835 serv = tmp;
838 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
840 union mysockaddr addr, source_addr;
841 char *token = strtok(line, " \t\n\r");
843 if (!token)
844 continue;
845 if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
846 continue;
847 if (!(token = strtok(NULL, " \t\n\r")))
848 continue;
850 memset(&addr, 0, sizeof(addr));
851 memset(&source_addr, 0, sizeof(source_addr));
853 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
855 #ifdef HAVE_SOCKADDR_SA_LEN
856 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
857 #endif
858 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
859 addr.in.sin_port = htons(NAMESERVER_PORT);
860 source_addr.in.sin_addr.s_addr = INADDR_ANY;
861 source_addr.in.sin_port = htons(daemon->query_port);
863 #ifdef HAVE_IPV6
864 else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
866 #ifdef HAVE_SOCKADDR_SA_LEN
867 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
868 #endif
869 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
870 addr.in6.sin6_port = htons(NAMESERVER_PORT);
871 source_addr.in6.sin6_addr = in6addr_any;
872 source_addr.in6.sin6_port = htons(daemon->query_port);
874 #endif /* IPV6 */
875 else
876 continue;
878 if (old_servers)
880 serv = old_servers;
881 old_servers = old_servers->next;
883 else if (!(serv = whine_malloc(sizeof (struct server))))
884 continue;
886 /* this list is reverse ordered:
887 it gets reversed again in check_servers */
888 serv->next = new_servers;
889 new_servers = serv;
890 serv->addr = addr;
891 serv->source_addr = source_addr;
892 serv->domain = NULL;
893 serv->interface[0] = 0;
894 serv->sfd = NULL;
895 serv->flags = SERV_FROM_RESOLV;
896 serv->queries = serv->failed_queries = 0;
897 gotone = 1;
900 /* Free any memory not used. */
901 while (old_servers)
903 struct server *tmp = old_servers->next;
904 free(old_servers);
905 old_servers = tmp;
908 daemon->servers = new_servers;
909 fclose(f);
911 return gotone;
915 /* Use an IPv4 listener socket for ioctling */
916 struct in_addr get_ifaddr(char *intr)
918 struct listener *l;
919 struct ifreq ifr;
920 struct sockaddr_in ret;
922 ret.sin_addr.s_addr = -1;
924 for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
926 strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
927 ifr.ifr_addr.sa_family = AF_INET;
929 if (l && ioctl(l->fd, SIOCGIFADDR, &ifr) != -1)
930 memcpy(&ret, &ifr.ifr_addr, sizeof(ret));
932 return ret.sin_addr;