blob: 6a8a433e5eab67cf94e525f90e7a3db7c5ad8ca0 [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 }
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -080087
San Mehatffd68722010-01-20 09:56:15 -080088 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
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800389#ifdef __ANDROID__
390/**
391 * for a single given irec (interface name and address) create
392 * a set of sockets listening. This is a copy of the code inside the loop
393 * of create_bound_listeners below and is added here to allow us
394 * to create just a single new listener dynamically when our interface
395 * list is changed.
396 *
397 * iface - input of the new interface details to listen on
398 * listeners - output. Creates a new struct listener and inserts at head of the list
399 *
400 * die's on errors, so don't pass bad data.
401 */
402void create_bound_listener(struct listener **listeners, struct irec *iface)
San Mehatffd68722010-01-20 09:56:15 -0800403{
San Mehatffd68722010-01-20 09:56:15 -0800404 int rc, opt = 1;
405#ifdef HAVE_IPV6
406 static int dad_count = 0;
407#endif
408
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800409 struct listener *new = safe_malloc(sizeof(struct listener));
410 new->family = iface->addr.sa.sa_family;
411 new->iface = iface;
412 new->next = *listeners;
413 new->tftpfd = -1;
414 new->tcpfd = -1;
415 new->fd = -1;
416 *listeners = new;
417
418 if (daemon->port != 0)
419 {
420 if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
421 (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
422 setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
423 setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
424 !fix_fd(new->tcpfd) ||
425 !fix_fd(new->fd))
426 die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
427
428#ifdef HAVE_IPV6
429 if (iface->addr.sa.sa_family == AF_INET6)
430 {
431 if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
432 setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
433 die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);\
434 }
435#endif
436
437 while(1)
438 {
439 if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
440 break;
441
442#ifdef HAVE_IPV6
443 /* An interface may have an IPv6 address which is still undergoing DAD.
444 If so, the bind will fail until the DAD completes, so we try over 20 seconds
445 before failing. */
446 if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) &&
447 dad_count++ < DAD_WAIT)
448 {
449 sleep(1);
450 continue;
451 }
452#endif
453 break;
454 }
455
456 if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
457 {
458 prettyprint_addr(&iface->addr, daemon->namebuff);
459 die(_("failed to bind listening socket for %s: %s"), daemon->namebuff, EC_BADNET);
460 }
461
462 if (listen(new->tcpfd, 5) == -1)
463 die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
464 }
465
466#ifdef HAVE_TFTP
467 if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
468 {
469 short save = iface->addr.in.sin_port;
470 iface->addr.in.sin_port = htons(TFTP_PORT);
471 if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
472 setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
473 !fix_fd(new->tftpfd) ||
474 bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
475 die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
476 iface->addr.in.sin_port = save;
477 }
478#endif
479}
480
481/**
Erik Klinee226bad2014-09-30 16:06:37 +0900482 * If a listener has a struct irec pointer whose address matches the newly
483 * malloc()d struct irec's address, update its pointer to refer to this new
484 * struct irec instance.
485 *
486 * Otherwise, any listeners that are preserved across interface list changes
487 * will point at interface structures that are free()d at the end of
488 * set_interfaces(), and can get overwritten by subsequent memory allocations.
489 *
490 * See b/17475756 for further discussion.
491 */
492void fixup_possible_existing_listener(struct irec *new_iface) {
493 /* find the listener, if present */
494 struct listener *l;
495 for (l = daemon->listeners; l; l = l->next) {
496 struct irec *listener_iface = l->iface;
497 if (listener_iface) {
498 if (sockaddr_isequal(&listener_iface->addr, &new_iface->addr)) {
499 l->iface = new_iface;
500 return;
501 }
502 }
503 }
504}
505
506/**
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800507 * Close the sockets listening on the given interface
508 *
509 * This new function is needed as we're dynamically changing the interfaces
510 * we listen on. Before they'd be opened once in create_bound_listeners and stay
511 * until we exited. Now, if an interface moves off the to-listen list we need to
512 * close out the listeners and keep trucking.
513 *
514 * interface - input of the interface details to listen on
515 */
516int close_bound_listener(struct irec *interface)
517{
518 /* find the listener */
519 struct listener **l, *listener;
520 for (l = &(daemon->listeners); *l; l = &((*l)->next)) {
521 struct irec *listener_iface = (*l)->iface;
522 if (listener_iface && interface) {
523 if (sockaddr_isequal(&listener_iface->addr, &interface->addr)) {
524 break;
525 }
526 } else {
527 if (interface == NULL && listener_iface == NULL) {
528 break;
529 }
530 }
531 }
532 listener = *l;
533 if (listener == NULL) return 0;
534
535 if (listener->tftpfd != -1)
536 {
537 close(listener->tftpfd);
538 listener->tftpfd = -1;
539 }
540 if (listener->tcpfd != -1)
541 {
542 close(listener->tcpfd);
543 listener->tcpfd = -1;
544 }
545 if (listener->fd != -1)
546 {
547 close(listener->fd);
548 listener->fd = -1;
549 }
550 *l = listener->next;
551 free(listener);
552 return -1;
553}
554#endif /* __ANDROID__ */
555
556struct listener *create_bound_listeners(void)
557{
558 struct listener *listeners = NULL;
559 struct irec *iface;
560#ifndef __ANDROID__
561 int rc, opt = 1;
562#ifdef HAVE_IPV6
563 static int dad_count = 0;
564#endif
565#endif
566
San Mehatffd68722010-01-20 09:56:15 -0800567 for (iface = daemon->interfaces; iface; iface = iface->next)
568 {
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800569#ifdef __ANDROID__
570 create_bound_listener(&listeners, iface);
571#else
San Mehatffd68722010-01-20 09:56:15 -0800572 struct listener *new = safe_malloc(sizeof(struct listener));
573 new->family = iface->addr.sa.sa_family;
574 new->iface = iface;
575 new->next = listeners;
576 new->tftpfd = -1;
577 new->tcpfd = -1;
578 new->fd = -1;
579 listeners = new;
580
581 if (daemon->port != 0)
582 {
583 if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
584 (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
585 setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
586 setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
587 !fix_fd(new->tcpfd) ||
588 !fix_fd(new->fd))
589 die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
590
591#ifdef HAVE_IPV6
592 if (iface->addr.sa.sa_family == AF_INET6)
593 {
594 if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
595 setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
596 die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
597 }
598#endif
599
600 while(1)
601 {
602 if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
603 break;
604
605#ifdef HAVE_IPV6
606 /* An interface may have an IPv6 address which is still undergoing DAD.
607 If so, the bind will fail until the DAD completes, so we try over 20 seconds
608 before failing. */
609 if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) &&
610 dad_count++ < DAD_WAIT)
611 {
612 sleep(1);
613 continue;
614 }
615#endif
616 break;
617 }
618
619 if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
620 {
621 prettyprint_addr(&iface->addr, daemon->namebuff);
622 die(_("failed to bind listening socket for %s: %s"),
623 daemon->namebuff, EC_BADNET);
624 }
625
626 if (listen(new->tcpfd, 5) == -1)
627 die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
628 }
629
630#ifdef HAVE_TFTP
631 if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
632 {
633 short save = iface->addr.in.sin_port;
634 iface->addr.in.sin_port = htons(TFTP_PORT);
635 if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
636 setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
637 !fix_fd(new->tftpfd) ||
638 bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
639 die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
640 iface->addr.in.sin_port = save;
641 }
642#endif
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800643#endif /* !__ANDROID */
San Mehatffd68722010-01-20 09:56:15 -0800644 }
645
646 return listeners;
647}
648
649
650/* return a UDP socket bound to a random port, have to cope with straying into
651 occupied port nos and reserved ones. */
652int random_sock(int family)
653{
654 int fd;
655
656 if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
657 {
658 union mysockaddr addr;
659 unsigned int ports_avail = 65536u - (unsigned short)daemon->min_port;
660 int tries = ports_avail < 30 ? 3 * ports_avail : 100;
661
662 memset(&addr, 0, sizeof(addr));
663 addr.sa.sa_family = family;
664
665 /* don't loop forever if all ports in use. */
666
667 if (fix_fd(fd))
668 while(tries--)
669 {
670 unsigned short port = rand16();
671
672 if (daemon->min_port != 0)
673 port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
674
675 if (family == AF_INET)
676 {
677 addr.in.sin_addr.s_addr = INADDR_ANY;
678 addr.in.sin_port = port;
679#ifdef HAVE_SOCKADDR_SA_LEN
680 addr.in.sin_len = sizeof(struct sockaddr_in);
681#endif
682 }
683#ifdef HAVE_IPV6
684 else
685 {
686 addr.in6.sin6_addr = in6addr_any;
687 addr.in6.sin6_port = port;
688#ifdef HAVE_SOCKADDR_SA_LEN
689 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
690#endif
691 }
692#endif
693
694 if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
695 return fd;
696
697 if (errno != EADDRINUSE && errno != EACCES)
698 break;
699 }
700
701 close(fd);
702 }
703
704 return -1;
705}
706
707
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700708int local_bind(int fd, union mysockaddr *addr, char *intname, uint32_t mark, int is_tcp)
San Mehatffd68722010-01-20 09:56:15 -0800709{
710 union mysockaddr addr_copy = *addr;
711
712 /* cannot set source _port_ for TCP connections. */
713 if (is_tcp)
714 {
715 if (addr_copy.sa.sa_family == AF_INET)
716 addr_copy.in.sin_port = 0;
717#ifdef HAVE_IPV6
718 else
719 addr_copy.in6.sin6_port = 0;
720#endif
721 }
722
723 if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
724 return 0;
725
726#if defined(SO_BINDTODEVICE)
727 if (intname[0] != 0 &&
728 setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, strlen(intname)) == -1)
729 return 0;
730#endif
731
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700732 if (mark != 0 && setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1)
733 return 0;
734
San Mehatffd68722010-01-20 09:56:15 -0800735 return 1;
736}
737
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700738static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname, uint32_t mark)
San Mehatffd68722010-01-20 09:56:15 -0800739{
740 struct serverfd *sfd;
741 int errsave;
742
743 /* when using random ports, servers which would otherwise use
744 the INADDR_ANY/port0 socket have sfd set to NULL */
745 if (!daemon->osport && intname[0] == 0)
746 {
747 errno = 0;
748
749 if (addr->sa.sa_family == AF_INET &&
750 addr->in.sin_addr.s_addr == INADDR_ANY &&
751 addr->in.sin_port == htons(0))
752 return NULL;
753
754#ifdef HAVE_IPV6
755 if (addr->sa.sa_family == AF_INET6 &&
756 memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
757 addr->in6.sin6_port == htons(0))
758 return NULL;
759#endif
760 }
761
762 /* may have a suitable one already */
763 for (sfd = daemon->sfds; sfd; sfd = sfd->next )
764 if (sockaddr_isequal(&sfd->source_addr, addr) &&
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700765 mark == sfd->mark &&
San Mehatffd68722010-01-20 09:56:15 -0800766 strcmp(intname, sfd->interface) == 0)
767 return sfd;
768
769 /* need to make a new one. */
770 errno = ENOMEM; /* in case malloc fails. */
771 if (!(sfd = whine_malloc(sizeof(struct serverfd))))
772 return NULL;
773
774 if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
775 {
776 free(sfd);
777 return NULL;
778 }
779
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700780 if (!local_bind(sfd->fd, addr, intname, mark, 0) || !fix_fd(sfd->fd))
San Mehatffd68722010-01-20 09:56:15 -0800781 {
782 errsave = errno; /* save error from bind. */
783 close(sfd->fd);
784 free(sfd);
785 errno = errsave;
786 return NULL;
787 }
788
789 strcpy(sfd->interface, intname);
790 sfd->source_addr = *addr;
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700791 sfd->mark = mark;
San Mehatffd68722010-01-20 09:56:15 -0800792 sfd->next = daemon->sfds;
793 daemon->sfds = sfd;
794 return sfd;
795}
796
797/* create upstream sockets during startup, before root is dropped which may be needed
798 this allows query_port to be a low port and interface binding */
799void pre_allocate_sfds(void)
800{
801 struct server *srv;
802
803 if (daemon->query_port != 0)
804 {
805 union mysockaddr addr;
806 memset(&addr, 0, sizeof(addr));
807 addr.in.sin_family = AF_INET;
808 addr.in.sin_addr.s_addr = INADDR_ANY;
809 addr.in.sin_port = htons(daemon->query_port);
810#ifdef HAVE_SOCKADDR_SA_LEN
811 addr.in.sin_len = sizeof(struct sockaddr_in);
812#endif
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700813 allocate_sfd(&addr, "", 0);
San Mehatffd68722010-01-20 09:56:15 -0800814#ifdef HAVE_IPV6
815 memset(&addr, 0, sizeof(addr));
816 addr.in6.sin6_family = AF_INET6;
817 addr.in6.sin6_addr = in6addr_any;
818 addr.in6.sin6_port = htons(daemon->query_port);
819#ifdef HAVE_SOCKADDR_SA_LEN
820 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
821#endif
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700822 allocate_sfd(&addr, "", 0);
San Mehatffd68722010-01-20 09:56:15 -0800823#endif
824 }
825
826 for (srv = daemon->servers; srv; srv = srv->next)
827 if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700828 !allocate_sfd(&srv->source_addr, srv->interface, srv->mark) &&
San Mehatffd68722010-01-20 09:56:15 -0800829 errno != 0 &&
830 (daemon->options & OPT_NOWILD))
831 {
832 prettyprint_addr(&srv->addr, daemon->namebuff);
833 if (srv->interface[0] != 0)
834 {
835 strcat(daemon->namebuff, " ");
836 strcat(daemon->namebuff, srv->interface);
837 }
838 die(_("failed to bind server socket for %s: %s"),
839 daemon->namebuff, EC_BADNET);
840 }
841}
842
843
844void check_servers(void)
845{
846 struct irec *iface;
847 struct server *new, *tmp, *ret = NULL;
848 int port = 0;
849
850 for (new = daemon->servers; new; new = tmp)
851 {
852 tmp = new->next;
853
854 if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)))
855 {
856 port = prettyprint_addr(&new->addr, daemon->namebuff);
857
858 /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
859 if (new->addr.sa.sa_family == AF_INET &&
860 new->addr.in.sin_addr.s_addr == 0)
861 {
862 free(new);
863 continue;
864 }
865
866 for (iface = daemon->interfaces; iface; iface = iface->next)
867 if (sockaddr_isequal(&new->addr, &iface->addr))
868 break;
869 if (iface)
870 {
871 my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
872 free(new);
873 continue;
874 }
875
876 /* Do we need a socket set? */
877 if (!new->sfd &&
Lorenzo Colitti68eff532014-08-26 14:06:34 -0700878 !(new->sfd = allocate_sfd(&new->source_addr, new->interface, new->mark)) &&
San Mehatffd68722010-01-20 09:56:15 -0800879 errno != 0)
880 {
881 my_syslog(LOG_WARNING,
882 _("ignoring nameserver %s - cannot make/bind socket: %s"),
883 daemon->namebuff, strerror(errno));
884 free(new);
885 continue;
886 }
887 }
888
889 /* reverse order - gets it right. */
890 new->next = ret;
891 ret = new;
892
893 if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS))
894 {
895 char *s1, *s2;
896 if (!(new->flags & SERV_HAS_DOMAIN))
897 s1 = _("unqualified"), s2 = _("names");
898 else if (strlen(new->domain) == 0)
899 s1 = _("default"), s2 = "";
900 else
901 s1 = _("domain"), s2 = new->domain;
902
903 if (new->flags & SERV_NO_ADDR)
904 my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
905 else if (!(new->flags & SERV_LITERAL_ADDRESS))
906 my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
907 }
908 else if (new->interface[0] != 0)
909 my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface);
910 else
911 my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
912 }
913
914 daemon->servers = ret;
915}
916
San Mehat33b34442010-01-20 10:54:48 -0800917#ifdef __ANDROID__
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800918/* #define __ANDROID_DEBUG__ 1 */
919/*
920 * Ingests a new list of interfaces and starts to listen on them, adding only the new
921 * and stopping to listen to any interfaces not on the new list.
922 *
923 * interfaces - input in the format "bt-pan:eth0:wlan0:..>" up to 1024 bytes long
924 */
925void set_interfaces(const char *interfaces)
926{
927 struct iname *if_tmp;
928 struct iname *prev_if_names;
929 struct irec *old_iface, *new_iface, *prev_interfaces;
930 char s[1024];
931 char *next = s;
932 char *interface;
933 int was_wild = 0;
934
935#ifdef __ANDROID_DEBUG__
936 my_syslog(LOG_DEBUG, _("set_interfaces(%s)"), interfaces);
937#endif
938 prev_if_names = daemon->if_names;
939 daemon->if_names = NULL;
940
941 prev_interfaces = daemon->interfaces;
942 daemon->interfaces = NULL;
943
944 if (strlen(interfaces) > sizeof(s)) {
945 die(_("interface string too long: %s"), NULL, EC_BADNET);
946 }
947 strncpy(s, interfaces, sizeof(s));
948 while((interface = strsep(&next, ":"))) {
949 if_tmp = safe_malloc(sizeof(struct iname));
Erik Klinee226bad2014-09-30 16:06:37 +0900950 memset(if_tmp, 0, sizeof(struct iname));
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800951 if ((if_tmp->name = strdup(interface)) == NULL) {
952 die(_("malloc failure in set_interfaces: %s"), NULL, EC_BADNET);
953 }
954 if_tmp->next = daemon->if_names;
955 daemon->if_names = if_tmp;
956 }
957
958 if (!enumerate_interfaces()) {
959 die(_("enumerate interfaces error in set_interfaces: %s"), NULL, EC_BADNET);
960 }
961
962 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next) {
963 if (if_tmp->name && !if_tmp->used) {
Subash Abhinov Kasiviswanathan39e3ece2014-02-24 18:28:55 -0700964 my_syslog(LOG_DEBUG, _("unknown interface given %s in set_interfaces"), if_tmp->name);
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800965 }
966 }
967 /* success! - setup to free the old */
968 /* check for any that have been removed */
969 for (old_iface = prev_interfaces; old_iface; old_iface=old_iface->next) {
970 int found = 0;
971 for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
972 if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
Erik Klinee226bad2014-09-30 16:06:37 +0900973 found = 1;
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800974 break;
975 }
976 }
Erik Klinee226bad2014-09-30 16:06:37 +0900977
978 if (found) {
979 fixup_possible_existing_listener(new_iface);
980 } else {
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -0800981#ifdef __ANDROID_DEBUG__
982 char debug_buff[MAXDNAME];
983 prettyprint_addr(&old_iface->addr, debug_buff);
984 my_syslog(LOG_DEBUG, _("closing listener for %s"), debug_buff);
985#endif
986
987 close_bound_listener(old_iface);
988 }
Subash Abhinov Kasiviswanathan39e3ece2014-02-24 18:28:55 -0700989 else
990 {
991 struct listener **l, *listener;
992 for (l = &(daemon->listeners); *l; l = &((*l)->next)) {
993 struct irec *listener_iface = (*l)->iface;
994 if (listener_iface && new_iface) {
995 if (sockaddr_isequal(&listener_iface->addr, &new_iface->addr)) {
996 break;
997 }
998 }
999 }
1000 listener = *l;
1001 if ( listener )
1002 listener->iface = new_iface;
1003 }
Robert Greenwalt41cd7ed2012-12-11 12:42:32 -08001004 }
1005
1006 /* remove wildchar listeners */
1007 was_wild = close_bound_listener(NULL);
1008 if (was_wild) daemon->options |= OPT_NOWILD;
1009
1010 /* check for any that have been added */
1011 for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
1012 int found = 0;
1013
1014 /* if the previous setup used a wildchar, then add any current interfaces */
1015 if (!was_wild) {
1016 for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
1017 if(sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
1018 found = -1;
1019 break;
1020 }
1021 }
1022 }
1023 if (!found) {
1024#ifdef __ANDROID_DEBUG__
1025 char debug_buff[MAXDNAME];
1026 prettyprint_addr(&new_iface->addr, debug_buff);
1027 my_syslog(LOG_DEBUG, _("adding listener for %s"), debug_buff);
1028#endif
1029 create_bound_listener(&(daemon->listeners), new_iface);
1030 }
1031 }
1032
1033 while (prev_if_names) {
1034 if (prev_if_names->name) free(prev_if_names->name);
1035 if_tmp = prev_if_names->next;
1036 free(prev_if_names);
1037 prev_if_names = if_tmp;
1038 }
1039 while (prev_interfaces) {
1040 struct irec *tmp_irec = prev_interfaces->next;
1041 free(prev_interfaces);
1042 prev_interfaces = tmp_irec;
1043 }
1044#ifdef __ANDROID_DEBUG__
1045 my_syslog(LOG_DEBUG, _("done with setInterfaces"));
1046#endif
1047}
1048
San Mehat33b34442010-01-20 10:54:48 -08001049/*
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001050 * Takes a string in the format "0x100b:1.2.3.4:1.2.3.4:..." - up to 1024 bytes in length
1051 * - The first element is the socket mark to set on sockets that forward DNS queries.
1052 * - The subsequent elements are the DNS servers to forward queries to.
San Mehat33b34442010-01-20 10:54:48 -08001053 */
1054int set_servers(const char *servers)
1055{
1056 char s[1024];
1057 struct server *old_servers = NULL;
1058 struct server *new_servers = NULL;
1059 struct server *serv;
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001060 char *mark_string;
1061 uint32_t mark;
San Mehat33b34442010-01-20 10:54:48 -08001062
1063 strncpy(s, servers, sizeof(s));
1064
1065 /* move old servers to free list - we can reuse the memory
1066 and not risk malloc if there are the same or fewer new servers.
1067 Servers which were specced on the command line go to the new list. */
1068 for (serv = daemon->servers; serv;)
1069 {
1070 struct server *tmp = serv->next;
1071 if (serv->flags & SERV_FROM_RESOLV)
1072 {
1073 serv->next = old_servers;
1074 old_servers = serv;
1075 /* forward table rules reference servers, so have to blow them away */
1076 server_gone(serv);
1077 }
1078 else
1079 {
1080 serv->next = new_servers;
1081 new_servers = serv;
1082 }
1083 serv = tmp;
1084 }
1085
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001086 char *next = s;
1087 char *saddr;
San Mehat33b34442010-01-20 10:54:48 -08001088
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001089 /* Parse the mark. */
1090 mark_string = strsep(&next, ":");
1091 mark = strtoul(mark_string, NULL, 0);
1092
1093 while ((saddr = strsep(&next, ":"))) {
San Mehat33b34442010-01-20 10:54:48 -08001094 union mysockaddr addr, source_addr;
1095 memset(&addr, 0, sizeof(addr));
1096 memset(&source_addr, 0, sizeof(source_addr));
1097
1098 if ((addr.in.sin_addr.s_addr = inet_addr(saddr)) != (in_addr_t) -1)
1099 {
1100#ifdef HAVE_SOCKADDR_SA_LEN
1101 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
1102#endif
1103 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
1104 addr.in.sin_port = htons(NAMESERVER_PORT);
1105 source_addr.in.sin_addr.s_addr = INADDR_ANY;
1106 source_addr.in.sin_port = htons(daemon->query_port);
1107 }
1108#ifdef HAVE_IPV6
1109 else if (inet_pton(AF_INET6, saddr, &addr.in6.sin6_addr) > 0)
1110 {
1111#ifdef HAVE_SOCKADDR_SA_LEN
1112 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
1113#endif
1114 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
1115 addr.in6.sin6_port = htons(NAMESERVER_PORT);
1116 source_addr.in6.sin6_addr = in6addr_any;
1117 source_addr.in6.sin6_port = htons(daemon->query_port);
1118 }
1119#endif /* IPV6 */
1120 else
1121 continue;
1122
1123 if (old_servers)
1124 {
1125 serv = old_servers;
1126 old_servers = old_servers->next;
1127 }
1128 else if (!(serv = whine_malloc(sizeof (struct server))))
1129 continue;
1130
1131 /* this list is reverse ordered:
1132 it gets reversed again in check_servers */
1133 serv->next = new_servers;
1134 new_servers = serv;
1135 serv->addr = addr;
1136 serv->source_addr = source_addr;
1137 serv->domain = NULL;
1138 serv->interface[0] = 0;
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001139 serv->mark = mark;
San Mehat33b34442010-01-20 10:54:48 -08001140 serv->sfd = NULL;
1141 serv->flags = SERV_FROM_RESOLV;
1142 serv->queries = serv->failed_queries = 0;
1143 }
1144
1145 /* Free any memory not used. */
1146 while (old_servers)
1147 {
1148 struct server *tmp = old_servers->next;
1149 free(old_servers);
1150 old_servers = tmp;
1151 }
1152
1153 daemon->servers = new_servers;
1154 return 0;
1155}
1156#endif
1157
San Mehatffd68722010-01-20 09:56:15 -08001158/* Return zero if no servers found, in that case we keep polling.
1159 This is a protection against an update-time/write race on resolv.conf */
1160int reload_servers(char *fname)
1161{
1162 FILE *f;
1163 char *line;
1164 struct server *old_servers = NULL;
1165 struct server *new_servers = NULL;
1166 struct server *serv;
1167 int gotone = 0;
1168
1169 /* buff happens to be MAXDNAME long... */
1170 if (!(f = fopen(fname, "r")))
1171 {
1172 my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
1173 return 0;
1174 }
1175
1176 /* move old servers to free list - we can reuse the memory
1177 and not risk malloc if there are the same or fewer new servers.
1178 Servers which were specced on the command line go to the new list. */
1179 for (serv = daemon->servers; serv;)
1180 {
1181 struct server *tmp = serv->next;
1182 if (serv->flags & SERV_FROM_RESOLV)
1183 {
1184 serv->next = old_servers;
1185 old_servers = serv;
1186 /* forward table rules reference servers, so have to blow them away */
1187 server_gone(serv);
1188 }
1189 else
1190 {
1191 serv->next = new_servers;
1192 new_servers = serv;
1193 }
1194 serv = tmp;
1195 }
1196
1197 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
1198 {
1199 union mysockaddr addr, source_addr;
1200 char *token = strtok(line, " \t\n\r");
1201
1202 if (!token)
1203 continue;
1204 if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
1205 continue;
1206 if (!(token = strtok(NULL, " \t\n\r")))
1207 continue;
1208
1209 memset(&addr, 0, sizeof(addr));
1210 memset(&source_addr, 0, sizeof(source_addr));
1211
1212 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
1213 {
1214#ifdef HAVE_SOCKADDR_SA_LEN
1215 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
1216#endif
1217 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
1218 addr.in.sin_port = htons(NAMESERVER_PORT);
1219 source_addr.in.sin_addr.s_addr = INADDR_ANY;
1220 source_addr.in.sin_port = htons(daemon->query_port);
1221 }
1222#ifdef HAVE_IPV6
1223 else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
1224 {
1225#ifdef HAVE_SOCKADDR_SA_LEN
1226 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
1227#endif
1228 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
1229 addr.in6.sin6_port = htons(NAMESERVER_PORT);
1230 source_addr.in6.sin6_addr = in6addr_any;
1231 source_addr.in6.sin6_port = htons(daemon->query_port);
1232 }
1233#endif /* IPV6 */
1234 else
1235 continue;
1236
1237 if (old_servers)
1238 {
1239 serv = old_servers;
1240 old_servers = old_servers->next;
1241 }
1242 else if (!(serv = whine_malloc(sizeof (struct server))))
1243 continue;
1244
1245 /* this list is reverse ordered:
1246 it gets reversed again in check_servers */
1247 serv->next = new_servers;
1248 new_servers = serv;
1249 serv->addr = addr;
1250 serv->source_addr = source_addr;
1251 serv->domain = NULL;
1252 serv->interface[0] = 0;
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001253 serv->mark = 0;
San Mehatffd68722010-01-20 09:56:15 -08001254 serv->sfd = NULL;
1255 serv->flags = SERV_FROM_RESOLV;
1256 serv->queries = serv->failed_queries = 0;
1257 gotone = 1;
1258 }
1259
1260 /* Free any memory not used. */
1261 while (old_servers)
1262 {
1263 struct server *tmp = old_servers->next;
1264 free(old_servers);
1265 old_servers = tmp;
1266 }
1267
1268 daemon->servers = new_servers;
1269 fclose(f);
1270
1271 return gotone;
1272}
1273
1274
1275/* Use an IPv4 listener socket for ioctling */
1276struct in_addr get_ifaddr(char *intr)
1277{
1278 struct listener *l;
1279 struct ifreq ifr;
1280
1281 for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
1282
1283 strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
1284 ifr.ifr_addr.sa_family = AF_INET;
1285
1286 if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
1287 ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
1288
1289 return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
1290}