1 /* dnsmasq is Copyright (c) 2000-2012 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/>.
19 #ifdef HAVE_LINUX_NETWORK
21 int indextoname(int fd
, int index
, char *name
)
28 ifr
.ifr_ifindex
= index
;
29 if (ioctl(fd
, SIOCGIFNAME
, &ifr
) == -1)
32 strncpy(name
, ifr
.ifr_name
, IF_NAMESIZE
);
38 #elif defined(HAVE_SOLARIS_NETWORK)
42 #ifndef LIFC_UNDER_IPMP
43 # define LIFC_UNDER_IPMP 0
46 int indextoname(int fd
, int index
, char *name
)
50 int numifs
, bufsize
, i
;
57 if (getzoneid() == GLOBAL_ZONEID
)
59 if (!if_indextoname(index
, name
))
64 lifc_flags
= LIFC_NOXMIT
| LIFC_TEMPORARY
| LIFC_ALLZONES
| LIFC_UNDER_IPMP
;
65 lifn
.lifn_family
= AF_UNSPEC
;
66 lifn
.lifn_flags
= lifc_flags
;
67 if (ioctl(fd
, SIOCGLIFNUM
, &lifn
) < 0)
70 numifs
= lifn
.lifn_count
;
71 bufsize
= numifs
* sizeof(struct lifreq
);
73 lifc
.lifc_family
= AF_UNSPEC
;
74 lifc
.lifc_flags
= lifc_flags
;
75 lifc
.lifc_len
= bufsize
;
76 lifc
.lifc_buf
= alloca(bufsize
);
78 if (ioctl(fd
, SIOCGLIFCONF
, &lifc
) < 0)
81 lifrp
= lifc
.lifc_req
;
82 for (i
= lifc
.lifc_len
/ sizeof(struct lifreq
); i
; i
--, lifrp
++)
85 strncpy(lifr
.lifr_name
, lifrp
->lifr_name
, IF_NAMESIZE
);
86 if (ioctl(fd
, SIOCGLIFINDEX
, &lifr
) < 0)
89 if (lifr
.lifr_index
== index
) {
90 strncpy(name
, lifr
.lifr_name
, IF_NAMESIZE
);
100 int indextoname(int fd
, int index
, char *name
)
102 if (index
== 0 || !if_indextoname(index
, name
))
110 int iface_check(int family
, struct all_addr
*addr
, char *name
, int *auth
)
115 /* Note: have to check all and not bail out early, so that we set the
121 if (daemon
->if_names
|| daemon
->if_addrs
)
125 for (tmp
= daemon
->if_names
; tmp
; tmp
= tmp
->next
)
126 if (tmp
->name
&& (strcmp(tmp
->name
, name
) == 0))
130 for (tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
131 if (tmp
->addr
.sa
.sa_family
== family
)
133 if (family
== AF_INET
&&
134 tmp
->addr
.in
.sin_addr
.s_addr
== addr
->addr
.addr4
.s_addr
)
137 else if (family
== AF_INET6
&&
138 IN6_ARE_ADDR_EQUAL(&tmp
->addr
.in6
.sin6_addr
,
145 for (tmp
= daemon
->if_except
; tmp
; tmp
= tmp
->next
)
146 if (tmp
->name
&& (strcmp(tmp
->name
, name
) == 0))
150 for (tmp
= daemon
->authinterface
; tmp
; tmp
= tmp
->next
)
153 if (strcmp(tmp
->name
, name
) == 0)
156 else if (addr
&& tmp
->addr
.sa
.sa_family
== AF_INET
&& family
== AF_INET
&&
157 tmp
->addr
.in
.sin_addr
.s_addr
== addr
->addr
.addr4
.s_addr
)
160 else if (addr
&& tmp
->addr
.sa
.sa_family
== AF_INET6
&& family
== AF_INET6
&&
161 IN6_ARE_ADDR_EQUAL(&tmp
->addr
.in6
.sin6_addr
, &addr
->addr
.addr6
))
174 static int iface_allowed(struct irec
**irecp
, int if_index
,
175 union mysockaddr
*addr
, struct in_addr netmask
, int dad
)
178 int fd
, mtu
= 0, loopback
;
180 int tftp_ok
= !!option_bool(OPT_TFTP
);
187 /* check whether the interface IP has been added already
188 we call this routine multiple times. */
189 for (iface
= *irecp
; iface
; iface
= iface
->next
)
190 if (sockaddr_isequal(&iface
->addr
, addr
))
196 if ((fd
= socket(PF_INET
, SOCK_DGRAM
, 0)) == -1 ||
197 !indextoname(fd
, if_index
, ifr
.ifr_name
) ||
198 ioctl(fd
, SIOCGIFFLAGS
, &ifr
) == -1)
209 loopback
= ifr
.ifr_flags
& IFF_LOOPBACK
;
214 if (ioctl(fd
, SIOCGIFMTU
, &ifr
) != -1)
219 /* If we are restricting the set of interfaces to use, make
220 sure that loopback interfaces are in that set. */
221 if (daemon
->if_names
&& loopback
)
224 for (lo
= daemon
->if_names
; lo
; lo
= lo
->next
)
225 if (lo
->name
&& strcmp(lo
->name
, ifr
.ifr_name
) == 0)
229 (lo
= whine_malloc(sizeof(struct iname
))) &&
230 (lo
->name
= whine_malloc(strlen(ifr
.ifr_name
)+1)))
232 strcpy(lo
->name
, ifr
.ifr_name
);
234 lo
->next
= daemon
->if_names
;
235 daemon
->if_names
= lo
;
239 if (addr
->sa
.sa_family
== AF_INET
&&
240 !iface_check(AF_INET
, (struct all_addr
*)&addr
->in
.sin_addr
, ifr
.ifr_name
, &auth_dns
))
244 if (addr
->sa
.sa_family
== AF_INET6
&&
245 !iface_check(AF_INET6
, (struct all_addr
*)&addr
->in6
.sin6_addr
, ifr
.ifr_name
, &auth_dns
))
250 /* No DHCP where we're doing auth DNS. */
257 for (tmp
= daemon
->dhcp_except
; tmp
; tmp
= tmp
->next
)
258 if (tmp
->name
&& (strcmp(tmp
->name
, ifr
.ifr_name
) == 0))
266 if ((iface
= whine_malloc(sizeof(struct irec
))))
269 iface
->netmask
= netmask
;
270 iface
->tftp_ok
= tftp_ok
;
271 iface
->dhcp_ok
= dhcp_ok
;
272 iface
->dns_auth
= auth_dns
;
275 iface
->done
= iface
->multicast_done
= 0;
276 iface
->index
= if_index
;
277 if ((iface
->name
= whine_malloc(strlen(ifr
.ifr_name
)+1)))
279 strcpy(iface
->name
, ifr
.ifr_name
);
280 iface
->next
= *irecp
;
293 static int iface_allowed_v6(struct in6_addr
*local
, int prefix
,
294 int scope
, int if_index
, int flags
,
295 int preferred
, int valid
, void *vparam
)
297 union mysockaddr addr
;
298 struct in_addr netmask
; /* dummy */
301 (void)prefix
; /* warning */
302 (void)scope
; /* warning */
306 memset(&addr
, 0, sizeof(addr
));
307 #ifdef HAVE_SOCKADDR_SA_LEN
308 addr
.in6
.sin6_len
= sizeof(addr
.in6
);
310 addr
.in6
.sin6_family
= AF_INET6
;
311 addr
.in6
.sin6_addr
= *local
;
312 addr
.in6
.sin6_port
= htons(daemon
->port
);
313 addr
.in6
.sin6_scope_id
= if_index
;
315 return iface_allowed((struct irec
**)vparam
, if_index
, &addr
, netmask
, !!(flags
& IFACE_TENTATIVE
));
319 static int iface_allowed_v4(struct in_addr local
, int if_index
,
320 struct in_addr netmask
, struct in_addr broadcast
, void *vparam
)
322 union mysockaddr addr
;
324 memset(&addr
, 0, sizeof(addr
));
325 #ifdef HAVE_SOCKADDR_SA_LEN
326 addr
.in
.sin_len
= sizeof(addr
.in
);
328 addr
.in
.sin_family
= AF_INET
;
329 addr
.in
.sin_addr
= broadcast
; /* warning */
330 addr
.in
.sin_addr
= local
;
331 addr
.in
.sin_port
= htons(daemon
->port
);
333 return iface_allowed((struct irec
**)vparam
, if_index
, &addr
, netmask
, 0);
336 int enumerate_interfaces(void)
339 if (!iface_enumerate(AF_INET6
, &daemon
->interfaces
, iface_allowed_v6
))
343 return iface_enumerate(AF_INET
, &daemon
->interfaces
, iface_allowed_v4
);
346 /* set NONBLOCK bit on fd: See Stevens 16.6 */
351 if ((flags
= fcntl(fd
, F_GETFL
)) == -1 ||
352 fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
) == -1)
358 static int make_sock(union mysockaddr
*addr
, int type
, int dienow
)
360 int family
= addr
->sa
.sa_family
;
363 if ((fd
= socket(family
, type
, 0)) == -1)
368 /* No error if the kernel just doesn't support this IP flavour */
369 if (errno
== EPROTONOSUPPORT
||
370 errno
== EAFNOSUPPORT
||
375 port
= prettyprint_addr(addr
, daemon
->addrbuff
);
376 if (!option_bool(OPT_NOWILD
) && !option_bool(OPT_CLEVERBIND
))
377 sprintf(daemon
->addrbuff
, "port %d", port
);
378 s
= _("failed to create listening socket for %s: %s");
385 /* failure to bind addresses given by --listen-address at this point
386 is OK if we're doing bind-dynamic */
387 if (!option_bool(OPT_CLEVERBIND
))
388 die(s
, daemon
->addrbuff
, EC_BADNET
);
391 my_syslog(LOG_WARNING
, s
, daemon
->addrbuff
, strerror(errno
));
396 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &opt
, sizeof(opt
)) == -1 || !fix_fd(fd
))
400 if (family
== AF_INET6
&& setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &opt
, sizeof(opt
)) == -1)
404 if ((rc
= bind(fd
, (struct sockaddr
*)addr
, sa_len(addr
))) == -1)
407 if (type
== SOCK_STREAM
)
409 if (listen(fd
, 5) == -1)
412 else if (!option_bool(OPT_NOWILD
))
414 if (family
== AF_INET
)
416 #if defined(HAVE_LINUX_NETWORK)
417 if (setsockopt(fd
, IPPROTO_IP
, IP_PKTINFO
, &opt
, sizeof(opt
)) == -1)
419 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
420 if (setsockopt(fd
, IPPROTO_IP
, IP_RECVDSTADDR
, &opt
, sizeof(opt
)) == -1 ||
421 setsockopt(fd
, IPPROTO_IP
, IP_RECVIF
, &opt
, sizeof(opt
)) == -1)
426 else if (!set_ipv6pktinfo(fd
))
435 int set_ipv6pktinfo(int fd
)
439 /* The API changed around Linux 2.6.14 but the old ABI is still supported:
440 handle all combinations of headers and kernel.
441 OpenWrt note that this fixes the problem addressed by your very broken patch. */
442 daemon
->v6pktinfo
= IPV6_PKTINFO
;
444 #ifdef IPV6_RECVPKTINFO
445 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
, &opt
, sizeof(opt
)) != -1)
447 # ifdef IPV6_2292PKTINFO
448 else if (errno
== ENOPROTOOPT
&& setsockopt(fd
, IPPROTO_IPV6
, IPV6_2292PKTINFO
, &opt
, sizeof(opt
)) != -1)
450 daemon
->v6pktinfo
= IPV6_2292PKTINFO
;
455 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_PKTINFO
, &opt
, sizeof(opt
)) != -1)
464 /* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
465 int tcp_interface(int fd
, int af
)
469 #ifdef HAVE_LINUX_NETWORK
471 struct cmsghdr
*cmptr
;
474 /* use mshdr do that the CMSDG_* macros are available */
475 msg
.msg_control
= daemon
->packet
;
476 msg
.msg_controllen
= daemon
->packet_buff_sz
;
478 /* we overwrote the buffer... */
479 daemon
->srv_save
= NULL
;
483 if (setsockopt(fd
, IPPROTO_IP
, IP_PKTINFO
, &opt
, sizeof(opt
)) != -1 &&
484 getsockopt(fd
, IPPROTO_IP
, IP_PKTOPTIONS
, msg
.msg_control
, (socklen_t
*)&msg
.msg_controllen
) != -1)
485 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
486 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_PKTINFO
)
490 struct in_pktinfo
*p
;
493 p
.c
= CMSG_DATA(cmptr
);
494 if_index
= p
.p
->ipi_ifindex
;
500 /* Only the RFC-2292 API has the ability to find the interface for TCP connections,
501 it was removed in RFC-3542 !!!!
503 Fortunately, Linux kept the 2292 ABI when it moved to 3542. The following code always
504 uses the old ABI, and should work with pre- and post-3542 kernel headers */
506 #ifdef IPV6_2292PKTOPTIONS
507 # define PKTOPTIONS IPV6_2292PKTOPTIONS
509 # define PKTOPTIONS IPV6_PKTOPTIONS
512 if (set_ipv6pktinfo(fd
) &&
513 getsockopt(fd
, IPPROTO_IPV6
, PKTOPTIONS
, msg
.msg_control
, (socklen_t
*)&msg
.msg_controllen
) != -1)
515 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
516 if (cmptr
->cmsg_level
== IPPROTO_IPV6
&& cmptr
->cmsg_type
== daemon
->v6pktinfo
)
520 struct in6_pktinfo
*p
;
522 p
.c
= CMSG_DATA(cmptr
);
524 if_index
= p
.p
->ipi6_ifindex
;
534 static struct listener
*create_listeners(union mysockaddr
*addr
, int do_tftp
, int dienow
)
536 struct listener
*l
= NULL
;
537 int fd
= -1, tcpfd
= -1, tftpfd
= -1;
539 if (daemon
->port
!= 0)
541 fd
= make_sock(addr
, SOCK_DGRAM
, dienow
);
542 tcpfd
= make_sock(addr
, SOCK_STREAM
, dienow
);
548 if (addr
->sa
.sa_family
== AF_INET
)
550 /* port must be restored to DNS port for TCP code */
551 short save
= addr
->in
.sin_port
;
552 addr
->in
.sin_port
= htons(TFTP_PORT
);
553 tftpfd
= make_sock(addr
, SOCK_DGRAM
, dienow
);
554 addr
->in
.sin_port
= save
;
559 short save
= addr
->in6
.sin6_port
;
560 addr
->in6
.sin6_port
= htons(TFTP_PORT
);
561 tftpfd
= make_sock(addr
, SOCK_DGRAM
, dienow
);
562 addr
->in6
.sin6_port
= save
;
568 if (fd
!= -1 || tcpfd
!= -1 || tftpfd
!= -1)
570 l
= safe_malloc(sizeof(struct listener
));
572 l
->family
= addr
->sa
.sa_family
;
581 void create_wildcard_listeners(void)
583 union mysockaddr addr
;
584 struct listener
*l
, *l6
;
586 memset(&addr
, 0, sizeof(addr
));
587 #ifdef HAVE_SOCKADDR_SA_LEN
588 addr
.in
.sin_len
= sizeof(addr
.in
);
590 addr
.in
.sin_family
= AF_INET
;
591 addr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
592 addr
.in
.sin_port
= htons(daemon
->port
);
594 l
= create_listeners(&addr
, !!option_bool(OPT_TFTP
), 1);
597 memset(&addr
, 0, sizeof(addr
));
598 # ifdef HAVE_SOCKADDR_SA_LEN
599 addr
.in6
.sin6_len
= sizeof(addr
.in6
);
601 addr
.in6
.sin6_family
= AF_INET6
;
602 addr
.in6
.sin6_addr
= in6addr_any
;
603 addr
.in6
.sin6_port
= htons(daemon
->port
);
605 l6
= create_listeners(&addr
, !!option_bool(OPT_TFTP
), 1);
612 daemon
->listeners
= l
;
615 void create_bound_listeners(int dienow
)
617 struct listener
*new;
619 struct iname
*if_tmp
;
621 for (iface
= daemon
->interfaces
; iface
; iface
= iface
->next
)
622 if (!iface
->done
&& !iface
->dad
&&
623 (new = create_listeners(&iface
->addr
, iface
->tftp_ok
, dienow
)))
626 new->next
= daemon
->listeners
;
627 daemon
->listeners
= new;
631 /* Check for --listen-address options that haven't been used because there's
632 no interface with a matching address. These may be valid: eg it's possible
633 to listen on 127.0.1.1 even if the loopback interface is 127.0.0.1
635 If the address isn't valid the bind() will fail and we'll die()
636 (except in bind-dynamic mode, when we'll complain but keep trying.)
638 The resulting listeners have the ->iface field NULL, and this has to be
639 handled by the DNS and TFTP code. It disables --localise-queries processing
640 (no netmask) and some MTU login the tftp code. */
642 for (if_tmp
= daemon
->if_addrs
; if_tmp
; if_tmp
= if_tmp
->next
)
644 (new = create_listeners(&if_tmp
->addr
, !!option_bool(OPT_TFTP
), dienow
)))
647 new->next
= daemon
->listeners
;
648 daemon
->listeners
= new;
652 int is_dad_listeners(void)
656 if (option_bool(OPT_NOWILD
))
657 for (iface
= daemon
->interfaces
; iface
; iface
= iface
->next
)
658 if (iface
->dad
&& !iface
->done
)
665 void join_multicast(int dienow
)
667 struct irec
*iface
, *tmp
;
669 for (iface
= daemon
->interfaces
; iface
; iface
= iface
->next
)
670 if (iface
->addr
.sa
.sa_family
== AF_INET6
&& iface
->dhcp_ok
&& !iface
->multicast_done
)
672 /* There's an irec per address but we only want to join for multicast
673 once per interface. Weed out duplicates. */
674 for (tmp
= daemon
->interfaces
; tmp
; tmp
= tmp
->next
)
675 if (tmp
->multicast_done
&& tmp
->index
== iface
->index
)
678 iface
->multicast_done
= 1;
682 struct ipv6_mreq mreq
;
685 mreq
.ipv6mr_interface
= iface
->index
;
687 inet_pton(AF_INET6
, ALL_RELAY_AGENTS_AND_SERVERS
, &mreq
.ipv6mr_multiaddr
);
689 if (daemon
->doing_dhcp6
&&
690 setsockopt(daemon
->dhcp6fd
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
, &mreq
, sizeof(mreq
)) == -1)
693 inet_pton(AF_INET6
, ALL_SERVERS
, &mreq
.ipv6mr_multiaddr
);
695 if (daemon
->doing_dhcp6
&&
696 setsockopt(daemon
->dhcp6fd
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
, &mreq
, sizeof(mreq
)) == -1)
699 inet_pton(AF_INET6
, ALL_ROUTERS
, &mreq
.ipv6mr_multiaddr
);
701 if (daemon
->doing_ra
&&
702 setsockopt(daemon
->icmp6fd
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
, &mreq
, sizeof(mreq
)) == -1)
707 char *s
= _("interface %s failed to join DHCPv6 multicast group: %s");
709 die(s
, iface
->name
, EC_BADNET
);
711 my_syslog(LOG_ERR
, s
, iface
->name
, strerror(errno
));
718 /* return a UDP socket bound to a random port, have to cope with straying into
719 occupied port nos and reserved ones. */
720 int random_sock(int family
)
724 if ((fd
= socket(family
, SOCK_DGRAM
, 0)) != -1)
726 union mysockaddr addr
;
727 unsigned int ports_avail
= 65536u - (unsigned short)daemon
->min_port
;
728 int tries
= ports_avail
< 30 ? 3 * ports_avail
: 100;
730 memset(&addr
, 0, sizeof(addr
));
731 addr
.sa
.sa_family
= family
;
733 /* don't loop forever if all ports in use. */
738 unsigned short port
= rand16();
740 if (daemon
->min_port
!= 0)
741 port
= htons(daemon
->min_port
+ (port
% ((unsigned short)ports_avail
)));
743 if (family
== AF_INET
)
745 addr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
746 addr
.in
.sin_port
= port
;
747 #ifdef HAVE_SOCKADDR_SA_LEN
748 addr
.in
.sin_len
= sizeof(struct sockaddr_in
);
754 addr
.in6
.sin6_addr
= in6addr_any
;
755 addr
.in6
.sin6_port
= port
;
756 #ifdef HAVE_SOCKADDR_SA_LEN
757 addr
.in6
.sin6_len
= sizeof(struct sockaddr_in6
);
762 if (bind(fd
, (struct sockaddr
*)&addr
, sa_len(&addr
)) == 0)
765 if (errno
!= EADDRINUSE
&& errno
!= EACCES
)
776 int local_bind(int fd
, union mysockaddr
*addr
, char *intname
, int is_tcp
)
778 union mysockaddr addr_copy
= *addr
;
780 /* cannot set source _port_ for TCP connections. */
783 if (addr_copy
.sa
.sa_family
== AF_INET
)
784 addr_copy
.in
.sin_port
= 0;
787 addr_copy
.in6
.sin6_port
= 0;
791 if (bind(fd
, (struct sockaddr
*)&addr_copy
, sa_len(&addr_copy
)) == -1)
794 #if defined(SO_BINDTODEVICE)
795 if (intname
[0] != 0 &&
796 setsockopt(fd
, SOL_SOCKET
, SO_BINDTODEVICE
, intname
, IF_NAMESIZE
) == -1)
803 static struct serverfd
*allocate_sfd(union mysockaddr
*addr
, char *intname
)
805 struct serverfd
*sfd
;
808 /* when using random ports, servers which would otherwise use
809 the INADDR_ANY/port0 socket have sfd set to NULL */
810 if (!daemon
->osport
&& intname
[0] == 0)
814 if (addr
->sa
.sa_family
== AF_INET
&&
815 addr
->in
.sin_addr
.s_addr
== INADDR_ANY
&&
816 addr
->in
.sin_port
== htons(0))
820 if (addr
->sa
.sa_family
== AF_INET6
&&
821 memcmp(&addr
->in6
.sin6_addr
, &in6addr_any
, sizeof(in6addr_any
)) == 0 &&
822 addr
->in6
.sin6_port
== htons(0))
827 /* may have a suitable one already */
828 for (sfd
= daemon
->sfds
; sfd
; sfd
= sfd
->next
)
829 if (sockaddr_isequal(&sfd
->source_addr
, addr
) &&
830 strcmp(intname
, sfd
->interface
) == 0)
833 /* need to make a new one. */
834 errno
= ENOMEM
; /* in case malloc fails. */
835 if (!(sfd
= whine_malloc(sizeof(struct serverfd
))))
838 if ((sfd
->fd
= socket(addr
->sa
.sa_family
, SOCK_DGRAM
, 0)) == -1)
844 if (!local_bind(sfd
->fd
, addr
, intname
, 0) || !fix_fd(sfd
->fd
))
846 errsave
= errno
; /* save error from bind. */
853 strcpy(sfd
->interface
, intname
);
854 sfd
->source_addr
= *addr
;
855 sfd
->next
= daemon
->sfds
;
860 /* create upstream sockets during startup, before root is dropped which may be needed
861 this allows query_port to be a low port and interface binding */
862 void pre_allocate_sfds(void)
866 if (daemon
->query_port
!= 0)
868 union mysockaddr addr
;
869 memset(&addr
, 0, sizeof(addr
));
870 addr
.in
.sin_family
= AF_INET
;
871 addr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
872 addr
.in
.sin_port
= htons(daemon
->query_port
);
873 #ifdef HAVE_SOCKADDR_SA_LEN
874 addr
.in
.sin_len
= sizeof(struct sockaddr_in
);
876 allocate_sfd(&addr
, "");
878 memset(&addr
, 0, sizeof(addr
));
879 addr
.in6
.sin6_family
= AF_INET6
;
880 addr
.in6
.sin6_addr
= in6addr_any
;
881 addr
.in6
.sin6_port
= htons(daemon
->query_port
);
882 #ifdef HAVE_SOCKADDR_SA_LEN
883 addr
.in6
.sin6_len
= sizeof(struct sockaddr_in6
);
885 allocate_sfd(&addr
, "");
889 for (srv
= daemon
->servers
; srv
; srv
= srv
->next
)
890 if (!(srv
->flags
& (SERV_LITERAL_ADDRESS
| SERV_NO_ADDR
| SERV_USE_RESOLV
| SERV_NO_REBIND
)) &&
891 !allocate_sfd(&srv
->source_addr
, srv
->interface
) &&
893 option_bool(OPT_NOWILD
))
895 prettyprint_addr(&srv
->source_addr
, daemon
->namebuff
);
896 if (srv
->interface
[0] != 0)
898 strcat(daemon
->namebuff
, " ");
899 strcat(daemon
->namebuff
, srv
->interface
);
901 die(_("failed to bind server socket for %s: %s"),
902 daemon
->namebuff
, EC_BADNET
);
907 void check_servers(void)
910 struct server
*new, *tmp
, *ret
= NULL
;
913 /* interface may be new since startup */
914 if (!option_bool(OPT_NOWILD
))
915 enumerate_interfaces();
917 for (new = daemon
->servers
; new; new = tmp
)
921 if (!(new->flags
& (SERV_LITERAL_ADDRESS
| SERV_NO_ADDR
| SERV_USE_RESOLV
| SERV_NO_REBIND
)))
923 port
= prettyprint_addr(&new->addr
, daemon
->namebuff
);
925 /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
926 if (new->addr
.sa
.sa_family
== AF_INET
&&
927 new->addr
.in
.sin_addr
.s_addr
== 0)
933 for (iface
= daemon
->interfaces
; iface
; iface
= iface
->next
)
934 if (sockaddr_isequal(&new->addr
, &iface
->addr
))
938 my_syslog(LOG_WARNING
, _("ignoring nameserver %s - local interface"), daemon
->namebuff
);
943 /* Do we need a socket set? */
945 !(new->sfd
= allocate_sfd(&new->source_addr
, new->interface
)) &&
948 my_syslog(LOG_WARNING
,
949 _("ignoring nameserver %s - cannot make/bind socket: %s"),
950 daemon
->namebuff
, strerror(errno
));
956 /* reverse order - gets it right. */
960 if (!(new->flags
& SERV_NO_REBIND
))
962 if (new->flags
& (SERV_HAS_DOMAIN
| SERV_FOR_NODOTS
| SERV_USE_RESOLV
))
965 if (!(new->flags
& SERV_HAS_DOMAIN
))
966 s1
= _("unqualified"), s2
= _("names");
967 else if (strlen(new->domain
) == 0)
968 s1
= _("default"), s2
= "";
970 s1
= _("domain"), s2
= new->domain
;
972 if (new->flags
& SERV_NO_ADDR
)
973 my_syslog(LOG_INFO
, _("using local addresses only for %s %s"), s1
, s2
);
974 else if (new->flags
& SERV_USE_RESOLV
)
975 my_syslog(LOG_INFO
, _("using standard nameservers for %s %s"), s1
, s2
);
976 else if (!(new->flags
& SERV_LITERAL_ADDRESS
))
977 my_syslog(LOG_INFO
, _("using nameserver %s#%d for %s %s"), daemon
->namebuff
, port
, s1
, s2
);
979 else if (new->interface
[0] != 0)
980 my_syslog(LOG_INFO
, _("using nameserver %s#%d(via %s)"), daemon
->namebuff
, port
, new->interface
);
982 my_syslog(LOG_INFO
, _("using nameserver %s#%d"), daemon
->namebuff
, port
);
986 daemon
->servers
= ret
;
989 /* Return zero if no servers found, in that case we keep polling.
990 This is a protection against an update-time/write race on resolv.conf */
991 int reload_servers(char *fname
)
995 struct server
*old_servers
= NULL
;
996 struct server
*new_servers
= NULL
;
1000 /* buff happens to be MAXDNAME long... */
1001 if (!(f
= fopen(fname
, "r")))
1003 my_syslog(LOG_ERR
, _("failed to read %s: %s"), fname
, strerror(errno
));
1007 /* move old servers to free list - we can reuse the memory
1008 and not risk malloc if there are the same or fewer new servers.
1009 Servers which were specced on the command line go to the new list. */
1010 for (serv
= daemon
->servers
; serv
;)
1012 struct server
*tmp
= serv
->next
;
1013 if (serv
->flags
& SERV_FROM_RESOLV
)
1015 serv
->next
= old_servers
;
1017 /* forward table rules reference servers, so have to blow them away */
1022 serv
->next
= new_servers
;
1028 while ((line
= fgets(daemon
->namebuff
, MAXDNAME
, f
)))
1030 union mysockaddr addr
, source_addr
;
1031 char *token
= strtok(line
, " \t\n\r");
1035 if (strcmp(token
, "nameserver") != 0 && strcmp(token
, "server") != 0)
1037 if (!(token
= strtok(NULL
, " \t\n\r")))
1040 memset(&addr
, 0, sizeof(addr
));
1041 memset(&source_addr
, 0, sizeof(source_addr
));
1043 if ((addr
.in
.sin_addr
.s_addr
= inet_addr(token
)) != (in_addr_t
) -1)
1045 #ifdef HAVE_SOCKADDR_SA_LEN
1046 source_addr
.in
.sin_len
= addr
.in
.sin_len
= sizeof(source_addr
.in
);
1048 source_addr
.in
.sin_family
= addr
.in
.sin_family
= AF_INET
;
1049 addr
.in
.sin_port
= htons(NAMESERVER_PORT
);
1050 source_addr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
1051 source_addr
.in
.sin_port
= htons(daemon
->query_port
);
1056 int scope_index
= 0;
1057 char *scope_id
= strchr(token
, '%');
1062 scope_index
= if_nametoindex(scope_id
);
1065 if (inet_pton(AF_INET6
, token
, &addr
.in6
.sin6_addr
) > 0)
1067 #ifdef HAVE_SOCKADDR_SA_LEN
1068 source_addr
.in6
.sin6_len
= addr
.in6
.sin6_len
= sizeof(source_addr
.in6
);
1070 source_addr
.in6
.sin6_family
= addr
.in6
.sin6_family
= AF_INET6
;
1071 source_addr
.in6
.sin6_flowinfo
= addr
.in6
.sin6_flowinfo
= 0;
1072 addr
.in6
.sin6_port
= htons(NAMESERVER_PORT
);
1073 addr
.in6
.sin6_scope_id
= scope_index
;
1074 source_addr
.in6
.sin6_addr
= in6addr_any
;
1075 source_addr
.in6
.sin6_port
= htons(daemon
->query_port
);
1076 source_addr
.in6
.sin6_scope_id
= 0;
1089 old_servers
= old_servers
->next
;
1091 else if (!(serv
= whine_malloc(sizeof (struct server
))))
1094 /* this list is reverse ordered:
1095 it gets reversed again in check_servers */
1096 serv
->next
= new_servers
;
1099 serv
->source_addr
= source_addr
;
1100 serv
->domain
= NULL
;
1101 serv
->interface
[0] = 0;
1103 serv
->flags
= SERV_FROM_RESOLV
;
1104 serv
->queries
= serv
->failed_queries
= 0;
1108 /* Free any memory not used. */
1111 struct server
*tmp
= old_servers
->next
;
1116 daemon
->servers
= new_servers
;
1123 /* Use an IPv4 listener socket for ioctling */
1124 struct in_addr
get_ifaddr(char *intr
)
1128 struct sockaddr_in ret
;
1130 ret
.sin_addr
.s_addr
= -1;
1132 for (l
= daemon
->listeners
;
1133 l
&& (l
->family
!= AF_INET
|| l
->fd
== -1);
1136 strncpy(ifr
.ifr_name
, intr
, IF_NAMESIZE
);
1137 ifr
.ifr_addr
.sa_family
= AF_INET
;
1139 if (l
&& ioctl(l
->fd
, SIOCGIFADDR
, &ifr
) != -1)
1140 memcpy(&ret
, &ifr
.ifr_addr
, sizeof(ret
));
1142 return ret
.sin_addr
;