blob: 68113fb42f08d6a539510de409c4765d12a7e5a2 [file] [log] [blame]
San Mehatffd68722010-01-20 09:56:15 -08001/* 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
21int 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
39int 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
49int 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
118static 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
207static 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
228static 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
245int 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 */
255int 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)
267static 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
319struct 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
389struct listener *create_bound_listeners(void)
390{
391 struct listener *listeners = NULL;
392 struct irec *iface;
393 int rc, opt = 1;
394#ifdef HAVE_IPV6
395 static int dad_count = 0;
396#endif
397
398 for (iface = daemon->interfaces; iface; iface = iface->next)
399 {
400 struct listener *new = safe_malloc(sizeof(struct listener));
401 new->family = iface->addr.sa.sa_family;
402 new->iface = iface;
403 new->next = listeners;
404 new->tftpfd = -1;
405 new->tcpfd = -1;
406 new->fd = -1;
407 listeners = new;
408
409 if (daemon->port != 0)
410 {
411 if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
412 (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
413 setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
414 setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
415 !fix_fd(new->tcpfd) ||
416 !fix_fd(new->fd))
417 die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
418
419#ifdef HAVE_IPV6
420 if (iface->addr.sa.sa_family == AF_INET6)
421 {
422 if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
423 setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
424 die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
425 }
426#endif
427
428 while(1)
429 {
430 if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
431 break;
432
433#ifdef HAVE_IPV6
434 /* An interface may have an IPv6 address which is still undergoing DAD.
435 If so, the bind will fail until the DAD completes, so we try over 20 seconds
436 before failing. */
437 if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) &&
438 dad_count++ < DAD_WAIT)
439 {
440 sleep(1);
441 continue;
442 }
443#endif
444 break;
445 }
446
447 if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
448 {
449 prettyprint_addr(&iface->addr, daemon->namebuff);
450 die(_("failed to bind listening socket for %s: %s"),
451 daemon->namebuff, EC_BADNET);
452 }
453
454 if (listen(new->tcpfd, 5) == -1)
455 die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
456 }
457
458#ifdef HAVE_TFTP
459 if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
460 {
461 short save = iface->addr.in.sin_port;
462 iface->addr.in.sin_port = htons(TFTP_PORT);
463 if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
464 setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
465 !fix_fd(new->tftpfd) ||
466 bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
467 die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
468 iface->addr.in.sin_port = save;
469 }
470#endif
471
472 }
473
474 return listeners;
475}
476
477
478/* return a UDP socket bound to a random port, have to cope with straying into
479 occupied port nos and reserved ones. */
480int random_sock(int family)
481{
482 int fd;
483
484 if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
485 {
486 union mysockaddr addr;
487 unsigned int ports_avail = 65536u - (unsigned short)daemon->min_port;
488 int tries = ports_avail < 30 ? 3 * ports_avail : 100;
489
490 memset(&addr, 0, sizeof(addr));
491 addr.sa.sa_family = family;
492
493 /* don't loop forever if all ports in use. */
494
495 if (fix_fd(fd))
496 while(tries--)
497 {
498 unsigned short port = rand16();
499
500 if (daemon->min_port != 0)
501 port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
502
503 if (family == AF_INET)
504 {
505 addr.in.sin_addr.s_addr = INADDR_ANY;
506 addr.in.sin_port = port;
507#ifdef HAVE_SOCKADDR_SA_LEN
508 addr.in.sin_len = sizeof(struct sockaddr_in);
509#endif
510 }
511#ifdef HAVE_IPV6
512 else
513 {
514 addr.in6.sin6_addr = in6addr_any;
515 addr.in6.sin6_port = port;
516#ifdef HAVE_SOCKADDR_SA_LEN
517 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
518#endif
519 }
520#endif
521
522 if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
523 return fd;
524
525 if (errno != EADDRINUSE && errno != EACCES)
526 break;
527 }
528
529 close(fd);
530 }
531
532 return -1;
533}
534
535
536int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
537{
538 union mysockaddr addr_copy = *addr;
539
540 /* cannot set source _port_ for TCP connections. */
541 if (is_tcp)
542 {
543 if (addr_copy.sa.sa_family == AF_INET)
544 addr_copy.in.sin_port = 0;
545#ifdef HAVE_IPV6
546 else
547 addr_copy.in6.sin6_port = 0;
548#endif
549 }
550
551 if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
552 return 0;
553
554#if defined(SO_BINDTODEVICE)
555 if (intname[0] != 0 &&
556 setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, strlen(intname)) == -1)
557 return 0;
558#endif
559
560 return 1;
561}
562
563static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
564{
565 struct serverfd *sfd;
566 int errsave;
567
568 /* when using random ports, servers which would otherwise use
569 the INADDR_ANY/port0 socket have sfd set to NULL */
570 if (!daemon->osport && intname[0] == 0)
571 {
572 errno = 0;
573
574 if (addr->sa.sa_family == AF_INET &&
575 addr->in.sin_addr.s_addr == INADDR_ANY &&
576 addr->in.sin_port == htons(0))
577 return NULL;
578
579#ifdef HAVE_IPV6
580 if (addr->sa.sa_family == AF_INET6 &&
581 memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
582 addr->in6.sin6_port == htons(0))
583 return NULL;
584#endif
585 }
586
587 /* may have a suitable one already */
588 for (sfd = daemon->sfds; sfd; sfd = sfd->next )
589 if (sockaddr_isequal(&sfd->source_addr, addr) &&
590 strcmp(intname, sfd->interface) == 0)
591 return sfd;
592
593 /* need to make a new one. */
594 errno = ENOMEM; /* in case malloc fails. */
595 if (!(sfd = whine_malloc(sizeof(struct serverfd))))
596 return NULL;
597
598 if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
599 {
600 free(sfd);
601 return NULL;
602 }
603
604 if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd))
605 {
606 errsave = errno; /* save error from bind. */
607 close(sfd->fd);
608 free(sfd);
609 errno = errsave;
610 return NULL;
611 }
612
613 strcpy(sfd->interface, intname);
614 sfd->source_addr = *addr;
615 sfd->next = daemon->sfds;
616 daemon->sfds = sfd;
617 return sfd;
618}
619
620/* create upstream sockets during startup, before root is dropped which may be needed
621 this allows query_port to be a low port and interface binding */
622void pre_allocate_sfds(void)
623{
624 struct server *srv;
625
626 if (daemon->query_port != 0)
627 {
628 union mysockaddr addr;
629 memset(&addr, 0, sizeof(addr));
630 addr.in.sin_family = AF_INET;
631 addr.in.sin_addr.s_addr = INADDR_ANY;
632 addr.in.sin_port = htons(daemon->query_port);
633#ifdef HAVE_SOCKADDR_SA_LEN
634 addr.in.sin_len = sizeof(struct sockaddr_in);
635#endif
636 allocate_sfd(&addr, "");
637#ifdef HAVE_IPV6
638 memset(&addr, 0, sizeof(addr));
639 addr.in6.sin6_family = AF_INET6;
640 addr.in6.sin6_addr = in6addr_any;
641 addr.in6.sin6_port = htons(daemon->query_port);
642#ifdef HAVE_SOCKADDR_SA_LEN
643 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
644#endif
645 allocate_sfd(&addr, "");
646#endif
647 }
648
649 for (srv = daemon->servers; srv; srv = srv->next)
650 if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
651 !allocate_sfd(&srv->source_addr, srv->interface) &&
652 errno != 0 &&
653 (daemon->options & OPT_NOWILD))
654 {
655 prettyprint_addr(&srv->addr, daemon->namebuff);
656 if (srv->interface[0] != 0)
657 {
658 strcat(daemon->namebuff, " ");
659 strcat(daemon->namebuff, srv->interface);
660 }
661 die(_("failed to bind server socket for %s: %s"),
662 daemon->namebuff, EC_BADNET);
663 }
664}
665
666
667void check_servers(void)
668{
669 struct irec *iface;
670 struct server *new, *tmp, *ret = NULL;
671 int port = 0;
672
673 for (new = daemon->servers; new; new = tmp)
674 {
675 tmp = new->next;
676
677 if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)))
678 {
679 port = prettyprint_addr(&new->addr, daemon->namebuff);
680
681 /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
682 if (new->addr.sa.sa_family == AF_INET &&
683 new->addr.in.sin_addr.s_addr == 0)
684 {
685 free(new);
686 continue;
687 }
688
689 for (iface = daemon->interfaces; iface; iface = iface->next)
690 if (sockaddr_isequal(&new->addr, &iface->addr))
691 break;
692 if (iface)
693 {
694 my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
695 free(new);
696 continue;
697 }
698
699 /* Do we need a socket set? */
700 if (!new->sfd &&
701 !(new->sfd = allocate_sfd(&new->source_addr, new->interface)) &&
702 errno != 0)
703 {
704 my_syslog(LOG_WARNING,
705 _("ignoring nameserver %s - cannot make/bind socket: %s"),
706 daemon->namebuff, strerror(errno));
707 free(new);
708 continue;
709 }
710 }
711
712 /* reverse order - gets it right. */
713 new->next = ret;
714 ret = new;
715
716 if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS))
717 {
718 char *s1, *s2;
719 if (!(new->flags & SERV_HAS_DOMAIN))
720 s1 = _("unqualified"), s2 = _("names");
721 else if (strlen(new->domain) == 0)
722 s1 = _("default"), s2 = "";
723 else
724 s1 = _("domain"), s2 = new->domain;
725
726 if (new->flags & SERV_NO_ADDR)
727 my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
728 else if (!(new->flags & SERV_LITERAL_ADDRESS))
729 my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
730 }
731 else if (new->interface[0] != 0)
732 my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface);
733 else
734 my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
735 }
736
737 daemon->servers = ret;
738}
739
740/* Return zero if no servers found, in that case we keep polling.
741 This is a protection against an update-time/write race on resolv.conf */
742int reload_servers(char *fname)
743{
744 FILE *f;
745 char *line;
746 struct server *old_servers = NULL;
747 struct server *new_servers = NULL;
748 struct server *serv;
749 int gotone = 0;
750
751 /* buff happens to be MAXDNAME long... */
752 if (!(f = fopen(fname, "r")))
753 {
754 my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
755 return 0;
756 }
757
758 /* move old servers to free list - we can reuse the memory
759 and not risk malloc if there are the same or fewer new servers.
760 Servers which were specced on the command line go to the new list. */
761 for (serv = daemon->servers; serv;)
762 {
763 struct server *tmp = serv->next;
764 if (serv->flags & SERV_FROM_RESOLV)
765 {
766 serv->next = old_servers;
767 old_servers = serv;
768 /* forward table rules reference servers, so have to blow them away */
769 server_gone(serv);
770 }
771 else
772 {
773 serv->next = new_servers;
774 new_servers = serv;
775 }
776 serv = tmp;
777 }
778
779 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
780 {
781 union mysockaddr addr, source_addr;
782 char *token = strtok(line, " \t\n\r");
783
784 if (!token)
785 continue;
786 if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
787 continue;
788 if (!(token = strtok(NULL, " \t\n\r")))
789 continue;
790
791 memset(&addr, 0, sizeof(addr));
792 memset(&source_addr, 0, sizeof(source_addr));
793
794 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
795 {
796#ifdef HAVE_SOCKADDR_SA_LEN
797 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
798#endif
799 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
800 addr.in.sin_port = htons(NAMESERVER_PORT);
801 source_addr.in.sin_addr.s_addr = INADDR_ANY;
802 source_addr.in.sin_port = htons(daemon->query_port);
803 }
804#ifdef HAVE_IPV6
805 else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
806 {
807#ifdef HAVE_SOCKADDR_SA_LEN
808 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
809#endif
810 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
811 addr.in6.sin6_port = htons(NAMESERVER_PORT);
812 source_addr.in6.sin6_addr = in6addr_any;
813 source_addr.in6.sin6_port = htons(daemon->query_port);
814 }
815#endif /* IPV6 */
816 else
817 continue;
818
819 if (old_servers)
820 {
821 serv = old_servers;
822 old_servers = old_servers->next;
823 }
824 else if (!(serv = whine_malloc(sizeof (struct server))))
825 continue;
826
827 /* this list is reverse ordered:
828 it gets reversed again in check_servers */
829 serv->next = new_servers;
830 new_servers = serv;
831 serv->addr = addr;
832 serv->source_addr = source_addr;
833 serv->domain = NULL;
834 serv->interface[0] = 0;
835 serv->sfd = NULL;
836 serv->flags = SERV_FROM_RESOLV;
837 serv->queries = serv->failed_queries = 0;
838 gotone = 1;
839 }
840
841 /* Free any memory not used. */
842 while (old_servers)
843 {
844 struct server *tmp = old_servers->next;
845 free(old_servers);
846 old_servers = tmp;
847 }
848
849 daemon->servers = new_servers;
850 fclose(f);
851
852 return gotone;
853}
854
855
856/* Use an IPv4 listener socket for ioctling */
857struct in_addr get_ifaddr(char *intr)
858{
859 struct listener *l;
860 struct ifreq ifr;
861
862 for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
863
864 strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
865 ifr.ifr_addr.sa_family = AF_INET;
866
867 if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
868 ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
869
870 return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
871}
872
873
874