blob: e7722fdce5b4aeea2518f5f8fc29d37a0329a415 [file] [log] [blame]
Simon Kelleyc49778d2016-01-06 18:52:33 +00001/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
Simon Kelley9e4abcb2004-01-22 19:47:41 +00002
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
Simon Kelley824af852008-02-12 20:43:05 +00005 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
Simon Kelley9e4abcb2004-01-22 19:47:41 +00008 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.
Simon Kelley824af852008-02-12 20:43:05 +000012
Simon Kelley73a08a22009-02-05 20:28:08 +000013 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/>.
Simon Kelley9e4abcb2004-01-22 19:47:41 +000015*/
16
Simon Kelley9e4abcb2004-01-22 19:47:41 +000017#include "dnsmasq.h"
18
Simon Kelley7622fc02009-06-04 20:32:05 +010019#ifdef HAVE_LINUX_NETWORK
20
21int indextoname(int fd, int index, char *name)
22{
23 struct ifreq ifr;
24
25 if (index == 0)
26 return 0;
27
28 ifr.ifr_ifindex = index;
29 if (ioctl(fd, SIOCGIFNAME, &ifr) == -1)
30 return 0;
31
32 strncpy(name, ifr.ifr_name, IF_NAMESIZE);
33
34 return 1;
35}
36
Simon Kelley28866e92011-02-14 20:19:14 +000037
38#elif defined(HAVE_SOLARIS_NETWORK)
39
40#include <zone.h>
41#include <alloca.h>
42#ifndef LIFC_UNDER_IPMP
43# define LIFC_UNDER_IPMP 0
44#endif
45
46int indextoname(int fd, int index, char *name)
47{
48 int64_t lifc_flags;
49 struct lifnum lifn;
50 int numifs, bufsize, i;
51 struct lifconf lifc;
52 struct lifreq *lifrp;
53
54 if (index == 0)
55 return 0;
56
57 if (getzoneid() == GLOBAL_ZONEID)
58 {
59 if (!if_indextoname(index, name))
60 return 0;
61 return 1;
62 }
63
64 lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES | LIFC_UNDER_IPMP;
65 lifn.lifn_family = AF_UNSPEC;
66 lifn.lifn_flags = lifc_flags;
67 if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0)
68 return 0;
69
70 numifs = lifn.lifn_count;
71 bufsize = numifs * sizeof(struct lifreq);
72
73 lifc.lifc_family = AF_UNSPEC;
74 lifc.lifc_flags = lifc_flags;
75 lifc.lifc_len = bufsize;
76 lifc.lifc_buf = alloca(bufsize);
77
78 if (ioctl(fd, SIOCGLIFCONF, &lifc) < 0)
79 return 0;
80
81 lifrp = lifc.lifc_req;
82 for (i = lifc.lifc_len / sizeof(struct lifreq); i; i--, lifrp++)
83 {
84 struct lifreq lifr;
85 strncpy(lifr.lifr_name, lifrp->lifr_name, IF_NAMESIZE);
86 if (ioctl(fd, SIOCGLIFINDEX, &lifr) < 0)
87 return 0;
88
89 if (lifr.lifr_index == index) {
90 strncpy(name, lifr.lifr_name, IF_NAMESIZE);
91 return 1;
92 }
93 }
94 return 0;
95}
96
97
Simon Kelley7622fc02009-06-04 20:32:05 +010098#else
99
100int indextoname(int fd, int index, char *name)
101{
Simon Kelley115ac3e2013-05-20 11:28:32 +0100102 (void)fd;
103
Simon Kelley7622fc02009-06-04 20:32:05 +0100104 if (index == 0 || !if_indextoname(index, name))
105 return 0;
106
107 return 1;
108}
109
110#endif
111
Simon Kelley4f7b3042012-11-28 21:27:02 +0000112int iface_check(int family, struct all_addr *addr, char *name, int *auth)
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000113{
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000114 struct iname *tmp;
Simon Kelleyedf0bde2013-07-29 17:21:48 +0100115 int ret = 1, match_addr = 0;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100116
Simon Kelley309331f2006-04-22 15:05:01 +0100117 /* Note: have to check all and not bail out early, so that we set the
Simon Kelley89500e32013-09-20 16:29:20 +0100118 "used" flags.
119
120 May be called with family == AF_LOCALto check interface by name only. */
Simon Kelley429798f2012-12-10 20:45:53 +0000121
Simon Kelley4f7b3042012-11-28 21:27:02 +0000122 if (auth)
Simon Kelley429798f2012-12-10 20:45:53 +0000123 *auth = 0;
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100124
Simon Kelleyc72daea2012-01-05 21:33:27 +0000125 if (daemon->if_names || daemon->if_addrs)
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100126 {
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100127 ret = 0;
128
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100129 for (tmp = daemon->if_names; tmp; tmp = tmp->next)
Simon Kelley49333cb2013-03-15 20:30:51 +0000130 if (tmp->name && wildcard_match(tmp->name, name))
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100131 ret = tmp->used = 1;
132
Simon Kelley429798f2012-12-10 20:45:53 +0000133 if (addr)
134 for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
135 if (tmp->addr.sa.sa_family == family)
136 {
137 if (family == AF_INET &&
138 tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
Simon Kelleyedf0bde2013-07-29 17:21:48 +0100139 ret = match_addr = tmp->used = 1;
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100140#ifdef HAVE_IPV6
Simon Kelley429798f2012-12-10 20:45:53 +0000141 else if (family == AF_INET6 &&
142 IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr,
143 &addr->addr.addr6))
Simon Kelleyedf0bde2013-07-29 17:21:48 +0100144 ret = match_addr = tmp->used = 1;
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100145#endif
Simon Kelley429798f2012-12-10 20:45:53 +0000146 }
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100147 }
148
Simon Kelleyedf0bde2013-07-29 17:21:48 +0100149 if (!match_addr)
150 for (tmp = daemon->if_except; tmp; tmp = tmp->next)
151 if (tmp->name && wildcard_match(tmp->name, name))
152 ret = 0;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000153
Simon Kelley429798f2012-12-10 20:45:53 +0000154
155 for (tmp = daemon->authinterface; tmp; tmp = tmp->next)
156 if (tmp->name)
157 {
Simon Kelleyf25e6c62013-11-17 12:23:42 +0000158 if (strcmp(tmp->name, name) == 0 &&
159 (tmp->addr.sa.sa_family == 0 || tmp->addr.sa.sa_family == family))
Simon Kelley429798f2012-12-10 20:45:53 +0000160 break;
161 }
162 else if (addr && tmp->addr.sa.sa_family == AF_INET && family == AF_INET &&
163 tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
164 break;
165#ifdef HAVE_IPV6
166 else if (addr && tmp->addr.sa.sa_family == AF_INET6 && family == AF_INET6 &&
167 IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr.addr6))
168 break;
169#endif
170
171 if (tmp && auth)
172 {
173 *auth = 1;
174 ret = 1;
175 }
176
Simon Kelley309331f2006-04-22 15:05:01 +0100177 return ret;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100178}
Simon Kelleye25db1f2013-01-29 22:10:26 +0000179
180
181/* Fix for problem that the kernel sometimes reports the loopback inerface as the
182 arrival interface when a packet originates locally, even when sent to address of
183 an interface other than the loopback. Accept packet if it arrived via a loopback
184 interface, even when we're not accepting packets that way, as long as the destination
185 address is one we're believing. Interface list must be up-to-date before calling. */
186int loopback_exception(int fd, int family, struct all_addr *addr, char *name)
187{
188 struct ifreq ifr;
189 struct irec *iface;
190
191 strncpy(ifr.ifr_name, name, IF_NAMESIZE);
192 if (ioctl(fd, SIOCGIFFLAGS, &ifr) != -1 &&
193 ifr.ifr_flags & IFF_LOOPBACK)
194 {
195 for (iface = daemon->interfaces; iface; iface = iface->next)
196 if (iface->addr.sa.sa_family == family)
197 {
198 if (family == AF_INET)
199 {
200 if (iface->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
201 return 1;
202 }
203#ifdef HAVE_IPV6
204 else if (IN6_ARE_ADDR_EQUAL(&iface->addr.in6.sin6_addr, &addr->addr.addr6))
205 return 1;
206#endif
207
208 }
209 }
210 return 0;
211}
212
Simon Kelley3f2873d2013-05-14 11:28:47 +0100213/* If we're configured with something like --interface=eth0:0 then we'll listen correctly
214 on the relevant address, but the name of the arrival interface, derived from the
215 index won't match the config. Check that we found an interface address for the arrival
216 interface: daemon->interfaces must be up-to-date. */
217int label_exception(int index, int family, struct all_addr *addr)
218{
219 struct irec *iface;
220
221 /* labels only supported on IPv4 addresses. */
222 if (family != AF_INET)
223 return 0;
224
225 for (iface = daemon->interfaces; iface; iface = iface->next)
226 if (iface->index == index && iface->addr.sa.sa_family == AF_INET &&
227 iface->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
228 return 1;
229
230 return 0;
231}
232
Simon Kelley115ac3e2013-05-20 11:28:32 +0100233struct iface_param {
234 struct addrlist *spare;
235 int fd;
236};
237
238static int iface_allowed(struct iface_param *param, int if_index, char *label,
Simon Kelley47669362014-12-17 12:41:56 +0000239 union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags)
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100240{
241 struct irec *iface;
Simon Kelley115ac3e2013-05-20 11:28:32 +0100242 int mtu = 0, loopback;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100243 struct ifreq ifr;
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100244 int tftp_ok = !!option_bool(OPT_TFTP);
Simon Kelley9380ba72012-04-16 14:41:56 +0100245 int dhcp_ok = 1;
Simon Kelley4f7b3042012-11-28 21:27:02 +0000246 int auth_dns = 0;
Simon Kelley91543f42013-09-23 12:41:20 +0100247#if defined(HAVE_DHCP) || defined(HAVE_TFTP)
Simon Kelley832af0b2007-01-21 20:01:28 +0000248 struct iname *tmp;
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100249#endif
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100250
Vladislav Grishenko3b195962013-11-26 11:08:21 +0000251 (void)prefixlen;
252
Simon Kelley115ac3e2013-05-20 11:28:32 +0100253 if (!indextoname(param->fd, if_index, ifr.ifr_name) ||
254 ioctl(param->fd, SIOCGIFFLAGS, &ifr) == -1)
255 return 0;
Simon Kelley1f15b812009-10-13 17:49:32 +0100256
257 loopback = ifr.ifr_flags & IFF_LOOPBACK;
Simon Kelley9380ba72012-04-16 14:41:56 +0100258
259 if (loopback)
Simon Kelley3f2873d2013-05-14 11:28:47 +0100260 dhcp_ok = 0;
261
Simon Kelley115ac3e2013-05-20 11:28:32 +0100262 if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
Simon Kelley1f15b812009-10-13 17:49:32 +0100263 mtu = ifr.ifr_mtu;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100264
Simon Kelley115ac3e2013-05-20 11:28:32 +0100265 if (!label)
266 label = ifr.ifr_name;
Simon Kelleyc8a80482014-03-05 14:29:54 +0000267
268 /* maintain a list of all addresses on all interfaces for --local-service option */
269 if (option_bool(OPT_LOCAL_SERVICE))
270 {
271 struct addrlist *al;
Simon Kelley115ac3e2013-05-20 11:28:32 +0100272
Simon Kelleyc8a80482014-03-05 14:29:54 +0000273 if (param->spare)
274 {
275 al = param->spare;
276 param->spare = al->next;
277 }
278 else
279 al = whine_malloc(sizeof(struct addrlist));
280
281 if (al)
282 {
283 al->next = daemon->interface_addrs;
284 daemon->interface_addrs = al;
285 al->prefixlen = prefixlen;
286
287 if (addr->sa.sa_family == AF_INET)
288 {
289 al->addr.addr.addr4 = addr->in.sin_addr;
290 al->flags = 0;
291 }
292#ifdef HAVE_IPV6
293 else
294 {
295 al->addr.addr.addr6 = addr->in6.sin6_addr;
296 al->flags = ADDRLIST_IPV6;
297 }
298#endif
299 }
300 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000301
Simon Kelley115ac3e2013-05-20 11:28:32 +0100302#ifdef HAVE_IPV6
303 if (addr->sa.sa_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&addr->in6.sin6_addr))
304#endif
305 {
306 struct interface_name *int_name;
307 struct addrlist *al;
Simon Kelley376d48c2013-11-13 13:04:30 +0000308#ifdef HAVE_AUTH
309 struct auth_zone *zone;
310 struct auth_name_list *name;
Simon Kelley115ac3e2013-05-20 11:28:32 +0100311
Simon Kelley376d48c2013-11-13 13:04:30 +0000312 /* Find subnets in auth_zones */
313 for (zone = daemon->auth_zones; zone; zone = zone->next)
314 for (name = zone->interface_names; name; name = name->next)
315 if (wildcard_match(name->name, label))
316 {
317 if (addr->sa.sa_family == AF_INET && (name->flags & AUTH4))
318 {
319 if (param->spare)
320 {
321 al = param->spare;
322 param->spare = al->next;
323 }
324 else
325 al = whine_malloc(sizeof(struct addrlist));
326
327 if (al)
328 {
329 al->next = zone->subnet;
330 zone->subnet = al;
331 al->prefixlen = prefixlen;
332 al->addr.addr.addr4 = addr->in.sin_addr;
333 al->flags = 0;
334 }
335 }
336
337#ifdef HAVE_IPV6
338 if (addr->sa.sa_family == AF_INET6 && (name->flags & AUTH6))
339 {
340 if (param->spare)
341 {
342 al = param->spare;
343 param->spare = al->next;
344 }
345 else
346 al = whine_malloc(sizeof(struct addrlist));
347
348 if (al)
349 {
350 al->next = zone->subnet;
351 zone->subnet = al;
Vladislav Grishenko3b195962013-11-26 11:08:21 +0000352 al->prefixlen = prefixlen;
353 al->addr.addr.addr6 = addr->in6.sin6_addr;
Simon Kelley376d48c2013-11-13 13:04:30 +0000354 al->flags = ADDRLIST_IPV6;
355 }
356 }
357#endif
358
359 }
360#endif
361
362 /* Update addresses from interface_names. These are a set independent
363 of the set we're listening on. */
Simon Kelley115ac3e2013-05-20 11:28:32 +0100364 for (int_name = daemon->int_names; int_name; int_name = int_name->next)
Simon Kelleyf7029f52013-11-21 15:09:09 +0000365 if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0 &&
366 (addr->sa.sa_family == int_name->family || int_name->family == 0))
Simon Kelley115ac3e2013-05-20 11:28:32 +0100367 {
368 if (param->spare)
369 {
370 al = param->spare;
371 param->spare = al->next;
372 }
373 else
374 al = whine_malloc(sizeof(struct addrlist));
375
376 if (al)
377 {
Simon Kelley376d48c2013-11-13 13:04:30 +0000378 al->next = int_name->addr;
379 int_name->addr = al;
380
Simon Kelley115ac3e2013-05-20 11:28:32 +0100381 if (addr->sa.sa_family == AF_INET)
382 {
383 al->addr.addr.addr4 = addr->in.sin_addr;
Simon Kelley376d48c2013-11-13 13:04:30 +0000384 al->flags = 0;
Simon Kelley115ac3e2013-05-20 11:28:32 +0100385 }
386#ifdef HAVE_IPV6
387 else
388 {
389 al->addr.addr.addr6 = addr->in6.sin6_addr;
Simon Kelley376d48c2013-11-13 13:04:30 +0000390 al->flags = ADDRLIST_IPV6;
Simon Kelley47669362014-12-17 12:41:56 +0000391 /* Privacy addresses and addresses still undergoing DAD and deprecated addresses
392 don't appear in forward queries, but will in reverse ones. */
393 if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE_DEPRECATED | IFACE_TENTATIVE)))
394 al->flags |= ADDRLIST_REVONLY;
Simon Kelley115ac3e2013-05-20 11:28:32 +0100395 }
396#endif
397 }
398 }
399 }
400
401 /* check whether the interface IP has been added already
402 we call this routine multiple times. */
403 for (iface = daemon->interfaces; iface; iface = iface->next)
404 if (sockaddr_isequal(&iface->addr, addr))
405 {
Simon Kelley47669362014-12-17 12:41:56 +0000406 iface->dad = !!(iface_flags & IFACE_TENTATIVE);
Simon Kelley08619212013-12-02 14:43:48 +0000407 iface->found = 1; /* for garbage collection */
Simon Kelley115ac3e2013-05-20 11:28:32 +0100408 return 1;
409 }
410
411 /* If we are restricting the set of interfaces to use, make
Simon Kelley59353a62004-11-21 19:34:28 +0000412 sure that loopback interfaces are in that set. */
Simon Kelley1f15b812009-10-13 17:49:32 +0100413 if (daemon->if_names && loopback)
Simon Kelley59353a62004-11-21 19:34:28 +0000414 {
415 struct iname *lo;
416 for (lo = daemon->if_names; lo; lo = lo->next)
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100417 if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
Simon Kelley4ce4f372012-06-14 11:50:45 +0100418 break;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100419
Simon Kelley38365ff2013-02-05 14:35:54 +0000420 if (!lo && (lo = whine_malloc(sizeof(struct iname))))
Simon Kelley59353a62004-11-21 19:34:28 +0000421 {
Simon Kelley38365ff2013-02-05 14:35:54 +0000422 if ((lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
423 {
424 strcpy(lo->name, ifr.ifr_name);
425 lo->used = 1;
426 lo->next = daemon->if_names;
427 daemon->if_names = lo;
428 }
429 else
430 free(lo);
Simon Kelley59353a62004-11-21 19:34:28 +0000431 }
432 }
433
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100434 if (addr->sa.sa_family == AF_INET &&
Simon Kelley3f2873d2013-05-14 11:28:47 +0100435 !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, label, &auth_dns))
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100436 return 1;
Simon Kelley4f7b3042012-11-28 21:27:02 +0000437
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100438#ifdef HAVE_IPV6
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100439 if (addr->sa.sa_family == AF_INET6 &&
Simon Kelley3f2873d2013-05-14 11:28:47 +0100440 !iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, label, &auth_dns))
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100441 return 1;
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100442#endif
Simon Kelley4f7b3042012-11-28 21:27:02 +0000443
444#ifdef HAVE_DHCP
445 /* No DHCP where we're doing auth DNS. */
446 if (auth_dns)
447 {
448 tftp_ok = 0;
449 dhcp_ok = 0;
450 }
451 else
452 for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
Simon Kelley49333cb2013-03-15 20:30:51 +0000453 if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
Simon Kelley4f7b3042012-11-28 21:27:02 +0000454 {
455 tftp_ok = 0;
456 dhcp_ok = 0;
457 }
458#endif
459
Simon Kelley2937f8a2013-07-29 19:49:07 +0100460
Simon Kelley91543f42013-09-23 12:41:20 +0100461#ifdef HAVE_TFTP
Simon Kelley2937f8a2013-07-29 19:49:07 +0100462 if (daemon->tftp_interfaces)
463 {
464 /* dedicated tftp interface list */
465 tftp_ok = 0;
466 for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
467 if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
468 tftp_ok = 1;
469 }
Simon Kelley91543f42013-09-23 12:41:20 +0100470#endif
Simon Kelley2937f8a2013-07-29 19:49:07 +0100471
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100472 /* add to list */
Simon Kelley5aabfc72007-08-29 11:24:47 +0100473 if ((iface = whine_malloc(sizeof(struct irec))))
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100474 {
475 iface->addr = *addr;
476 iface->netmask = netmask;
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100477 iface->tftp_ok = tftp_ok;
Simon Kelley9380ba72012-04-16 14:41:56 +0100478 iface->dhcp_ok = dhcp_ok;
Simon Kelley4f7b3042012-11-28 21:27:02 +0000479 iface->dns_auth = auth_dns;
Simon Kelley1f15b812009-10-13 17:49:32 +0100480 iface->mtu = mtu;
Simon Kelley47669362014-12-17 12:41:56 +0000481 iface->dad = !!(iface_flags & IFACE_TENTATIVE);
Simon Kelley08619212013-12-02 14:43:48 +0000482 iface->found = 1;
Simon Kelleydc27e142013-10-16 13:09:53 +0100483 iface->done = iface->multicast_done = iface->warned = 0;
Simon Kelley5d162f22012-12-20 14:55:46 +0000484 iface->index = if_index;
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100485 if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
Simon Kelley6f13e532012-04-17 14:25:06 +0100486 {
487 strcpy(iface->name, ifr.ifr_name);
Simon Kelley115ac3e2013-05-20 11:28:32 +0100488 iface->next = daemon->interfaces;
489 daemon->interfaces = iface;
Simon Kelley6f13e532012-04-17 14:25:06 +0100490 return 1;
491 }
492 free(iface);
Simon Kelley5d162f22012-12-20 14:55:46 +0000493
Simon Kelley44a2a312004-03-10 20:04:35 +0000494 }
495
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100496 errno = ENOMEM;
497 return 0;
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000498}
499
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100500#ifdef HAVE_IPV6
Simon Kelleyc72daea2012-01-05 21:33:27 +0000501static int iface_allowed_v6(struct in6_addr *local, int prefix,
Simon Kelleybad7b872012-12-20 22:00:39 +0000502 int scope, int if_index, int flags,
Simon Kelley1f776932012-12-16 19:46:08 +0000503 int preferred, int valid, void *vparam)
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000504{
Simon Kelley59353a62004-11-21 19:34:28 +0000505 union mysockaddr addr;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100506 struct in_addr netmask; /* dummy */
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100507 netmask.s_addr = 0;
Simon Kelley52b92f42012-01-22 16:05:15 +0000508
Simon Kelley52b92f42012-01-22 16:05:15 +0000509 (void)scope; /* warning */
Simon Kelley1f776932012-12-16 19:46:08 +0000510 (void)preferred;
511 (void)valid;
Simon Kelley44a2a312004-03-10 20:04:35 +0000512
Simon Kelley849a8352006-06-09 21:02:31 +0100513 memset(&addr, 0, sizeof(addr));
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000514#ifdef HAVE_SOCKADDR_SA_LEN
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100515 addr.in6.sin6_len = sizeof(addr.in6);
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000516#endif
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100517 addr.in6.sin6_family = AF_INET6;
518 addr.in6.sin6_addr = *local;
519 addr.in6.sin6_port = htons(daemon->port);
Simon Kelley62ab3cc2013-12-03 11:53:53 +0000520 /* FreeBSD insists this is zero for non-linklocal addresses */
521 if (IN6_IS_ADDR_LINKLOCAL(local))
522 addr.in6.sin6_scope_id = if_index;
523 else
524 addr.in6.sin6_scope_id = 0;
Simon Kelley1ee9be42013-12-09 16:50:19 +0000525
Simon Kelley47669362014-12-17 12:41:56 +0000526 return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, flags);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100527}
528#endif
Simon Kelley59353a62004-11-21 19:34:28 +0000529
Simon Kelley3f2873d2013-05-14 11:28:47 +0100530static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100531 struct in_addr netmask, struct in_addr broadcast, void *vparam)
532{
533 union mysockaddr addr;
Simon Kelley376d48c2013-11-13 13:04:30 +0000534 int prefix, bit;
Simon Kelleyb8ac4662016-03-10 18:40:53 +0000535
536 (void)broadcast; /* warning */
Simon Kelley849a8352006-06-09 21:02:31 +0100537
538 memset(&addr, 0, sizeof(addr));
Simon Kelley1ab84e22004-01-29 16:48:35 +0000539#ifdef HAVE_SOCKADDR_SA_LEN
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100540 addr.in.sin_len = sizeof(addr.in);
Simon Kelley1ab84e22004-01-29 16:48:35 +0000541#endif
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100542 addr.in.sin_family = AF_INET;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100543 addr.in.sin_addr = local;
544 addr.in.sin_port = htons(daemon->port);
Simon Kelley44a2a312004-03-10 20:04:35 +0000545
Simon Kelley376d48c2013-11-13 13:04:30 +0000546 /* determine prefix length from netmask */
547 for (prefix = 32, bit = 1; (bit & ntohl(netmask.s_addr)) == 0 && prefix != 0; bit = bit << 1, prefix--);
548
549 return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100550}
551
Simon Kelley115ac3e2013-05-20 11:28:32 +0100552int enumerate_interfaces(int reset)
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100553{
Simon Kelley115ac3e2013-05-20 11:28:32 +0100554 static struct addrlist *spare = NULL;
Simon Kelleya0358e52014-06-07 13:38:48 +0100555 static int done = 0;
Simon Kelley115ac3e2013-05-20 11:28:32 +0100556 struct iface_param param;
557 int errsave, ret = 1;
558 struct addrlist *addr, *tmp;
559 struct interface_name *intname;
Simon Kelley08619212013-12-02 14:43:48 +0000560 struct irec *iface;
Simon Kelley376d48c2013-11-13 13:04:30 +0000561#ifdef HAVE_AUTH
562 struct auth_zone *zone;
563#endif
564
Simon Kelley76dd75d2013-05-23 10:04:25 +0100565 /* Do this max once per select cycle - also inhibits netlink socket use
566 in TCP child processes. */
Simon Kelley397542b2013-09-05 11:27:34 +0100567
Simon Kelley115ac3e2013-05-20 11:28:32 +0100568 if (reset)
569 {
570 done = 0;
571 return 1;
572 }
573
Simon Kelleya0358e52014-06-07 13:38:48 +0100574 if (done)
Simon Kelley115ac3e2013-05-20 11:28:32 +0100575 return 1;
576
577 done = 1;
578
579 if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
580 return 0;
581
Simon Kelley08619212013-12-02 14:43:48 +0000582 /* Mark interfaces for garbage collection */
583 for (iface = daemon->interfaces; iface; iface = iface->next)
584 iface->found = 0;
585
Simon Kelley115ac3e2013-05-20 11:28:32 +0100586 /* remove addresses stored against interface_names */
587 for (intname = daemon->int_names; intname; intname = intname->next)
588 {
Simon Kelley376d48c2013-11-13 13:04:30 +0000589 for (addr = intname->addr; addr; addr = tmp)
Simon Kelley115ac3e2013-05-20 11:28:32 +0100590 {
591 tmp = addr->next;
592 addr->next = spare;
593 spare = addr;
594 }
595
Simon Kelley376d48c2013-11-13 13:04:30 +0000596 intname->addr = NULL;
Simon Kelley115ac3e2013-05-20 11:28:32 +0100597 }
Simon Kelley376d48c2013-11-13 13:04:30 +0000598
Simon Kelleyc8a80482014-03-05 14:29:54 +0000599 /* Remove list of addresses of local interfaces */
600 for (addr = daemon->interface_addrs; addr; addr = tmp)
601 {
602 tmp = addr->next;
603 addr->next = spare;
604 spare = addr;
605 }
606 daemon->interface_addrs = NULL;
607
Simon Kelley376d48c2013-11-13 13:04:30 +0000608#ifdef HAVE_AUTH
609 /* remove addresses stored against auth_zone subnets, but not
610 ones configured as address literals */
611 for (zone = daemon->auth_zones; zone; zone = zone->next)
612 if (zone->interface_names)
613 {
614 struct addrlist **up;
615 for (up = &zone->subnet, addr = zone->subnet; addr; addr = tmp)
616 {
617 tmp = addr->next;
618 if (addr->flags & ADDRLIST_LITERAL)
619 up = &addr->next;
620 else
621 {
622 *up = addr->next;
623 addr->next = spare;
624 spare = addr;
625 }
626 }
627 }
628#endif
629
Simon Kelley115ac3e2013-05-20 11:28:32 +0100630 param.spare = spare;
631
632#ifdef HAVE_IPV6
633 ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100634#endif
Simon Kelley28866e92011-02-14 20:19:14 +0000635
Simon Kelley115ac3e2013-05-20 11:28:32 +0100636 if (ret)
637 ret = iface_enumerate(AF_INET, &param, iface_allowed_v4);
638
639 errsave = errno;
640 close(param.fd);
Simon Kelley08619212013-12-02 14:43:48 +0000641
642 if (option_bool(OPT_CLEVERBIND))
643 {
644 /* Garbage-collect listeners listening on addresses that no longer exist.
645 Does nothing when not binding interfaces or for listeners on localhost,
646 since the ->iface field is NULL. Note that this needs the protections
647 against re-entrancy, hence it's here. It also means there's a possibility,
648 in OPT_CLEVERBIND mode, that at listener will just disappear after
649 a call to enumerate_interfaces, this is checked OK on all calls. */
650 struct listener *l, *tmp, **up;
651
652 for (up = &daemon->listeners, l = daemon->listeners; l; l = tmp)
653 {
654 tmp = l->next;
655
656 if (!l->iface || l->iface->found)
657 up = &l->next;
658 else
659 {
660 *up = l->next;
661
662 /* In case it ever returns */
663 l->iface->done = 0;
664
665 if (l->fd != -1)
666 close(l->fd);
667 if (l->tcpfd != -1)
668 close(l->tcpfd);
669 if (l->tftpfd != -1)
670 close(l->tftpfd);
671
672 free(l);
673 }
674 }
675 }
676
Simon Kelley115ac3e2013-05-20 11:28:32 +0100677 errno = errsave;
Simon Kelley115ac3e2013-05-20 11:28:32 +0100678 spare = param.spare;
Simon Kelleya0358e52014-06-07 13:38:48 +0100679
Simon Kelley115ac3e2013-05-20 11:28:32 +0100680 return ret;
Simon Kelley44a2a312004-03-10 20:04:35 +0000681}
682
Simon Kelley5aabfc72007-08-29 11:24:47 +0100683/* set NONBLOCK bit on fd: See Stevens 16.6 */
Simon Kelley7cebd202006-05-06 14:13:33 +0100684int fix_fd(int fd)
685{
686 int flags;
687
688 if ((flags = fcntl(fd, F_GETFL)) == -1 ||
Simon Kelley5aabfc72007-08-29 11:24:47 +0100689 fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
Simon Kelley7cebd202006-05-06 14:13:33 +0100690 return 0;
Simon Kelley5aabfc72007-08-29 11:24:47 +0100691
Simon Kelley7cebd202006-05-06 14:13:33 +0100692 return 1;
693}
694
Simon Kelley74c95c22011-10-19 09:33:39 +0100695static int make_sock(union mysockaddr *addr, int type, int dienow)
Simon Kelley44a2a312004-03-10 20:04:35 +0000696{
Simon Kelley28866e92011-02-14 20:19:14 +0000697 int family = addr->sa.sa_family;
698 int fd, rc, opt = 1;
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100699
Simon Kelley28866e92011-02-14 20:19:14 +0000700 if ((fd = socket(family, type, 0)) == -1)
Simon Kelley316e2732010-01-22 20:16:09 +0000701 {
Matthias Andree71aaa5a2013-12-03 11:20:45 +0000702 int port, errsav;
Simon Kelley39f1b8e2012-06-20 20:04:27 +0100703 char *s;
Simon Kelley28866e92011-02-14 20:19:14 +0000704
705 /* No error if the kernel just doesn't support this IP flavour */
706 if (errno == EPROTONOSUPPORT ||
707 errno == EAFNOSUPPORT ||
708 errno == EINVAL)
709 return -1;
710
711 err:
Matthias Andree71aaa5a2013-12-03 11:20:45 +0000712 errsav = errno;
Simon Kelley39f1b8e2012-06-20 20:04:27 +0100713 port = prettyprint_addr(addr, daemon->addrbuff);
714 if (!option_bool(OPT_NOWILD) && !option_bool(OPT_CLEVERBIND))
715 sprintf(daemon->addrbuff, "port %d", port);
716 s = _("failed to create listening socket for %s: %s");
717
Simon Kelley5f11b3e2012-08-16 14:04:05 +0100718 if (fd != -1)
Matthias Andree71aaa5a2013-12-03 11:20:45 +0000719 close (fd);
720
721 errno = errsav;
Simon Kelley1ee9be42013-12-09 16:50:19 +0000722
Simon Kelley5f11b3e2012-08-16 14:04:05 +0100723 if (dienow)
724 {
725 /* failure to bind addresses given by --listen-address at this point
726 is OK if we're doing bind-dynamic */
727 if (!option_bool(OPT_CLEVERBIND))
728 die(s, daemon->addrbuff, EC_BADNET);
729 }
730 else
731 my_syslog(LOG_WARNING, s, daemon->addrbuff, strerror(errno));
732
Simon Kelley74c95c22011-10-19 09:33:39 +0100733 return -1;
Simon Kelley28866e92011-02-14 20:19:14 +0000734 }
Simon Kelley5f11b3e2012-08-16 14:04:05 +0100735
Simon Kelley28866e92011-02-14 20:19:14 +0000736 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd))
737 goto err;
738
739#ifdef HAVE_IPV6
Simon Kelleyc72daea2012-01-05 21:33:27 +0000740 if (family == AF_INET6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
Simon Kelley28866e92011-02-14 20:19:14 +0000741 goto err;
742#endif
743
Simon Kelley74c95c22011-10-19 09:33:39 +0100744 if ((rc = bind(fd, (struct sockaddr *)addr, sa_len(addr))) == -1)
Simon Kelley28866e92011-02-14 20:19:14 +0000745 goto err;
746
747 if (type == SOCK_STREAM)
748 {
749 if (listen(fd, 5) == -1)
750 goto err;
751 }
Simon Kelley2329bef2013-12-03 13:41:16 +0000752 else if (family == AF_INET)
Simon Kelley28866e92011-02-14 20:19:14 +0000753 {
Simon Kelley2329bef2013-12-03 13:41:16 +0000754 if (!option_bool(OPT_NOWILD))
Simon Kelley28866e92011-02-14 20:19:14 +0000755 {
756#if defined(HAVE_LINUX_NETWORK)
Simon Kelleyc72daea2012-01-05 21:33:27 +0000757 if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1)
Simon Kelley28866e92011-02-14 20:19:14 +0000758 goto err;
759#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
760 if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
761 setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1)
762 goto err;
763#endif
764 }
Simon Kelley28866e92011-02-14 20:19:14 +0000765 }
Simon Kelley2329bef2013-12-03 13:41:16 +0000766#ifdef HAVE_IPV6
767 else if (!set_ipv6pktinfo(fd))
768 goto err;
769#endif
Simon Kelleyc72daea2012-01-05 21:33:27 +0000770
Simon Kelley28866e92011-02-14 20:19:14 +0000771 return fd;
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100772}
Simon Kelleyc72daea2012-01-05 21:33:27 +0000773
774#ifdef HAVE_IPV6
775int set_ipv6pktinfo(int fd)
776{
777 int opt = 1;
778
779 /* The API changed around Linux 2.6.14 but the old ABI is still supported:
780 handle all combinations of headers and kernel.
781 OpenWrt note that this fixes the problem addressed by your very broken patch. */
782 daemon->v6pktinfo = IPV6_PKTINFO;
783
784#ifdef IPV6_RECVPKTINFO
785 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &opt, sizeof(opt)) != -1)
786 return 1;
787# ifdef IPV6_2292PKTINFO
788 else if (errno == ENOPROTOOPT && setsockopt(fd, IPPROTO_IPV6, IPV6_2292PKTINFO, &opt, sizeof(opt)) != -1)
789 {
790 daemon->v6pktinfo = IPV6_2292PKTINFO;
791 return 1;
792 }
793# endif
794#else
795 if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &opt, sizeof(opt)) != -1)
796 return 1;
797#endif
798
799 return 0;
800}
801#endif
Simon Kelley22ce5502013-01-22 13:53:04 +0000802
803
804/* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
805int tcp_interface(int fd, int af)
806{
807 int if_index = 0;
808
809#ifdef HAVE_LINUX_NETWORK
810 int opt = 1;
811 struct cmsghdr *cmptr;
812 struct msghdr msg;
Simon Kelley529b0302016-03-16 19:00:45 +0000813 socklen_t len;
Simon Kelley22ce5502013-01-22 13:53:04 +0000814
Simon Kelley529b0302016-03-16 19:00:45 +0000815 /* use mshdr so that the CMSDG_* macros are available */
Simon Kelley22ce5502013-01-22 13:53:04 +0000816 msg.msg_control = daemon->packet;
Simon Kelley529b0302016-03-16 19:00:45 +0000817 msg.msg_controllen = len = daemon->packet_buff_sz;
Simon Kelley22ce5502013-01-22 13:53:04 +0000818
819 /* we overwrote the buffer... */
820 daemon->srv_save = NULL;
821
822 if (af == AF_INET)
823 {
824 if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) != -1 &&
Simon Kelley529b0302016-03-16 19:00:45 +0000825 getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, &len) != -1)
826 {
827 msg.msg_controllen = len;
828 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
829 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
830 {
831 union {
832 unsigned char *c;
833 struct in_pktinfo *p;
834 } p;
835
836 p.c = CMSG_DATA(cmptr);
837 if_index = p.p->ipi_ifindex;
838 }
839 }
Simon Kelley22ce5502013-01-22 13:53:04 +0000840 }
841#ifdef HAVE_IPV6
842 else
843 {
844 /* Only the RFC-2292 API has the ability to find the interface for TCP connections,
845 it was removed in RFC-3542 !!!!
846
847 Fortunately, Linux kept the 2292 ABI when it moved to 3542. The following code always
848 uses the old ABI, and should work with pre- and post-3542 kernel headers */
849
850#ifdef IPV6_2292PKTOPTIONS
851# define PKTOPTIONS IPV6_2292PKTOPTIONS
852#else
853# define PKTOPTIONS IPV6_PKTOPTIONS
854#endif
855
856 if (set_ipv6pktinfo(fd) &&
Simon Kelley529b0302016-03-16 19:00:45 +0000857 getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, &len) != -1)
Simon Kelley22ce5502013-01-22 13:53:04 +0000858 {
Simon Kelley529b0302016-03-16 19:00:45 +0000859 msg.msg_controllen = len;
860 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
Simon Kelley22ce5502013-01-22 13:53:04 +0000861 if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
862 {
863 union {
864 unsigned char *c;
865 struct in6_pktinfo *p;
866 } p;
867 p.c = CMSG_DATA(cmptr);
868
869 if_index = p.p->ipi6_ifindex;
870 }
871 }
872 }
873#endif /* IPV6 */
874#endif /* Linux */
875
876 return if_index;
877}
Simon Kelley28866e92011-02-14 20:19:14 +0000878
Simon Kelley74c95c22011-10-19 09:33:39 +0100879static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
Simon Kelley28866e92011-02-14 20:19:14 +0000880{
881 struct listener *l = NULL;
882 int fd = -1, tcpfd = -1, tftpfd = -1;
883
Vladislav Grishenko408c3682013-09-24 16:18:49 +0100884 (void)do_tftp;
885
Simon Kelley28866e92011-02-14 20:19:14 +0000886 if (daemon->port != 0)
887 {
Simon Kelley74c95c22011-10-19 09:33:39 +0100888 fd = make_sock(addr, SOCK_DGRAM, dienow);
889 tcpfd = make_sock(addr, SOCK_STREAM, dienow);
Simon Kelley28866e92011-02-14 20:19:14 +0000890 }
891
892#ifdef HAVE_TFTP
893 if (do_tftp)
894 {
895 if (addr->sa.sa_family == AF_INET)
896 {
897 /* port must be restored to DNS port for TCP code */
898 short save = addr->in.sin_port;
899 addr->in.sin_port = htons(TFTP_PORT);
Simon Kelley74c95c22011-10-19 09:33:39 +0100900 tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
Simon Kelley28866e92011-02-14 20:19:14 +0000901 addr->in.sin_port = save;
902 }
903# ifdef HAVE_IPV6
904 else
905 {
906 short save = addr->in6.sin6_port;
907 addr->in6.sin6_port = htons(TFTP_PORT);
Simon Kelley74c95c22011-10-19 09:33:39 +0100908 tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
Simon Kelley28866e92011-02-14 20:19:14 +0000909 addr->in6.sin6_port = save;
910 }
911# endif
912 }
Simon Kelley44a2a312004-03-10 20:04:35 +0000913#endif
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100914
Simon Kelley28866e92011-02-14 20:19:14 +0000915 if (fd != -1 || tcpfd != -1 || tftpfd != -1)
916 {
917 l = safe_malloc(sizeof(struct listener));
918 l->next = NULL;
919 l->family = addr->sa.sa_family;
920 l->fd = fd;
921 l->tcpfd = tcpfd;
Simon Kelley08619212013-12-02 14:43:48 +0000922 l->tftpfd = tftpfd;
923 l->iface = NULL;
Simon Kelley28866e92011-02-14 20:19:14 +0000924 }
925
926 return l;
927}
928
Simon Kelley74c95c22011-10-19 09:33:39 +0100929void create_wildcard_listeners(void)
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100930{
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100931 union mysockaddr addr;
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100932 struct listener *l, *l6;
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100933
Simon Kelley849a8352006-06-09 21:02:31 +0100934 memset(&addr, 0, sizeof(addr));
Simon Kelley28866e92011-02-14 20:19:14 +0000935#ifdef HAVE_SOCKADDR_SA_LEN
936 addr.in.sin_len = sizeof(addr.in);
937#endif
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100938 addr.in.sin_family = AF_INET;
939 addr.in.sin_addr.s_addr = INADDR_ANY;
Simon Kelley5aabfc72007-08-29 11:24:47 +0100940 addr.in.sin_port = htons(daemon->port);
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100941
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100942 l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
Simon Kelley28866e92011-02-14 20:19:14 +0000943
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100944#ifdef HAVE_IPV6
Simon Kelley28866e92011-02-14 20:19:14 +0000945 memset(&addr, 0, sizeof(addr));
946# ifdef HAVE_SOCKADDR_SA_LEN
947 addr.in6.sin6_len = sizeof(addr.in6);
948# endif
949 addr.in6.sin6_family = AF_INET6;
950 addr.in6.sin6_addr = in6addr_any;
951 addr.in6.sin6_port = htons(daemon->port);
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100952
953 l6 = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
Simon Kelley28866e92011-02-14 20:19:14 +0000954 if (l)
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100955 l->next = l6;
Simon Kelley28866e92011-02-14 20:19:14 +0000956 else
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100957 l = l6;
Simon Kelley832af0b2007-01-21 20:01:28 +0000958#endif
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100959
Simon Kelley74c95c22011-10-19 09:33:39 +0100960 daemon->listeners = l;
Simon Kelley44a2a312004-03-10 20:04:35 +0000961}
962
Simon Kelley74c95c22011-10-19 09:33:39 +0100963void create_bound_listeners(int dienow)
Simon Kelley44a2a312004-03-10 20:04:35 +0000964{
Simon Kelley74c95c22011-10-19 09:33:39 +0100965 struct listener *new;
Simon Kelley44a2a312004-03-10 20:04:35 +0000966 struct irec *iface;
Simon Kelley52d4abf2012-03-21 21:39:48 +0000967 struct iname *if_tmp;
Simon Kelley73a08a22009-02-05 20:28:08 +0000968
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100969 for (iface = daemon->interfaces; iface; iface = iface->next)
Simon Kelley08619212013-12-02 14:43:48 +0000970 if (!iface->done && !iface->dad && iface->found &&
Simon Kelley74c95c22011-10-19 09:33:39 +0100971 (new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
Simon Kelley28866e92011-02-14 20:19:14 +0000972 {
973 new->iface = iface;
Simon Kelley74c95c22011-10-19 09:33:39 +0100974 new->next = daemon->listeners;
975 daemon->listeners = new;
976 iface->done = 1;
Simon Kelley28866e92011-02-14 20:19:14 +0000977 }
Simon Kelley52d4abf2012-03-21 21:39:48 +0000978
979 /* Check for --listen-address options that haven't been used because there's
980 no interface with a matching address. These may be valid: eg it's possible
981 to listen on 127.0.1.1 even if the loopback interface is 127.0.0.1
982
Simon Kelley5f11b3e2012-08-16 14:04:05 +0100983 If the address isn't valid the bind() will fail and we'll die()
984 (except in bind-dynamic mode, when we'll complain but keep trying.)
Simon Kelley52d4abf2012-03-21 21:39:48 +0000985
986 The resulting listeners have the ->iface field NULL, and this has to be
987 handled by the DNS and TFTP code. It disables --localise-queries processing
988 (no netmask) and some MTU login the tftp code. */
989
990 for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
991 if (!if_tmp->used &&
Simon Kelley8bc4cec2012-07-03 21:04:11 +0100992 (new = create_listeners(&if_tmp->addr, !!option_bool(OPT_TFTP), dienow)))
Simon Kelley52d4abf2012-03-21 21:39:48 +0000993 {
Simon Kelley52d4abf2012-03-21 21:39:48 +0000994 new->next = daemon->listeners;
995 daemon->listeners = new;
996 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000997}
998
Simon Kelleydc27e142013-10-16 13:09:53 +0100999/* In --bind-interfaces, the only access control is the addresses we're listening on.
1000 There's nothing to avoid a query to the address of an internal interface arriving via
1001 an external interface where we don't want to accept queries, except that in the usual
1002 case the addresses of internal interfaces are RFC1918. When bind-interfaces in use,
1003 and we listen on an address that looks like it's probably globally routeable, shout.
1004
1005 The fix is to use --bind-dynamic, which actually checks the arrival interface too.
1006 Tough if your platform doesn't support this.
Simon Kelley2329bef2013-12-03 13:41:16 +00001007
1008 Note that checking the arrival interface is supported in the standard IPv6 API and
1009 always done, so we don't warn about any IPv6 addresses here.
Simon Kelleydc27e142013-10-16 13:09:53 +01001010*/
1011
1012void warn_bound_listeners(void)
1013{
1014 struct irec *iface;
1015 int advice = 0;
1016
1017 for (iface = daemon->interfaces; iface; iface = iface->next)
Simon Kelleyf7029f52013-11-21 15:09:09 +00001018 if (!iface->dns_auth)
Simon Kelleydc27e142013-10-16 13:09:53 +01001019 {
Simon Kelleydc27e142013-10-16 13:09:53 +01001020 if (iface->addr.sa.sa_family == AF_INET)
1021 {
1022 if (!private_net(iface->addr.in.sin_addr, 1))
1023 {
1024 inet_ntop(AF_INET, &iface->addr.in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
Simon Kelley2329bef2013-12-03 13:41:16 +00001025 iface->warned = advice = 1;
1026 my_syslog(LOG_WARNING,
1027 _("LOUD WARNING: listening on %s may accept requests via interfaces other than %s"),
1028 daemon->addrbuff, iface->name);
Simon Kelleydc27e142013-10-16 13:09:53 +01001029 }
1030 }
Simon Kelleydc27e142013-10-16 13:09:53 +01001031 }
1032
1033 if (advice)
Simon Kelleyf7029f52013-11-21 15:09:09 +00001034 my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"));
Simon Kelleydc27e142013-10-16 13:09:53 +01001035}
1036
Simon Kelleyf7029f52013-11-21 15:09:09 +00001037void warn_int_names(void)
1038{
1039 struct interface_name *intname;
1040
1041 for (intname = daemon->int_names; intname; intname = intname->next)
1042 if (!intname->addr)
1043 my_syslog(LOG_WARNING, _("warning: no addresses found for interface %s"), intname->intr);
1044}
1045
Simon Kelley74c95c22011-10-19 09:33:39 +01001046int is_dad_listeners(void)
1047{
1048 struct irec *iface;
1049
1050 if (option_bool(OPT_NOWILD))
1051 for (iface = daemon->interfaces; iface; iface = iface->next)
1052 if (iface->dad && !iface->done)
1053 return 1;
1054
1055 return 0;
1056}
Simon Kelley5d162f22012-12-20 14:55:46 +00001057
1058#ifdef HAVE_DHCP6
1059void join_multicast(int dienow)
1060{
1061 struct irec *iface, *tmp;
1062
1063 for (iface = daemon->interfaces; iface; iface = iface->next)
Simon Kelley19624462012-12-28 11:18:09 +00001064 if (iface->addr.sa.sa_family == AF_INET6 && iface->dhcp_ok && !iface->multicast_done)
Simon Kelley5d162f22012-12-20 14:55:46 +00001065 {
1066 /* There's an irec per address but we only want to join for multicast
1067 once per interface. Weed out duplicates. */
1068 for (tmp = daemon->interfaces; tmp; tmp = tmp->next)
1069 if (tmp->multicast_done && tmp->index == iface->index)
1070 break;
1071
1072 iface->multicast_done = 1;
1073
1074 if (!tmp)
1075 {
1076 struct ipv6_mreq mreq;
1077 int err = 0;
1078
1079 mreq.ipv6mr_interface = iface->index;
1080
1081 inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
1082
Simon Kelleyff7eea22013-09-04 18:01:38 +01001083 if ((daemon->doing_dhcp6 || daemon->relay6) &&
Simon Kelley5d162f22012-12-20 14:55:46 +00001084 setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
Simon Kelley9cdcfe92015-08-26 22:38:08 +01001085 err = errno;
Simon Kelley5d162f22012-12-20 14:55:46 +00001086
1087 inet_pton(AF_INET6, ALL_SERVERS, &mreq.ipv6mr_multiaddr);
1088
1089 if (daemon->doing_dhcp6 &&
1090 setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
Simon Kelley9cdcfe92015-08-26 22:38:08 +01001091 err = errno;
Simon Kelley5d162f22012-12-20 14:55:46 +00001092
1093 inet_pton(AF_INET6, ALL_ROUTERS, &mreq.ipv6mr_multiaddr);
1094
1095 if (daemon->doing_ra &&
1096 setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
Simon Kelley9cdcfe92015-08-26 22:38:08 +01001097 err = errno;
Simon Kelley5d162f22012-12-20 14:55:46 +00001098
1099 if (err)
1100 {
1101 char *s = _("interface %s failed to join DHCPv6 multicast group: %s");
Simon Kelley9cdcfe92015-08-26 22:38:08 +01001102 errno = err;
1103
1104#ifdef HAVE_LINUX_NETWORK
1105 if (errno == ENOMEM)
1106 my_syslog(LOG_ERR, _("try increasing /proc/sys/net/core/optmem_max"));
1107#endif
1108
Simon Kelley5d162f22012-12-20 14:55:46 +00001109 if (dienow)
1110 die(s, iface->name, EC_BADNET);
1111 else
1112 my_syslog(LOG_ERR, s, iface->name, strerror(errno));
1113 }
1114 }
1115 }
1116}
1117#endif
1118
Simon Kelley9009d742008-11-14 20:04:27 +00001119/* return a UDP socket bound to a random port, have to cope with straying into
Simon Kelley1a6bca82008-07-11 11:11:42 +01001120 occupied port nos and reserved ones. */
1121int random_sock(int family)
1122{
1123 int fd;
1124
1125 if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
1126 {
Simon Kelley3927da42008-07-20 15:10:39 +01001127 union mysockaddr addr;
Hans Dedecker926332a2016-01-23 10:48:12 +00001128 unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
Simon Kelley9009d742008-11-14 20:04:27 +00001129 int tries = ports_avail < 30 ? 3 * ports_avail : 100;
Simon Kelley3927da42008-07-20 15:10:39 +01001130
Simon Kelley1a6bca82008-07-11 11:11:42 +01001131 memset(&addr, 0, sizeof(addr));
Simon Kelley3927da42008-07-20 15:10:39 +01001132 addr.sa.sa_family = family;
Simon Kelley1a6bca82008-07-11 11:11:42 +01001133
Simon Kelley1ad24ae2008-07-20 20:22:50 +01001134 /* don't loop forever if all ports in use. */
1135
Simon Kelley1a6bca82008-07-11 11:11:42 +01001136 if (fix_fd(fd))
Simon Kelley9009d742008-11-14 20:04:27 +00001137 while(tries--)
Simon Kelley1a6bca82008-07-11 11:11:42 +01001138 {
1139 unsigned short port = rand16();
1140
Hans Dedecker926332a2016-01-23 10:48:12 +00001141 if (daemon->min_port != 0 || daemon->max_port != MAX_PORT)
1142 port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
Simon Kelley1a6bca82008-07-11 11:11:42 +01001143
1144 if (family == AF_INET)
1145 {
1146 addr.in.sin_addr.s_addr = INADDR_ANY;
Simon Kelley3927da42008-07-20 15:10:39 +01001147 addr.in.sin_port = port;
Simon Kelley1a6bca82008-07-11 11:11:42 +01001148#ifdef HAVE_SOCKADDR_SA_LEN
1149 addr.in.sin_len = sizeof(struct sockaddr_in);
1150#endif
1151 }
1152#ifdef HAVE_IPV6
1153 else
1154 {
1155 addr.in6.sin6_addr = in6addr_any;
Simon Kelley3927da42008-07-20 15:10:39 +01001156 addr.in6.sin6_port = port;
Simon Kelley1a6bca82008-07-11 11:11:42 +01001157#ifdef HAVE_SOCKADDR_SA_LEN
1158 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
1159#endif
1160 }
1161#endif
1162
1163 if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
1164 return fd;
1165
1166 if (errno != EADDRINUSE && errno != EACCES)
1167 break;
1168 }
1169
1170 close(fd);
1171 }
1172
1173 return -1;
1174}
1175
1176
Simon Kelley824af852008-02-12 20:43:05 +00001177int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
1178{
1179 union mysockaddr addr_copy = *addr;
1180
1181 /* cannot set source _port_ for TCP connections. */
1182 if (is_tcp)
1183 {
1184 if (addr_copy.sa.sa_family == AF_INET)
1185 addr_copy.in.sin_port = 0;
1186#ifdef HAVE_IPV6
1187 else
1188 addr_copy.in6.sin6_port = 0;
1189#endif
1190 }
1191
1192 if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
1193 return 0;
1194
1195#if defined(SO_BINDTODEVICE)
Simon Kelley73a08a22009-02-05 20:28:08 +00001196 if (intname[0] != 0 &&
Simon Kelley316e2732010-01-22 20:16:09 +00001197 setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
Simon Kelley824af852008-02-12 20:43:05 +00001198 return 0;
1199#endif
1200
1201 return 1;
1202}
1203
1204static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001205{
1206 struct serverfd *sfd;
Simon Kelley824af852008-02-12 20:43:05 +00001207 int errsave;
Simon Kelleyfd9fa482004-10-21 20:24:00 +01001208
Simon Kelley1a6bca82008-07-11 11:11:42 +01001209 /* when using random ports, servers which would otherwise use
1210 the INADDR_ANY/port0 socket have sfd set to NULL */
Simon Kelley73a08a22009-02-05 20:28:08 +00001211 if (!daemon->osport && intname[0] == 0)
Simon Kelley1a6bca82008-07-11 11:11:42 +01001212 {
1213 errno = 0;
1214
1215 if (addr->sa.sa_family == AF_INET &&
1216 addr->in.sin_addr.s_addr == INADDR_ANY &&
1217 addr->in.sin_port == htons(0))
1218 return NULL;
1219
1220#ifdef HAVE_IPV6
1221 if (addr->sa.sa_family == AF_INET6 &&
1222 memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
1223 addr->in6.sin6_port == htons(0))
1224 return NULL;
1225#endif
1226 }
1227
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001228 /* may have a suitable one already */
Simon Kelley824af852008-02-12 20:43:05 +00001229 for (sfd = daemon->sfds; sfd; sfd = sfd->next )
1230 if (sockaddr_isequal(&sfd->source_addr, addr) &&
1231 strcmp(intname, sfd->interface) == 0)
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001232 return sfd;
1233
1234 /* need to make a new one. */
1235 errno = ENOMEM; /* in case malloc fails. */
Simon Kelley5aabfc72007-08-29 11:24:47 +01001236 if (!(sfd = whine_malloc(sizeof(struct serverfd))))
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001237 return NULL;
1238
1239 if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
1240 {
1241 free(sfd);
1242 return NULL;
1243 }
1244
Simon Kelley824af852008-02-12 20:43:05 +00001245 if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd))
1246 {
1247 errsave = errno; /* save error from bind. */
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001248 close(sfd->fd);
1249 free(sfd);
1250 errno = errsave;
1251 return NULL;
1252 }
Simon Kelley824af852008-02-12 20:43:05 +00001253
1254 strcpy(sfd->interface, intname);
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001255 sfd->source_addr = *addr;
Simon Kelley824af852008-02-12 20:43:05 +00001256 sfd->next = daemon->sfds;
1257 daemon->sfds = sfd;
1258 return sfd;
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001259}
1260
Simon Kelley824af852008-02-12 20:43:05 +00001261/* create upstream sockets during startup, before root is dropped which may be needed
1262 this allows query_port to be a low port and interface binding */
1263void pre_allocate_sfds(void)
1264{
1265 struct server *srv;
1266
1267 if (daemon->query_port != 0)
1268 {
1269 union mysockaddr addr;
1270 memset(&addr, 0, sizeof(addr));
1271 addr.in.sin_family = AF_INET;
1272 addr.in.sin_addr.s_addr = INADDR_ANY;
1273 addr.in.sin_port = htons(daemon->query_port);
1274#ifdef HAVE_SOCKADDR_SA_LEN
1275 addr.in.sin_len = sizeof(struct sockaddr_in);
1276#endif
1277 allocate_sfd(&addr, "");
1278#ifdef HAVE_IPV6
1279 memset(&addr, 0, sizeof(addr));
1280 addr.in6.sin6_family = AF_INET6;
1281 addr.in6.sin6_addr = in6addr_any;
1282 addr.in6.sin6_port = htons(daemon->query_port);
1283#ifdef HAVE_SOCKADDR_SA_LEN
1284 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
1285#endif
1286 allocate_sfd(&addr, "");
1287#endif
1288 }
1289
1290 for (srv = daemon->servers; srv; srv = srv->next)
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001291 if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
Simon Kelley824af852008-02-12 20:43:05 +00001292 !allocate_sfd(&srv->source_addr, srv->interface) &&
Simon Kelley1a6bca82008-07-11 11:11:42 +01001293 errno != 0 &&
Simon Kelley28866e92011-02-14 20:19:14 +00001294 option_bool(OPT_NOWILD))
Simon Kelley824af852008-02-12 20:43:05 +00001295 {
Simon Kelley316e2732010-01-22 20:16:09 +00001296 prettyprint_addr(&srv->source_addr, daemon->namebuff);
Simon Kelley73a08a22009-02-05 20:28:08 +00001297 if (srv->interface[0] != 0)
Simon Kelley824af852008-02-12 20:43:05 +00001298 {
1299 strcat(daemon->namebuff, " ");
1300 strcat(daemon->namebuff, srv->interface);
1301 }
1302 die(_("failed to bind server socket for %s: %s"),
1303 daemon->namebuff, EC_BADNET);
1304 }
1305}
1306
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001307void mark_servers(int flag)
1308{
1309 struct server *serv;
1310
1311 /* mark everything with argument flag */
1312 for (serv = daemon->servers; serv; serv = serv->next)
Simon Kelley40766e52014-07-29 16:52:00 +01001313 {
1314 if (serv->flags & flag)
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +01001315 serv->flags |= SERV_MARK;
1316#ifdef HAVE_LOOP
Simon Kelley40766e52014-07-29 16:52:00 +01001317 /* Give looped servers another chance */
1318 serv->flags &= ~SERV_LOOP;
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +01001319#endif
Simon Kelley40766e52014-07-29 16:52:00 +01001320 }
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001321}
1322
1323void cleanup_servers(void)
1324{
1325 struct server *serv, *tmp, **up;
1326
1327 /* unlink and free anything still marked. */
1328 for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
1329 {
1330 tmp = serv->next;
1331 if (serv->flags & SERV_MARK)
1332 {
1333 server_gone(serv);
1334 *up = serv->next;
1335 if (serv->domain)
1336 free(serv->domain);
1337 free(serv);
1338 }
1339 else
1340 up = &serv->next;
1341 }
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +01001342
1343#ifdef HAVE_LOOP
1344 /* Now we have a new set of servers, test for loops. */
1345 loop_send_probes();
1346#endif
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001347}
1348
1349void add_update_server(int flags,
1350 union mysockaddr *addr,
1351 union mysockaddr *source_addr,
1352 const char *interface,
1353 const char *domain)
1354{
Simon Kelley7b1eae42014-02-20 13:43:28 +00001355 struct server *serv, *next = NULL;
1356 char *domain_str = NULL;
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001357
1358 /* See if there is a suitable candidate, and unmark */
1359 for (serv = daemon->servers; serv; serv = serv->next)
1360 if (serv->flags & SERV_MARK)
1361 {
1362 if (domain)
1363 {
1364 if (!(serv->flags & SERV_HAS_DOMAIN) || !hostname_isequal(domain, serv->domain))
1365 continue;
1366 }
1367 else
1368 {
1369 if (serv->flags & SERV_HAS_DOMAIN)
1370 continue;
1371 }
1372
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001373 break;
1374 }
Simon Kelley7b1eae42014-02-20 13:43:28 +00001375
1376 if (serv)
1377 {
1378 domain_str = serv->domain;
1379 next = serv->next;
1380 }
1381 else if ((serv = whine_malloc(sizeof (struct server))))
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001382 {
1383 /* Not found, create a new one. */
Simon Kelley7b1eae42014-02-20 13:43:28 +00001384 if (domain && !(domain_str = whine_malloc(strlen(domain)+1)))
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001385 {
1386 free(serv);
1387 serv = NULL;
1388 }
1389 else
1390 {
1391 struct server *s;
1392 /* Add to the end of the chain, for order */
1393 if (!daemon->servers)
1394 daemon->servers = serv;
1395 else
1396 {
1397 for (s = daemon->servers; s->next; s = s->next);
1398 s->next = serv;
1399 }
1400 if (domain)
Simon Kelley7b1eae42014-02-20 13:43:28 +00001401 strcpy(domain_str, domain);
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001402 }
1403 }
1404
1405 if (serv)
1406 {
Simon Kelley7b1eae42014-02-20 13:43:28 +00001407 memset(serv, 0, sizeof(struct server));
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001408 serv->flags = flags;
Simon Kelley7b1eae42014-02-20 13:43:28 +00001409 serv->domain = domain_str;
1410 serv->next = next;
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001411 serv->queries = serv->failed_queries = 0;
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +01001412#ifdef HAVE_LOOP
1413 serv->uid = rand32();
1414#endif
1415
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001416 if (domain)
1417 serv->flags |= SERV_HAS_DOMAIN;
1418
1419 if (interface)
Simon Kelley7b1eae42014-02-20 13:43:28 +00001420 strcpy(serv->interface, interface);
1421 if (addr)
1422 serv->addr = *addr;
1423 if (source_addr)
1424 serv->source_addr = *source_addr;
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001425 }
1426}
Simon Kelley824af852008-02-12 20:43:05 +00001427
Simon Kelley5aabfc72007-08-29 11:24:47 +01001428void check_servers(void)
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001429{
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001430 struct irec *iface;
Simon Kelley7bcca002014-02-19 17:45:17 +00001431 struct server *serv;
Simon Kelleyb9702602016-05-03 22:34:06 +01001432 int port = 0, count;
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001433
Simon Kelley316e2732010-01-22 20:16:09 +00001434 /* interface may be new since startup */
Simon Kelley28866e92011-02-14 20:19:14 +00001435 if (!option_bool(OPT_NOWILD))
Simon Kelley115ac3e2013-05-20 11:28:32 +01001436 enumerate_interfaces(0);
Simon Kelley316e2732010-01-22 20:16:09 +00001437
Simon Kelley367341f2016-01-12 15:58:23 +00001438#ifdef HAVE_DNSSEC
1439 /* Disable DNSSEC validation when using server=/domain/.... servers
1440 unless there's a configured trust anchor. */
1441 for (serv = daemon->servers; serv; serv = serv->next)
1442 serv->flags |= SERV_DO_DNSSEC;
1443#endif
1444
Simon Kelleyb9702602016-05-03 22:34:06 +01001445 for (count = 0, serv = daemon->servers; serv; serv = serv->next)
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001446 {
Simon Kelley367341f2016-01-12 15:58:23 +00001447 if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001448 {
Simon Kelley14ffa072016-04-25 16:36:44 +01001449 /* Init edns_pktsz for newly created server records. */
1450 if (serv->edns_pktsz == 0)
1451 serv->edns_pktsz = daemon->edns_pktsz;
1452
Simon Kelley367341f2016-01-12 15:58:23 +00001453#ifdef HAVE_DNSSEC
Simon Kelley92be34a2016-01-16 18:39:54 +00001454 if (option_bool(OPT_DNSSEC_VALID))
1455 {
1456 if (serv->flags & SERV_HAS_DOMAIN)
1457 {
1458 struct ds_config *ds;
1459 char *domain = serv->domain;
1460
1461 /* .example.com is valid */
1462 while (*domain == '.')
1463 domain++;
1464
1465 for (ds = daemon->ds; ds; ds = ds->next)
1466 if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
1467 break;
1468
1469 if (!ds)
1470 serv->flags &= ~SERV_DO_DNSSEC;
1471 }
1472 else if (serv->flags & SERV_FOR_NODOTS)
Simon Kelley367341f2016-01-12 15:58:23 +00001473 serv->flags &= ~SERV_DO_DNSSEC;
1474 }
1475#endif
1476
1477 port = prettyprint_addr(&serv->addr, daemon->namebuff);
1478
Simon Kelley16972692006-10-16 20:04:18 +01001479 /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
Simon Kelley7bcca002014-02-19 17:45:17 +00001480 if (serv->addr.sa.sa_family == AF_INET &&
1481 serv->addr.in.sin_addr.s_addr == 0)
Simon Kelley16972692006-10-16 20:04:18 +01001482 {
Simon Kelley7bcca002014-02-19 17:45:17 +00001483 serv->flags |= SERV_MARK;
Simon Kelley16972692006-10-16 20:04:18 +01001484 continue;
1485 }
1486
Simon Kelley3d8df262005-08-29 12:19:27 +01001487 for (iface = daemon->interfaces; iface; iface = iface->next)
Simon Kelley7bcca002014-02-19 17:45:17 +00001488 if (sockaddr_isequal(&serv->addr, &iface->addr))
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001489 break;
1490 if (iface)
1491 {
Simon Kelleyf2621c72007-04-29 19:47:21 +01001492 my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
Simon Kelley7bcca002014-02-19 17:45:17 +00001493 serv->flags |= SERV_MARK;
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001494 continue;
1495 }
1496
1497 /* Do we need a socket set? */
Simon Kelley7bcca002014-02-19 17:45:17 +00001498 if (!serv->sfd &&
1499 !(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface)) &&
Simon Kelley1a6bca82008-07-11 11:11:42 +01001500 errno != 0)
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001501 {
Simon Kelleyf2621c72007-04-29 19:47:21 +01001502 my_syslog(LOG_WARNING,
1503 _("ignoring nameserver %s - cannot make/bind socket: %s"),
1504 daemon->namebuff, strerror(errno));
Simon Kelley7bcca002014-02-19 17:45:17 +00001505 serv->flags |= SERV_MARK;
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001506 continue;
1507 }
1508 }
1509
Simon Kelley979fe862015-03-19 22:50:22 +00001510 if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001511 {
Simon Kelleyb9702602016-05-03 22:34:06 +01001512 if (++count > SERVERS_LOGGED)
1513 continue;
1514
Simon Kelley7bcca002014-02-19 17:45:17 +00001515 if (serv->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001516 {
Simon Kelley367341f2016-01-12 15:58:23 +00001517 char *s1, *s2, *s3 = "";
1518#ifdef HAVE_DNSSEC
1519 if (option_bool(OPT_DNSSEC_VALID) && !(serv->flags & SERV_DO_DNSSEC))
1520 s3 = _("(no DNSSEC)");
1521#endif
Simon Kelley7bcca002014-02-19 17:45:17 +00001522 if (!(serv->flags & SERV_HAS_DOMAIN))
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001523 s1 = _("unqualified"), s2 = _("names");
Simon Kelley7bcca002014-02-19 17:45:17 +00001524 else if (strlen(serv->domain) == 0)
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001525 s1 = _("default"), s2 = "";
1526 else
Simon Kelley7bcca002014-02-19 17:45:17 +00001527 s1 = _("domain"), s2 = serv->domain;
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001528
Simon Kelley7bcca002014-02-19 17:45:17 +00001529 if (serv->flags & SERV_NO_ADDR)
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001530 my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
Simon Kelley7bcca002014-02-19 17:45:17 +00001531 else if (serv->flags & SERV_USE_RESOLV)
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001532 my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
Simon Kelley979fe862015-03-19 22:50:22 +00001533 else
Simon Kelley367341f2016-01-12 15:58:23 +00001534 my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s %s"), daemon->namebuff, port, s1, s2, s3);
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001535 }
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +01001536#ifdef HAVE_LOOP
1537 else if (serv->flags & SERV_LOOP)
1538 my_syslog(LOG_INFO, _("NOT using nameserver %s#%d - query loop detected"), daemon->namebuff, port);
1539#endif
Simon Kelley7bcca002014-02-19 17:45:17 +00001540 else if (serv->interface[0] != 0)
1541 my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, serv->interface);
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001542 else
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001543 my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001544 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001545 }
Simon Kelleyb9702602016-05-03 22:34:06 +01001546
1547 if (count - 1 > SERVERS_LOGGED)
1548 my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
Simon Kelley7bcca002014-02-19 17:45:17 +00001549
1550 cleanup_servers();
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001551}
Simon Kelley849a8352006-06-09 21:02:31 +01001552
1553/* Return zero if no servers found, in that case we keep polling.
1554 This is a protection against an update-time/write race on resolv.conf */
Simon Kelley5aabfc72007-08-29 11:24:47 +01001555int reload_servers(char *fname)
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001556{
1557 FILE *f;
1558 char *line;
Simon Kelley849a8352006-06-09 21:02:31 +01001559 int gotone = 0;
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001560
Simon Kelley849a8352006-06-09 21:02:31 +01001561 /* buff happens to be MAXDNAME long... */
1562 if (!(f = fopen(fname, "r")))
1563 {
Simon Kelleyf2621c72007-04-29 19:47:21 +01001564 my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
Simon Kelley849a8352006-06-09 21:02:31 +01001565 return 0;
1566 }
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001567
1568 mark_servers(SERV_FROM_RESOLV);
1569
Simon Kelley849a8352006-06-09 21:02:31 +01001570 while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
1571 {
1572 union mysockaddr addr, source_addr;
1573 char *token = strtok(line, " \t\n\r");
1574
Simon Kelley5aabfc72007-08-29 11:24:47 +01001575 if (!token)
1576 continue;
1577 if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
Simon Kelley849a8352006-06-09 21:02:31 +01001578 continue;
1579 if (!(token = strtok(NULL, " \t\n\r")))
1580 continue;
1581
1582 memset(&addr, 0, sizeof(addr));
1583 memset(&source_addr, 0, sizeof(source_addr));
1584
1585 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
1586 {
1587#ifdef HAVE_SOCKADDR_SA_LEN
1588 source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
1589#endif
1590 source_addr.in.sin_family = addr.in.sin_family = AF_INET;
1591 addr.in.sin_port = htons(NAMESERVER_PORT);
1592 source_addr.in.sin_addr.s_addr = INADDR_ANY;
1593 source_addr.in.sin_port = htons(daemon->query_port);
1594 }
1595#ifdef HAVE_IPV6
Simon Kelley7de060b2011-08-26 17:24:52 +01001596 else
1597 {
1598 int scope_index = 0;
1599 char *scope_id = strchr(token, '%');
1600
1601 if (scope_id)
1602 {
1603 *(scope_id++) = 0;
1604 scope_index = if_nametoindex(scope_id);
1605 }
1606
1607 if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
1608 {
Simon Kelley849a8352006-06-09 21:02:31 +01001609#ifdef HAVE_SOCKADDR_SA_LEN
Simon Kelley7de060b2011-08-26 17:24:52 +01001610 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
Simon Kelley849a8352006-06-09 21:02:31 +01001611#endif
Simon Kelley7de060b2011-08-26 17:24:52 +01001612 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
1613 source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0;
1614 addr.in6.sin6_port = htons(NAMESERVER_PORT);
1615 addr.in6.sin6_scope_id = scope_index;
1616 source_addr.in6.sin6_addr = in6addr_any;
1617 source_addr.in6.sin6_port = htons(daemon->query_port);
1618 source_addr.in6.sin6_scope_id = 0;
1619 }
1620 else
1621 continue;
Simon Kelley849a8352006-06-09 21:02:31 +01001622 }
Simon Kelley7de060b2011-08-26 17:24:52 +01001623#else /* IPV6 */
Simon Kelley849a8352006-06-09 21:02:31 +01001624 else
1625 continue;
Simon Kelley7de060b2011-08-26 17:24:52 +01001626#endif
1627
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001628 add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL);
Simon Kelley849a8352006-06-09 21:02:31 +01001629 gotone = 1;
1630 }
1631
Simon Kelley849a8352006-06-09 21:02:31 +01001632 fclose(f);
Simon Kelleyd68c2ca2014-02-18 22:30:30 +00001633 cleanup_servers();
Simon Kelley849a8352006-06-09 21:02:31 +01001634
1635 return gotone;
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001636}
1637
Simon Kelley1ee9be42013-12-09 16:50:19 +00001638/* Called when addresses are added or deleted from an interface */
1639void newaddress(time_t now)
1640{
1641 (void)now;
1642
Simon Kelley89b12ed2014-03-06 13:27:57 +00001643 if (option_bool(OPT_CLEVERBIND) || option_bool(OPT_LOCAL_SERVICE) ||
1644 daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
Simon Kelley1ee9be42013-12-09 16:50:19 +00001645 enumerate_interfaces(0);
1646
1647 if (option_bool(OPT_CLEVERBIND))
1648 create_bound_listeners(0);
1649
1650#ifdef HAVE_DHCP6
1651 if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
1652 join_multicast(0);
1653
1654 if (daemon->doing_dhcp6 || daemon->doing_ra)
1655 dhcp_construct_contexts(now);
1656
1657 if (daemon->doing_dhcp6)
1658 lease_find_interfaces(now);
1659#endif
1660}
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001661
1662
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001663
1664
1665