]> git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/network.c
import of dnsmasq-2.28.tar.gz
[people/ms/dnsmasq.git] / src / network.c
1 /* dnsmasq is Copyright (c) 2000 - 2006 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.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11 */
12
13 #include "dnsmasq.h"
14
15 int iface_check(struct daemon *daemon, int family, struct all_addr *addr, char *name)
16 {
17 struct iname *tmp;
18
19 for (tmp = daemon->if_except; tmp; tmp = tmp->next)
20 if (tmp->name && (strcmp(tmp->name, name) == 0))
21 return 0;
22
23 if (daemon->if_names || daemon->if_addrs)
24 {
25 for (tmp = daemon->if_names; tmp; tmp = tmp->next)
26 if (tmp->name && (strcmp(tmp->name, name) == 0))
27 {
28 tmp->used = 1;
29 return 1;
30 }
31
32 for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
33 if (tmp->addr.sa.sa_family == family)
34 {
35 if (family == AF_INET &&
36 tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
37 {
38 tmp->used = 1;
39 return 1;
40 }
41 #ifdef HAVE_IPV6
42 else if (family == AF_INET6 &&
43 IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr,
44 &addr->addr.addr6))
45 {
46 tmp->used = 1;
47 return 1;
48 }
49 #endif
50 }
51 return 0;
52 }
53
54 return 1;
55 }
56
57 static int iface_allowed(struct daemon *daemon, struct irec **irecp, int if_index,
58 union mysockaddr *addr, struct in_addr netmask)
59 {
60 struct irec *iface;
61 int fd;
62 struct ifreq ifr;
63
64 /* check whether the interface IP has been added already
65 we call this routine multiple times. */
66 for (iface = *irecp; iface; iface = iface->next)
67 if (sockaddr_isequal(&iface->addr, addr))
68 return 1;
69
70 #ifdef HAVE_LINUX_NETWORK
71 ifr.ifr_ifindex = if_index;
72 #endif
73
74 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 ||
75 #ifdef HAVE_LINUX_NETWORK
76 ioctl(fd, SIOCGIFNAME, &ifr) == -1 ||
77 #else
78 !if_indextoname(if_index, ifr.ifr_name) ||
79 #endif
80 ioctl(fd, SIOCGIFFLAGS, &ifr) == -1)
81 {
82 if (fd != -1)
83 {
84 int errsave = errno;
85 close(fd);
86 errno = errsave;
87 }
88 return 0;
89 }
90
91 close(fd);
92
93 /* If we are restricting the set of interfaces to use, make
94 sure that loopback interfaces are in that set. */
95 if (daemon->if_names && (ifr.ifr_flags & IFF_LOOPBACK))
96 {
97 struct iname *lo;
98 for (lo = daemon->if_names; lo; lo = lo->next)
99 if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
100 {
101 lo->isloop = 1;
102 break;
103 }
104
105 if (!lo && (lo = malloc(sizeof(struct iname))))
106 {
107 lo->name = safe_malloc(strlen(ifr.ifr_name)+1);
108 strcpy(lo->name, ifr.ifr_name);
109 lo->isloop = lo->used = 1;
110 lo->next = daemon->if_names;
111 daemon->if_names = lo;
112 }
113 }
114
115 if (addr->sa.sa_family == AF_INET &&
116 !iface_check(daemon, AF_INET, (struct all_addr *)&addr->in.sin_addr, ifr.ifr_name))
117 return 1;
118
119 #ifdef HAVE_IPV6
120 if (addr->sa.sa_family == AF_INET6 &&
121 !iface_check(daemon, AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, ifr.ifr_name))
122 return 1;
123 #endif
124
125 /* add to list */
126 if ((iface = malloc(sizeof(struct irec))))
127 {
128 iface->addr = *addr;
129 iface->netmask = netmask;
130 iface->next = *irecp;
131 *irecp = iface;
132 return 1;
133 }
134
135 errno = ENOMEM;
136 return 0;
137 }
138
139 #ifdef HAVE_IPV6
140 static int iface_allowed_v6(struct daemon *daemon, struct in6_addr *local,
141 int scope, int if_index, void *vparam)
142 {
143 union mysockaddr addr;
144 struct in_addr netmask; /* dummy */
145
146 netmask.s_addr = 0;
147
148 #ifdef HAVE_SOCKADDR_SA_LEN
149 addr.in6.sin6_len = sizeof(addr.in6);
150 #endif
151 addr.in6.sin6_family = AF_INET6;
152 addr.in6.sin6_addr = *local;
153 addr.in6.sin6_port = htons(daemon->port);
154 addr.in6.sin6_scope_id = scope;
155 addr.in6.sin6_flowinfo = 0;
156
157 return iface_allowed(daemon, (struct irec **)vparam, if_index, &addr, netmask);
158 }
159 #endif
160
161 static int iface_allowed_v4(struct daemon *daemon, struct in_addr local, int if_index,
162 struct in_addr netmask, struct in_addr broadcast, void *vparam)
163 {
164 union mysockaddr addr;
165
166 #ifdef HAVE_SOCKADDR_SA_LEN
167 addr.in.sin_len = sizeof(addr.in);
168 #endif
169 addr.in.sin_family = AF_INET;
170 addr.in.sin_addr = broadcast; /* warning */
171 addr.in.sin_addr = local;
172 addr.in.sin_port = htons(daemon->port);
173
174 return iface_allowed(daemon, (struct irec **)vparam, if_index, &addr, netmask);
175 }
176
177
178 int enumerate_interfaces(struct daemon *daemon)
179 {
180 #ifdef HAVE_IPV6
181 return iface_enumerate(daemon, &daemon->interfaces, iface_allowed_v4, iface_allowed_v6);
182 #else
183 return iface_enumerate(daemon, &daemon->interfaces, iface_allowed_v4, NULL);
184 #endif
185 }
186
187 #if defined(HAVE_IPV6) && \
188 (defined(HAVE_LINUX_NETWORK) || \
189 (defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR)))
190 static int create_ipv6_listener(struct listener **link, int port)
191 {
192 union mysockaddr addr;
193 int tcpfd, fd, flags, save;
194 struct listener *l;
195 int opt = 1;
196
197 addr.in6.sin6_family = AF_INET6;
198 addr.in6.sin6_addr = in6addr_any;
199 addr.in6.sin6_port = htons(port);
200 addr.in6.sin6_flowinfo = 0;
201 addr.in6.sin6_scope_id = 0;
202 #ifdef HAVE_SOCKADDR_SA_LEN
203 addr.in6.sin6_len = sizeof(addr.in6);
204 #endif
205
206 /* No error of the kernel doesn't support IPv6 */
207 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
208 return (errno == EPROTONOSUPPORT ||
209 errno == EAFNOSUPPORT ||
210 errno == EINVAL);
211
212 if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
213 {
214 save = errno;
215 close(fd);
216 errno = save;
217 return 0;
218 }
219
220 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
221 setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
222 setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
223 setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
224 (flags = fcntl(fd, F_GETFL, 0)) == -1 ||
225 fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1 ||
226 (flags = fcntl(tcpfd, F_GETFL, 0)) == -1 ||
227 fcntl(tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 ||
228 #ifdef IPV6_RECVPKTINFO
229 setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
230 #else
231 setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
232 #endif
233 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
234 listen(tcpfd, 5) == -1 ||
235 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
236 {
237 save = errno;
238 close(fd);
239 close(tcpfd);
240 errno = save;
241 return 0;
242 }
243
244 l = safe_malloc(sizeof(struct listener));
245 l->fd = fd;
246 l->tcpfd = tcpfd;
247 l->family = AF_INET6;
248 l->next = NULL;
249 *link = l;
250
251 return 1;
252 }
253 #endif
254
255 struct listener *create_wildcard_listeners(int port)
256 {
257 #if !(defined(HAVE_LINUX_NETWORK) || (defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR)))
258 port = 0; /* eliminate warning */
259 return NULL;
260 #else
261 union mysockaddr addr;
262 int opt = 1;
263 struct listener *l, *l6 = NULL;
264 int flags;
265 int tcpfd, fd;
266
267 addr.in.sin_family = AF_INET;
268 addr.in.sin_addr.s_addr = INADDR_ANY;
269 addr.in.sin_port = htons(port);
270 #ifdef HAVE_SOCKADDR_SA_LEN
271 addr.in.sin_len = sizeof(struct sockaddr_in);
272 #endif
273
274 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
275 return NULL;
276
277 if ((tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
278 {
279 close (fd);
280 return NULL;
281 }
282
283 if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
284 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
285 listen(tcpfd, 5) == -1 ||
286 (flags = fcntl(tcpfd, F_GETFL, 0)) == -1 ||
287 fcntl(tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 ||
288 #ifdef HAVE_IPV6
289 !create_ipv6_listener(&l6, port) ||
290 #endif
291 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
292 (flags = fcntl(fd, F_GETFL, 0)) == -1 ||
293 fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1 ||
294 #if defined(HAVE_LINUX_NETWORK)
295 setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
296 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
297 setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
298 setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
299 #endif
300 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
301 {
302 close(fd);
303 close(tcpfd);
304 return NULL;
305 }
306
307 l = safe_malloc(sizeof(struct listener));
308 l->family = AF_INET;
309 l->fd = fd;
310 l->tcpfd = tcpfd;
311 l->next = l6;
312
313 return l;
314
315 #endif
316 }
317
318 struct listener *create_bound_listeners(struct daemon *daemon)
319 {
320
321 struct listener *listeners = NULL;
322 struct irec *iface;
323 int flags, opt = 1;
324
325 for (iface = daemon->interfaces; iface; iface = iface->next)
326 {
327 struct listener *new = safe_malloc(sizeof(struct listener));
328 new->family = iface->addr.sa.sa_family;
329 new->iface = iface;
330 new->next = listeners;
331 if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
332 (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
333 setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
334 setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
335 /* See Stevens 16.6 */
336 (flags = fcntl(new->tcpfd, F_GETFL, 0)) == -1 ||
337 fcntl(new->tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 ||
338 (flags = fcntl(new->fd, F_GETFL, 0)) == -1 ||
339 fcntl(new->fd, F_SETFL, flags | O_NONBLOCK) == -1)
340 die(_("failed to create listening socket: %s"), NULL);
341
342 #ifdef HAVE_IPV6
343 if (iface->addr.sa.sa_family == AF_INET6)
344 {
345 if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
346 setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
347 die(_("failed to set IPV6 options on listening socket: %s"), NULL);
348 }
349 #endif
350
351 if (bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1 ||
352 bind(new->fd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
353 {
354 #ifdef HAVE_IPV6
355 if (iface->addr.sa.sa_family == AF_INET6 && errno == ENODEV)
356 {
357 close(new->tcpfd);
358 close(new->fd);
359 free(new);
360 }
361 else
362 #endif
363 {
364 prettyprint_addr(&iface->addr, daemon->namebuff);
365 die(_("failed to bind listening socket for %s: %s"),
366 daemon->namebuff);
367 }
368 }
369 else
370 {
371 listeners = new;
372 if (listen(new->tcpfd, 5) == -1)
373 die(_("failed to listen on socket: %s"), NULL);
374 }
375 }
376
377 return listeners;
378 }
379
380 struct serverfd *allocate_sfd(union mysockaddr *addr, struct serverfd **sfds)
381 {
382 struct serverfd *sfd;
383 int flags;
384
385 /* may have a suitable one already */
386 for (sfd = *sfds; sfd; sfd = sfd->next )
387 if (sockaddr_isequal(&sfd->source_addr, addr))
388 return sfd;
389
390 /* need to make a new one. */
391 errno = ENOMEM; /* in case malloc fails. */
392 if (!(sfd = malloc(sizeof(struct serverfd))))
393 return NULL;
394
395 if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
396 {
397 free(sfd);
398 return NULL;
399 }
400
401 if (bind(sfd->fd, (struct sockaddr *)addr, sa_len(addr)) == -1 ||
402 (flags = fcntl(sfd->fd, F_GETFL, 0)) == -1 ||
403 fcntl(sfd->fd, F_SETFL, flags | O_NONBLOCK) == -1)
404 {
405 int errsave = errno; /* save error from bind. */
406 close(sfd->fd);
407 free(sfd);
408 errno = errsave;
409 return NULL;
410 }
411
412 sfd->source_addr = *addr;
413 sfd->next = *sfds;
414 *sfds = sfd;
415
416 return sfd;
417 }
418
419 void check_servers(struct daemon *daemon)
420 {
421 struct irec *iface;
422 struct server *new, *tmp, *ret = NULL;
423 int port = 0;
424
425 /* forward table rules reference servers, so have to blow them away */
426 forward_init(0);
427
428 daemon->last_server = daemon->srv_save = NULL;
429
430 for (new = daemon->servers; new; new = tmp)
431 {
432 tmp = new->next;
433
434 if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)))
435 {
436 port = prettyprint_addr(&new->addr, daemon->namebuff);
437
438 for (iface = daemon->interfaces; iface; iface = iface->next)
439 if (sockaddr_isequal(&new->addr, &iface->addr))
440 break;
441 if (iface)
442 {
443 syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
444 free(new);
445 continue;
446 }
447
448 /* Do we need a socket set? */
449 if (!new->sfd && !(new->sfd = allocate_sfd(&new->source_addr, &daemon->sfds)))
450 {
451 syslog(LOG_WARNING,
452 _("ignoring nameserver %s - cannot make/bind socket: %m"), daemon->namebuff);
453 free(new);
454 continue;
455 }
456 }
457
458 /* reverse order - gets it right. */
459 new->next = ret;
460 ret = new;
461
462 if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS))
463 {
464 char *s1, *s2;
465 if (new->flags & SERV_HAS_DOMAIN)
466 s1 = _("domain"), s2 = new->domain;
467 else
468 s1 = _("unqualified"), s2 = _("domains");
469
470 if (new->flags & SERV_NO_ADDR)
471 syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
472 else if (!(new->flags & SERV_LITERAL_ADDRESS))
473 syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
474 }
475 else
476 syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
477 }
478
479 daemon->servers = ret;
480 }
481
482 void reload_servers(char *fname, struct daemon *daemon)
483 {
484 FILE *f;
485 char *line;
486 struct server *old_servers = NULL;
487 struct server *new_servers = NULL;
488 struct server *serv = daemon->servers;
489
490 /* move old servers to free list - we can reuse the memory
491 and not risk malloc if there are the same or fewer new servers.
492 Servers which were specced on the command line go to the new list. */
493 while (serv)
494 {
495 struct server *tmp = serv->next;
496 if (serv->flags & SERV_FROM_RESOLV)
497 {
498 serv->next = old_servers;
499 old_servers = serv;
500 }
501 else
502 {
503 serv->next = new_servers;
504 new_servers = serv;
505 }
506 serv = tmp;
507 }
508
509 /* buff happens to be NAXDNAME long... */
510 f = fopen(fname, "r");
511 if (!f)
512 {
513 syslog(LOG_ERR, _("failed to read %s: %m"), fname);
514 }
515 else
516 {
517 syslog(LOG_INFO, _("reading %s"), fname);
518 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
519 {
520 union mysockaddr addr, source_addr;
521 char *token = strtok(line, " \t\n\r");
522 struct server *serv;
523
524 if (!token || strcmp(token, "nameserver") != 0)
525 continue;
526 if (!(token = strtok(NULL, " \t\n\r")))
527 continue;
528
529 #ifdef HAVE_IPV6
530 if (inet_pton(AF_INET, token, &addr.in.sin_addr) > 0)
531 #else
532 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
533 #endif
534 {
535 #ifdef HAVE_SOCKADDR_SA_LEN
536 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
537 #endif
538 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
539 addr.in.sin_port = htons(NAMESERVER_PORT);
540 source_addr.in.sin_addr.s_addr = INADDR_ANY;
541 source_addr.in.sin_port = htons(daemon->query_port);
542 }
543 #ifdef HAVE_IPV6
544 else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
545 {
546 #ifdef HAVE_SOCKADDR_SA_LEN
547 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
548 #endif
549 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
550 addr.in6.sin6_port = htons(NAMESERVER_PORT);
551 source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0;
552 source_addr.in6.sin6_scope_id = addr.in6.sin6_scope_id = 0;
553 source_addr.in6.sin6_addr = in6addr_any;
554 source_addr.in6.sin6_port = htons(daemon->query_port);
555 }
556 #endif /* IPV6 */
557 else
558 continue;
559
560 if (old_servers)
561 {
562 serv = old_servers;
563 old_servers = old_servers->next;
564 }
565 else if (!(serv = malloc(sizeof (struct server))))
566 continue;
567
568 /* this list is reverse ordered:
569 it gets reversed again in check_servers */
570 serv->next = new_servers;
571 new_servers = serv;
572 serv->addr = addr;
573 serv->source_addr = source_addr;
574 serv->domain = NULL;
575 serv->sfd = NULL;
576 serv->flags = SERV_FROM_RESOLV;
577 }
578
579 fclose(f);
580 }
581
582 /* Free any memory not used. */
583 while(old_servers)
584 {
585 struct server *tmp = old_servers->next;
586 free(old_servers);
587 old_servers = tmp;
588 }
589
590 daemon->servers = new_servers;
591 }
592
593
594
595
596
597
598