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