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