]> git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/network.c
First checkin of interface-address constructor mode for DHCPv6 and RA.
[people/ms/dnsmasq.git] / src / network.c
1 /* dnsmasq is Copyright (c) 2000-2012 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
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
38 #elif defined(HAVE_SOLARIS_NETWORK)
39
40 #include <zone.h>
41 #include <alloca.h>
42 #ifndef LIFC_UNDER_IPMP
43 # define LIFC_UNDER_IPMP 0
44 #endif
45
46 int indextoname(int fd, int index, char *name)
47 {
48 int64_t lifc_flags;
49 struct lifnum lifn;
50 int numifs, bufsize, i;
51 struct lifconf lifc;
52 struct lifreq *lifrp;
53
54 if (index == 0)
55 return 0;
56
57 if (getzoneid() == GLOBAL_ZONEID)
58 {
59 if (!if_indextoname(index, name))
60 return 0;
61 return 1;
62 }
63
64 lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES | LIFC_UNDER_IPMP;
65 lifn.lifn_family = AF_UNSPEC;
66 lifn.lifn_flags = lifc_flags;
67 if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0)
68 return 0;
69
70 numifs = lifn.lifn_count;
71 bufsize = numifs * sizeof(struct lifreq);
72
73 lifc.lifc_family = AF_UNSPEC;
74 lifc.lifc_flags = lifc_flags;
75 lifc.lifc_len = bufsize;
76 lifc.lifc_buf = alloca(bufsize);
77
78 if (ioctl(fd, SIOCGLIFCONF, &lifc) < 0)
79 return 0;
80
81 lifrp = lifc.lifc_req;
82 for (i = lifc.lifc_len / sizeof(struct lifreq); i; i--, lifrp++)
83 {
84 struct lifreq lifr;
85 strncpy(lifr.lifr_name, lifrp->lifr_name, IF_NAMESIZE);
86 if (ioctl(fd, SIOCGLIFINDEX, &lifr) < 0)
87 return 0;
88
89 if (lifr.lifr_index == index) {
90 strncpy(name, lifr.lifr_name, IF_NAMESIZE);
91 return 1;
92 }
93 }
94 return 0;
95 }
96
97
98 #else
99
100 int indextoname(int fd, int index, char *name)
101 {
102 if (index == 0 || !if_indextoname(index, name))
103 return 0;
104
105 return 1;
106 }
107
108 #endif
109
110 int iface_check(int family, struct all_addr *addr, char *name, int *auth)
111 {
112 struct iname *tmp;
113 int ret = 1;
114
115 /* Note: have to check all and not bail out early, so that we set the
116 "used" flags. */
117
118 if (auth)
119 *auth = 0;
120
121 if (daemon->if_names || daemon->if_addrs)
122 {
123 ret = 0;
124
125 for (tmp = daemon->if_names; tmp; tmp = tmp->next)
126 if (tmp->name && (strcmp(tmp->name, name) == 0))
127 ret = tmp->used = 1;
128
129 if (addr)
130 for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
131 if (tmp->addr.sa.sa_family == family)
132 {
133 if (family == AF_INET &&
134 tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
135 ret = tmp->used = 1;
136 #ifdef HAVE_IPV6
137 else if (family == AF_INET6 &&
138 IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr,
139 &addr->addr.addr6))
140 ret = tmp->used = 1;
141 #endif
142 }
143 }
144
145 for (tmp = daemon->if_except; tmp; tmp = tmp->next)
146 if (tmp->name && (strcmp(tmp->name, name) == 0))
147 ret = 0;
148
149
150 for (tmp = daemon->authinterface; tmp; tmp = tmp->next)
151 if (tmp->name)
152 {
153 if (strcmp(tmp->name, name) == 0)
154 break;
155 }
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)
158 break;
159 #ifdef HAVE_IPV6
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))
162 break;
163 #endif
164
165 if (tmp && auth)
166 {
167 *auth = 1;
168 ret = 1;
169 }
170
171 return ret;
172 }
173
174 static int iface_allowed(struct irec **irecp, int if_index,
175 union mysockaddr *addr, struct in_addr netmask, int dad)
176 {
177 struct irec *iface;
178 int fd, mtu = 0, loopback;
179 struct ifreq ifr;
180 int tftp_ok = !!option_bool(OPT_TFTP);
181 int dhcp_ok = 1;
182 int auth_dns = 0;
183 #ifdef HAVE_DHCP
184 struct iname *tmp;
185 #endif
186
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))
191 {
192 iface->dad = dad;
193 return 1;
194 }
195
196 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 ||
197 !indextoname(fd, if_index, ifr.ifr_name) ||
198 ioctl(fd, SIOCGIFFLAGS, &ifr) == -1)
199 {
200 if (fd != -1)
201 {
202 int errsave = errno;
203 close(fd);
204 errno = errsave;
205 }
206 return 0;
207 }
208
209 loopback = ifr.ifr_flags & IFF_LOOPBACK;
210
211 if (loopback)
212 dhcp_ok = 0;
213
214 if (ioctl(fd, SIOCGIFMTU, &ifr) != -1)
215 mtu = ifr.ifr_mtu;
216
217 close(fd);
218
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)
222 {
223 struct iname *lo;
224 for (lo = daemon->if_names; lo; lo = lo->next)
225 if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
226 break;
227
228 if (!lo &&
229 (lo = whine_malloc(sizeof(struct iname))) &&
230 (lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
231 {
232 strcpy(lo->name, ifr.ifr_name);
233 lo->used = 1;
234 lo->next = daemon->if_names;
235 daemon->if_names = lo;
236 }
237 }
238
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))
241 return 1;
242
243 #ifdef HAVE_IPV6
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))
246 return 1;
247 #endif
248
249 #ifdef HAVE_DHCP
250 /* No DHCP where we're doing auth DNS. */
251 if (auth_dns)
252 {
253 tftp_ok = 0;
254 dhcp_ok = 0;
255 }
256 else
257 for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
258 if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
259 {
260 tftp_ok = 0;
261 dhcp_ok = 0;
262 }
263 #endif
264
265 /* add to list */
266 if ((iface = whine_malloc(sizeof(struct irec))))
267 {
268 iface->addr = *addr;
269 iface->netmask = netmask;
270 iface->tftp_ok = tftp_ok;
271 iface->dhcp_ok = dhcp_ok;
272 iface->dns_auth = auth_dns;
273 iface->mtu = mtu;
274 iface->dad = dad;
275 iface->done = 0;
276 if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
277 {
278 strcpy(iface->name, ifr.ifr_name);
279 iface->next = *irecp;
280 *irecp = iface;
281 return 1;
282 }
283 free(iface);
284 }
285
286 errno = ENOMEM;
287 return 0;
288 }
289
290 #ifdef HAVE_IPV6
291 static int iface_allowed_v6(struct in6_addr *local, int prefix,
292 int scope, int if_index, int dad,
293 int preferred, int valid, void *vparam)
294 {
295 union mysockaddr addr;
296 struct in_addr netmask; /* dummy */
297 netmask.s_addr = 0;
298
299 (void)prefix; /* warning */
300 (void)scope; /* warning */
301 (void)preferred;
302 (void)valid;
303
304 memset(&addr, 0, sizeof(addr));
305 #ifdef HAVE_SOCKADDR_SA_LEN
306 addr.in6.sin6_len = sizeof(addr.in6);
307 #endif
308 addr.in6.sin6_family = AF_INET6;
309 addr.in6.sin6_addr = *local;
310 addr.in6.sin6_port = htons(daemon->port);
311 addr.in6.sin6_scope_id = if_index;
312
313 return iface_allowed((struct irec **)vparam, if_index, &addr, netmask, dad);
314 }
315 #endif
316
317 static int iface_allowed_v4(struct in_addr local, int if_index,
318 struct in_addr netmask, struct in_addr broadcast, void *vparam)
319 {
320 union mysockaddr addr;
321
322 memset(&addr, 0, sizeof(addr));
323 #ifdef HAVE_SOCKADDR_SA_LEN
324 addr.in.sin_len = sizeof(addr.in);
325 #endif
326 addr.in.sin_family = AF_INET;
327 addr.in.sin_addr = broadcast; /* warning */
328 addr.in.sin_addr = local;
329 addr.in.sin_port = htons(daemon->port);
330
331 return iface_allowed((struct irec **)vparam, if_index, &addr, netmask, 0);
332 }
333
334 int enumerate_interfaces(void)
335 {
336 #ifdef HAVE_IPV6
337 if (!iface_enumerate(AF_INET6, &daemon->interfaces, iface_allowed_v6))
338 return 0;
339 #endif
340
341 return iface_enumerate(AF_INET, &daemon->interfaces, iface_allowed_v4);
342 }
343
344 /* set NONBLOCK bit on fd: See Stevens 16.6 */
345 int fix_fd(int fd)
346 {
347 int flags;
348
349 if ((flags = fcntl(fd, F_GETFL)) == -1 ||
350 fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
351 return 0;
352
353 return 1;
354 }
355
356 static int make_sock(union mysockaddr *addr, int type, int dienow)
357 {
358 int family = addr->sa.sa_family;
359 int fd, rc, opt = 1;
360
361 if ((fd = socket(family, type, 0)) == -1)
362 {
363 int port;
364 char *s;
365
366 /* No error if the kernel just doesn't support this IP flavour */
367 if (errno == EPROTONOSUPPORT ||
368 errno == EAFNOSUPPORT ||
369 errno == EINVAL)
370 return -1;
371
372 err:
373 port = prettyprint_addr(addr, daemon->addrbuff);
374 if (!option_bool(OPT_NOWILD) && !option_bool(OPT_CLEVERBIND))
375 sprintf(daemon->addrbuff, "port %d", port);
376 s = _("failed to create listening socket for %s: %s");
377
378 if (fd != -1)
379 close (fd);
380
381 if (dienow)
382 {
383 /* failure to bind addresses given by --listen-address at this point
384 is OK if we're doing bind-dynamic */
385 if (!option_bool(OPT_CLEVERBIND))
386 die(s, daemon->addrbuff, EC_BADNET);
387 }
388 else
389 my_syslog(LOG_WARNING, s, daemon->addrbuff, strerror(errno));
390
391 return -1;
392 }
393
394 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd))
395 goto err;
396
397 #ifdef HAVE_IPV6
398 if (family == AF_INET6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
399 goto err;
400 #endif
401
402 if ((rc = bind(fd, (struct sockaddr *)addr, sa_len(addr))) == -1)
403 goto err;
404
405 if (type == SOCK_STREAM)
406 {
407 if (listen(fd, 5) == -1)
408 goto err;
409 }
410 else if (!option_bool(OPT_NOWILD))
411 {
412 if (family == AF_INET)
413 {
414 #if defined(HAVE_LINUX_NETWORK)
415 if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1)
416 goto err;
417 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
418 if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
419 setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1)
420 goto err;
421 #endif
422 }
423 #ifdef HAVE_IPV6
424 else if (!set_ipv6pktinfo(fd))
425 goto err;
426 #endif
427 }
428
429 return fd;
430 }
431
432 #ifdef HAVE_IPV6
433 int set_ipv6pktinfo(int fd)
434 {
435 int opt = 1;
436
437 /* The API changed around Linux 2.6.14 but the old ABI is still supported:
438 handle all combinations of headers and kernel.
439 OpenWrt note that this fixes the problem addressed by your very broken patch. */
440 daemon->v6pktinfo = IPV6_PKTINFO;
441
442 #ifdef IPV6_RECVPKTINFO
443 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &opt, sizeof(opt)) != -1)
444 return 1;
445 # ifdef IPV6_2292PKTINFO
446 else if (errno == ENOPROTOOPT && setsockopt(fd, IPPROTO_IPV6, IPV6_2292PKTINFO, &opt, sizeof(opt)) != -1)
447 {
448 daemon->v6pktinfo = IPV6_2292PKTINFO;
449 return 1;
450 }
451 # endif
452 #else
453 if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &opt, sizeof(opt)) != -1)
454 return 1;
455 #endif
456
457 return 0;
458 }
459 #endif
460
461 static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
462 {
463 struct listener *l = NULL;
464 int fd = -1, tcpfd = -1, tftpfd = -1;
465
466 if (daemon->port != 0)
467 {
468 fd = make_sock(addr, SOCK_DGRAM, dienow);
469 tcpfd = make_sock(addr, SOCK_STREAM, dienow);
470 }
471
472 #ifdef HAVE_TFTP
473 if (do_tftp)
474 {
475 if (addr->sa.sa_family == AF_INET)
476 {
477 /* port must be restored to DNS port for TCP code */
478 short save = addr->in.sin_port;
479 addr->in.sin_port = htons(TFTP_PORT);
480 tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
481 addr->in.sin_port = save;
482 }
483 # ifdef HAVE_IPV6
484 else
485 {
486 short save = addr->in6.sin6_port;
487 addr->in6.sin6_port = htons(TFTP_PORT);
488 tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
489 addr->in6.sin6_port = save;
490 }
491 # endif
492 }
493 #endif
494
495 if (fd != -1 || tcpfd != -1 || tftpfd != -1)
496 {
497 l = safe_malloc(sizeof(struct listener));
498 l->next = NULL;
499 l->family = addr->sa.sa_family;
500 l->fd = fd;
501 l->tcpfd = tcpfd;
502 l->tftpfd = tftpfd;
503 }
504
505 return l;
506 }
507
508 void create_wildcard_listeners(void)
509 {
510 union mysockaddr addr;
511 struct listener *l, *l6;
512
513 memset(&addr, 0, sizeof(addr));
514 #ifdef HAVE_SOCKADDR_SA_LEN
515 addr.in.sin_len = sizeof(addr.in);
516 #endif
517 addr.in.sin_family = AF_INET;
518 addr.in.sin_addr.s_addr = INADDR_ANY;
519 addr.in.sin_port = htons(daemon->port);
520
521 l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
522
523 #ifdef HAVE_IPV6
524 memset(&addr, 0, sizeof(addr));
525 # ifdef HAVE_SOCKADDR_SA_LEN
526 addr.in6.sin6_len = sizeof(addr.in6);
527 # endif
528 addr.in6.sin6_family = AF_INET6;
529 addr.in6.sin6_addr = in6addr_any;
530 addr.in6.sin6_port = htons(daemon->port);
531
532 l6 = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
533 if (l)
534 l->next = l6;
535 else
536 l = l6;
537 #endif
538
539 daemon->listeners = l;
540 }
541
542 void create_bound_listeners(int dienow)
543 {
544 struct listener *new;
545 struct irec *iface;
546 struct iname *if_tmp;
547
548 for (iface = daemon->interfaces; iface; iface = iface->next)
549 if (!iface->done && !iface->dad &&
550 (new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
551 {
552 new->iface = iface;
553 new->next = daemon->listeners;
554 daemon->listeners = new;
555 iface->done = 1;
556 }
557
558 /* Check for --listen-address options that haven't been used because there's
559 no interface with a matching address. These may be valid: eg it's possible
560 to listen on 127.0.1.1 even if the loopback interface is 127.0.0.1
561
562 If the address isn't valid the bind() will fail and we'll die()
563 (except in bind-dynamic mode, when we'll complain but keep trying.)
564
565 The resulting listeners have the ->iface field NULL, and this has to be
566 handled by the DNS and TFTP code. It disables --localise-queries processing
567 (no netmask) and some MTU login the tftp code. */
568
569 for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
570 if (!if_tmp->used &&
571 (new = create_listeners(&if_tmp->addr, !!option_bool(OPT_TFTP), dienow)))
572 {
573 new->iface = NULL;
574 new->next = daemon->listeners;
575 daemon->listeners = new;
576 }
577 }
578
579 int is_dad_listeners(void)
580 {
581 struct irec *iface;
582
583 if (option_bool(OPT_NOWILD))
584 for (iface = daemon->interfaces; iface; iface = iface->next)
585 if (iface->dad && !iface->done)
586 return 1;
587
588 return 0;
589 }
590 /* return a UDP socket bound to a random port, have to cope with straying into
591 occupied port nos and reserved ones. */
592 int random_sock(int family)
593 {
594 int fd;
595
596 if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
597 {
598 union mysockaddr addr;
599 unsigned int ports_avail = 65536u - (unsigned short)daemon->min_port;
600 int tries = ports_avail < 30 ? 3 * ports_avail : 100;
601
602 memset(&addr, 0, sizeof(addr));
603 addr.sa.sa_family = family;
604
605 /* don't loop forever if all ports in use. */
606
607 if (fix_fd(fd))
608 while(tries--)
609 {
610 unsigned short port = rand16();
611
612 if (daemon->min_port != 0)
613 port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
614
615 if (family == AF_INET)
616 {
617 addr.in.sin_addr.s_addr = INADDR_ANY;
618 addr.in.sin_port = port;
619 #ifdef HAVE_SOCKADDR_SA_LEN
620 addr.in.sin_len = sizeof(struct sockaddr_in);
621 #endif
622 }
623 #ifdef HAVE_IPV6
624 else
625 {
626 addr.in6.sin6_addr = in6addr_any;
627 addr.in6.sin6_port = port;
628 #ifdef HAVE_SOCKADDR_SA_LEN
629 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
630 #endif
631 }
632 #endif
633
634 if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
635 return fd;
636
637 if (errno != EADDRINUSE && errno != EACCES)
638 break;
639 }
640
641 close(fd);
642 }
643
644 return -1;
645 }
646
647
648 int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
649 {
650 union mysockaddr addr_copy = *addr;
651
652 /* cannot set source _port_ for TCP connections. */
653 if (is_tcp)
654 {
655 if (addr_copy.sa.sa_family == AF_INET)
656 addr_copy.in.sin_port = 0;
657 #ifdef HAVE_IPV6
658 else
659 addr_copy.in6.sin6_port = 0;
660 #endif
661 }
662
663 if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
664 return 0;
665
666 #if defined(SO_BINDTODEVICE)
667 if (intname[0] != 0 &&
668 setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
669 return 0;
670 #endif
671
672 return 1;
673 }
674
675 static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
676 {
677 struct serverfd *sfd;
678 int errsave;
679
680 /* when using random ports, servers which would otherwise use
681 the INADDR_ANY/port0 socket have sfd set to NULL */
682 if (!daemon->osport && intname[0] == 0)
683 {
684 errno = 0;
685
686 if (addr->sa.sa_family == AF_INET &&
687 addr->in.sin_addr.s_addr == INADDR_ANY &&
688 addr->in.sin_port == htons(0))
689 return NULL;
690
691 #ifdef HAVE_IPV6
692 if (addr->sa.sa_family == AF_INET6 &&
693 memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
694 addr->in6.sin6_port == htons(0))
695 return NULL;
696 #endif
697 }
698
699 /* may have a suitable one already */
700 for (sfd = daemon->sfds; sfd; sfd = sfd->next )
701 if (sockaddr_isequal(&sfd->source_addr, addr) &&
702 strcmp(intname, sfd->interface) == 0)
703 return sfd;
704
705 /* need to make a new one. */
706 errno = ENOMEM; /* in case malloc fails. */
707 if (!(sfd = whine_malloc(sizeof(struct serverfd))))
708 return NULL;
709
710 if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
711 {
712 free(sfd);
713 return NULL;
714 }
715
716 if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd))
717 {
718 errsave = errno; /* save error from bind. */
719 close(sfd->fd);
720 free(sfd);
721 errno = errsave;
722 return NULL;
723 }
724
725 strcpy(sfd->interface, intname);
726 sfd->source_addr = *addr;
727 sfd->next = daemon->sfds;
728 daemon->sfds = sfd;
729 return sfd;
730 }
731
732 /* create upstream sockets during startup, before root is dropped which may be needed
733 this allows query_port to be a low port and interface binding */
734 void pre_allocate_sfds(void)
735 {
736 struct server *srv;
737
738 if (daemon->query_port != 0)
739 {
740 union mysockaddr addr;
741 memset(&addr, 0, sizeof(addr));
742 addr.in.sin_family = AF_INET;
743 addr.in.sin_addr.s_addr = INADDR_ANY;
744 addr.in.sin_port = htons(daemon->query_port);
745 #ifdef HAVE_SOCKADDR_SA_LEN
746 addr.in.sin_len = sizeof(struct sockaddr_in);
747 #endif
748 allocate_sfd(&addr, "");
749 #ifdef HAVE_IPV6
750 memset(&addr, 0, sizeof(addr));
751 addr.in6.sin6_family = AF_INET6;
752 addr.in6.sin6_addr = in6addr_any;
753 addr.in6.sin6_port = htons(daemon->query_port);
754 #ifdef HAVE_SOCKADDR_SA_LEN
755 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
756 #endif
757 allocate_sfd(&addr, "");
758 #endif
759 }
760
761 for (srv = daemon->servers; srv; srv = srv->next)
762 if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
763 !allocate_sfd(&srv->source_addr, srv->interface) &&
764 errno != 0 &&
765 option_bool(OPT_NOWILD))
766 {
767 prettyprint_addr(&srv->source_addr, daemon->namebuff);
768 if (srv->interface[0] != 0)
769 {
770 strcat(daemon->namebuff, " ");
771 strcat(daemon->namebuff, srv->interface);
772 }
773 die(_("failed to bind server socket for %s: %s"),
774 daemon->namebuff, EC_BADNET);
775 }
776 }
777
778
779 void check_servers(void)
780 {
781 struct irec *iface;
782 struct server *new, *tmp, *ret = NULL;
783 int port = 0;
784
785 /* interface may be new since startup */
786 if (!option_bool(OPT_NOWILD))
787 enumerate_interfaces();
788
789 for (new = daemon->servers; new; new = tmp)
790 {
791 tmp = new->next;
792
793 if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
794 {
795 port = prettyprint_addr(&new->addr, daemon->namebuff);
796
797 /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
798 if (new->addr.sa.sa_family == AF_INET &&
799 new->addr.in.sin_addr.s_addr == 0)
800 {
801 free(new);
802 continue;
803 }
804
805 for (iface = daemon->interfaces; iface; iface = iface->next)
806 if (sockaddr_isequal(&new->addr, &iface->addr))
807 break;
808 if (iface)
809 {
810 my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
811 free(new);
812 continue;
813 }
814
815 /* Do we need a socket set? */
816 if (!new->sfd &&
817 !(new->sfd = allocate_sfd(&new->source_addr, new->interface)) &&
818 errno != 0)
819 {
820 my_syslog(LOG_WARNING,
821 _("ignoring nameserver %s - cannot make/bind socket: %s"),
822 daemon->namebuff, strerror(errno));
823 free(new);
824 continue;
825 }
826 }
827
828 /* reverse order - gets it right. */
829 new->next = ret;
830 ret = new;
831
832 if (!(new->flags & SERV_NO_REBIND))
833 {
834 if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
835 {
836 char *s1, *s2;
837 if (!(new->flags & SERV_HAS_DOMAIN))
838 s1 = _("unqualified"), s2 = _("names");
839 else if (strlen(new->domain) == 0)
840 s1 = _("default"), s2 = "";
841 else
842 s1 = _("domain"), s2 = new->domain;
843
844 if (new->flags & SERV_NO_ADDR)
845 my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
846 else if (new->flags & SERV_USE_RESOLV)
847 my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
848 else if (!(new->flags & SERV_LITERAL_ADDRESS))
849 my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
850 }
851 else if (new->interface[0] != 0)
852 my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface);
853 else
854 my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
855 }
856 }
857
858 daemon->servers = ret;
859 }
860
861 /* Return zero if no servers found, in that case we keep polling.
862 This is a protection against an update-time/write race on resolv.conf */
863 int reload_servers(char *fname)
864 {
865 FILE *f;
866 char *line;
867 struct server *old_servers = NULL;
868 struct server *new_servers = NULL;
869 struct server *serv;
870 int gotone = 0;
871
872 /* buff happens to be MAXDNAME long... */
873 if (!(f = fopen(fname, "r")))
874 {
875 my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
876 return 0;
877 }
878
879 /* move old servers to free list - we can reuse the memory
880 and not risk malloc if there are the same or fewer new servers.
881 Servers which were specced on the command line go to the new list. */
882 for (serv = daemon->servers; serv;)
883 {
884 struct server *tmp = serv->next;
885 if (serv->flags & SERV_FROM_RESOLV)
886 {
887 serv->next = old_servers;
888 old_servers = serv;
889 /* forward table rules reference servers, so have to blow them away */
890 server_gone(serv);
891 }
892 else
893 {
894 serv->next = new_servers;
895 new_servers = serv;
896 }
897 serv = tmp;
898 }
899
900 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
901 {
902 union mysockaddr addr, source_addr;
903 char *token = strtok(line, " \t\n\r");
904
905 if (!token)
906 continue;
907 if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
908 continue;
909 if (!(token = strtok(NULL, " \t\n\r")))
910 continue;
911
912 memset(&addr, 0, sizeof(addr));
913 memset(&source_addr, 0, sizeof(source_addr));
914
915 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
916 {
917 #ifdef HAVE_SOCKADDR_SA_LEN
918 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
919 #endif
920 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
921 addr.in.sin_port = htons(NAMESERVER_PORT);
922 source_addr.in.sin_addr.s_addr = INADDR_ANY;
923 source_addr.in.sin_port = htons(daemon->query_port);
924 }
925 #ifdef HAVE_IPV6
926 else
927 {
928 int scope_index = 0;
929 char *scope_id = strchr(token, '%');
930
931 if (scope_id)
932 {
933 *(scope_id++) = 0;
934 scope_index = if_nametoindex(scope_id);
935 }
936
937 if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
938 {
939 #ifdef HAVE_SOCKADDR_SA_LEN
940 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
941 #endif
942 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
943 source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0;
944 addr.in6.sin6_port = htons(NAMESERVER_PORT);
945 addr.in6.sin6_scope_id = scope_index;
946 source_addr.in6.sin6_addr = in6addr_any;
947 source_addr.in6.sin6_port = htons(daemon->query_port);
948 source_addr.in6.sin6_scope_id = 0;
949 }
950 else
951 continue;
952 }
953 #else /* IPV6 */
954 else
955 continue;
956 #endif
957
958 if (old_servers)
959 {
960 serv = old_servers;
961 old_servers = old_servers->next;
962 }
963 else if (!(serv = whine_malloc(sizeof (struct server))))
964 continue;
965
966 /* this list is reverse ordered:
967 it gets reversed again in check_servers */
968 serv->next = new_servers;
969 new_servers = serv;
970 serv->addr = addr;
971 serv->source_addr = source_addr;
972 serv->domain = NULL;
973 serv->interface[0] = 0;
974 serv->sfd = NULL;
975 serv->flags = SERV_FROM_RESOLV;
976 serv->queries = serv->failed_queries = 0;
977 gotone = 1;
978 }
979
980 /* Free any memory not used. */
981 while (old_servers)
982 {
983 struct server *tmp = old_servers->next;
984 free(old_servers);
985 old_servers = tmp;
986 }
987
988 daemon->servers = new_servers;
989 fclose(f);
990
991 return gotone;
992 }
993
994
995 /* Use an IPv4 listener socket for ioctling */
996 struct in_addr get_ifaddr(char *intr)
997 {
998 struct listener *l;
999 struct ifreq ifr;
1000 struct sockaddr_in ret;
1001
1002 ret.sin_addr.s_addr = -1;
1003
1004 for (l = daemon->listeners;
1005 l && (l->family != AF_INET || l->fd == -1);
1006 l = l->next);
1007
1008 strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
1009 ifr.ifr_addr.sa_family = AF_INET;
1010
1011 if (l && ioctl(l->fd, SIOCGIFADDR, &ifr) != -1)
1012 memcpy(&ret, &ifr.ifr_addr, sizeof(ret));
1013
1014 return ret.sin_addr;
1015 }
1016
1017
1018