blob: b0ffc6b82341c30507df3765c19df00f0c036c1c [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
San Mehat33b34442010-01-20 10:54:48 -0800740#ifdef __ANDROID__
741/*
742 * Takes a string in the format "1.2.3.4:1.2.3.4:..." - up to 1024 bytes in length
743 */
744int set_servers(const char *servers)
745{
746 char s[1024];
747 struct server *old_servers = NULL;
748 struct server *new_servers = NULL;
749 struct server *serv;
750
751 strncpy(s, servers, sizeof(s));
752
753 /* move old servers to free list - we can reuse the memory
754 and not risk malloc if there are the same or fewer new servers.
755 Servers which were specced on the command line go to the new list. */
756 for (serv = daemon->servers; serv;)
757 {
758 struct server *tmp = serv->next;
759 if (serv->flags & SERV_FROM_RESOLV)
760 {
761 serv->next = old_servers;
762 old_servers = serv;
763 /* forward table rules reference servers, so have to blow them away */
764 server_gone(serv);
765 }
766 else
767 {
768 serv->next = new_servers;
769 new_servers = serv;
770 }
771 serv = tmp;
772 }
773
774 char *next = s;
775 char *saddr;
776
777 while ((saddr = strsep(&next, ":"))) {
778 union mysockaddr addr, source_addr;
779 memset(&addr, 0, sizeof(addr));
780 memset(&source_addr, 0, sizeof(source_addr));
781
782 if ((addr.in.sin_addr.s_addr = inet_addr(saddr)) != (in_addr_t) -1)
783 {
784#ifdef HAVE_SOCKADDR_SA_LEN
785 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
786#endif
787 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
788 addr.in.sin_port = htons(NAMESERVER_PORT);
789 source_addr.in.sin_addr.s_addr = INADDR_ANY;
790 source_addr.in.sin_port = htons(daemon->query_port);
791 }
792#ifdef HAVE_IPV6
793 else if (inet_pton(AF_INET6, saddr, &addr.in6.sin6_addr) > 0)
794 {
795#ifdef HAVE_SOCKADDR_SA_LEN
796 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
797#endif
798 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
799 addr.in6.sin6_port = htons(NAMESERVER_PORT);
800 source_addr.in6.sin6_addr = in6addr_any;
801 source_addr.in6.sin6_port = htons(daemon->query_port);
802 }
803#endif /* IPV6 */
804 else
805 continue;
806
807 if (old_servers)
808 {
809 serv = old_servers;
810 old_servers = old_servers->next;
811 }
812 else if (!(serv = whine_malloc(sizeof (struct server))))
813 continue;
814
815 /* this list is reverse ordered:
816 it gets reversed again in check_servers */
817 serv->next = new_servers;
818 new_servers = serv;
819 serv->addr = addr;
820 serv->source_addr = source_addr;
821 serv->domain = NULL;
822 serv->interface[0] = 0;
823 serv->sfd = NULL;
824 serv->flags = SERV_FROM_RESOLV;
825 serv->queries = serv->failed_queries = 0;
826 }
827
828 /* Free any memory not used. */
829 while (old_servers)
830 {
831 struct server *tmp = old_servers->next;
832 free(old_servers);
833 old_servers = tmp;
834 }
835
836 daemon->servers = new_servers;
837 return 0;
838}
839#endif
840
San Mehatffd68722010-01-20 09:56:15 -0800841/* Return zero if no servers found, in that case we keep polling.
842 This is a protection against an update-time/write race on resolv.conf */
843int reload_servers(char *fname)
844{
845 FILE *f;
846 char *line;
847 struct server *old_servers = NULL;
848 struct server *new_servers = NULL;
849 struct server *serv;
850 int gotone = 0;
851
852 /* buff happens to be MAXDNAME long... */
853 if (!(f = fopen(fname, "r")))
854 {
855 my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
856 return 0;
857 }
858
859 /* move old servers to free list - we can reuse the memory
860 and not risk malloc if there are the same or fewer new servers.
861 Servers which were specced on the command line go to the new list. */
862 for (serv = daemon->servers; serv;)
863 {
864 struct server *tmp = serv->next;
865 if (serv->flags & SERV_FROM_RESOLV)
866 {
867 serv->next = old_servers;
868 old_servers = serv;
869 /* forward table rules reference servers, so have to blow them away */
870 server_gone(serv);
871 }
872 else
873 {
874 serv->next = new_servers;
875 new_servers = serv;
876 }
877 serv = tmp;
878 }
879
880 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
881 {
882 union mysockaddr addr, source_addr;
883 char *token = strtok(line, " \t\n\r");
884
885 if (!token)
886 continue;
887 if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
888 continue;
889 if (!(token = strtok(NULL, " \t\n\r")))
890 continue;
891
892 memset(&addr, 0, sizeof(addr));
893 memset(&source_addr, 0, sizeof(source_addr));
894
895 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
896 {
897#ifdef HAVE_SOCKADDR_SA_LEN
898 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
899#endif
900 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
901 addr.in.sin_port = htons(NAMESERVER_PORT);
902 source_addr.in.sin_addr.s_addr = INADDR_ANY;
903 source_addr.in.sin_port = htons(daemon->query_port);
904 }
905#ifdef HAVE_IPV6
906 else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
907 {
908#ifdef HAVE_SOCKADDR_SA_LEN
909 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
910#endif
911 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
912 addr.in6.sin6_port = htons(NAMESERVER_PORT);
913 source_addr.in6.sin6_addr = in6addr_any;
914 source_addr.in6.sin6_port = htons(daemon->query_port);
915 }
916#endif /* IPV6 */
917 else
918 continue;
919
920 if (old_servers)
921 {
922 serv = old_servers;
923 old_servers = old_servers->next;
924 }
925 else if (!(serv = whine_malloc(sizeof (struct server))))
926 continue;
927
928 /* this list is reverse ordered:
929 it gets reversed again in check_servers */
930 serv->next = new_servers;
931 new_servers = serv;
932 serv->addr = addr;
933 serv->source_addr = source_addr;
934 serv->domain = NULL;
935 serv->interface[0] = 0;
936 serv->sfd = NULL;
937 serv->flags = SERV_FROM_RESOLV;
938 serv->queries = serv->failed_queries = 0;
939 gotone = 1;
940 }
941
942 /* Free any memory not used. */
943 while (old_servers)
944 {
945 struct server *tmp = old_servers->next;
946 free(old_servers);
947 old_servers = tmp;
948 }
949
950 daemon->servers = new_servers;
951 fclose(f);
952
953 return gotone;
954}
955
956
957/* Use an IPv4 listener socket for ioctling */
958struct in_addr get_ifaddr(char *intr)
959{
960 struct listener *l;
961 struct ifreq ifr;
962
963 for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
964
965 strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
966 ifr.ifr_addr.sa_family = AF_INET;
967
968 if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
969 ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
970
971 return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
972}
973
974
975