xref: /minix/external/bsd/dhcpcd/dist/ipv4.c (revision 9f20bfa6)
1 #include <sys/cdefs.h>
2  __RCSID("$NetBSD: ipv4.c,v 1.17 2015/08/21 10:39:00 roy Exp $");
3 
4 /*
5  * dhcpcd - DHCP client daemon
6  * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
7  * All rights reserved
8 
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/socket.h>
32 #include <sys/types.h>
33 
34 #include <arpa/inet.h>
35 #include <net/if.h>
36 #include <net/route.h>
37 #include <netinet/if_ether.h>
38 #include <netinet/in.h>
39 
40 #include <assert.h>
41 #include <ctype.h>
42 #include <errno.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46 
47 #include "config.h"
48 #include "arp.h"
49 #include "common.h"
50 #include "dhcpcd.h"
51 #include "dhcp.h"
52 #include "if.h"
53 #include "if-options.h"
54 #include "ipv4.h"
55 #include "ipv4ll.h"
56 #include "script.h"
57 
58 #define IPV4_LOOPBACK_ROUTE
59 #if defined(__linux__) || (defined(BSD) && defined(RTF_LOCAL))
60 /* Linux has had loopback routes in the local table since 2.2 */
61 #undef IPV4_LOOPBACK_ROUTE
62 #endif
63 
64 uint8_t
inet_ntocidr(struct in_addr address)65 inet_ntocidr(struct in_addr address)
66 {
67 	uint8_t cidr = 0;
68 	uint32_t mask = htonl(address.s_addr);
69 
70 	while (mask) {
71 		cidr++;
72 		mask <<= 1;
73 	}
74 	return cidr;
75 }
76 
77 int
inet_cidrtoaddr(int cidr,struct in_addr * addr)78 inet_cidrtoaddr(int cidr, struct in_addr *addr)
79 {
80 	int ocets;
81 
82 	if (cidr < 1 || cidr > 32) {
83 		errno = EINVAL;
84 		return -1;
85 	}
86 	ocets = (cidr + 7) / NBBY;
87 
88 	addr->s_addr = 0;
89 	if (ocets > 0) {
90 		memset(&addr->s_addr, 255, (size_t)ocets - 1);
91 		memset((unsigned char *)&addr->s_addr + (ocets - 1),
92 		    (256 - (1 << (32 - cidr) % NBBY)), 1);
93 	}
94 
95 	return 0;
96 }
97 
98 uint32_t
ipv4_getnetmask(uint32_t addr)99 ipv4_getnetmask(uint32_t addr)
100 {
101 	uint32_t dst;
102 
103 	if (addr == 0)
104 		return 0;
105 
106 	dst = htonl(addr);
107 	if (IN_CLASSA(dst))
108 		return ntohl(IN_CLASSA_NET);
109 	if (IN_CLASSB(dst))
110 		return ntohl(IN_CLASSB_NET);
111 	if (IN_CLASSC(dst))
112 		return ntohl(IN_CLASSC_NET);
113 
114 	return 0;
115 }
116 
117 struct ipv4_addr *
ipv4_iffindaddr(struct interface * ifp,const struct in_addr * addr,const struct in_addr * net)118 ipv4_iffindaddr(struct interface *ifp,
119     const struct in_addr *addr, const struct in_addr *net)
120 {
121 	struct ipv4_state *state;
122 	struct ipv4_addr *ap;
123 
124 	state = IPV4_STATE(ifp);
125 	if (state) {
126 		TAILQ_FOREACH(ap, &state->addrs, next) {
127 			if ((addr == NULL || ap->addr.s_addr == addr->s_addr) &&
128 			    (net == NULL || ap->net.s_addr == net->s_addr))
129 				return ap;
130 		}
131 	}
132 	return NULL;
133 }
134 
135 struct ipv4_addr *
ipv4_iffindlladdr(struct interface * ifp)136 ipv4_iffindlladdr(struct interface *ifp)
137 {
138 	struct ipv4_state *state;
139 	struct ipv4_addr *ap;
140 
141 	state = IPV4_STATE(ifp);
142 	if (state) {
143 		TAILQ_FOREACH(ap, &state->addrs, next) {
144 			if (IN_LINKLOCAL(htonl(ap->addr.s_addr)))
145 				return ap;
146 		}
147 	}
148 	return NULL;
149 }
150 
151 struct ipv4_addr *
ipv4_findaddr(struct dhcpcd_ctx * ctx,const struct in_addr * addr)152 ipv4_findaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
153 {
154 	struct interface *ifp;
155 	struct ipv4_addr *ap;
156 
157 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
158 		ap = ipv4_iffindaddr(ifp, addr, NULL);
159 		if (ap)
160 			return ap;
161 	}
162 	return NULL;
163 }
164 
165 int
ipv4_hasaddr(const struct interface * ifp)166 ipv4_hasaddr(const struct interface *ifp)
167 {
168 	const struct dhcp_state *dstate;
169 	const struct ipv4ll_state *istate;
170 
171 	dstate = D_CSTATE(ifp);
172 	istate = IPV4LL_CSTATE(ifp);
173 	return ((dstate &&
174 	    dstate->added == STATE_ADDED &&
175 	    dstate->addr.s_addr != INADDR_ANY) ||
176 	    (istate && istate->addr.s_addr != INADDR_ANY));
177 }
178 
179 void
ipv4_freeroutes(struct rt_head * rts)180 ipv4_freeroutes(struct rt_head *rts)
181 {
182 
183 	if (rts) {
184 		ipv4_freerts(rts);
185 		free(rts);
186 	}
187 }
188 
189 int
ipv4_init(struct dhcpcd_ctx * ctx)190 ipv4_init(struct dhcpcd_ctx *ctx)
191 {
192 
193 	if (ctx->ipv4_routes == NULL) {
194 		ctx->ipv4_routes = malloc(sizeof(*ctx->ipv4_routes));
195 		if (ctx->ipv4_routes == NULL)
196 			return -1;
197 		TAILQ_INIT(ctx->ipv4_routes);
198 	}
199 	if (ctx->ipv4_kroutes == NULL) {
200 		ctx->ipv4_kroutes = malloc(sizeof(*ctx->ipv4_kroutes));
201 		if (ctx->ipv4_kroutes == NULL)
202 			return -1;
203 		TAILQ_INIT(ctx->ipv4_kroutes);
204 	}
205 	return 0;
206 }
207 
208 int
ipv4_protocol_fd(const struct interface * ifp,uint16_t protocol)209 ipv4_protocol_fd(const struct interface *ifp, uint16_t protocol)
210 {
211 
212 	if (protocol == ETHERTYPE_ARP) {
213 		const struct iarp_state *istate;
214 
215 		istate = ARP_CSTATE(ifp);
216 		assert(istate != NULL);
217 		return istate->fd;
218 	} else {
219 		const struct dhcp_state *dstate;
220 
221 		dstate = D_CSTATE(ifp);
222 		assert(dstate != NULL);
223 		return dstate->raw_fd;
224 	}
225 }
226 
227 /* Interface comparer for working out ordering. */
228 int
ipv4_ifcmp(const struct interface * si,const struct interface * ti)229 ipv4_ifcmp(const struct interface *si, const struct interface *ti)
230 {
231 	const struct dhcp_state *sis, *tis;
232 
233 	sis = D_CSTATE(si);
234 	tis = D_CSTATE(ti);
235 	if (sis && !tis)
236 		return -1;
237 	if (!sis && tis)
238 		return 1;
239 	if (!sis && !tis)
240 		return 0;
241 	/* If one has a lease and the other not, it takes precedence. */
242 	if (sis->new && !tis->new)
243 		return -1;
244 	if (!sis->new && tis->new)
245 		return 1;
246 	/* Always prefer proper leases */
247 	if (!(sis->added & STATE_FAKE) && (sis->added & STATE_FAKE))
248 		return -1;
249 	if ((sis->added & STATE_FAKE) && !(sis->added & STATE_FAKE))
250 		return 1;
251 	/* If we are either, they neither have a lease, or they both have.
252 	 * We need to check for IPv4LL and make it non-preferred. */
253 	if (sis->new && tis->new) {
254 		int sill = (sis->new->cookie == htonl(MAGIC_COOKIE));
255 		int till = (tis->new->cookie == htonl(MAGIC_COOKIE));
256 		if (sill && !till)
257 			return -1;
258 		if (!sill && till)
259 			return 1;
260 	}
261 	return 0;
262 }
263 
264 static struct rt *
find_route(struct rt_head * rts,const struct rt * r,const struct rt * srt)265 find_route(struct rt_head *rts, const struct rt *r, const struct rt *srt)
266 {
267 	struct rt *rt;
268 
269 	if (rts == NULL)
270 		return NULL;
271 	TAILQ_FOREACH(rt, rts, next) {
272 		if (rt->dest.s_addr == r->dest.s_addr &&
273 #ifdef HAVE_ROUTE_METRIC
274 		    (srt || (r->iface == NULL || rt->iface == NULL ||
275 		    rt->iface->metric == r->iface->metric)) &&
276 #endif
277                     (!srt || srt != rt) &&
278 		    rt->net.s_addr == r->net.s_addr)
279 			return rt;
280 	}
281 	return NULL;
282 }
283 
284 static void
desc_route(const char * cmd,const struct rt * rt)285 desc_route(const char *cmd, const struct rt *rt)
286 {
287 	char addr[sizeof("000.000.000.000") + 1];
288 	struct dhcpcd_ctx *ctx = rt->iface ? rt->iface->ctx : NULL;
289 	const char *ifname = rt->iface ? rt->iface->name : NULL;
290 
291 	strlcpy(addr, inet_ntoa(rt->dest), sizeof(addr));
292 	if (rt->net.s_addr == htonl(INADDR_BROADCAST) &&
293 	    rt->gate.s_addr == htonl(INADDR_ANY))
294 		logger(ctx, LOG_INFO, "%s: %s host route to %s",
295 		    ifname, cmd, addr);
296 	else if (rt->net.s_addr == htonl(INADDR_BROADCAST))
297 		logger(ctx, LOG_INFO, "%s: %s host route to %s via %s",
298 		    ifname, cmd, addr, inet_ntoa(rt->gate));
299 	else if (rt->dest.s_addr == htonl(INADDR_ANY) &&
300 	    rt->net.s_addr == htonl(INADDR_ANY) &&
301 	    rt->gate.s_addr == htonl(INADDR_ANY))
302 		logger(ctx, LOG_INFO, "%s: %s default route",
303 		    ifname, cmd);
304 	else if (rt->gate.s_addr == htonl(INADDR_ANY))
305 		logger(ctx, LOG_INFO, "%s: %s route to %s/%d",
306 		    ifname, cmd, addr, inet_ntocidr(rt->net));
307 	else if (rt->dest.s_addr == htonl(INADDR_ANY) &&
308 	    rt->net.s_addr == htonl(INADDR_ANY))
309 		logger(ctx, LOG_INFO, "%s: %s default route via %s",
310 		    ifname, cmd, inet_ntoa(rt->gate));
311 	else
312 		logger(ctx, LOG_INFO, "%s: %s route to %s/%d via %s",
313 		    ifname, cmd, addr, inet_ntocidr(rt->net),
314 		    inet_ntoa(rt->gate));
315 }
316 
317 static struct rt *
ipv4_findrt(struct dhcpcd_ctx * ctx,const struct rt * rt,int flags)318 ipv4_findrt(struct dhcpcd_ctx *ctx, const struct rt *rt, int flags)
319 {
320 	struct rt *r;
321 
322 	if (ctx->ipv4_kroutes == NULL)
323 		return NULL;
324 	TAILQ_FOREACH(r, ctx->ipv4_kroutes, next) {
325 		if (rt->dest.s_addr == r->dest.s_addr &&
326 #ifdef HAVE_ROUTE_METRIC
327 		    rt->iface == r->iface &&
328 		    (!flags || rt->metric == r->metric) &&
329 #else
330 		    (!flags || rt->iface == r->iface) &&
331 #endif
332 		    rt->net.s_addr == r->net.s_addr)
333 			return r;
334 	}
335 	return NULL;
336 }
337 
338 void
ipv4_freerts(struct rt_head * routes)339 ipv4_freerts(struct rt_head *routes)
340 {
341 	struct rt *rt;
342 
343 	while ((rt = TAILQ_FIRST(routes))) {
344 		TAILQ_REMOVE(routes, rt, next);
345 		free(rt);
346 	}
347 }
348 
349 /* If something other than dhcpcd removes a route,
350  * we need to remove it from our internal table. */
351 int
ipv4_handlert(struct dhcpcd_ctx * ctx,int cmd,struct rt * rt)352 ipv4_handlert(struct dhcpcd_ctx *ctx, int cmd, struct rt *rt)
353 {
354 	struct rt *f;
355 
356 	if (ctx->ipv4_kroutes == NULL)
357 		return 0;
358 
359 	f = ipv4_findrt(ctx, rt, 1);
360 	switch (cmd) {
361 	case RTM_ADD:
362 		if (f == NULL) {
363 			if ((f = malloc(sizeof(*f))) == NULL)
364 				return -1;
365 			*f = *rt;
366 			TAILQ_INSERT_TAIL(ctx->ipv4_kroutes, f, next);
367 		}
368 		break;
369 	case RTM_DELETE:
370 		if (f) {
371 			TAILQ_REMOVE(ctx->ipv4_kroutes, f, next);
372 			free(f);
373 		}
374 
375 		/* If we manage the route, remove it */
376 		if ((f = find_route(ctx->ipv4_routes, rt, NULL))) {
377 			desc_route("removing", f);
378 			TAILQ_REMOVE(ctx->ipv4_routes, f, next);
379 			free(f);
380 		}
381 		break;
382 	}
383 	return 0;
384 }
385 
386 #define n_route(a)	 nc_route(NULL, a)
387 #define c_route(a, b)	 nc_route(a, b)
388 static int
nc_route(struct rt * ort,struct rt * nrt)389 nc_route(struct rt *ort, struct rt *nrt)
390 {
391 	int change;
392 
393 	/* Don't set default routes if not asked to */
394 	if (nrt->dest.s_addr == 0 &&
395 	    nrt->net.s_addr == 0 &&
396 	    !(nrt->iface->options->options & DHCPCD_GATEWAY))
397 		return -1;
398 
399 	desc_route(ort == NULL ? "adding" : "changing", nrt);
400 
401 	change = 0;
402 	if (ort == NULL) {
403 		ort = ipv4_findrt(nrt->iface->ctx, nrt, 0);
404 		if (ort &&
405 		    ((ort->flags & RTF_REJECT && nrt->flags & RTF_REJECT) ||
406 		     (ort->iface == nrt->iface &&
407 #ifdef HAVE_ROUTE_METRIC
408 		    ort->metric == nrt->metric &&
409 #endif
410 		    ort->gate.s_addr == nrt->gate.s_addr)))
411 		{
412 			if (ort->mtu == nrt->mtu)
413 				return 0;
414 			change = 1;
415 		}
416 	} else if (ort->state & STATE_FAKE && !(nrt->state & STATE_FAKE) &&
417 	    ort->iface == nrt->iface &&
418 #ifdef HAVE_ROUTE_METRIC
419 	    ort->metric == nrt->metric &&
420 #endif
421 	    ort->dest.s_addr == nrt->dest.s_addr &&
422 	    ort->net.s_addr ==  nrt->net.s_addr &&
423 	    ort->gate.s_addr == nrt->gate.s_addr)
424 	{
425 		if (ort->mtu == nrt->mtu)
426 			return 0;
427 		change = 1;
428 	}
429 
430 #ifdef RTF_CLONING
431 	/* BSD can set routes to be cloning routes.
432 	 * Cloned routes inherit the parent flags.
433 	 * As such, we need to delete and re-add the route to flush children
434 	 * to correct the flags. */
435 	if (change && ort != NULL && ort->flags & RTF_CLONING)
436 		change = 0;
437 #endif
438 
439 	if (change) {
440 		if (if_route(RTM_CHANGE, nrt) == 0)
441 			return 0;
442 		if (errno != ESRCH)
443 			logger(nrt->iface->ctx, LOG_ERR, "if_route (CHG): %m");
444 	}
445 
446 #ifdef HAVE_ROUTE_METRIC
447 	/* With route metrics, we can safely add the new route before
448 	 * deleting the old route. */
449 	if (if_route(RTM_ADD, nrt) == 0) {
450 		if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
451 			logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
452 		return 0;
453 	}
454 
455 	/* If the kernel claims the route exists we need to rip out the
456 	 * old one first. */
457 	if (errno != EEXIST || ort == NULL)
458 		goto logerr;
459 #endif
460 
461 	/* No route metrics, we need to delete the old route before
462 	 * adding the new one. */
463 	if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
464 		logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
465 	if (if_route(RTM_ADD, nrt) == 0)
466 		return 0;
467 #ifdef HAVE_ROUTE_METRIC
468 logerr:
469 #endif
470 	logger(nrt->iface->ctx, LOG_ERR, "if_route (ADD): %m");
471 	return -1;
472 }
473 
474 static int
d_route(struct rt * rt)475 d_route(struct rt *rt)
476 {
477 	int retval;
478 
479 	desc_route("deleting", rt);
480 	retval = if_route(RTM_DELETE, rt);
481 	if (retval != 0 && errno != ENOENT && errno != ESRCH)
482 		logger(rt->iface->ctx, LOG_ERR,
483 		    "%s: if_delroute: %m", rt->iface->name);
484 	return retval;
485 }
486 
487 static struct rt_head *
add_subnet_route(struct rt_head * rt,const struct interface * ifp)488 add_subnet_route(struct rt_head *rt, const struct interface *ifp)
489 {
490 	const struct dhcp_state *s;
491 	struct rt *r;
492 
493 	if (rt == NULL) /* earlier malloc failed */
494 		return NULL;
495 
496 	s = D_CSTATE(ifp);
497 	/* Don't create a subnet route for these addresses */
498 	if (s->net.s_addr == INADDR_ANY)
499 		return rt;
500 #ifndef BSD
501 	/* BSD adds a route in this instance */
502 	if (s->net.s_addr == INADDR_BROADCAST)
503 		return rt;
504 #endif
505 
506 	if ((r = calloc(1, sizeof(*r))) == NULL) {
507 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
508 		ipv4_freeroutes(rt);
509 		return NULL;
510 	}
511 	r->dest.s_addr = s->addr.s_addr & s->net.s_addr;
512 	r->net.s_addr = s->net.s_addr;
513 	r->gate.s_addr = INADDR_ANY;
514 	r->mtu = dhcp_get_mtu(ifp);
515 	r->src = s->addr;
516 
517 	TAILQ_INSERT_HEAD(rt, r, next);
518 	return rt;
519 }
520 
521 #ifdef IPV4_LOOPBACK_ROUTE
522 static struct rt_head *
add_loopback_route(struct rt_head * rt,const struct interface * ifp)523 add_loopback_route(struct rt_head *rt, const struct interface *ifp)
524 {
525 	struct rt *r;
526 	const struct dhcp_state *s;
527 
528 	if (rt == NULL) /* earlier malloc failed */
529 		return NULL;
530 
531 	s = D_CSTATE(ifp);
532 	if (s->addr.s_addr == INADDR_ANY)
533 		return rt;
534 
535 	if ((r = calloc(1, sizeof(*r))) == NULL) {
536 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
537 		ipv4_freeroutes(rt);
538 		return NULL;
539 	}
540 	r->dest = s->addr;
541 	r->net.s_addr = INADDR_BROADCAST;
542 	r->gate.s_addr = htonl(INADDR_LOOPBACK);
543 	r->mtu = dhcp_get_mtu(ifp);
544 	r->src = s->addr;
545 	TAILQ_INSERT_HEAD(rt, r, next);
546 	return rt;
547 }
548 #endif
549 
550 static struct rt_head *
get_routes(struct interface * ifp)551 get_routes(struct interface *ifp)
552 {
553 	struct rt_head *nrt;
554 	struct rt *rt, *r = NULL;
555 	const struct dhcp_state *state;
556 
557 	if (ifp->options->routes && TAILQ_FIRST(ifp->options->routes)) {
558 		if ((nrt = malloc(sizeof(*nrt))) == NULL)
559 			return NULL;
560 		TAILQ_INIT(nrt);
561 		TAILQ_FOREACH(rt, ifp->options->routes, next) {
562 			if (rt->gate.s_addr == 0)
563 				break;
564 			if ((r = calloc(1, sizeof(*r))) == NULL) {
565 				logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
566 				ipv4_freeroutes(nrt);
567 				return NULL;
568 			}
569 			memcpy(r, rt, sizeof(*r));
570 			TAILQ_INSERT_TAIL(nrt, r, next);
571 		}
572 	} else
573 		nrt = dhcp_get_routes(ifp);
574 
575 	/* Copy our address as the source address */
576 	if (nrt) {
577 		state = D_CSTATE(ifp);
578 		TAILQ_FOREACH(rt, nrt, next) {
579 			rt->src = state->addr;
580 		}
581 	}
582 
583 	return nrt;
584 }
585 
586 static struct rt_head *
add_destination_route(struct rt_head * rt,const struct interface * ifp)587 add_destination_route(struct rt_head *rt, const struct interface *ifp)
588 {
589 	struct rt *r;
590 	const struct dhcp_state *state;
591 
592 	if (rt == NULL || /* failed a malloc earlier probably */
593 	    !(ifp->flags & IFF_POINTOPOINT) ||
594 	    !has_option_mask(ifp->options->dstmask, DHO_ROUTER) ||
595 	    (state = D_CSTATE(ifp)) == NULL)
596 		return rt;
597 
598 	if ((r = calloc(1, sizeof(*r))) == NULL) {
599 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
600 		ipv4_freeroutes(rt);
601 		return NULL;
602 	}
603 	r->dest.s_addr = INADDR_ANY;
604 	r->net.s_addr = INADDR_ANY;
605 	r->gate.s_addr = state->dst.s_addr;
606 	r->mtu = dhcp_get_mtu(ifp);
607 	r->src = state->addr;
608 	TAILQ_INSERT_HEAD(rt, r, next);
609 	return rt;
610 }
611 
612 /* We should check to ensure the routers are on the same subnet
613  * OR supply a host route. If not, warn and add a host route. */
614 static struct rt_head *
add_router_host_route(struct rt_head * rt,const struct interface * ifp)615 add_router_host_route(struct rt_head *rt, const struct interface *ifp)
616 {
617 	struct rt *rtp, *rtn;
618 	const char *cp, *cp2, *cp3, *cplim;
619 	struct if_options *ifo;
620 	const struct dhcp_state *state;
621 
622 	if (rt == NULL) /* earlier malloc failed */
623 		return NULL;
624 
625 	TAILQ_FOREACH(rtp, rt, next) {
626 		if (rtp->dest.s_addr != INADDR_ANY)
627 			continue;
628 		/* Scan for a route to match */
629 		TAILQ_FOREACH(rtn, rt, next) {
630 			if (rtn == rtp)
631 				break;
632 			/* match host */
633 			if (rtn->dest.s_addr == rtp->gate.s_addr)
634 				break;
635 			/* match subnet */
636 			cp = (const char *)&rtp->gate.s_addr;
637 			cp2 = (const char *)&rtn->dest.s_addr;
638 			cp3 = (const char *)&rtn->net.s_addr;
639 			cplim = cp3 + sizeof(rtn->net.s_addr);
640 			while (cp3 < cplim) {
641 				if ((*cp++ ^ *cp2++) & *cp3++)
642 					break;
643 			}
644 			if (cp3 == cplim)
645 				break;
646 		}
647 		if (rtn != rtp)
648 			continue;
649 		if ((state = D_CSTATE(ifp)) == NULL)
650 			continue;
651 		ifo = ifp->options;
652 		if (ifp->flags & IFF_NOARP) {
653 			if (!(ifo->options & DHCPCD_ROUTER_HOST_ROUTE_WARNED) &&
654 			    !(state->added & STATE_FAKE))
655 			{
656 				ifo->options |= DHCPCD_ROUTER_HOST_ROUTE_WARNED;
657 				logger(ifp->ctx, LOG_WARNING,
658 				    "%s: forcing router %s through interface",
659 				    ifp->name, inet_ntoa(rtp->gate));
660 			}
661 			rtp->gate.s_addr = 0;
662 			continue;
663 		}
664 		if (!(ifo->options & DHCPCD_ROUTER_HOST_ROUTE_WARNED) &&
665 		    !(state->added & STATE_FAKE))
666 		{
667 			ifo->options |= DHCPCD_ROUTER_HOST_ROUTE_WARNED;
668 			logger(ifp->ctx, LOG_WARNING,
669 			    "%s: router %s requires a host route",
670 			    ifp->name, inet_ntoa(rtp->gate));
671 		}
672 		if ((rtn = calloc(1, sizeof(*rtn))) == NULL) {
673 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
674 			ipv4_freeroutes(rt);
675 			return NULL;
676 		}
677 		rtn->dest.s_addr = rtp->gate.s_addr;
678 		rtn->net.s_addr = htonl(INADDR_BROADCAST);
679 		rtn->gate.s_addr = htonl(INADDR_ANY);
680 		rtn->mtu = dhcp_get_mtu(ifp);
681 		rtn->src = state->addr;
682 		TAILQ_INSERT_BEFORE(rtp, rtn, next);
683 	}
684 	return rt;
685 }
686 
687 static int
ipv4_doroute(struct rt * rt,struct rt_head * nrs)688 ipv4_doroute(struct rt *rt, struct rt_head *nrs)
689 {
690 	const struct dhcp_state *state;
691 	struct rt *or;
692 
693 	state = D_CSTATE(rt->iface);
694 	rt->state = state->added & STATE_FAKE;
695 #ifdef HAVE_ROUTE_METRIC
696 	rt->metric = rt->iface->metric;
697 #endif
698 	/* Is this route already in our table? */
699 	if ((find_route(nrs, rt, NULL)) != NULL)
700 		return 0;
701 	/* Do we already manage it? */
702 	if ((or = find_route(rt->iface->ctx->ipv4_routes, rt, NULL))) {
703 		if (state->added & STATE_FAKE)
704 			return 0;
705 		if (or->state & STATE_FAKE ||
706 		    or->iface != rt->iface ||
707 #ifdef HAVE_ROUTE_METRIC
708 		    rt->metric != or->metric ||
709 #endif
710 		    rt->src.s_addr != or->src.s_addr ||
711 		    rt->gate.s_addr != or->gate.s_addr ||
712 		    rt->mtu != or->mtu)
713 		{
714 			if (c_route(or, rt) != 0)
715 				return 0;
716 		}
717 		TAILQ_REMOVE(rt->iface->ctx->ipv4_routes, or, next);
718 		free(or);
719 	} else {
720 		if (state->added & STATE_FAKE) {
721 			if ((or = ipv4_findrt(rt->iface->ctx, rt, 1)) == NULL)
722 				return 0;
723 			rt->iface = or->iface;
724 			rt->gate.s_addr = or->gate.s_addr;
725 #ifdef HAVE_ROUTE_METRIC
726 			rt->metric = or->metric;
727 #endif
728 			rt->mtu = or->mtu;
729 			rt->flags = or->flags;
730 		} else {
731 			if (n_route(rt) != 0)
732 				return 0;
733 		}
734 	}
735 	return 1;
736 }
737 
738 void
ipv4_buildroutes(struct dhcpcd_ctx * ctx)739 ipv4_buildroutes(struct dhcpcd_ctx *ctx)
740 {
741 	struct rt_head *nrs, *dnr;
742 	struct rt *rt, *rtn;
743 	struct interface *ifp;
744 	const struct dhcp_state *state;
745 	int has_default;
746 
747 	/* We need to have the interfaces in the correct order to ensure
748 	 * our routes are managed correctly. */
749 	if_sortinterfaces(ctx);
750 
751 	if ((nrs = malloc(sizeof(*nrs))) == NULL) {
752 		logger(ctx, LOG_ERR, "%s: %m", __func__);
753 		return;
754 	}
755 	TAILQ_INIT(nrs);
756 
757 	has_default = 0;
758 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
759 		state = D_CSTATE(ifp);
760 		if (state != NULL && state->new != NULL && state->added) {
761 			dnr = get_routes(ifp);
762 			dnr = add_subnet_route(dnr, ifp);
763 		} else
764 			dnr = NULL;
765 		if ((rt = ipv4ll_subnet_route(ifp)) != NULL) {
766 			if (dnr == NULL) {
767 				if ((dnr = malloc(sizeof(*dnr))) == NULL) {
768 					logger(ifp->ctx, LOG_ERR,
769 					    "%s: malloc %m", __func__);
770 					continue;
771 				}
772 				TAILQ_INIT(dnr);
773 			}
774 			TAILQ_INSERT_HEAD(dnr, rt, next);
775 		}
776 		if (dnr == NULL)
777 			continue;
778 #ifdef IPV4_LOOPBACK_ROUTE
779 		dnr = add_loopback_route(dnr, ifp);
780 #endif
781 		if (ifp->options->options & DHCPCD_GATEWAY) {
782 			dnr = add_router_host_route(dnr, ifp);
783 			dnr = add_destination_route(dnr, ifp);
784 		}
785 		if (dnr == NULL)
786 			continue;
787 		TAILQ_FOREACH_SAFE(rt, dnr, next, rtn) {
788 			rt->iface = ifp;
789 			if (ipv4_doroute(rt, nrs) == 1) {
790 				TAILQ_REMOVE(dnr, rt, next);
791 				TAILQ_INSERT_TAIL(nrs, rt, next);
792 				if (rt->dest.s_addr == INADDR_ANY)
793 					has_default = 1;
794 			}
795 		}
796 		ipv4_freeroutes(dnr);
797 	}
798 
799 	/* If we don't manage a default route, grab one without a
800 	 * gateway for any IPv4LL enabled interfaces. */
801 	if (!has_default) {
802 		TAILQ_FOREACH(ifp, ctx->ifaces, next) {
803 			if ((rt = ipv4ll_default_route(ifp)) != NULL) {
804 				if (ipv4_doroute(rt, nrs) == 1)
805 					TAILQ_INSERT_TAIL(nrs, rt, next);
806 				else
807 					free(rt);
808 			}
809 		}
810 	}
811 
812 	/* Remove old routes we used to manage */
813 	if (ctx->ipv4_routes) {
814 		TAILQ_FOREACH(rt, ctx->ipv4_routes, next) {
815 			if (find_route(nrs, rt, NULL) == NULL &&
816 			    (rt->iface->options->options &
817 			    (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
818 			    (DHCPCD_EXITING | DHCPCD_PERSISTENT))
819 				d_route(rt);
820 		}
821 	}
822 	ipv4_freeroutes(ctx->ipv4_routes);
823 	ctx->ipv4_routes = nrs;
824 }
825 
826 int
ipv4_deladdr(struct interface * ifp,const struct in_addr * addr,const struct in_addr * net,int keeparp)827 ipv4_deladdr(struct interface *ifp,
828     const struct in_addr *addr, const struct in_addr *net, int keeparp)
829 {
830 	struct dhcp_state *dstate;
831 	int r;
832 	struct ipv4_state *state;
833 	struct ipv4_addr *ap;
834 	struct arp_state *astate;
835 
836 	logger(ifp->ctx, LOG_DEBUG, "%s: deleting IP address %s/%d",
837 	    ifp->name, inet_ntoa(*addr), inet_ntocidr(*net));
838 
839 	r = if_deladdress(ifp, addr, net);
840 	if (r == -1 && errno != EADDRNOTAVAIL && errno != ENXIO &&
841 	    errno != ENODEV)
842 		logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
843 
844 	if (!keeparp && (astate = arp_find(ifp, addr)) != NULL)
845 		arp_free(astate);
846 
847 	state = IPV4_STATE(ifp);
848 	TAILQ_FOREACH(ap, &state->addrs, next) {
849 		if (ap->addr.s_addr == addr->s_addr &&
850 		    ap->net.s_addr == net->s_addr)
851 		{
852 			TAILQ_REMOVE(&state->addrs, ap, next);
853 			free(ap);
854 			break;
855 		}
856 	}
857 
858 	/* Have to do this last incase the function arguments
859 	 * were these very pointers. */
860 	dstate = D_STATE(ifp);
861 	if (dstate &&
862 	    dstate->addr.s_addr == addr->s_addr &&
863 	    dstate->net.s_addr == net->s_addr)
864 	{
865 		dstate->added = 0;
866 		dstate->addr.s_addr = 0;
867 		dstate->net.s_addr = 0;
868 	}
869 	return r;
870 }
871 
872 static int
delete_address(struct interface * ifp)873 delete_address(struct interface *ifp)
874 {
875 	int r;
876 	struct if_options *ifo;
877 	struct dhcp_state *state;
878 
879 	state = D_STATE(ifp);
880 	ifo = ifp->options;
881 	if (ifo->options & DHCPCD_INFORM ||
882 	    (ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0))
883 		return 0;
884 	r = ipv4_deladdr(ifp, &state->addr, &state->net, 0);
885 	return r;
886 }
887 
888 struct ipv4_state *
ipv4_getstate(struct interface * ifp)889 ipv4_getstate(struct interface *ifp)
890 {
891 	struct ipv4_state *state;
892 
893 	state = IPV4_STATE(ifp);
894 	if (state == NULL) {
895 	        ifp->if_data[IF_DATA_IPV4] = malloc(sizeof(*state));
896 		state = IPV4_STATE(ifp);
897 		if (state == NULL) {
898 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
899 			return NULL;
900 		}
901 		TAILQ_INIT(&state->addrs);
902 		TAILQ_INIT(&state->routes);
903 #ifdef BSD
904 		state->buffer_size = state->buffer_len = state->buffer_pos = 0;
905 		state->buffer = NULL;
906 #endif
907 	}
908 	return state;
909 }
910 
911 struct ipv4_addr *
ipv4_addaddr(struct interface * ifp,const struct in_addr * addr,const struct in_addr * mask,const struct in_addr * bcast)912 ipv4_addaddr(struct interface *ifp, const struct in_addr *addr,
913     const struct in_addr *mask, const struct in_addr *bcast)
914 {
915 	struct ipv4_state *state;
916 	struct ipv4_addr *ia;
917 
918 	if ((state = ipv4_getstate(ifp)) == NULL) {
919 		logger(ifp->ctx, LOG_ERR, "%s: ipv4_getstate: %m", __func__);
920 		return NULL;
921 	}
922 	if (ifp->options->options & DHCPCD_NOALIAS) {
923 		struct ipv4_addr *ian;
924 
925 		TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ian) {
926 			if (ia->addr.s_addr != addr->s_addr)
927 				ipv4_deladdr(ifp, &ia->addr, &ia->net, 0);
928 		}
929 	}
930 
931 	if ((ia = malloc(sizeof(*ia))) == NULL) {
932 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
933 		return NULL;
934 	}
935 
936 	logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s/%d",
937 	    ifp->name, inet_ntoa(*addr), inet_ntocidr(*mask));
938 	if (if_addaddress(ifp, addr, mask, bcast) == -1) {
939 		if (errno != EEXIST)
940 			logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m",
941 			    __func__);
942 		free(ia);
943 		return NULL;
944 	}
945 
946 	ia->iface = ifp;
947 	ia->addr = *addr;
948 	ia->net = *mask;
949 #ifdef IN_IFF_TENTATIVE
950 	ia->addr_flags = IN_IFF_TENTATIVE;
951 #endif
952 	TAILQ_INSERT_TAIL(&state->addrs, ia, next);
953 	return ia;
954 }
955 
956 static int
ipv4_daddaddr(struct interface * ifp,const struct dhcp_lease * lease)957 ipv4_daddaddr(struct interface *ifp, const struct dhcp_lease *lease)
958 {
959 	struct dhcp_state *state;
960 
961 	if (ipv4_addaddr(ifp, &lease->addr, &lease->net, &lease->brd) == NULL)
962 		return -1;
963 
964 	state = D_STATE(ifp);
965 	state->added = STATE_ADDED;
966 
967 	state->addr.s_addr = lease->addr.s_addr;
968 	state->net.s_addr = lease->net.s_addr;
969 
970 	return 0;
971 }
972 
973 int
ipv4_preferanother(struct interface * ifp)974 ipv4_preferanother(struct interface *ifp)
975 {
976 	struct dhcp_state *state = D_STATE(ifp), *nstate;
977 	struct interface *ifn;
978 	int preferred;
979 
980 	if (state == NULL)
981 		return 0;
982 
983 	preferred = 0;
984 	if (!state->added)
985 		goto out;
986 
987 	TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
988 		if (ifn == ifp)
989 			break; /* We are already the most preferred */
990 		nstate = D_STATE(ifn);
991 		if (nstate && !nstate->added &&
992 		    nstate->lease.addr.s_addr == state->addr.s_addr)
993 		{
994 			preferred = 1;
995 			delete_address(ifp);
996 			if (ifn->options->options & DHCPCD_ARP)
997 				dhcp_bind(ifn);
998 			else {
999 				ipv4_daddaddr(ifn, &nstate->lease);
1000 				nstate->added = STATE_ADDED;
1001 			}
1002 			break;
1003 		}
1004 	}
1005 
1006 out:
1007 	ipv4_buildroutes(ifp->ctx);
1008 	return preferred;
1009 }
1010 
1011 void
ipv4_applyaddr(void * arg)1012 ipv4_applyaddr(void *arg)
1013 {
1014 	struct interface *ifp = arg, *ifn;
1015 	struct dhcp_state *state = D_STATE(ifp), *nstate;
1016 	struct dhcp_message *dhcp;
1017 	struct dhcp_lease *lease;
1018 	struct if_options *ifo = ifp->options;
1019 	struct ipv4_addr *ap;
1020 	int r;
1021 
1022 	if (state == NULL)
1023 		return;
1024 	dhcp = state->new;
1025 	lease = &state->lease;
1026 
1027 	if_sortinterfaces(ifp->ctx);
1028 	if (dhcp == NULL) {
1029 		if ((ifo->options & (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
1030 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT))
1031 		{
1032 			if (state->added && !ipv4_preferanother(ifp)) {
1033 				delete_address(ifp);
1034 				ipv4_buildroutes(ifp->ctx);
1035 			}
1036 			script_runreason(ifp, state->reason);
1037 		} else
1038 			ipv4_buildroutes(ifp->ctx);
1039 		return;
1040 	}
1041 
1042 	/* Ensure only one interface has the address */
1043 	r = 0;
1044 	TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
1045 		if (ifn == ifp) {
1046 			r = 1; /* past ourselves */
1047 			continue;
1048 		}
1049 		nstate = D_STATE(ifn);
1050 		if (nstate && nstate->added &&
1051 		    nstate->addr.s_addr == lease->addr.s_addr)
1052 		{
1053 			if (r == 0) {
1054 				logger(ifp->ctx, LOG_INFO,
1055 				    "%s: preferring %s on %s",
1056 				    ifp->name,
1057 				    inet_ntoa(lease->addr),
1058 				    ifn->name);
1059 				return;
1060 			}
1061 			logger(ifp->ctx, LOG_INFO, "%s: preferring %s on %s",
1062 			    ifn->name,
1063 			    inet_ntoa(lease->addr),
1064 			    ifp->name);
1065 			ipv4_deladdr(ifn, &nstate->addr, &nstate->net, 0);
1066 			break;
1067 		}
1068 	}
1069 
1070 	/* Does another interface already have the address from a prior boot? */
1071 	if (ifn == NULL) {
1072 		TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
1073 			if (ifn == ifp)
1074 				continue;
1075 			ap = ipv4_iffindaddr(ifn, &lease->addr, NULL);
1076 			if (ap)
1077 				ipv4_deladdr(ifn, &ap->addr, &ap->net, 0);
1078 		}
1079 	}
1080 
1081 	/* If the netmask is different, delete the addresss */
1082 	ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
1083 	if (ap && ap->net.s_addr != lease->net.s_addr)
1084 		ipv4_deladdr(ifp, &ap->addr, &ap->net, 0);
1085 
1086 	if (ipv4_iffindaddr(ifp, &lease->addr, &lease->net))
1087 		logger(ifp->ctx, LOG_DEBUG,
1088 		    "%s: IP address %s/%d already exists",
1089 		    ifp->name, inet_ntoa(lease->addr),
1090 		    inet_ntocidr(lease->net));
1091 	else {
1092 		r = ipv4_daddaddr(ifp, lease);
1093 		if (r == -1 && errno != EEXIST)
1094 			return;
1095 	}
1096 
1097 #ifdef IN_IFF_NOTUSEABLE
1098 	ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
1099 	if (ap == NULL) {
1100 		logger(ifp->ctx, LOG_ERR, "%s: added address vanished",
1101 		    ifp->name);
1102 		return;
1103 	} else if (ap->addr_flags & IN_IFF_NOTUSEABLE)
1104 		return;
1105 #endif
1106 
1107 	/* Delete the old address if different */
1108 	if (state->addr.s_addr != lease->addr.s_addr &&
1109 	    state->addr.s_addr != 0 &&
1110 	    ipv4_iffindaddr(ifp, &lease->addr, NULL))
1111 		delete_address(ifp);
1112 
1113 	state->added = STATE_ADDED;
1114 	state->addr.s_addr = lease->addr.s_addr;
1115 	state->net.s_addr = lease->net.s_addr;
1116 
1117 	/* Find any freshly added routes, such as the subnet route.
1118 	 * We do this because we cannot rely on recieving the kernel
1119 	 * notification right now via our link socket. */
1120 	if_initrt(ifp);
1121 	ipv4_buildroutes(ifp->ctx);
1122 	script_runreason(ifp, state->reason);
1123 
1124 	dhcpcd_daemonise(ifp->ctx);
1125 }
1126 
1127 void
ipv4_handleifa(struct dhcpcd_ctx * ctx,int cmd,struct if_head * ifs,const char * ifname,const struct in_addr * addr,const struct in_addr * net,const struct in_addr * dst,int flags)1128 ipv4_handleifa(struct dhcpcd_ctx *ctx,
1129     int cmd, struct if_head *ifs, const char *ifname,
1130     const struct in_addr *addr, const struct in_addr *net,
1131     const struct in_addr *dst, int flags)
1132 {
1133 	struct interface *ifp;
1134 	struct ipv4_state *state;
1135 	struct ipv4_addr *ap;
1136 
1137 	if (ifs == NULL)
1138 		ifs = ctx->ifaces;
1139 	if (ifs == NULL) {
1140 		errno = ESRCH;
1141 		return;
1142 	}
1143 	if (addr->s_addr == INADDR_ANY) {
1144 		errno = EINVAL;
1145 		return;
1146 	}
1147 	if ((ifp = if_find(ifs, ifname)) == NULL)
1148 		return;
1149 	if ((state = ipv4_getstate(ifp)) == NULL) {
1150 		errno = ENOENT;
1151 		return;
1152 	}
1153 
1154 	ap = ipv4_iffindaddr(ifp, addr, net);
1155 	if (cmd == RTM_NEWADDR) {
1156 		if (ap == NULL) {
1157 			if ((ap = malloc(sizeof(*ap))) == NULL) {
1158 				logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1159 				return;
1160 			}
1161 			ap->iface = ifp;
1162 			ap->addr = *addr;
1163 			ap->net = *net;
1164 			if (dst)
1165 				ap->dst.s_addr = dst->s_addr;
1166 			else
1167 				ap->dst.s_addr = INADDR_ANY;
1168 			TAILQ_INSERT_TAIL(&state->addrs, ap, next);
1169 		}
1170 		ap->addr_flags = flags;
1171 	} else if (cmd == RTM_DELADDR) {
1172 		if (ap) {
1173 			TAILQ_REMOVE(&state->addrs, ap, next);
1174 			free(ap);
1175 		}
1176 	}
1177 
1178 	dhcp_handleifa(cmd, ifp, addr, net, dst, flags);
1179 	arp_handleifa(cmd, ifp, addr, flags);
1180 }
1181 
1182 void
ipv4_free(struct interface * ifp)1183 ipv4_free(struct interface *ifp)
1184 {
1185 	struct ipv4_state *state;
1186 	struct ipv4_addr *addr;
1187 
1188 	if (ifp) {
1189 		state = IPV4_STATE(ifp);
1190 		if (state) {
1191 		        while ((addr = TAILQ_FIRST(&state->addrs))) {
1192 				TAILQ_REMOVE(&state->addrs, addr, next);
1193 				free(addr);
1194 			}
1195 			ipv4_freerts(&state->routes);
1196 #ifdef BSD
1197 			free(state->buffer);
1198 #endif
1199 			free(state);
1200 		}
1201 	}
1202 }
1203 
1204 void
ipv4_ctxfree(struct dhcpcd_ctx * ctx)1205 ipv4_ctxfree(struct dhcpcd_ctx *ctx)
1206 {
1207 
1208 	ipv4_freeroutes(ctx->ipv4_routes);
1209 	ipv4_freeroutes(ctx->ipv4_kroutes);
1210 }
1211