blob: 5880974424188e3918586d525c1ecf64a31b7911 [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 }
989 }
990
991 /* remove wildchar listeners */
992 was_wild = close_bound_listener(NULL);
993 if (was_wild) daemon->options |= OPT_NOWILD;
994
995 /* check for any that have been added */
996 for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
997 int found = 0;
998
999 /* if the previous setup used a wildchar, then add any current interfaces */
1000 if (!was_wild) {
1001 for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
1002 if(sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
1003 found = -1;
1004 break;
1005 }
1006 }
1007 }
1008 if (!found) {
1009#ifdef __ANDROID_DEBUG__
1010 char debug_buff[MAXDNAME];
1011 prettyprint_addr(&new_iface->addr, debug_buff);
1012 my_syslog(LOG_DEBUG, _("adding listener for %s"), debug_buff);
1013#endif
1014 create_bound_listener(&(daemon->listeners), new_iface);
1015 }
1016 }
1017
1018 while (prev_if_names) {
1019 if (prev_if_names->name) free(prev_if_names->name);
1020 if_tmp = prev_if_names->next;
1021 free(prev_if_names);
1022 prev_if_names = if_tmp;
1023 }
1024 while (prev_interfaces) {
1025 struct irec *tmp_irec = prev_interfaces->next;
1026 free(prev_interfaces);
1027 prev_interfaces = tmp_irec;
1028 }
1029#ifdef __ANDROID_DEBUG__
1030 my_syslog(LOG_DEBUG, _("done with setInterfaces"));
1031#endif
1032}
1033
San Mehat33b34442010-01-20 10:54:48 -08001034/*
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001035 * Takes a string in the format "0x100b:1.2.3.4:1.2.3.4:..." - up to 1024 bytes in length
1036 * - The first element is the socket mark to set on sockets that forward DNS queries.
1037 * - The subsequent elements are the DNS servers to forward queries to.
San Mehat33b34442010-01-20 10:54:48 -08001038 */
1039int set_servers(const char *servers)
1040{
1041 char s[1024];
1042 struct server *old_servers = NULL;
1043 struct server *new_servers = NULL;
1044 struct server *serv;
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001045 char *mark_string;
1046 uint32_t mark;
San Mehat33b34442010-01-20 10:54:48 -08001047
1048 strncpy(s, servers, sizeof(s));
1049
1050 /* move old servers to free list - we can reuse the memory
1051 and not risk malloc if there are the same or fewer new servers.
1052 Servers which were specced on the command line go to the new list. */
1053 for (serv = daemon->servers; serv;)
1054 {
1055 struct server *tmp = serv->next;
1056 if (serv->flags & SERV_FROM_RESOLV)
1057 {
1058 serv->next = old_servers;
1059 old_servers = serv;
1060 /* forward table rules reference servers, so have to blow them away */
1061 server_gone(serv);
1062 }
1063 else
1064 {
1065 serv->next = new_servers;
1066 new_servers = serv;
1067 }
1068 serv = tmp;
1069 }
1070
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001071 char *next = s;
1072 char *saddr;
San Mehat33b34442010-01-20 10:54:48 -08001073
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001074 /* Parse the mark. */
1075 mark_string = strsep(&next, ":");
1076 mark = strtoul(mark_string, NULL, 0);
1077
1078 while ((saddr = strsep(&next, ":"))) {
San Mehat33b34442010-01-20 10:54:48 -08001079 union mysockaddr addr, source_addr;
1080 memset(&addr, 0, sizeof(addr));
1081 memset(&source_addr, 0, sizeof(source_addr));
1082
1083 if ((addr.in.sin_addr.s_addr = inet_addr(saddr)) != (in_addr_t) -1)
1084 {
1085#ifdef HAVE_SOCKADDR_SA_LEN
1086 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
1087#endif
1088 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
1089 addr.in.sin_port = htons(NAMESERVER_PORT);
1090 source_addr.in.sin_addr.s_addr = INADDR_ANY;
1091 source_addr.in.sin_port = htons(daemon->query_port);
1092 }
1093#ifdef HAVE_IPV6
1094 else if (inet_pton(AF_INET6, saddr, &addr.in6.sin6_addr) > 0)
1095 {
1096#ifdef HAVE_SOCKADDR_SA_LEN
1097 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
1098#endif
1099 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
1100 addr.in6.sin6_port = htons(NAMESERVER_PORT);
1101 source_addr.in6.sin6_addr = in6addr_any;
1102 source_addr.in6.sin6_port = htons(daemon->query_port);
1103 }
1104#endif /* IPV6 */
1105 else
1106 continue;
1107
1108 if (old_servers)
1109 {
1110 serv = old_servers;
1111 old_servers = old_servers->next;
1112 }
1113 else if (!(serv = whine_malloc(sizeof (struct server))))
1114 continue;
1115
1116 /* this list is reverse ordered:
1117 it gets reversed again in check_servers */
1118 serv->next = new_servers;
1119 new_servers = serv;
1120 serv->addr = addr;
1121 serv->source_addr = source_addr;
1122 serv->domain = NULL;
1123 serv->interface[0] = 0;
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001124 serv->mark = mark;
San Mehat33b34442010-01-20 10:54:48 -08001125 serv->sfd = NULL;
1126 serv->flags = SERV_FROM_RESOLV;
1127 serv->queries = serv->failed_queries = 0;
1128 }
1129
1130 /* Free any memory not used. */
1131 while (old_servers)
1132 {
1133 struct server *tmp = old_servers->next;
1134 free(old_servers);
1135 old_servers = tmp;
1136 }
1137
1138 daemon->servers = new_servers;
1139 return 0;
1140}
1141#endif
1142
San Mehatffd68722010-01-20 09:56:15 -08001143/* Return zero if no servers found, in that case we keep polling.
1144 This is a protection against an update-time/write race on resolv.conf */
1145int reload_servers(char *fname)
1146{
1147 FILE *f;
1148 char *line;
1149 struct server *old_servers = NULL;
1150 struct server *new_servers = NULL;
1151 struct server *serv;
1152 int gotone = 0;
1153
1154 /* buff happens to be MAXDNAME long... */
1155 if (!(f = fopen(fname, "r")))
1156 {
1157 my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
1158 return 0;
1159 }
1160
1161 /* move old servers to free list - we can reuse the memory
1162 and not risk malloc if there are the same or fewer new servers.
1163 Servers which were specced on the command line go to the new list. */
1164 for (serv = daemon->servers; serv;)
1165 {
1166 struct server *tmp = serv->next;
1167 if (serv->flags & SERV_FROM_RESOLV)
1168 {
1169 serv->next = old_servers;
1170 old_servers = serv;
1171 /* forward table rules reference servers, so have to blow them away */
1172 server_gone(serv);
1173 }
1174 else
1175 {
1176 serv->next = new_servers;
1177 new_servers = serv;
1178 }
1179 serv = tmp;
1180 }
1181
1182 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
1183 {
1184 union mysockaddr addr, source_addr;
1185 char *token = strtok(line, " \t\n\r");
1186
1187 if (!token)
1188 continue;
1189 if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
1190 continue;
1191 if (!(token = strtok(NULL, " \t\n\r")))
1192 continue;
1193
1194 memset(&addr, 0, sizeof(addr));
1195 memset(&source_addr, 0, sizeof(source_addr));
1196
1197 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
1198 {
1199#ifdef HAVE_SOCKADDR_SA_LEN
1200 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
1201#endif
1202 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
1203 addr.in.sin_port = htons(NAMESERVER_PORT);
1204 source_addr.in.sin_addr.s_addr = INADDR_ANY;
1205 source_addr.in.sin_port = htons(daemon->query_port);
1206 }
1207#ifdef HAVE_IPV6
1208 else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
1209 {
1210#ifdef HAVE_SOCKADDR_SA_LEN
1211 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
1212#endif
1213 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
1214 addr.in6.sin6_port = htons(NAMESERVER_PORT);
1215 source_addr.in6.sin6_addr = in6addr_any;
1216 source_addr.in6.sin6_port = htons(daemon->query_port);
1217 }
1218#endif /* IPV6 */
1219 else
1220 continue;
1221
1222 if (old_servers)
1223 {
1224 serv = old_servers;
1225 old_servers = old_servers->next;
1226 }
1227 else if (!(serv = whine_malloc(sizeof (struct server))))
1228 continue;
1229
1230 /* this list is reverse ordered:
1231 it gets reversed again in check_servers */
1232 serv->next = new_servers;
1233 new_servers = serv;
1234 serv->addr = addr;
1235 serv->source_addr = source_addr;
1236 serv->domain = NULL;
1237 serv->interface[0] = 0;
Lorenzo Colitti68eff532014-08-26 14:06:34 -07001238 serv->mark = 0;
San Mehatffd68722010-01-20 09:56:15 -08001239 serv->sfd = NULL;
1240 serv->flags = SERV_FROM_RESOLV;
1241 serv->queries = serv->failed_queries = 0;
1242 gotone = 1;
1243 }
1244
1245 /* Free any memory not used. */
1246 while (old_servers)
1247 {
1248 struct server *tmp = old_servers->next;
1249 free(old_servers);
1250 old_servers = tmp;
1251 }
1252
1253 daemon->servers = new_servers;
1254 fclose(f);
1255
1256 return gotone;
1257}
1258
1259
1260/* Use an IPv4 listener socket for ioctling */
1261struct in_addr get_ifaddr(char *intr)
1262{
1263 struct listener *l;
1264 struct ifreq ifr;
1265
1266 for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
1267
1268 strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
1269 ifr.ifr_addr.sa_family = AF_INET;
1270
1271 if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
1272 ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
1273
1274 return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
1275}