1 /* 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 static const char SEPARATOR[] = "|";
20
21 #ifdef HAVE_LINUX_NETWORK
22
indextoname(int fd,int index,char * name)23 int indextoname(int fd, int index, char *name)
24 {
25 struct ifreq ifr;
26
27 if (index == 0)
28 return 0;
29
30 ifr.ifr_ifindex = index;
31 if (ioctl(fd, SIOCGIFNAME, &ifr) == -1)
32 return 0;
33
34 strncpy(name, ifr.ifr_name, IF_NAMESIZE);
35
36 return 1;
37 }
38
39 #else
40
indextoname(int fd,int index,char * name)41 int indextoname(int fd, int index, char *name)
42 {
43 if (index == 0 || !if_indextoname(index, name))
44 return 0;
45
46 return 1;
47 }
48
49 #endif
50
iface_check(int family,struct all_addr * addr,char * name,int * indexp)51 int iface_check(int family, struct all_addr *addr, char *name, int *indexp)
52 {
53 struct iname *tmp;
54 int ret = 1;
55
56 /* Note: have to check all and not bail out early, so that we set the
57 "used" flags. */
58
59 if (indexp)
60 {
61 /* One form of bridging on BSD has the property that packets
62 can be recieved on bridge interfaces which do not have an IP address.
63 We allow these to be treated as aliases of another interface which does have
64 an IP address with --dhcp-bridge=interface,alias,alias */
65 struct dhcp_bridge *bridge, *alias;
66 for (bridge = daemon->bridges; bridge; bridge = bridge->next)
67 {
68 for (alias = bridge->alias; alias; alias = alias->next)
69 if (strncmp(name, alias->iface, IF_NAMESIZE) == 0)
70 {
71 int newindex;
72
73 if (!(newindex = if_nametoindex(bridge->iface)))
74 {
75 my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), name);
76 return 0;
77 }
78 else
79 {
80 *indexp = newindex;
81 strncpy(name, bridge->iface, IF_NAMESIZE);
82 break;
83 }
84 }
85 if (alias)
86 break;
87 }
88 }
89
90 if (daemon->if_names || (addr && daemon->if_addrs))
91 {
92 ret = 0;
93
94 for (tmp = daemon->if_names; tmp; tmp = tmp->next)
95 if (tmp->name && (strcmp(tmp->name, name) == 0))
96 ret = tmp->used = 1;
97
98 for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
99 if (addr && tmp->addr.sa.sa_family == family)
100 {
101 if (family == AF_INET &&
102 tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
103 ret = tmp->used = 1;
104 #ifdef HAVE_IPV6
105 else if (family == AF_INET6 &&
106 IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr,
107 &addr->addr.addr6) &&
108 (!IN6_IS_ADDR_LINKLOCAL(&addr->addr.addr6) ||
109 (tmp->addr.in6.sin6_scope_id == (uint32_t) *indexp)))
110 ret = tmp->used = 1;
111 #endif
112 }
113 }
114
115 for (tmp = daemon->if_except; tmp; tmp = tmp->next)
116 if (tmp->name && (strcmp(tmp->name, name) == 0))
117 ret = 0;
118
119 return ret;
120 }
121
iface_allowed(struct irec ** irecp,int if_index,union mysockaddr * addr,struct in_addr netmask)122 static int iface_allowed(struct irec **irecp, int if_index,
123 union mysockaddr *addr, struct in_addr netmask)
124 {
125 struct irec *iface;
126 int fd, mtu = 0, loopback;
127 struct ifreq ifr;
128 int dhcp_ok = 1;
129 struct iname *tmp;
130
131 /* check whether the interface IP has been added already
132 we call this routine multiple times. */
133 for (iface = *irecp; iface; iface = iface->next)
134 if (sockaddr_isequal(&iface->addr, addr))
135 return 1;
136
137 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 ||
138 !indextoname(fd, if_index, ifr.ifr_name) ||
139 ioctl(fd, SIOCGIFFLAGS, &ifr) == -1)
140 {
141 if (fd != -1)
142 {
143 int errsave = errno;
144 close(fd);
145 errno = errsave;
146 }
147 return 0;
148 }
149
150 loopback = ifr.ifr_flags & IFF_LOOPBACK;
151
152 if (ioctl(fd, SIOCGIFMTU, &ifr) != -1)
153 mtu = ifr.ifr_mtu;
154
155 close(fd);
156
157 /* If we are restricting the set of interfaces to use, make
158 sure that loopback interfaces are in that set. */
159 if (daemon->if_names && loopback)
160 {
161 struct iname *lo;
162 for (lo = daemon->if_names; lo; lo = lo->next)
163 if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
164 {
165 lo->isloop = 1;
166 break;
167 }
168
169 if (!lo &&
170 (lo = whine_malloc(sizeof(struct iname))) &&
171 (lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
172 {
173 strcpy(lo->name, ifr.ifr_name);
174 lo->isloop = lo->used = 1;
175 lo->next = daemon->if_names;
176 daemon->if_names = lo;
177 }
178 }
179
180 if (addr->sa.sa_family == AF_INET &&
181 !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, ifr.ifr_name, NULL))
182 return 1;
183
184 for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
185 if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
186 dhcp_ok = 0;
187
188 #ifdef HAVE_IPV6
189 int ifindex = (int) addr->in6.sin6_scope_id;
190 if (addr->sa.sa_family == AF_INET6 &&
191 !iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, ifr.ifr_name, &ifindex))
192 return 1;
193 #endif
194
195 /* add to list */
196 if ((iface = whine_malloc(sizeof(struct irec))))
197 {
198 iface->addr = *addr;
199 iface->netmask = netmask;
200 iface->dhcp_ok = dhcp_ok;
201 iface->mtu = mtu;
202 iface->next = *irecp;
203 *irecp = iface;
204 return 1;
205 }
206
207 errno = ENOMEM;
208 return 0;
209 }
210
211 #ifdef HAVE_IPV6
iface_allowed_v6(struct in6_addr * local,int scope,int if_index,void * vparam)212 static int iface_allowed_v6(struct in6_addr *local,
213 int scope, int if_index, void *vparam)
214 {
215 union mysockaddr addr;
216 struct in_addr netmask; /* dummy */
217
218 netmask.s_addr = 0;
219
220 memset(&addr, 0, sizeof(addr));
221 #ifdef HAVE_SOCKADDR_SA_LEN
222 addr.in6.sin6_len = sizeof(addr.in6);
223 #endif
224 addr.in6.sin6_family = AF_INET6;
225 addr.in6.sin6_addr = *local;
226 addr.in6.sin6_port = htons(daemon->port);
227 /**
228 * Only populate the scope ID if the address is link-local.
229 * Scope IDs are not meaningful for global addresses. Also, we do not want to
230 * think that two addresses are different if they differ only in scope ID,
231 * because the kernel will treat them as if they are the same.
232 */
233 if (IN6_IS_ADDR_LINKLOCAL(local)) {
234 addr.in6.sin6_scope_id = scope;
235 }
236
237 return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
238 }
239 #endif
240
iface_allowed_v4(struct in_addr local,int if_index,struct in_addr netmask,struct in_addr broadcast,void * vparam)241 static int iface_allowed_v4(struct in_addr local, int if_index,
242 struct in_addr netmask, struct in_addr broadcast, void *vparam)
243 {
244 union mysockaddr addr;
245
246 memset(&addr, 0, sizeof(addr));
247 #ifdef HAVE_SOCKADDR_SA_LEN
248 addr.in.sin_len = sizeof(addr.in);
249 #endif
250 addr.in.sin_family = AF_INET;
251 addr.in.sin_addr = broadcast; /* warning */
252 addr.in.sin_addr = local;
253 addr.in.sin_port = htons(daemon->port);
254
255 return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
256 }
257
enumerate_interfaces(void)258 int enumerate_interfaces(void)
259 {
260 #ifdef HAVE_IPV6
261 return iface_enumerate(&daemon->interfaces, iface_allowed_v4, iface_allowed_v6);
262 #else
263 return iface_enumerate(&daemon->interfaces, iface_allowed_v4, NULL);
264 #endif
265 }
266
267 /* set NONBLOCK bit on fd: See Stevens 16.6 */
fix_fd(int fd)268 int fix_fd(int fd)
269 {
270 int flags;
271
272 if ((flags = fcntl(fd, F_GETFL)) == -1 ||
273 fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
274 return 0;
275
276 return 1;
277 }
278
279 #if defined(HAVE_IPV6)
create_ipv6_listener(struct listener ** link,int port)280 static int create_ipv6_listener(struct listener **link, int port)
281 {
282 union mysockaddr addr;
283 int tcpfd, fd;
284 struct listener *l;
285 int opt = 1;
286
287 memset(&addr, 0, sizeof(addr));
288 addr.in6.sin6_family = AF_INET6;
289 addr.in6.sin6_addr = in6addr_any;
290 addr.in6.sin6_port = htons(port);
291 #ifdef HAVE_SOCKADDR_SA_LEN
292 addr.in6.sin6_len = sizeof(addr.in6);
293 #endif
294
295 /* No error of the kernel doesn't support IPv6 */
296 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
297 return (errno == EPROTONOSUPPORT ||
298 errno == EAFNOSUPPORT ||
299 errno == EINVAL);
300
301 if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
302 return 0;
303
304 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
305 setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
306 setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
307 setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
308 !fix_fd(fd) ||
309 !fix_fd(tcpfd) ||
310 #ifdef IPV6_RECVPKTINFO
311 setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
312 #else
313 setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
314 #endif
315 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
316 listen(tcpfd, 5) == -1 ||
317 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
318 return 0;
319
320 l = safe_malloc(sizeof(struct listener));
321 l->fd = fd;
322 l->tcpfd = tcpfd;
323 l->tftpfd = -1;
324 l->family = AF_INET6;
325 l->iface = NULL;
326 l->next = NULL;
327 *link = l;
328
329 return 1;
330 }
331 #endif
332
create_wildcard_listeners(void)333 struct listener *create_wildcard_listeners(void)
334 {
335 union mysockaddr addr;
336 int opt = 1;
337 struct listener *l, *l6 = NULL;
338 int tcpfd = -1, fd = -1, tftpfd = -1;
339
340 memset(&addr, 0, sizeof(addr));
341 addr.in.sin_family = AF_INET;
342 addr.in.sin_addr.s_addr = INADDR_ANY;
343 addr.in.sin_port = htons(daemon->port);
344 #ifdef HAVE_SOCKADDR_SA_LEN
345 addr.in.sin_len = sizeof(struct sockaddr_in);
346 #endif
347
348 if (daemon->port != 0)
349 {
350
351 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
352 (tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
353 return NULL;
354
355 if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
356 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
357 listen(tcpfd, 5) == -1 ||
358 !fix_fd(tcpfd) ||
359 #ifdef HAVE_IPV6
360 !create_ipv6_listener(&l6, daemon->port) ||
361 #endif
362 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
363 !fix_fd(fd) ||
364 #if defined(HAVE_LINUX_NETWORK)
365 setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
366 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
367 setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
368 setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
369 #endif
370 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
371 return NULL;
372 }
373
374 #ifdef HAVE_TFTP
375 if (daemon->options & OPT_TFTP)
376 {
377 addr.in.sin_port = htons(TFTP_PORT);
378 if ((tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
379 return NULL;
380
381 if (!fix_fd(tftpfd) ||
382 #if defined(HAVE_LINUX_NETWORK)
383 setsockopt(tftpfd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
384 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
385 setsockopt(tftpfd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
386 setsockopt(tftpfd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
387 #endif
388 bind(tftpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
389 return NULL;
390 }
391 #endif
392
393 l = safe_malloc(sizeof(struct listener));
394 l->family = AF_INET;
395 l->fd = fd;
396 l->tcpfd = tcpfd;
397 l->tftpfd = tftpfd;
398 l->iface = NULL;
399 l->next = l6;
400
401 return l;
402 }
403
404 #ifdef __ANDROID__
405 /**
406 * for a single given irec (interface name and address) create
407 * a set of sockets listening. This is a copy of the code inside the loop
408 * of create_bound_listeners below and is added here to allow us
409 * to create just a single new listener dynamically when our interface
410 * list is changed.
411 *
412 * iface - input of the new interface details to listen on
413 * listeners - output. Creates a new struct listener and inserts at head of the list
414 *
415 * die's on errors, so don't pass bad data.
416 */
create_bound_listener(struct listener ** listeners,struct irec * iface)417 void create_bound_listener(struct listener **listeners, struct irec *iface)
418 {
419 int rc, opt = 1;
420 #ifdef HAVE_IPV6
421 static int dad_count = 0;
422 #endif
423
424 struct listener *new = safe_malloc(sizeof(struct listener));
425 new->family = iface->addr.sa.sa_family;
426 new->iface = iface;
427 new->next = *listeners;
428 new->tftpfd = -1;
429 new->tcpfd = -1;
430 new->fd = -1;
431 *listeners = new;
432
433 if (daemon->port != 0)
434 {
435 if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
436 (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
437 setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
438 setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
439 !fix_fd(new->tcpfd) ||
440 !fix_fd(new->fd))
441 die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
442
443 #ifdef HAVE_IPV6
444 if (iface->addr.sa.sa_family == AF_INET6)
445 {
446 if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
447 setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
448 die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);\
449 }
450 #endif
451
452 while(1)
453 {
454 if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
455 break;
456
457 #ifdef HAVE_IPV6
458 /* An interface may have an IPv6 address which is still undergoing DAD.
459 If so, the bind will fail until the DAD completes, so we try over 20 seconds
460 before failing. */
461 /* TODO: What to do here? 20 seconds is way too long. We use optimistic addresses, so bind()
462 will only fail if the address has already failed DAD, in which case retrying won't help. */
463 if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) &&
464 dad_count++ < DAD_WAIT)
465 {
466 sleep(1);
467 continue;
468 }
469 #endif
470 break;
471 }
472
473 if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
474 {
475 prettyprint_addr(&iface->addr, daemon->namebuff);
476 die(_("failed to bind listening socket for %s: %s"), daemon->namebuff, EC_BADNET);
477 }
478
479 if (listen(new->tcpfd, 5) == -1)
480 die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
481 }
482
483 #ifdef HAVE_TFTP
484 if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
485 {
486 short save = iface->addr.in.sin_port;
487 iface->addr.in.sin_port = htons(TFTP_PORT);
488 if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
489 setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
490 !fix_fd(new->tftpfd) ||
491 bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
492 die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
493 iface->addr.in.sin_port = save;
494 }
495 #endif
496 }
497
498 /**
499 * If a listener has a struct irec pointer whose address matches the newly
500 * malloc()d struct irec's address, update its pointer to refer to this new
501 * struct irec instance.
502 *
503 * Otherwise, any listeners that are preserved across interface list changes
504 * will point at interface structures that are free()d at the end of
505 * set_interfaces(), and can get overwritten by subsequent memory allocations.
506 *
507 * See b/17475756 for further discussion.
508 */
fixup_possible_existing_listener(struct irec * new_iface)509 void fixup_possible_existing_listener(struct irec *new_iface) {
510 /* find the listener, if present */
511 struct listener *l;
512 for (l = daemon->listeners; l; l = l->next) {
513 struct irec *listener_iface = l->iface;
514 if (listener_iface) {
515 if (sockaddr_isequal(&listener_iface->addr, &new_iface->addr)) {
516 l->iface = new_iface;
517 return;
518 }
519 }
520 }
521 }
522
523 /**
524 * Closes the sockets of the specified listener, deletes it from the list, and frees it.
525 *
526 */
delete_listener(struct listener ** l)527 int delete_listener(struct listener **l)
528 {
529 struct listener *listener = *l;
530 if (listener == NULL) return 0;
531
532 if (listener->iface) {
533 int port = prettyprint_addr(&listener->iface->addr, daemon->namebuff);
534 my_syslog(LOG_INFO, _("Closing listener [%s]:%d"), daemon->namebuff, port);
535 } else {
536 my_syslog(LOG_INFO, _("Closing wildcard listener family=%d"), listener->family);
537 }
538
539 if (listener->tftpfd != -1)
540 {
541 close(listener->tftpfd);
542 listener->tftpfd = -1;
543 }
544 if (listener->tcpfd != -1)
545 {
546 close(listener->tcpfd);
547 listener->tcpfd = -1;
548 }
549 if (listener->fd != -1)
550 {
551 close(listener->fd);
552 listener->fd = -1;
553 }
554 *l = listener->next;
555 free(listener);
556 return -1;
557 }
558
559 /**
560 * Close the sockets listening on the given interface
561 *
562 * This new function is needed as we're dynamically changing the interfaces
563 * we listen on. Before they'd be opened once in create_bound_listeners and stay
564 * until we exited. Now, if an interface moves off the to-listen list we need to
565 * close out the listeners and keep trucking.
566 *
567 * interface - input of the interface details to listen on
568 */
close_bound_listener(struct irec * iface)569 int close_bound_listener(struct irec *iface)
570 {
571 /* find the listener */
572 int ret = 0;
573 struct listener **l = &daemon->listeners;
574 while (*l) {
575 struct irec *listener_iface = (*l)->iface;
576 struct listener **next = &((*l)->next);
577 if (iface && listener_iface && sockaddr_isequal(&listener_iface->addr, &iface->addr)) {
578 // Listener bound to an IP address. There can be only one of these.
579 ret = delete_listener(l);
580 break;
581 }
582 if (iface == NULL && listener_iface == NULL) {
583 // Wildcard listener. There is one of these per address family.
584 ret = delete_listener(l);
585 continue;
586 }
587 l = next;
588 }
589 return ret;
590 }
591 #endif /* __ANDROID__ */
592
create_bound_listeners(void)593 struct listener *create_bound_listeners(void)
594 {
595 struct listener *listeners = NULL;
596 struct irec *iface;
597 #ifndef __ANDROID__
598 int rc, opt = 1;
599 #ifdef HAVE_IPV6
600 static int dad_count = 0;
601 #endif
602 #endif
603
604 for (iface = daemon->interfaces; iface; iface = iface->next)
605 {
606 #ifdef __ANDROID__
607 create_bound_listener(&listeners, iface);
608 #else
609 struct listener *new = safe_malloc(sizeof(struct listener));
610 new->family = iface->addr.sa.sa_family;
611 new->iface = iface;
612 new->next = listeners;
613 new->tftpfd = -1;
614 new->tcpfd = -1;
615 new->fd = -1;
616 listeners = new;
617
618 if (daemon->port != 0)
619 {
620 if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
621 (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
622 setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
623 setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
624 !fix_fd(new->tcpfd) ||
625 !fix_fd(new->fd))
626 die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
627
628 #ifdef HAVE_IPV6
629 if (iface->addr.sa.sa_family == AF_INET6)
630 {
631 if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
632 setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
633 die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
634 }
635 #endif
636
637 while(1)
638 {
639 if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
640 break;
641
642 #ifdef HAVE_IPV6
643 /* An interface may have an IPv6 address which is still undergoing DAD.
644 If so, the bind will fail until the DAD completes, so we try over 20 seconds
645 before failing. */
646 if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) &&
647 dad_count++ < DAD_WAIT)
648 {
649 sleep(1);
650 continue;
651 }
652 #endif
653 break;
654 }
655
656 if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
657 {
658 prettyprint_addr(&iface->addr, daemon->namebuff);
659 die(_("failed to bind listening socket for %s: %s"),
660 daemon->namebuff, EC_BADNET);
661 }
662
663 if (listen(new->tcpfd, 5) == -1)
664 die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
665 }
666
667 #ifdef HAVE_TFTP
668 if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
669 {
670 short save = iface->addr.in.sin_port;
671 iface->addr.in.sin_port = htons(TFTP_PORT);
672 if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
673 setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
674 !fix_fd(new->tftpfd) ||
675 bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
676 die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
677 iface->addr.in.sin_port = save;
678 }
679 #endif
680 #endif /* !__ANDROID */
681 }
682
683 return listeners;
684 }
685
686
687 /* return a UDP socket bound to a random port, have to cope with straying into
688 occupied port nos and reserved ones. */
random_sock(int family)689 int random_sock(int family)
690 {
691 int fd;
692
693 if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
694 {
695 union mysockaddr addr;
696 unsigned int ports_avail = 65536u - (unsigned short)daemon->min_port;
697 int tries = ports_avail < 30 ? 3 * ports_avail : 100;
698
699 memset(&addr, 0, sizeof(addr));
700 addr.sa.sa_family = family;
701
702 /* don't loop forever if all ports in use. */
703
704 if (fix_fd(fd))
705 while(tries--)
706 {
707 unsigned short port = rand16();
708
709 if (daemon->min_port != 0)
710 port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
711
712 if (family == AF_INET)
713 {
714 addr.in.sin_addr.s_addr = INADDR_ANY;
715 addr.in.sin_port = port;
716 #ifdef HAVE_SOCKADDR_SA_LEN
717 addr.in.sin_len = sizeof(struct sockaddr_in);
718 #endif
719 }
720 #ifdef HAVE_IPV6
721 else
722 {
723 addr.in6.sin6_addr = in6addr_any;
724 addr.in6.sin6_port = port;
725 #ifdef HAVE_SOCKADDR_SA_LEN
726 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
727 #endif
728 }
729 #endif
730
731 if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
732 return fd;
733
734 if (errno != EADDRINUSE && errno != EACCES)
735 break;
736 }
737
738 close(fd);
739 }
740
741 return -1;
742 }
743
744
local_bind(int fd,union mysockaddr * addr,char * intname,uint32_t mark,int is_tcp)745 int local_bind(int fd, union mysockaddr *addr, char *intname, uint32_t mark, int is_tcp)
746 {
747 union mysockaddr addr_copy = *addr;
748
749 /* cannot set source _port_ for TCP connections. */
750 if (is_tcp)
751 {
752 if (addr_copy.sa.sa_family == AF_INET)
753 addr_copy.in.sin_port = 0;
754 #ifdef HAVE_IPV6
755 else
756 addr_copy.in6.sin6_port = 0;
757 #endif
758 }
759
760 if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
761 return 0;
762
763 #if defined(SO_BINDTODEVICE)
764 if (intname[0] != 0 &&
765 setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, strlen(intname)) == -1)
766 return 0;
767 #endif
768
769 if (mark != 0 && setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1)
770 return 0;
771
772 return 1;
773 }
774
allocate_sfd(union mysockaddr * addr,char * intname,uint32_t mark)775 static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname, uint32_t mark)
776 {
777 struct serverfd *sfd;
778 int errsave;
779
780 /* when using random ports, servers which would otherwise use
781 the INADDR_ANY/port0 socket have sfd set to NULL */
782 if (!daemon->osport && intname[0] == 0)
783 {
784 errno = 0;
785
786 if (addr->sa.sa_family == AF_INET &&
787 addr->in.sin_addr.s_addr == INADDR_ANY &&
788 addr->in.sin_port == htons(0))
789 return NULL;
790
791 #ifdef HAVE_IPV6
792 if (addr->sa.sa_family == AF_INET6 &&
793 memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
794 addr->in6.sin6_port == htons(0))
795 return NULL;
796 #endif
797 }
798
799 /* may have a suitable one already */
800 for (sfd = daemon->sfds; sfd; sfd = sfd->next )
801 if (sockaddr_isequal(&sfd->source_addr, addr) &&
802 mark == sfd->mark &&
803 strcmp(intname, sfd->interface) == 0)
804 return sfd;
805
806 /* need to make a new one. */
807 errno = ENOMEM; /* in case malloc fails. */
808 if (!(sfd = whine_malloc(sizeof(struct serverfd))))
809 return NULL;
810
811 if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
812 {
813 free(sfd);
814 return NULL;
815 }
816
817 if (!local_bind(sfd->fd, addr, intname, mark, 0) || !fix_fd(sfd->fd))
818 {
819 errsave = errno; /* save error from bind. */
820 close(sfd->fd);
821 free(sfd);
822 errno = errsave;
823 return NULL;
824 }
825
826 strcpy(sfd->interface, intname);
827 sfd->source_addr = *addr;
828 sfd->mark = mark;
829 sfd->next = daemon->sfds;
830 daemon->sfds = sfd;
831 return sfd;
832 }
833
834 /* create upstream sockets during startup, before root is dropped which may be needed
835 this allows query_port to be a low port and interface binding */
pre_allocate_sfds(void)836 void pre_allocate_sfds(void)
837 {
838 struct server *srv;
839
840 if (daemon->query_port != 0)
841 {
842 union mysockaddr addr;
843 memset(&addr, 0, sizeof(addr));
844 addr.in.sin_family = AF_INET;
845 addr.in.sin_addr.s_addr = INADDR_ANY;
846 addr.in.sin_port = htons(daemon->query_port);
847 #ifdef HAVE_SOCKADDR_SA_LEN
848 addr.in.sin_len = sizeof(struct sockaddr_in);
849 #endif
850 allocate_sfd(&addr, "", 0);
851 #ifdef HAVE_IPV6
852 memset(&addr, 0, sizeof(addr));
853 addr.in6.sin6_family = AF_INET6;
854 addr.in6.sin6_addr = in6addr_any;
855 addr.in6.sin6_port = htons(daemon->query_port);
856 #ifdef HAVE_SOCKADDR_SA_LEN
857 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
858 #endif
859 allocate_sfd(&addr, "", 0);
860 #endif
861 }
862
863 for (srv = daemon->servers; srv; srv = srv->next)
864 if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
865 !allocate_sfd(&srv->source_addr, srv->interface, srv->mark) &&
866 errno != 0 &&
867 (daemon->options & OPT_NOWILD))
868 {
869 prettyprint_addr(&srv->addr, daemon->namebuff);
870 if (srv->interface[0] != 0)
871 {
872 strcat(daemon->namebuff, " ");
873 strcat(daemon->namebuff, srv->interface);
874 }
875 die(_("failed to bind server socket for %s: %s"),
876 daemon->namebuff, EC_BADNET);
877 }
878 }
879
880
check_servers(void)881 void check_servers(void)
882 {
883 struct irec *iface;
884 struct server *new, *tmp, *ret = NULL;
885 int port = 0;
886
887 for (new = daemon->servers; new; new = tmp)
888 {
889 tmp = new->next;
890
891 if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)))
892 {
893 port = prettyprint_addr(&new->addr, daemon->namebuff);
894
895 /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
896 if (new->addr.sa.sa_family == AF_INET &&
897 new->addr.in.sin_addr.s_addr == 0)
898 {
899 free(new);
900 continue;
901 }
902
903 for (iface = daemon->interfaces; iface; iface = iface->next)
904 if (sockaddr_isequal(&new->addr, &iface->addr))
905 break;
906 if (iface)
907 {
908 my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
909 free(new);
910 continue;
911 }
912
913 /* Do we need a socket set? */
914 if (!new->sfd &&
915 !(new->sfd = allocate_sfd(&new->source_addr, new->interface, new->mark)) &&
916 errno != 0)
917 {
918 my_syslog(LOG_WARNING,
919 _("ignoring nameserver %s - cannot make/bind socket: %s"),
920 daemon->namebuff, strerror(errno));
921 free(new);
922 continue;
923 }
924 }
925
926 /* reverse order - gets it right. */
927 new->next = ret;
928 ret = new;
929
930 if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS))
931 {
932 char *s1, *s2;
933 if (!(new->flags & SERV_HAS_DOMAIN))
934 s1 = _("unqualified"), s2 = _("names");
935 else if (strlen(new->domain) == 0)
936 s1 = _("default"), s2 = "";
937 else
938 s1 = _("domain"), s2 = new->domain;
939
940 if (new->flags & SERV_NO_ADDR)
941 my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
942 else if (!(new->flags & SERV_LITERAL_ADDRESS))
943 my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
944 }
945 else if (new->interface[0] != 0)
946 my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface);
947 else
948 my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
949 }
950
951 daemon->servers = ret;
952 }
953
954 #if defined(__ANDROID__) && !defined(__BRILLO__)
955 /* #define __ANDROID_DEBUG__ 1 */
956 /*
957 * Ingests a new list of interfaces and starts to listen on them, adding only the new
958 * and stopping to listen to any interfaces not on the new list.
959 *
960 * interfaces - input in the format "bt-pan|eth0|wlan0|..>" up to 1024 bytes long
961 */
set_interfaces(const char * interfaces)962 void set_interfaces(const char *interfaces)
963 {
964 struct iname *if_tmp;
965 struct iname *prev_if_names;
966 struct irec *old_iface, *new_iface, *prev_interfaces;
967 char s[1024];
968 char *next = s;
969 char *interface;
970 int was_wild = 0;
971
972 #ifdef __ANDROID_DEBUG__
973 my_syslog(LOG_DEBUG, _("set_interfaces(%s)"), interfaces);
974 #endif
975 prev_if_names = daemon->if_names;
976 daemon->if_names = NULL;
977
978 prev_interfaces = daemon->interfaces;
979 daemon->interfaces = NULL;
980
981 if (strlen(interfaces) > sizeof(s)) {
982 die(_("interface string too long: %s"), NULL, EC_BADNET);
983 }
984 strncpy(s, interfaces, sizeof(s));
985 while((interface = strsep(&next, SEPARATOR))) {
986 if (!if_nametoindex(interface)) {
987 my_syslog(LOG_ERR,
988 _("interface given in %s: '%s' has no ifindex; ignoring"),
989 __FUNCTION__, interface);
990 continue;
991 }
992 if_tmp = safe_malloc(sizeof(struct iname));
993 memset(if_tmp, 0, sizeof(struct iname));
994 if ((if_tmp->name = strdup(interface)) == NULL) {
995 die(_("malloc failure in set_interfaces: %s"), NULL, EC_BADNET);
996 }
997 if_tmp->next = daemon->if_names;
998 daemon->if_names = if_tmp;
999 }
1000
1001 /*
1002 * Enumerate IP addresses (via RTM_GETADDR), adding IP entries to
1003 * daemon->interfaces for interface names listed in daemon->if_names.
1004 * The sockets are created by the create_bound_listener call below.
1005 */
1006 if (!enumerate_interfaces()) {
1007 die(_("enumerate interfaces error in set_interfaces: %s"), NULL, EC_BADNET);
1008 }
1009
1010 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next) {
1011 if (if_tmp->name && !if_tmp->used) {
1012 my_syslog(LOG_ERR, _("unknown interface given %s in set_interfaces()"), if_tmp->name);
1013 }
1014 }
1015
1016 /* success! - setup to free the old */
1017 /* check for any that have been removed */
1018 for (old_iface = prev_interfaces; old_iface; old_iface=old_iface->next) {
1019 int found = 0;
1020 for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
1021 if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
1022 found = 1;
1023 break;
1024 }
1025 }
1026
1027 if (found) {
1028 fixup_possible_existing_listener(new_iface);
1029 } else {
1030 #ifdef __ANDROID_DEBUG__
1031 char debug_buff[MAXDNAME];
1032 prettyprint_addr(&old_iface->addr, debug_buff);
1033 my_syslog(LOG_DEBUG, _("closing listener for %s"), debug_buff);
1034 #endif
1035
1036 close_bound_listener(old_iface);
1037 }
1038 }
1039
1040 /* remove wildchar listeners */
1041 was_wild = close_bound_listener(NULL);
1042 if (was_wild) daemon->options |= OPT_NOWILD;
1043
1044 /* check for any that have been added */
1045 for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
1046 int found = 0;
1047
1048 /* if the previous setup used a wildchar, then add any current interfaces */
1049 if (!was_wild) {
1050 for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
1051 if(sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
1052 found = -1;
1053 break;
1054 }
1055 }
1056 }
1057 if (!found) {
1058 #ifdef __ANDROID_DEBUG__
1059 char debug_buff[MAXDNAME];
1060 prettyprint_addr(&new_iface->addr, debug_buff);
1061 my_syslog(LOG_DEBUG, _("adding listener for %s"), debug_buff);
1062 #endif
1063 create_bound_listener(&(daemon->listeners), new_iface);
1064 }
1065 }
1066
1067 while (prev_if_names) {
1068 if (prev_if_names->name) free(prev_if_names->name);
1069 if_tmp = prev_if_names->next;
1070 free(prev_if_names);
1071 prev_if_names = if_tmp;
1072 }
1073 while (prev_interfaces) {
1074 struct irec *tmp_irec = prev_interfaces->next;
1075 free(prev_interfaces);
1076 prev_interfaces = tmp_irec;
1077 }
1078 #ifdef __ANDROID_DEBUG__
1079 my_syslog(LOG_DEBUG, _("done with setInterfaces"));
1080 #endif
1081 }
1082
1083 /*
1084 * Takes a string in the format "0x100b|1.2.3.4|1.2.3.4|..." - up to 1024 bytes in length
1085 * - The first element is the socket mark to set on sockets that forward DNS queries.
1086 * - The subsequent elements are the DNS servers to forward queries to.
1087 */
set_servers(const char * servers)1088 int set_servers(const char *servers)
1089 {
1090 char s[1024];
1091 struct server *old_servers = NULL;
1092 struct server *new_servers = NULL;
1093 struct server *serv;
1094 char *mark_string;
1095 uint32_t mark;
1096
1097 strncpy(s, servers, sizeof(s));
1098
1099 /* move old servers to free list - we can reuse the memory
1100 and not risk malloc if there are the same or fewer new servers.
1101 Servers which were specced on the command line go to the new list. */
1102 for (serv = daemon->servers; serv;)
1103 {
1104 struct server *tmp = serv->next;
1105 if (serv->flags & SERV_FROM_RESOLV)
1106 {
1107 serv->next = old_servers;
1108 old_servers = serv;
1109 /* forward table rules reference servers, so have to blow them away */
1110 server_gone(serv);
1111 }
1112 else
1113 {
1114 serv->next = new_servers;
1115 new_servers = serv;
1116 }
1117 serv = tmp;
1118 }
1119
1120 char *next = s;
1121 char *saddr;
1122
1123 /* Parse the mark. */
1124 mark_string = strsep(&next, SEPARATOR);
1125 mark = strtoul(mark_string, NULL, 0);
1126
1127 while ((saddr = strsep(&next, SEPARATOR))) {
1128 union mysockaddr addr, source_addr;
1129 memset(&addr, 0, sizeof(addr));
1130 memset(&source_addr, 0, sizeof(source_addr));
1131
1132 if (parse_addr(AF_INET, saddr, &addr) == 0)
1133 {
1134 addr.in.sin_port = htons(NAMESERVER_PORT);
1135 source_addr.in.sin_family = AF_INET;
1136 source_addr.in.sin_addr.s_addr = INADDR_ANY;
1137 source_addr.in.sin_port = htons(daemon->query_port);
1138 }
1139 #ifdef HAVE_IPV6
1140 else if (parse_addr(AF_INET6, saddr, &addr) == 0)
1141 {
1142 addr.in6.sin6_port = htons(NAMESERVER_PORT);
1143 source_addr.in6.sin6_family = AF_INET6;
1144 source_addr.in6.sin6_addr = in6addr_any;
1145 source_addr.in6.sin6_port = htons(daemon->query_port);
1146 }
1147 #endif /* IPV6 */
1148 else
1149 continue;
1150
1151 if (old_servers)
1152 {
1153 serv = old_servers;
1154 old_servers = old_servers->next;
1155 }
1156 else if (!(serv = whine_malloc(sizeof (struct server))))
1157 continue;
1158
1159 /* this list is reverse ordered:
1160 it gets reversed again in check_servers */
1161 serv->next = new_servers;
1162 new_servers = serv;
1163 serv->addr = addr;
1164 serv->source_addr = source_addr;
1165 serv->domain = NULL;
1166 serv->interface[0] = 0;
1167 serv->mark = mark;
1168 serv->sfd = NULL;
1169 serv->flags = SERV_FROM_RESOLV;
1170 serv->queries = serv->failed_queries = 0;
1171 }
1172
1173 /* Free any memory not used. */
1174 while (old_servers)
1175 {
1176 struct server *tmp = old_servers->next;
1177 free(old_servers);
1178 old_servers = tmp;
1179 }
1180
1181 daemon->servers = new_servers;
1182 return 0;
1183 }
1184 #endif
1185
1186 /* Return zero if no servers found, in that case we keep polling.
1187 This is a protection against an update-time/write race on resolv.conf */
reload_servers(char * fname)1188 int reload_servers(char *fname)
1189 {
1190 FILE *f;
1191 char *line;
1192 struct server *old_servers = NULL;
1193 struct server *new_servers = NULL;
1194 struct server *serv;
1195 int gotone = 0;
1196
1197 /* buff happens to be MAXDNAME long... */
1198 if (!(f = fopen(fname, "r")))
1199 {
1200 my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
1201 return 0;
1202 }
1203
1204 /* move old servers to free list - we can reuse the memory
1205 and not risk malloc if there are the same or fewer new servers.
1206 Servers which were specced on the command line go to the new list. */
1207 for (serv = daemon->servers; serv;)
1208 {
1209 struct server *tmp = serv->next;
1210 if (serv->flags & SERV_FROM_RESOLV)
1211 {
1212 serv->next = old_servers;
1213 old_servers = serv;
1214 /* forward table rules reference servers, so have to blow them away */
1215 server_gone(serv);
1216 }
1217 else
1218 {
1219 serv->next = new_servers;
1220 new_servers = serv;
1221 }
1222 serv = tmp;
1223 }
1224
1225 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
1226 {
1227 union mysockaddr addr, source_addr;
1228 char *token = strtok(line, " \t\n\r");
1229
1230 if (!token)
1231 continue;
1232 if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
1233 continue;
1234 if (!(token = strtok(NULL, " \t\n\r")))
1235 continue;
1236
1237 memset(&addr, 0, sizeof(addr));
1238 memset(&source_addr, 0, sizeof(source_addr));
1239
1240 if (parse_addr(AF_INET, token, &addr) == 0)
1241 {
1242 addr.in.sin_port = htons(NAMESERVER_PORT);
1243 source_addr.in.sin_family = AF_INET;
1244 source_addr.in.sin_addr.s_addr = INADDR_ANY;
1245 source_addr.in.sin_port = htons(daemon->query_port);
1246 }
1247 #ifdef HAVE_IPV6
1248 else if (parse_addr(AF_INET6, token, &addr) == 0)
1249 {
1250 addr.in6.sin6_port = htons(NAMESERVER_PORT);
1251 source_addr.in6.sin6_family = AF_INET6;
1252 source_addr.in6.sin6_addr = in6addr_any;
1253 source_addr.in6.sin6_port = htons(daemon->query_port);
1254 }
1255 #endif /* IPV6 */
1256 else
1257 continue;
1258
1259 if (old_servers)
1260 {
1261 serv = old_servers;
1262 old_servers = old_servers->next;
1263 }
1264 else if (!(serv = whine_malloc(sizeof (struct server))))
1265 continue;
1266
1267 /* this list is reverse ordered:
1268 it gets reversed again in check_servers */
1269 serv->next = new_servers;
1270 new_servers = serv;
1271 serv->addr = addr;
1272 serv->source_addr = source_addr;
1273 serv->domain = NULL;
1274 serv->interface[0] = 0;
1275 serv->mark = 0;
1276 serv->sfd = NULL;
1277 serv->flags = SERV_FROM_RESOLV;
1278 serv->queries = serv->failed_queries = 0;
1279 gotone = 1;
1280 }
1281
1282 /* Free any memory not used. */
1283 while (old_servers)
1284 {
1285 struct server *tmp = old_servers->next;
1286 free(old_servers);
1287 old_servers = tmp;
1288 }
1289
1290 daemon->servers = new_servers;
1291 fclose(f);
1292
1293 return gotone;
1294 }
1295
1296
1297 /* Use an IPv4 listener socket for ioctling */
get_ifaddr(char * intr)1298 struct in_addr get_ifaddr(char *intr)
1299 {
1300 struct listener *l;
1301 struct ifreq ifr;
1302
1303 for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
1304
1305 strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
1306 ifr.ifr_addr.sa_family = AF_INET;
1307
1308 if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
1309 ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
1310
1311 return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
1312 }
1313