Import dhcpcd-8.0.4 to vendor branch.
[dragonfly.git] / contrib / dhcpcd / src / ipv4.c
blob05fc8066affda5032e758e6b5cddd7f13dd9a3d0
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * dhcpcd - DHCP client daemon
4 * Copyright (c) 2006-2019 Roy Marples <roy@marples.name>
5 * All rights reserved
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
29 #include <sys/socket.h>
30 #include <sys/types.h>
32 #include <arpa/inet.h>
33 #include <net/if.h>
34 #include <net/route.h>
35 #include <netinet/if_ether.h>
36 #include <netinet/in.h>
38 #include <assert.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #include <stdbool.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
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 "logerr.h"
57 #include "route.h"
58 #include "script.h"
59 #include "sa.h"
61 #define IPV4_LOOPBACK_ROUTE
62 #if defined(__linux__) || defined(__sun) || (defined(BSD) && defined(RTF_LOCAL))
63 /* Linux has had loopback routes in the local table since 2.2
64 * Solaris does not seem to support loopback routes. */
65 #undef IPV4_LOOPBACK_ROUTE
66 #endif
68 uint8_t
69 inet_ntocidr(struct in_addr address)
71 uint8_t cidr = 0;
72 uint32_t mask = htonl(address.s_addr);
74 while (mask) {
75 cidr++;
76 mask <<= 1;
78 return cidr;
81 int
82 inet_cidrtoaddr(int cidr, struct in_addr *addr)
84 int ocets;
86 if (cidr < 1 || cidr > 32) {
87 errno = EINVAL;
88 return -1;
90 ocets = (cidr + 7) / NBBY;
92 addr->s_addr = 0;
93 if (ocets > 0) {
94 memset(&addr->s_addr, 255, (size_t)ocets - 1);
95 memset((unsigned char *)&addr->s_addr + (ocets - 1),
96 (256 - (1 << (32 - cidr) % NBBY)), 1);
99 return 0;
102 uint32_t
103 ipv4_getnetmask(uint32_t addr)
105 uint32_t dst;
107 if (addr == 0)
108 return 0;
110 dst = htonl(addr);
111 if (IN_CLASSA(dst))
112 return ntohl(IN_CLASSA_NET);
113 if (IN_CLASSB(dst))
114 return ntohl(IN_CLASSB_NET);
115 if (IN_CLASSC(dst))
116 return ntohl(IN_CLASSC_NET);
118 return 0;
121 struct ipv4_addr *
122 ipv4_iffindaddr(struct interface *ifp,
123 const struct in_addr *addr, const struct in_addr *mask)
125 struct ipv4_state *state;
126 struct ipv4_addr *ap;
128 state = IPV4_STATE(ifp);
129 if (state) {
130 TAILQ_FOREACH(ap, &state->addrs, next) {
131 if ((addr == NULL || ap->addr.s_addr == addr->s_addr) &&
132 (mask == NULL || ap->mask.s_addr == mask->s_addr))
133 return ap;
136 return NULL;
139 struct ipv4_addr *
140 ipv4_iffindlladdr(struct interface *ifp)
142 struct ipv4_state *state;
143 struct ipv4_addr *ap;
145 state = IPV4_STATE(ifp);
146 if (state) {
147 TAILQ_FOREACH(ap, &state->addrs, next) {
148 if (IN_LINKLOCAL(htonl(ap->addr.s_addr)))
149 return ap;
152 return NULL;
155 static struct ipv4_addr *
156 ipv4_iffindmaskaddr(struct interface *ifp, const struct in_addr *addr)
158 struct ipv4_state *state;
159 struct ipv4_addr *ap;
161 state = IPV4_STATE(ifp);
162 if (state) {
163 TAILQ_FOREACH (ap, &state->addrs, next) {
164 if ((ap->addr.s_addr & ap->mask.s_addr) ==
165 (addr->s_addr & ap->mask.s_addr))
166 return ap;
169 return NULL;
172 struct ipv4_addr *
173 ipv4_findaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
175 struct interface *ifp;
176 struct ipv4_addr *ap;
178 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
179 ap = ipv4_iffindaddr(ifp, addr, NULL);
180 if (ap)
181 return ap;
183 return NULL;
186 struct ipv4_addr *
187 ipv4_findmaskaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
189 struct interface *ifp;
190 struct ipv4_addr *ap;
192 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
193 ap = ipv4_iffindmaskaddr(ifp, addr);
194 if (ap)
195 return ap;
197 return NULL;
201 ipv4_hasaddr(const struct interface *ifp)
203 const struct dhcp_state *dstate;
205 #ifdef IPV4LL
206 if (IPV4LL_STATE_RUNNING(ifp))
207 return 1;
208 #endif
210 dstate = D_CSTATE(ifp);
211 return (dstate &&
212 dstate->added == STATE_ADDED &&
213 dstate->addr != NULL);
216 /* Interface comparer for working out ordering. */
218 ipv4_ifcmp(const struct interface *si, const struct interface *ti)
220 const struct dhcp_state *sis, *tis;
222 sis = D_CSTATE(si);
223 tis = D_CSTATE(ti);
224 if (sis && !tis)
225 return -1;
226 if (!sis && tis)
227 return 1;
228 if (!sis && !tis)
229 return 0;
230 /* If one has a lease and the other not, it takes precedence. */
231 if (sis->new && !tis->new)
232 return -1;
233 if (!sis->new && tis->new)
234 return 1;
235 /* Always prefer proper leases */
236 if (!(sis->added & STATE_FAKE) && (tis->added & STATE_FAKE))
237 return -1;
238 if ((sis->added & STATE_FAKE) && !(tis->added & STATE_FAKE))
239 return 1;
240 /* If we are either, they neither have a lease, or they both have.
241 * We need to check for IPv4LL and make it non-preferred. */
242 if (sis->new && tis->new) {
243 if (IS_DHCP(sis->new) && !IS_DHCP(tis->new))
244 return -1;
245 if (!IS_DHCP(sis->new) && IS_DHCP(tis->new))
246 return 1;
248 return 0;
251 static int
252 inet_dhcproutes(rb_tree_t *routes, struct interface *ifp, bool *have_default)
254 const struct dhcp_state *state;
255 rb_tree_t nroutes;
256 struct rt *rt, *r = NULL;
257 struct in_addr in;
258 uint16_t mtu;
259 int n;
261 state = D_CSTATE(ifp);
262 if (state == NULL || state->state != DHS_BOUND || !state->added)
263 return 0;
265 /* An address does have to exist. */
266 assert(state->addr);
268 rb_tree_init(&nroutes, &rt_compare_proto_ops);
270 /* First, add a subnet route. */
271 if (state->addr->mask.s_addr != INADDR_ANY
272 #ifndef BSD
273 /* BSD adds a route in this instance */
274 && state->addr->mask.s_addr != INADDR_BROADCAST
275 #endif
277 if ((rt = rt_new(ifp)) == NULL)
278 return -1;
279 rt->rt_dflags |= RTDF_IFA_ROUTE;
280 in.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
281 sa_in_init(&rt->rt_dest, &in);
282 in.s_addr = state->addr->mask.s_addr;
283 sa_in_init(&rt->rt_netmask, &in);
284 //in.s_addr = INADDR_ANY;
285 //sa_in_init(&rt->rt_gateway, &in);
286 rt->rt_gateway.sa_family = AF_UNSPEC;
287 rt_proto_add(&nroutes, rt);
290 /* If any set routes, grab them, otherwise DHCP routes. */
291 if (RB_TREE_MIN(&ifp->options->routes)) {
292 RB_TREE_FOREACH(r, &ifp->options->routes) {
293 if (sa_is_unspecified(&r->rt_gateway))
294 break;
295 if ((rt = rt_new0(ifp->ctx)) == NULL)
296 return -1;
297 memcpy(rt, r, sizeof(*rt));
298 rt_setif(rt, ifp);
299 rt->rt_dflags = RTDF_STATIC;
300 rt_proto_add(&nroutes, rt);
302 } else {
303 if (dhcp_get_routes(&nroutes, ifp) == -1)
304 return -1;
307 /* If configured, install a gateway to the desintion
308 * for P2P interfaces. */
309 if (ifp->flags & IFF_POINTOPOINT &&
310 has_option_mask(ifp->options->dstmask, DHO_ROUTER))
312 if ((rt = rt_new(ifp)) == NULL)
313 return -1;
314 in.s_addr = INADDR_ANY;
315 sa_in_init(&rt->rt_dest, &in);
316 sa_in_init(&rt->rt_netmask, &in);
317 sa_in_init(&rt->rt_gateway, &state->addr->brd);
318 sa_in_init(&rt->rt_ifa, &state->addr->addr);
319 rt_proto_add(&nroutes, rt);
322 /* Copy our address as the source address and set mtu */
323 mtu = dhcp_get_mtu(ifp);
324 n = 0;
325 while ((rt = RB_TREE_MIN(&nroutes)) != NULL) {
326 rb_tree_remove_node(&nroutes, rt);
327 rt->rt_mtu = mtu;
328 if (!(rt->rt_dflags & RTDF_STATIC))
329 rt->rt_dflags |= RTDF_DHCP;
330 sa_in_init(&rt->rt_ifa, &state->addr->addr);
331 if (rb_tree_insert_node(routes, rt) != rt) {
332 rt_free(rt);
333 continue;
335 if (rt_is_default(rt))
336 *have_default = true;
337 n = 1;
340 return n;
343 /* We should check to ensure the routers are on the same subnet
344 * OR supply a host route. If not, warn and add a host route. */
345 static int
346 inet_routerhostroute(rb_tree_t *routes, struct interface *ifp)
348 struct rt *rt, *rth, *rtp;
349 struct sockaddr_in *dest, *netmask, *gateway;
350 const char *cp, *cp2, *cp3, *cplim;
351 struct if_options *ifo;
352 const struct dhcp_state *state;
353 struct in_addr in;
354 rb_tree_t troutes;
356 /* Don't add a host route for these interfaces. */
357 if (ifp->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
358 return 0;
360 rb_tree_init(&troutes, &rt_compare_proto_ops);
362 RB_TREE_FOREACH(rt, routes) {
363 if (rt->rt_dest.sa_family != AF_INET)
364 continue;
365 if (!sa_is_unspecified(&rt->rt_dest) ||
366 sa_is_unspecified(&rt->rt_gateway))
367 continue;
368 gateway = satosin(&rt->rt_gateway);
369 /* Scan for a route to match */
370 RB_TREE_FOREACH(rth, routes) {
371 if (rth == rt)
372 break;
373 /* match host */
374 if (sa_cmp(&rth->rt_dest, &rt->rt_gateway) == 0)
375 break;
376 /* match subnet */
377 /* XXX ADD TO RT_COMARE? XXX */
378 cp = (const char *)&gateway->sin_addr.s_addr;
379 dest = satosin(&rth->rt_dest);
380 cp2 = (const char *)&dest->sin_addr.s_addr;
381 netmask = satosin(&rth->rt_netmask);
382 cp3 = (const char *)&netmask->sin_addr.s_addr;
383 cplim = cp3 + sizeof(netmask->sin_addr.s_addr);
384 while (cp3 < cplim) {
385 if ((*cp++ ^ *cp2++) & *cp3++)
386 break;
388 if (cp3 == cplim)
389 break;
391 if (rth != rt)
392 continue;
393 if ((state = D_CSTATE(ifp)) == NULL)
394 continue;
395 ifo = ifp->options;
396 if (ifp->flags & IFF_NOARP) {
397 if (!(ifo->options & DHCPCD_ROUTER_HOST_ROUTE_WARNED) &&
398 !(state->added & STATE_FAKE))
400 char buf[INET_MAX_ADDRSTRLEN];
402 ifo->options |= DHCPCD_ROUTER_HOST_ROUTE_WARNED;
403 logwarnx("%s: forcing router %s through "
404 "interface",
405 ifp->name,
406 sa_addrtop(&rt->rt_gateway,
407 buf, sizeof(buf)));
409 gateway->sin_addr.s_addr = INADDR_ANY;
410 continue;
412 if (!(ifo->options & DHCPCD_ROUTER_HOST_ROUTE_WARNED) &&
413 !(state->added & STATE_FAKE))
415 char buf[INET_MAX_ADDRSTRLEN];
417 ifo->options |= DHCPCD_ROUTER_HOST_ROUTE_WARNED;
418 logwarnx("%s: router %s requires a host route",
419 ifp->name,
420 sa_addrtop(&rt->rt_gateway, buf, sizeof(buf)));
423 if ((rth = rt_new(ifp)) == NULL)
424 return -1;
425 rth->rt_flags |= RTF_HOST;
426 sa_in_init(&rth->rt_dest, &gateway->sin_addr);
427 in.s_addr = INADDR_BROADCAST;
428 sa_in_init(&rth->rt_netmask, &in);
429 in.s_addr = INADDR_ANY;
430 sa_in_init(&rth->rt_gateway, &in);
431 rth->rt_mtu = dhcp_get_mtu(ifp);
432 sa_in_init(&rth->rt_ifa, &state->addr->addr);
434 /* We need to insert the host route just before the router. */
435 while ((rtp = RB_TREE_MAX(routes)) != NULL) {
436 rb_tree_remove_node(routes, rtp);
437 rt_proto_add(&troutes, rtp);
438 if (rtp == rt)
439 break;
441 rt_proto_add(routes, rth);
442 /* troutes is now reversed, so add backwards again. */
443 while ((rtp = RB_TREE_MAX(&troutes)) != NULL) {
444 rb_tree_remove_node(&troutes, rtp);
445 rt_proto_add(routes, rtp);
448 return 0;
451 bool
452 inet_getroutes(struct dhcpcd_ctx *ctx, rb_tree_t *routes)
454 struct interface *ifp;
455 bool have_default = false;
457 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
458 if (!ifp->active)
459 continue;
460 if (inet_dhcproutes(routes, ifp, &have_default) == -1)
461 return false;
462 #ifdef IPV4LL
463 if (ipv4ll_subnetroute(routes, ifp) == -1)
464 return false;
465 #endif
466 if (inet_routerhostroute(routes, ifp) == -1)
467 return false;
470 #ifdef IPV4LL
471 /* If there is no default route, see if we can use an IPv4LL one. */
472 if (have_default)
473 return true;
475 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
476 if (ifp->active &&
477 ipv4ll_defaultroute(routes, ifp) == 1)
478 break;
480 #endif
482 return true;
486 ipv4_deladdr(struct ipv4_addr *addr, int keeparp)
488 int r;
489 struct ipv4_state *state;
490 struct ipv4_addr *ap;
492 logdebugx("%s: deleting IP address %s",
493 addr->iface->name, addr->saddr);
495 r = if_address(RTM_DELADDR, addr);
496 if (r == -1 &&
497 errno != EADDRNOTAVAIL && errno != ESRCH &&
498 errno != ENXIO && errno != ENODEV)
499 logerr("%s: %s", addr->iface->name, __func__);
501 #ifdef ARP
502 if (!keeparp)
503 arp_freeaddr(addr->iface, &addr->addr);
504 #else
505 UNUSED(keeparp);
506 #endif
508 state = IPV4_STATE(addr->iface);
509 TAILQ_FOREACH(ap, &state->addrs, next) {
510 if (IPV4_MASK_EQ(ap, addr)) {
511 struct dhcp_state *dstate;
513 dstate = D_STATE(ap->iface);
514 TAILQ_REMOVE(&state->addrs, ap, next);
515 free(ap);
517 if (dstate && dstate->addr == ap) {
518 dstate->added = 0;
519 dstate->addr = NULL;
521 break;
525 return r;
528 static int
529 delete_address(struct interface *ifp)
531 int r;
532 struct if_options *ifo;
533 struct dhcp_state *state;
535 state = D_STATE(ifp);
536 ifo = ifp->options;
537 /* The lease could have been added, but the address deleted
538 * by a 3rd party. */
539 if (state->addr == NULL ||
540 ifo->options & DHCPCD_INFORM ||
541 (ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0))
542 return 0;
543 #ifdef ARP
544 arp_freeaddr(ifp, &state->addr->addr);
545 #endif
546 r = ipv4_deladdr(state->addr, 0);
547 return r;
550 struct ipv4_state *
551 ipv4_getstate(struct interface *ifp)
553 struct ipv4_state *state;
555 state = IPV4_STATE(ifp);
556 if (state == NULL) {
557 ifp->if_data[IF_DATA_IPV4] = malloc(sizeof(*state));
558 state = IPV4_STATE(ifp);
559 if (state == NULL) {
560 logerr(__func__);
561 return NULL;
563 TAILQ_INIT(&state->addrs);
564 state->buffer_size = state->buffer_len = state->buffer_pos = 0;
565 state->buffer = NULL;
567 return state;
570 #ifdef ALIAS_ADDR
571 /* Find the next logical aliase address we can use. */
572 static int
573 ipv4_aliasaddr(struct ipv4_addr *ia, struct ipv4_addr **repl)
575 struct ipv4_state *state;
576 struct ipv4_addr *iap;
577 unsigned int lun;
578 char alias[IF_NAMESIZE];
580 if (ia->alias[0] != '\0')
581 return 0;
583 lun = 0;
584 state = IPV4_STATE(ia->iface);
585 find_lun:
586 if (if_makealias(alias, IF_NAMESIZE, ia->iface->name, lun) >=
587 IF_NAMESIZE)
589 errno = ENOMEM;
590 return -1;
592 TAILQ_FOREACH(iap, &state->addrs, next) {
593 if (iap->alias[0] != '\0' && iap->addr.s_addr == INADDR_ANY) {
594 /* No address assigned? Lets use it. */
595 strlcpy(ia->alias, iap->alias, sizeof(ia->alias));
596 if (repl)
597 *repl = iap;
598 return 1;
600 if (strcmp(iap->alias, alias) == 0)
601 break;
604 if (iap != NULL) {
605 if (lun == UINT_MAX) {
606 errno = ERANGE;
607 return -1;
609 lun++;
610 goto find_lun;
613 strlcpy(ia->alias, alias, sizeof(ia->alias));
614 return 0;
616 #endif
618 struct ipv4_addr *
619 ipv4_addaddr(struct interface *ifp, const struct in_addr *addr,
620 const struct in_addr *mask, const struct in_addr *bcast,
621 uint32_t vltime, uint32_t pltime)
623 struct ipv4_state *state;
624 struct ipv4_addr *ia;
625 bool is_new = false;
626 #ifdef ALIAS_ADDR
627 int replaced, blank;
628 struct ipv4_addr *replaced_ia;
629 #endif
631 if ((state = ipv4_getstate(ifp)) == NULL) {
632 logerr(__func__);
633 return NULL;
635 if (ifp->options->options & DHCPCD_NOALIAS) {
636 struct ipv4_addr *ian;
638 TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ian) {
639 if (ia->addr.s_addr != addr->s_addr)
640 ipv4_deladdr(ia, 0);
644 ia = ipv4_iffindaddr(ifp, addr, NULL);
645 if (ia == NULL) {
646 ia = malloc(sizeof(*ia));
647 if (ia == NULL) {
648 logerr(__func__);
649 return NULL;
651 ia->iface = ifp;
652 ia->addr = *addr;
653 #ifdef IN_IFF_TENTATIVE
654 ia->addr_flags = IN_IFF_TENTATIVE;
655 #endif
656 is_new = true;
659 ia->mask = *mask;
660 ia->brd = *bcast;
661 #ifdef IP_LIFETIME
662 ia->vltime = vltime;
663 ia->pltime = pltime;
664 #else
665 UNUSED(vltime);
666 UNUSED(pltime);
667 #endif
668 snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
669 inet_ntoa(*addr), inet_ntocidr(*mask));
671 #ifdef ALIAS_ADDR
672 blank = (ia->alias[0] == '\0');
673 if ((replaced = ipv4_aliasaddr(ia, &replaced_ia)) == -1) {
674 logerr("%s: ipv4_aliasaddr", ifp->name);
675 free(ia);
676 return NULL;
678 if (blank)
679 logdebugx("%s: aliased %s", ia->alias, ia->saddr);
680 #endif
682 logdebugx("%s: adding IP address %s %s %s",
683 ifp->name, ia->saddr,
684 ifp->flags & IFF_POINTOPOINT ? "destination" : "broadcast",
685 inet_ntoa(*bcast));
686 if (if_address(RTM_NEWADDR, ia) == -1) {
687 if (errno != EEXIST)
688 logerr("%s: if_addaddress",
689 __func__);
690 free(ia);
691 return NULL;
694 #ifdef ALIAS_ADDR
695 if (replaced) {
696 TAILQ_REMOVE(&state->addrs, replaced_ia, next);
697 free(replaced_ia);
699 #endif
701 if (is_new)
702 TAILQ_INSERT_TAIL(&state->addrs, ia, next);
703 return ia;
706 static int
707 ipv4_daddaddr(struct interface *ifp, const struct dhcp_lease *lease)
709 struct dhcp_state *state;
710 struct ipv4_addr *ia;
712 ia = ipv4_addaddr(ifp, &lease->addr, &lease->mask, &lease->brd,
713 lease->leasetime, lease->rebindtime);
714 if (ia == NULL)
715 return -1;
717 state = D_STATE(ifp);
718 state->added = STATE_ADDED;
719 state->addr = ia;
720 return 0;
723 void
724 ipv4_applyaddr(void *arg)
726 struct interface *ifp = arg;
727 struct dhcp_state *state = D_STATE(ifp);
728 struct dhcp_lease *lease;
729 struct if_options *ifo = ifp->options;
730 struct ipv4_addr *ia;
732 if (state == NULL)
733 return;
735 lease = &state->lease;
736 if (state->new == NULL) {
737 if ((ifo->options & (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
738 (DHCPCD_EXITING | DHCPCD_PERSISTENT))
740 if (state->added) {
741 delete_address(ifp);
742 rt_build(ifp->ctx, AF_INET);
743 #ifdef ARP
744 /* Announce the preferred address to
745 * kick ARP caches. */
746 if (!(ifp->flags & IFF_NOARP))
747 arp_announceaddr(ifp->ctx,&lease->addr);
748 #endif
750 script_runreason(ifp, state->reason);
751 } else
752 rt_build(ifp->ctx, AF_INET);
753 return;
756 ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
757 /* If the netmask or broadcast is different, re-add the addresss.
758 * If IP addresses do not have lifetimes, there is a very real chance
759 * that re-adding them will scrub the subnet route temporarily
760 * which is a bad thing, so avoid it. */
761 if (ia != NULL &&
762 ia->mask.s_addr == lease->mask.s_addr &&
763 ia->brd.s_addr == lease->brd.s_addr)
765 #ifndef IP_LIFETIME
766 logdebugx("%s: IP address %s already exists",
767 ifp->name, ia->saddr);
768 #endif
769 } else {
770 #ifdef __linux__
771 /* Linux does not change netmask/broadcast address
772 * for re-added addresses, so we need to delete the old one
773 * first. */
774 if (ia != NULL)
775 ipv4_deladdr(ia, 0);
776 #endif
777 #ifndef IP_LIFETIME
778 if (ipv4_daddaddr(ifp, lease) == -1 && errno != EEXIST)
779 return;
780 #endif
782 #ifdef IP_LIFETIME
783 if (ipv4_daddaddr(ifp, lease) == -1 && errno != EEXIST)
784 return;
785 #endif
787 ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
788 if (ia == NULL) {
789 logerrx("%s: added address vanished", ifp->name);
790 return;
792 #if defined(ARP) && defined(IN_IFF_NOTUSEABLE)
793 if (ia->addr_flags & IN_IFF_NOTUSEABLE)
794 return;
795 #endif
797 /* Delete the old address if different */
798 if (state->addr &&
799 state->addr->addr.s_addr != lease->addr.s_addr &&
800 ipv4_iffindaddr(ifp, &lease->addr, NULL))
801 delete_address(ifp);
803 state->addr = ia;
804 state->added = STATE_ADDED;
806 rt_build(ifp->ctx, AF_INET);
808 #ifdef ARP
809 if (!(ifp->flags & IFF_NOARP))
810 arp_announceaddr(ifp->ctx, &state->addr->addr);
811 #endif
813 if (state->state == DHS_BOUND) {
814 script_runreason(ifp, state->reason);
815 dhcpcd_daemonise(ifp->ctx);
819 void
820 ipv4_markaddrsstale(struct interface *ifp)
822 struct ipv4_state *state;
823 struct ipv4_addr *ia;
825 state = IPV4_STATE(ifp);
826 if (state == NULL)
827 return;
829 TAILQ_FOREACH(ia, &state->addrs, next) {
830 ia->flags |= IPV4_AF_STALE;
834 void
835 ipv4_deletestaleaddrs(struct interface *ifp)
837 struct ipv4_state *state;
838 struct ipv4_addr *ia, *ia1;
840 state = IPV4_STATE(ifp);
841 if (state == NULL)
842 return;
844 TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ia1) {
845 if (!(ia->flags & IPV4_AF_STALE))
846 continue;
847 ipv4_handleifa(ifp->ctx, RTM_DELADDR,
848 ifp->ctx->ifaces, ifp->name,
849 &ia->addr, &ia->mask, &ia->brd, 0, getpid());
853 void
854 ipv4_handleifa(struct dhcpcd_ctx *ctx,
855 int cmd, struct if_head *ifs, const char *ifname,
856 const struct in_addr *addr, const struct in_addr *mask,
857 const struct in_addr *brd, int addrflags, pid_t pid)
859 struct interface *ifp;
860 struct ipv4_state *state;
861 struct ipv4_addr *ia;
862 bool ia_is_new;
864 #if 0
865 char sbrdbuf[INET_ADDRSTRLEN];
866 const char *sbrd;
868 if (brd)
869 sbrd = inet_ntop(AF_INET, brd, sbrdbuf, sizeof(sbrdbuf));
870 else
871 sbrd = NULL;
872 logdebugx("%s: %s %s/%d %s %d", ifname,
873 cmd == RTM_NEWADDR ? "RTM_NEWADDR" :
874 cmd == RTM_DELADDR ? "RTM_DELADDR" : "???",
875 inet_ntoa(*addr), inet_ntocidr(*mask), sbrd, addrflags);
876 #endif
878 if (ifs == NULL)
879 ifs = ctx->ifaces;
880 if (ifs == NULL) {
881 errno = ESRCH;
882 return;
884 if ((ifp = if_find(ifs, ifname)) == NULL)
885 return;
886 if ((state = ipv4_getstate(ifp)) == NULL) {
887 errno = ENOENT;
888 return;
891 ia = ipv4_iffindaddr(ifp, addr, NULL);
892 switch (cmd) {
893 case RTM_NEWADDR:
894 if (ia == NULL) {
895 if ((ia = malloc(sizeof(*ia))) == NULL) {
896 logerr(__func__);
897 return;
899 ia->iface = ifp;
900 ia->addr = *addr;
901 ia->mask = *mask;
902 ia->flags = 0;
903 ia_is_new = true;
904 #ifdef ALIAS_ADDR
905 strlcpy(ia->alias, ifname, sizeof(ia->alias));
906 #endif
907 TAILQ_INSERT_TAIL(&state->addrs, ia, next);
908 } else
909 ia_is_new = false;
910 /* Mask could have changed */
911 if (ia_is_new ||
912 (mask->s_addr != INADDR_ANY &&
913 mask->s_addr != ia->mask.s_addr))
915 ia->mask = *mask;
916 snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
917 inet_ntoa(*addr), inet_ntocidr(*mask));
919 if (brd != NULL)
920 ia->brd = *brd;
921 else
922 ia->brd.s_addr = INADDR_ANY;
923 ia->addr_flags = addrflags;
924 ia->flags &= ~IPV4_AF_STALE;
925 break;
926 case RTM_DELADDR:
927 if (ia == NULL)
928 return;
929 if (mask->s_addr != INADDR_ANY &&
930 mask->s_addr != ia->mask.s_addr)
931 return;
932 TAILQ_REMOVE(&state->addrs, ia, next);
933 break;
934 default:
935 return;
938 if (addr->s_addr != INADDR_ANY && addr->s_addr != INADDR_BROADCAST) {
939 dhcp_handleifa(cmd, ia, pid);
940 #ifdef IPV4LL
941 ipv4ll_handleifa(cmd, ia, pid);
942 #endif
945 if (cmd == RTM_DELADDR)
946 free(ia);
949 void
950 ipv4_free(struct interface *ifp)
952 struct ipv4_state *state;
953 struct ipv4_addr *ia;
955 if (ifp) {
956 state = IPV4_STATE(ifp);
957 if (state) {
958 while ((ia = TAILQ_FIRST(&state->addrs))) {
959 TAILQ_REMOVE(&state->addrs, ia, next);
960 free(ia);
962 free(state->buffer);
963 free(state);