]> git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/network.c
import of dnsmasq-2.42.tar.gz
[people/ms/dnsmasq.git] / src / network.c
1 /* dnsmasq is Copyright (c) 2000-2007 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 int iface_check(int family, struct all_addr *addr,
20 struct ifreq *ifr, int *indexp)
21 {
22 struct iname *tmp;
23 int ret = 1;
24
25 /* Note: have to check all and not bail out early, so that we set the
26 "used" flags. */
27
28 if (indexp)
29 {
30 #ifdef HAVE_BSD_BRIDGE
31 /* One form of bridging on BSD has the property that packets
32 can be recieved on bridge interfaces which do not have an IP address.
33 We allow these to be treated as aliases of another interface which does have
34 an IP address with --dhcp-bridge=interface,alias,alias */
35 struct dhcp_bridge *bridge, *alias;
36 for (bridge = daemon->bridges; bridge; bridge = bridge->next)
37 {
38 for (alias = bridge->alias; alias; alias = alias->next)
39 if (strncmp(ifr->ifr_name, alias->iface, IF_NAMESIZE) == 0)
40 {
41 int newindex;
42
43 if (!(newindex = if_nametoindex(bridge->iface)))
44 {
45 my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), ifr->ifr_name);
46 return 0;
47 }
48 else
49 {
50 *indexp = newindex;
51 strncpy(ifr->ifr_name, bridge->iface, IF_NAMESIZE);
52 break;
53 }
54 }
55 if (alias)
56 break;
57 }
58 #endif
59 }
60
61 if (daemon->if_names || (addr && daemon->if_addrs))
62 {
63 ret = 0;
64
65 for (tmp = daemon->if_names; tmp; tmp = tmp->next)
66 if (tmp->name && (strcmp(tmp->name, ifr->ifr_name) == 0))
67 ret = tmp->used = 1;
68
69 for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
70 if (addr && tmp->addr.sa.sa_family == family)
71 {
72 if (family == AF_INET &&
73 tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
74 ret = tmp->used = 1;
75 #ifdef HAVE_IPV6
76 else if (family == AF_INET6 &&
77 IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr,
78 &addr->addr.addr6))
79 ret = tmp->used = 1;
80 #endif
81 }
82 }
83
84 for (tmp = daemon->if_except; tmp; tmp = tmp->next)
85 if (tmp->name && (strcmp(tmp->name, ifr->ifr_name) == 0))
86 ret = 0;
87
88 return ret;
89 }
90
91 static int iface_allowed(struct irec **irecp, int if_index,
92 union mysockaddr *addr, struct in_addr netmask)
93 {
94 struct irec *iface;
95 int fd;
96 struct ifreq ifr;
97 int dhcp_ok = 1;
98 struct iname *tmp;
99
100 /* check whether the interface IP has been added already
101 we call this routine multiple times. */
102 for (iface = *irecp; iface; iface = iface->next)
103 if (sockaddr_isequal(&iface->addr, addr))
104 return 1;
105
106 #ifdef HAVE_LINUX_NETWORK
107 ifr.ifr_ifindex = if_index;
108 #endif
109
110 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 ||
111 #ifdef HAVE_LINUX_NETWORK
112 ioctl(fd, SIOCGIFNAME, &ifr) == -1 ||
113 #else
114 !if_indextoname(if_index, ifr.ifr_name) ||
115 #endif
116 ioctl(fd, SIOCGIFFLAGS, &ifr) == -1)
117 {
118 if (fd != -1)
119 {
120 int errsave = errno;
121 close(fd);
122 errno = errsave;
123 }
124 return 0;
125 }
126
127 close(fd);
128
129 /* If we are restricting the set of interfaces to use, make
130 sure that loopback interfaces are in that set. */
131 if (daemon->if_names && (ifr.ifr_flags & IFF_LOOPBACK))
132 {
133 struct iname *lo;
134 for (lo = daemon->if_names; lo; lo = lo->next)
135 if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
136 {
137 lo->isloop = 1;
138 break;
139 }
140
141 if (!lo &&
142 (lo = whine_malloc(sizeof(struct iname))) &&
143 (lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
144 {
145 strcpy(lo->name, ifr.ifr_name);
146 lo->isloop = lo->used = 1;
147 lo->next = daemon->if_names;
148 daemon->if_names = lo;
149 }
150 }
151
152 if (addr->sa.sa_family == AF_INET &&
153 !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, &ifr, NULL))
154 return 1;
155
156 for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
157 if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
158 dhcp_ok = 0;
159
160 #ifdef HAVE_IPV6
161 if (addr->sa.sa_family == AF_INET6 &&
162 !iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, &ifr, NULL))
163 return 1;
164 #endif
165
166 /* add to list */
167 if ((iface = whine_malloc(sizeof(struct irec))))
168 {
169 iface->addr = *addr;
170 iface->netmask = netmask;
171 iface->dhcp_ok = dhcp_ok;
172 iface->next = *irecp;
173 *irecp = iface;
174 return 1;
175 }
176
177 errno = ENOMEM;
178 return 0;
179 }
180
181 #ifdef HAVE_IPV6
182 static int iface_allowed_v6(struct in6_addr *local,
183 int scope, int if_index, void *vparam)
184 {
185 union mysockaddr addr;
186 struct in_addr netmask; /* dummy */
187
188 netmask.s_addr = 0;
189
190 memset(&addr, 0, sizeof(addr));
191 #ifdef HAVE_SOCKADDR_SA_LEN
192 addr.in6.sin6_len = sizeof(addr.in6);
193 #endif
194 addr.in6.sin6_family = AF_INET6;
195 addr.in6.sin6_addr = *local;
196 addr.in6.sin6_port = htons(daemon->port);
197 addr.in6.sin6_scope_id = scope;
198
199 return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
200 }
201 #endif
202
203 static int iface_allowed_v4(struct in_addr local, int if_index,
204 struct in_addr netmask, struct in_addr broadcast, void *vparam)
205 {
206 union mysockaddr addr;
207
208 memset(&addr, 0, sizeof(addr));
209 #ifdef HAVE_SOCKADDR_SA_LEN
210 addr.in.sin_len = sizeof(addr.in);
211 #endif
212 addr.in.sin_family = AF_INET;
213 addr.in.sin_addr = broadcast; /* warning */
214 addr.in.sin_addr = local;
215 addr.in.sin_port = htons(daemon->port);
216
217 return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
218 }
219
220
221 int enumerate_interfaces(void)
222 {
223 #ifdef HAVE_IPV6
224 return iface_enumerate(&daemon->interfaces, iface_allowed_v4, iface_allowed_v6);
225 #else
226 return iface_enumerate(&daemon->interfaces, iface_allowed_v4, NULL);
227 #endif
228 }
229
230 /* set NONBLOCK bit on fd: See Stevens 16.6 */
231 int fix_fd(int fd)
232 {
233 int flags;
234
235 if ((flags = fcntl(fd, F_GETFL)) == -1 ||
236 fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
237 return 0;
238
239 return 1;
240 }
241
242 #if defined(HAVE_IPV6)
243 static int create_ipv6_listener(struct listener **link, int port)
244 {
245 union mysockaddr addr;
246 int tcpfd, fd;
247 struct listener *l;
248 int opt = 1;
249
250 memset(&addr, 0, sizeof(addr));
251 addr.in6.sin6_family = AF_INET6;
252 addr.in6.sin6_addr = in6addr_any;
253 addr.in6.sin6_port = htons(port);
254 #ifdef HAVE_SOCKADDR_SA_LEN
255 addr.in6.sin6_len = sizeof(addr.in6);
256 #endif
257
258 /* No error of the kernel doesn't support IPv6 */
259 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
260 return (errno == EPROTONOSUPPORT ||
261 errno == EAFNOSUPPORT ||
262 errno == EINVAL);
263
264 if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
265 return 0;
266
267 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
268 setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
269 setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
270 setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
271 !fix_fd(fd) ||
272 !fix_fd(tcpfd) ||
273 #ifdef IPV6_RECVPKTINFO
274 setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
275 #else
276 setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
277 #endif
278 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
279 listen(tcpfd, 5) == -1 ||
280 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
281 return 0;
282
283 l = safe_malloc(sizeof(struct listener));
284 l->fd = fd;
285 l->tcpfd = tcpfd;
286 l->tftpfd = -1;
287 l->family = AF_INET6;
288 l->next = NULL;
289 *link = l;
290
291 return 1;
292 }
293 #endif
294
295 struct listener *create_wildcard_listeners(void)
296 {
297 union mysockaddr addr;
298 int opt = 1;
299 struct listener *l, *l6 = NULL;
300 int tcpfd = -1, fd = -1, tftpfd = -1;
301
302 memset(&addr, 0, sizeof(addr));
303 addr.in.sin_family = AF_INET;
304 addr.in.sin_addr.s_addr = INADDR_ANY;
305 addr.in.sin_port = htons(daemon->port);
306 #ifdef HAVE_SOCKADDR_SA_LEN
307 addr.in.sin_len = sizeof(struct sockaddr_in);
308 #endif
309
310 if (daemon->port != 0)
311 {
312
313 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
314 (tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
315 return NULL;
316
317 if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
318 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
319 listen(tcpfd, 5) == -1 ||
320 !fix_fd(tcpfd) ||
321 #ifdef HAVE_IPV6
322 !create_ipv6_listener(&l6, daemon->port) ||
323 #endif
324 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
325 !fix_fd(fd) ||
326 #if defined(HAVE_LINUX_NETWORK)
327 setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
328 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
329 setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
330 setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
331 #endif
332 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
333 return NULL;
334 }
335
336 #ifdef HAVE_TFTP
337 if (daemon->options & OPT_TFTP)
338 {
339 addr.in.sin_port = htons(TFTP_PORT);
340 if ((tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
341 return NULL;
342
343 if (!fix_fd(tftpfd) ||
344 #if defined(HAVE_LINUX_NETWORK)
345 setsockopt(tftpfd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
346 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
347 setsockopt(tftpfd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
348 setsockopt(tftpfd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
349 #endif
350 bind(tftpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
351 return NULL;
352 }
353 #endif
354
355 l = safe_malloc(sizeof(struct listener));
356 l->family = AF_INET;
357 l->fd = fd;
358 l->tcpfd = tcpfd;
359 l->tftpfd = tftpfd;
360 l->next = l6;
361
362 return l;
363 }
364
365 struct listener *create_bound_listeners(void)
366 {
367 struct listener *listeners = NULL;
368 struct irec *iface;
369 int opt = 1;
370
371 for (iface = daemon->interfaces; iface; iface = iface->next)
372 {
373 struct listener *new = safe_malloc(sizeof(struct listener));
374 new->family = iface->addr.sa.sa_family;
375 new->iface = iface;
376 new->next = listeners;
377 new->tftpfd = -1;
378 new->tcpfd = -1;
379 new->fd = -1;
380
381 if (daemon->port != 0)
382 {
383 if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
384 (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
385 setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
386 setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
387 !fix_fd(new->tcpfd) ||
388 !fix_fd(new->fd))
389 die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
390
391 #ifdef HAVE_IPV6
392 if (iface->addr.sa.sa_family == AF_INET6)
393 {
394 if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
395 setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
396 die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
397 }
398 #endif
399
400 if (bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1 ||
401 bind(new->fd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
402 {
403 #ifdef HAVE_IPV6
404 if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL))
405 {
406 close(new->tcpfd);
407 close(new->fd);
408 free(new);
409 new = NULL;
410 }
411 else
412 #endif
413 {
414 prettyprint_addr(&iface->addr, daemon->namebuff);
415 die(_("failed to bind listening socket for %s: %s"),
416 daemon->namebuff, EC_BADNET);
417 }
418 }
419 else if (listen(new->tcpfd, 5) == -1)
420 die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
421 }
422
423 #ifdef HAVE_TFTP
424 if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
425 {
426 short save = iface->addr.in.sin_port;
427 iface->addr.in.sin_port = htons(TFTP_PORT);
428 if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
429 setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
430 !fix_fd(new->tftpfd) ||
431 bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
432 die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
433 iface->addr.in.sin_port = save;
434 }
435 #endif
436
437 if (new)
438 listeners = new;
439 }
440
441 return listeners;
442 }
443
444 int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
445 {
446 union mysockaddr addr_copy = *addr;
447
448 /* cannot set source _port_ for TCP connections. */
449 if (is_tcp)
450 {
451 if (addr_copy.sa.sa_family == AF_INET)
452 addr_copy.in.sin_port = 0;
453 #ifdef HAVE_IPV6
454 else
455 addr_copy.in6.sin6_port = 0;
456 #endif
457 }
458
459 if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
460 return 0;
461
462 #if defined(SO_BINDTODEVICE)
463 if (strlen(intname) != 0 &&
464 setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, sizeof(intname)) == -1)
465 return 0;
466 #endif
467
468 return 1;
469 }
470
471 static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
472 {
473 struct serverfd *sfd;
474 int errsave;
475
476 /* may have a suitable one already */
477 for (sfd = daemon->sfds; sfd; sfd = sfd->next )
478 if (sockaddr_isequal(&sfd->source_addr, addr) &&
479 strcmp(intname, sfd->interface) == 0)
480 return sfd;
481
482 /* need to make a new one. */
483 errno = ENOMEM; /* in case malloc fails. */
484 if (!(sfd = whine_malloc(sizeof(struct serverfd))))
485 return NULL;
486
487 if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
488 {
489 free(sfd);
490 return NULL;
491 }
492
493 if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd))
494 {
495 errsave = errno; /* save error from bind. */
496 close(sfd->fd);
497 free(sfd);
498 errno = errsave;
499 return NULL;
500 }
501
502 strcpy(sfd->interface, intname);
503 sfd->source_addr = *addr;
504 sfd->next = daemon->sfds;
505 daemon->sfds = sfd;
506 return sfd;
507 }
508
509 /* create upstream sockets during startup, before root is dropped which may be needed
510 this allows query_port to be a low port and interface binding */
511 void pre_allocate_sfds(void)
512 {
513 struct server *srv;
514
515 if (daemon->query_port != 0)
516 {
517 union mysockaddr addr;
518 memset(&addr, 0, sizeof(addr));
519 addr.in.sin_family = AF_INET;
520 addr.in.sin_addr.s_addr = INADDR_ANY;
521 addr.in.sin_port = htons(daemon->query_port);
522 #ifdef HAVE_SOCKADDR_SA_LEN
523 addr.in.sin_len = sizeof(struct sockaddr_in);
524 #endif
525 allocate_sfd(&addr, "");
526 #ifdef HAVE_IPV6
527 memset(&addr, 0, sizeof(addr));
528 addr.in6.sin6_family = AF_INET6;
529 addr.in6.sin6_addr = in6addr_any;
530 addr.in6.sin6_port = htons(daemon->query_port);
531 #ifdef HAVE_SOCKADDR_SA_LEN
532 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
533 #endif
534 allocate_sfd(&addr, "");
535 #endif
536 }
537
538 for (srv = daemon->servers; srv; srv = srv->next)
539 if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
540 !allocate_sfd(&srv->source_addr, srv->interface) &&
541 (daemon->options & OPT_NOWILD))
542 {
543 prettyprint_addr(&srv->addr, daemon->namebuff);
544 if (strlen(srv->interface) != 0)
545 {
546 strcat(daemon->namebuff, " ");
547 strcat(daemon->namebuff, srv->interface);
548 }
549 die(_("failed to bind server socket for %s: %s"),
550 daemon->namebuff, EC_BADNET);
551 }
552 }
553
554
555 void check_servers(void)
556 {
557 struct irec *iface;
558 struct server *new, *tmp, *ret = NULL;
559 int port = 0;
560
561 for (new = daemon->servers; new; new = tmp)
562 {
563 tmp = new->next;
564
565 if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)))
566 {
567 port = prettyprint_addr(&new->addr, daemon->namebuff);
568
569 /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
570 if (new->addr.sa.sa_family == AF_INET &&
571 new->addr.in.sin_addr.s_addr == 0)
572 {
573 free(new);
574 continue;
575 }
576
577 for (iface = daemon->interfaces; iface; iface = iface->next)
578 if (sockaddr_isequal(&new->addr, &iface->addr))
579 break;
580 if (iface)
581 {
582 my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
583 free(new);
584 continue;
585 }
586
587 /* Do we need a socket set? */
588 if (!new->sfd && !(new->sfd = allocate_sfd(&new->source_addr, new->interface)))
589 {
590 my_syslog(LOG_WARNING,
591 _("ignoring nameserver %s - cannot make/bind socket: %s"),
592 daemon->namebuff, strerror(errno));
593 free(new);
594 continue;
595 }
596 }
597
598 /* reverse order - gets it right. */
599 new->next = ret;
600 ret = new;
601
602 if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS))
603 {
604 char *s1, *s2;
605 if (!(new->flags & SERV_HAS_DOMAIN))
606 s1 = _("unqualified"), s2 = _("names");
607 else if (strlen(new->domain) == 0)
608 s1 = _("default"), s2 = "";
609 else
610 s1 = _("domain"), s2 = new->domain;
611
612 if (new->flags & SERV_NO_ADDR)
613 my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
614 else if (!(new->flags & SERV_LITERAL_ADDRESS))
615 my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
616 }
617 else if (strlen(new->interface) != 0)
618 my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface);
619 else
620 my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
621 }
622
623 daemon->servers = ret;
624 }
625
626 /* Return zero if no servers found, in that case we keep polling.
627 This is a protection against an update-time/write race on resolv.conf */
628 int reload_servers(char *fname)
629 {
630 FILE *f;
631 char *line;
632 struct server *old_servers = NULL;
633 struct server *new_servers = NULL;
634 struct server *serv;
635 int gotone = 0;
636
637 /* buff happens to be MAXDNAME long... */
638 if (!(f = fopen(fname, "r")))
639 {
640 my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
641 return 0;
642 }
643
644 /* move old servers to free list - we can reuse the memory
645 and not risk malloc if there are the same or fewer new servers.
646 Servers which were specced on the command line go to the new list. */
647 for (serv = daemon->servers; serv;)
648 {
649 struct server *tmp = serv->next;
650 if (serv->flags & SERV_FROM_RESOLV)
651 {
652 serv->next = old_servers;
653 old_servers = serv;
654 /* forward table rules reference servers, so have to blow them away */
655 server_gone(serv);
656 }
657 else
658 {
659 serv->next = new_servers;
660 new_servers = serv;
661 }
662 serv = tmp;
663 }
664
665 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
666 {
667 union mysockaddr addr, source_addr;
668 char *token = strtok(line, " \t\n\r");
669
670 if (!token)
671 continue;
672 if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
673 continue;
674 if (!(token = strtok(NULL, " \t\n\r")))
675 continue;
676
677 memset(&addr, 0, sizeof(addr));
678 memset(&source_addr, 0, sizeof(source_addr));
679
680 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
681 {
682 #ifdef HAVE_SOCKADDR_SA_LEN
683 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
684 #endif
685 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
686 addr.in.sin_port = htons(NAMESERVER_PORT);
687 source_addr.in.sin_addr.s_addr = INADDR_ANY;
688 source_addr.in.sin_port = htons(daemon->query_port);
689 }
690 #ifdef HAVE_IPV6
691 else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
692 {
693 #ifdef HAVE_SOCKADDR_SA_LEN
694 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
695 #endif
696 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
697 addr.in6.sin6_port = htons(NAMESERVER_PORT);
698 source_addr.in6.sin6_addr = in6addr_any;
699 source_addr.in6.sin6_port = htons(daemon->query_port);
700 }
701 #endif /* IPV6 */
702 else
703 continue;
704
705 if (old_servers)
706 {
707 serv = old_servers;
708 old_servers = old_servers->next;
709 }
710 else if (!(serv = whine_malloc(sizeof (struct server))))
711 continue;
712
713 /* this list is reverse ordered:
714 it gets reversed again in check_servers */
715 serv->next = new_servers;
716 new_servers = serv;
717 serv->addr = addr;
718 serv->source_addr = source_addr;
719 serv->domain = NULL;
720 serv->interface[0] = 0;
721 serv->sfd = NULL;
722 serv->flags = SERV_FROM_RESOLV;
723 serv->queries = serv->failed_queries = 0;
724 gotone = 1;
725 }
726
727 /* Free any memory not used. */
728 while (old_servers)
729 {
730 struct server *tmp = old_servers->next;
731 free(old_servers);
732 old_servers = tmp;
733 }
734
735 daemon->servers = new_servers;
736 fclose(f);
737
738 return gotone;
739 }
740
741
742 /* Use an IPv4 listener socket for ioctling */
743 struct in_addr get_ifaddr(char *intr)
744 {
745 struct listener *l;
746 struct ifreq ifr;
747
748 for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
749
750 strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
751 ifr.ifr_addr.sa_family = AF_INET;
752
753 if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
754 ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
755
756 return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
757 }
758
759
760