xref: /dragonfly/contrib/dhcpcd/src/ipv4.c (revision c80c9bba1b2fa2824af94c686145cb7eb7db2cd5)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * dhcpcd - DHCP client daemon
4  * Copyright (c) 2006-2023 Roy Marples <roy@marples.name>
5  * All rights reserved
6 
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.
15  *
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.
27  */
28 
29 #include <sys/socket.h>
30 #include <sys/types.h>
31 
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>
37 
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>
46 
47 #include "config.h"
48 #include "arp.h"
49 #include "common.h"
50 #include "dhcpcd.h"
51 #include "dhcp.h"
52 #include "eloop.h"
53 #include "if.h"
54 #include "if-options.h"
55 #include "ipv4.h"
56 #include "ipv4ll.h"
57 #include "logerr.h"
58 #include "route.h"
59 #include "script.h"
60 #include "sa.h"
61 
62 #define IPV4_LOOPBACK_ROUTE
63 #if defined(__linux__) || defined(__sun) || (defined(BSD) && defined(RTF_LOCAL))
64 /* Linux has had loopback routes in the local table since 2.2
65  * Solaris does not seem to support loopback routes. */
66 #undef IPV4_LOOPBACK_ROUTE
67 #endif
68 
69 uint8_t
inet_ntocidr(struct in_addr address)70 inet_ntocidr(struct in_addr address)
71 {
72           uint8_t cidr = 0;
73           uint32_t mask = htonl(address.s_addr);
74 
75           while (mask) {
76                     cidr++;
77                     mask <<= 1;
78           }
79           return cidr;
80 }
81 
82 int
inet_cidrtoaddr(int cidr,struct in_addr * addr)83 inet_cidrtoaddr(int cidr, struct in_addr *addr)
84 {
85           int ocets;
86 
87           if (cidr < 1 || cidr > 32) {
88                     errno = EINVAL;
89                     return -1;
90           }
91           ocets = (cidr + 7) / NBBY;
92 
93           addr->s_addr = 0;
94           if (ocets > 0) {
95                     memset(&addr->s_addr, 255, (size_t)ocets - 1);
96                     memset((unsigned char *)&addr->s_addr + (ocets - 1),
97                         (256 - (1 << (32 - cidr) % NBBY)), 1);
98           }
99 
100           return 0;
101 }
102 
103 uint32_t
ipv4_getnetmask(uint32_t addr)104 ipv4_getnetmask(uint32_t addr)
105 {
106           uint32_t dst;
107 
108           if (addr == 0)
109                     return 0;
110 
111           dst = htonl(addr);
112           if (IN_CLASSA(dst))
113                     return ntohl(IN_CLASSA_NET);
114           if (IN_CLASSB(dst))
115                     return ntohl(IN_CLASSB_NET);
116           if (IN_CLASSC(dst))
117                     return ntohl(IN_CLASSC_NET);
118 
119           return 0;
120 }
121 
122 struct ipv4_addr *
ipv4_iffindaddr(struct interface * ifp,const struct in_addr * addr,const struct in_addr * mask)123 ipv4_iffindaddr(struct interface *ifp,
124     const struct in_addr *addr, const struct in_addr *mask)
125 {
126           struct ipv4_state *state;
127           struct ipv4_addr *ap;
128 
129           state = IPV4_STATE(ifp);
130           if (state) {
131                     TAILQ_FOREACH(ap, &state->addrs, next) {
132                               if ((addr == NULL || ap->addr.s_addr == addr->s_addr) &&
133                                   (mask == NULL || ap->mask.s_addr == mask->s_addr))
134                                         return ap;
135                     }
136           }
137           return NULL;
138 }
139 
140 struct ipv4_addr *
ipv4_iffindlladdr(struct interface * ifp)141 ipv4_iffindlladdr(struct interface *ifp)
142 {
143           struct ipv4_state *state;
144           struct ipv4_addr *ap;
145 
146           state = IPV4_STATE(ifp);
147           if (state) {
148                     TAILQ_FOREACH(ap, &state->addrs, next) {
149                               if (IN_LINKLOCAL(ntohl(ap->addr.s_addr)))
150                                         return ap;
151                     }
152           }
153           return NULL;
154 }
155 
156 static struct ipv4_addr *
ipv4_iffindmaskaddr(struct interface * ifp,const struct in_addr * addr)157 ipv4_iffindmaskaddr(struct interface *ifp, const struct in_addr *addr)
158 {
159           struct ipv4_state *state;
160           struct ipv4_addr *ap;
161 
162           state = IPV4_STATE(ifp);
163           if (state) {
164                     TAILQ_FOREACH (ap, &state->addrs, next) {
165                               if ((ap->addr.s_addr & ap->mask.s_addr) ==
166                                   (addr->s_addr & ap->mask.s_addr))
167                                         return ap;
168                     }
169           }
170           return NULL;
171 }
172 
173 static struct ipv4_addr *
ipv4_iffindmaskbrd(struct interface * ifp,const struct in_addr * addr)174 ipv4_iffindmaskbrd(struct interface *ifp, const struct in_addr *addr)
175 {
176           struct ipv4_state *state;
177           struct ipv4_addr *ap;
178 
179           state = IPV4_STATE(ifp);
180           if (state) {
181                     TAILQ_FOREACH (ap, &state->addrs, next) {
182                               if ((ap->brd.s_addr & ap->mask.s_addr) ==
183                                   (addr->s_addr & ap->mask.s_addr))
184                                         return ap;
185                     }
186           }
187           return NULL;
188 }
189 
190 struct ipv4_addr *
ipv4_findaddr(struct dhcpcd_ctx * ctx,const struct in_addr * addr)191 ipv4_findaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
192 {
193           struct interface *ifp;
194           struct ipv4_addr *ap;
195 
196           TAILQ_FOREACH(ifp, ctx->ifaces, next) {
197                     ap = ipv4_iffindaddr(ifp, addr, NULL);
198                     if (ap)
199                               return ap;
200           }
201           return NULL;
202 }
203 
204 struct ipv4_addr *
ipv4_findmaskaddr(struct dhcpcd_ctx * ctx,const struct in_addr * addr)205 ipv4_findmaskaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
206 {
207           struct interface *ifp;
208           struct ipv4_addr *ap;
209 
210           TAILQ_FOREACH(ifp, ctx->ifaces, next) {
211                     ap = ipv4_iffindmaskaddr(ifp, addr);
212                     if (ap)
213                               return ap;
214           }
215           return NULL;
216 }
217 
218 struct ipv4_addr *
ipv4_findmaskbrd(struct dhcpcd_ctx * ctx,const struct in_addr * addr)219 ipv4_findmaskbrd(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
220 {
221           struct interface *ifp;
222           struct ipv4_addr *ap;
223 
224           TAILQ_FOREACH(ifp, ctx->ifaces, next) {
225                     ap = ipv4_iffindmaskbrd(ifp, addr);
226                     if (ap)
227                               return ap;
228           }
229           return NULL;
230 }
231 
232 int
ipv4_hasaddr(const struct interface * ifp)233 ipv4_hasaddr(const struct interface *ifp)
234 {
235           const struct dhcp_state *dstate;
236 
237 #ifdef IPV4LL
238           if (IPV4LL_STATE_RUNNING(ifp))
239                     return 1;
240 #endif
241 
242           dstate = D_CSTATE(ifp);
243           return (dstate &&
244               dstate->added == STATE_ADDED &&
245               dstate->addr != NULL);
246 }
247 
248 /* Interface comparer for working out ordering. */
249 int
ipv4_ifcmp(const struct interface * si,const struct interface * ti)250 ipv4_ifcmp(const struct interface *si, const struct interface *ti)
251 {
252           const struct dhcp_state *sis, *tis;
253 
254           sis = D_CSTATE(si);
255           tis = D_CSTATE(ti);
256           if (sis && !tis)
257                     return -1;
258           if (!sis && tis)
259                     return 1;
260           if (!sis && !tis)
261                     return 0;
262           /* If one has a lease and the other not, it takes precedence. */
263           if (sis->new && !tis->new)
264                     return -1;
265           if (!sis->new && tis->new)
266                     return 1;
267           /* Always prefer proper leases */
268           if (!(sis->added & STATE_FAKE) && (tis->added & STATE_FAKE))
269                     return -1;
270           if ((sis->added & STATE_FAKE) && !(tis->added & STATE_FAKE))
271                     return 1;
272           /* If we are either, they neither have a lease, or they both have.
273            * We need to check for IPv4LL and make it non-preferred. */
274           if (sis->new && tis->new) {
275                     if (IS_DHCP(sis->new) && !IS_DHCP(tis->new))
276                               return -1;
277                     if (!IS_DHCP(sis->new) && IS_DHCP(tis->new))
278                               return 1;
279           }
280           return 0;
281 }
282 
283 static int
inet_dhcproutes(rb_tree_t * routes,struct interface * ifp,bool * have_default)284 inet_dhcproutes(rb_tree_t *routes, struct interface *ifp, bool *have_default)
285 {
286           const struct dhcp_state *state;
287           rb_tree_t nroutes;
288           struct rt *rt, *r = NULL;
289           struct in_addr in;
290           uint16_t mtu;
291           int n;
292 
293           state = D_CSTATE(ifp);
294           if (state == NULL || state->state != DHS_BOUND || !state->added)
295                     return 0;
296 
297           /* An address does have to exist. */
298           assert(state->addr);
299 
300           rb_tree_init(&nroutes, &rt_compare_proto_ops);
301 
302           /* First, add a subnet route. */
303           if (state->addr->mask.s_addr != INADDR_ANY
304 #ifndef BSD
305               /* BSD adds a route in this instance */
306               && state->addr->mask.s_addr != INADDR_BROADCAST
307 #endif
308           ) {
309                     if ((rt = rt_new(ifp)) == NULL)
310                               return -1;
311                     rt->rt_dflags |= RTDF_IFA_ROUTE;
312                     in.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
313                     sa_in_init(&rt->rt_dest, &in);
314                     in.s_addr = state->addr->mask.s_addr;
315                     sa_in_init(&rt->rt_netmask, &in);
316                     //in.s_addr = INADDR_ANY;
317                     //sa_in_init(&rt->rt_gateway, &in);
318                     rt->rt_gateway.sa_family = AF_UNSPEC;
319                     rt_proto_add(&nroutes, rt);
320           }
321 
322           /* If any set routes, grab them, otherwise DHCP routes. */
323           if (RB_TREE_MIN(&ifp->options->routes)) {
324                     RB_TREE_FOREACH(r, &ifp->options->routes) {
325                               if (sa_is_unspecified(&r->rt_gateway))
326                                         break;
327                               if ((rt = rt_new0(ifp->ctx)) == NULL)
328                                         return -1;
329                               memcpy(rt, r, sizeof(*rt));
330                               rt_setif(rt, ifp);
331                               rt->rt_dflags = RTDF_STATIC;
332                               rt_proto_add(&nroutes, rt);
333                     }
334           } else {
335                     if (dhcp_get_routes(&nroutes, ifp) == -1)
336                               return -1;
337           }
338 
339           /* If configured, install a gateway to the desintion
340            * for P2P interfaces. */
341           if (ifp->flags & IFF_POINTOPOINT &&
342               has_option_mask(ifp->options->dstmask, DHO_ROUTER))
343           {
344                     if ((rt = rt_new(ifp)) == NULL)
345                               return -1;
346                     in.s_addr = INADDR_ANY;
347                     sa_in_init(&rt->rt_dest, &in);
348                     sa_in_init(&rt->rt_netmask, &in);
349                     sa_in_init(&rt->rt_gateway, &state->addr->brd);
350                     sa_in_init(&rt->rt_ifa, &state->addr->addr);
351                     rt_proto_add(&nroutes, rt);
352           }
353 
354           /* Copy our address as the source address and set mtu */
355           mtu = dhcp_get_mtu(ifp);
356           n = 0;
357           while ((rt = RB_TREE_MIN(&nroutes)) != NULL) {
358                     rb_tree_remove_node(&nroutes, rt);
359                     rt->rt_mtu = mtu;
360                     if (!(rt->rt_dflags & RTDF_STATIC))
361                               rt->rt_dflags |= RTDF_DHCP;
362                     sa_in_init(&rt->rt_ifa, &state->addr->addr);
363                     if (rb_tree_insert_node(routes, rt) != rt) {
364                               rt_free(rt);
365                               continue;
366                     }
367                     if (rt_is_default(rt))
368                               *have_default = true;
369                     n = 1;
370           }
371 
372           return n;
373 }
374 
375 /* We should check to ensure the routers are on the same subnet
376  * OR supply a host route. If not, warn and add a host route. */
377 static int
inet_routerhostroute(rb_tree_t * routes,struct interface * ifp)378 inet_routerhostroute(rb_tree_t *routes, struct interface *ifp)
379 {
380           struct rt *rt, *rth, *rtp;
381           struct sockaddr_in *dest, *netmask, *gateway;
382           const char *cp, *cp2, *cp3, *cplim;
383           struct if_options *ifo;
384           const struct dhcp_state *state;
385           struct in_addr in;
386           rb_tree_t troutes;
387 
388           /* Don't add a host route for these interfaces. */
389           if (ifp->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
390                     return 0;
391 
392           rb_tree_init(&troutes, &rt_compare_proto_ops);
393 
394           RB_TREE_FOREACH(rt, routes) {
395                     if (rt->rt_dest.sa_family != AF_INET)
396                               continue;
397                     if (!sa_is_unspecified(&rt->rt_dest) ||
398                         sa_is_unspecified(&rt->rt_gateway))
399                               continue;
400                     gateway = satosin(&rt->rt_gateway);
401                     /* Scan for a route to match */
402                     RB_TREE_FOREACH(rth, routes) {
403                               if (rth == rt)
404                                         break;
405                               /* match host */
406                               if (sa_cmp(&rth->rt_dest, &rt->rt_gateway) == 0)
407                                         break;
408                               /* match subnet */
409                               /* XXX ADD TO RT_COMARE? XXX */
410                               cp = (const char *)&gateway->sin_addr.s_addr;
411                               dest = satosin(&rth->rt_dest);
412                               cp2 = (const char *)&dest->sin_addr.s_addr;
413                               netmask = satosin(&rth->rt_netmask);
414                               cp3 = (const char *)&netmask->sin_addr.s_addr;
415                               cplim = cp3 + sizeof(netmask->sin_addr.s_addr);
416                               while (cp3 < cplim) {
417                                         if ((*cp++ ^ *cp2++) & *cp3++)
418                                                   break;
419                               }
420                               if (cp3 == cplim)
421                                         break;
422                     }
423                     if (rth != rt)
424                               continue;
425                     if ((state = D_CSTATE(ifp)) == NULL)
426                               continue;
427                     ifo = ifp->options;
428                     if (ifp->flags & IFF_NOARP) {
429                               if (!(ifo->options & DHCPCD_ROUTER_HOST_ROUTE_WARNED) &&
430                                   !(state->added & STATE_FAKE))
431                               {
432                                         char buf[INET_MAX_ADDRSTRLEN];
433 
434                                         ifo->options |= DHCPCD_ROUTER_HOST_ROUTE_WARNED;
435                                         logwarnx("%s: forcing router %s through "
436                                             "interface",
437                                             ifp->name,
438                                             sa_addrtop(&rt->rt_gateway,
439                                             buf, sizeof(buf)));
440                               }
441                               gateway->sin_addr.s_addr = INADDR_ANY;
442                               continue;
443                     }
444                     if (!(ifo->options & DHCPCD_ROUTER_HOST_ROUTE_WARNED) &&
445                         !(state->added & STATE_FAKE))
446                     {
447                               char buf[INET_MAX_ADDRSTRLEN];
448 
449                               ifo->options |= DHCPCD_ROUTER_HOST_ROUTE_WARNED;
450                               logwarnx("%s: router %s requires a host route",
451                                   ifp->name,
452                                   sa_addrtop(&rt->rt_gateway, buf, sizeof(buf)));
453                     }
454 
455                     if ((rth = rt_new(ifp)) == NULL)
456                               return -1;
457                     rth->rt_flags |= RTF_HOST;
458                     sa_in_init(&rth->rt_dest, &gateway->sin_addr);
459                     in.s_addr = INADDR_BROADCAST;
460                     sa_in_init(&rth->rt_netmask, &in);
461                     in.s_addr = INADDR_ANY;
462                     sa_in_init(&rth->rt_gateway, &in);
463                     rth->rt_mtu = dhcp_get_mtu(ifp);
464                     if (state->addr != NULL)
465                               sa_in_init(&rth->rt_ifa, &state->addr->addr);
466                     else
467                               rth->rt_ifa.sa_family = AF_UNSPEC;
468 
469                     /* We need to insert the host route just before the router. */
470                     while ((rtp = RB_TREE_MAX(routes)) != NULL) {
471                               rb_tree_remove_node(routes, rtp);
472                               rt_proto_add(&troutes, rtp);
473                               if (rtp == rt)
474                                         break;
475                     }
476                     rt_proto_add(routes, rth);
477                     /* troutes is now reversed, so add backwards again. */
478                     while ((rtp = RB_TREE_MAX(&troutes)) != NULL) {
479                               rb_tree_remove_node(&troutes, rtp);
480                               rt_proto_add(routes, rtp);
481                     }
482           }
483           return 0;
484 }
485 
486 bool
inet_getroutes(struct dhcpcd_ctx * ctx,rb_tree_t * routes)487 inet_getroutes(struct dhcpcd_ctx *ctx, rb_tree_t *routes)
488 {
489           struct interface *ifp;
490           bool have_default = false;
491 
492           TAILQ_FOREACH(ifp, ctx->ifaces, next) {
493                     if (!ifp->active)
494                               continue;
495                     if (inet_dhcproutes(routes, ifp, &have_default) == -1)
496                               return false;
497 #ifdef IPV4LL
498                     if (ipv4ll_subnetroute(routes, ifp) == -1)
499                               return false;
500 #endif
501                     if (inet_routerhostroute(routes, ifp) == -1)
502                               return false;
503           }
504 
505 #ifdef IPV4LL
506           /* If there is no default route, see if we can use an IPv4LL one. */
507           if (have_default)
508                     return true;
509 
510           TAILQ_FOREACH(ifp, ctx->ifaces, next) {
511                     if (ifp->active &&
512                         ipv4ll_defaultroute(routes, ifp) == 1)
513                               break;
514           }
515 #endif
516 
517           return true;
518 }
519 
520 int
ipv4_deladdr(struct ipv4_addr * addr,int keeparp)521 ipv4_deladdr(struct ipv4_addr *addr, int keeparp)
522 {
523           int r;
524           struct ipv4_state *state;
525           struct ipv4_addr *ap;
526 
527           logdebugx("%s: deleting IP address %s",
528               addr->iface->name, addr->saddr);
529 
530           r = if_address(RTM_DELADDR, addr);
531           if (r == -1 &&
532               errno != EADDRNOTAVAIL && errno != ESRCH &&
533               errno != ENXIO && errno != ENODEV)
534                     logerr("%s: %s", addr->iface->name, __func__);
535 
536 #ifdef ARP
537           if (!keeparp)
538                     arp_freeaddr(addr->iface, &addr->addr);
539 #else
540           UNUSED(keeparp);
541 #endif
542 
543           state = IPV4_STATE(addr->iface);
544           TAILQ_FOREACH(ap, &state->addrs, next) {
545                     if (IPV4_MASK_EQ(ap, addr)) {
546                               struct dhcp_state *dstate;
547 
548                               dstate = D_STATE(ap->iface);
549                               TAILQ_REMOVE(&state->addrs, ap, next);
550                               free(ap);
551 
552                               if (dstate && dstate->addr == ap) {
553                                         dstate->added = 0;
554                                         dstate->addr = NULL;
555                               }
556                               break;
557                     }
558           }
559 
560           return r;
561 }
562 
563 static int
delete_address(struct interface * ifp)564 delete_address(struct interface *ifp)
565 {
566           int r;
567           struct if_options *ifo;
568           struct dhcp_state *state;
569 
570           state = D_STATE(ifp);
571           ifo = ifp->options;
572           /* The lease could have been added, but the address deleted
573            * by a 3rd party. */
574           if (state->addr == NULL ||
575               ifo->options & DHCPCD_INFORM ||
576               (ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0))
577                     return 0;
578 #ifdef ARP
579           arp_freeaddr(ifp, &state->addr->addr);
580 #endif
581           r = ipv4_deladdr(state->addr, 0);
582           return r;
583 }
584 
585 struct ipv4_state *
ipv4_getstate(struct interface * ifp)586 ipv4_getstate(struct interface *ifp)
587 {
588           struct ipv4_state *state;
589 
590           state = IPV4_STATE(ifp);
591           if (state == NULL) {
592                   ifp->if_data[IF_DATA_IPV4] = malloc(sizeof(*state));
593                     state = IPV4_STATE(ifp);
594                     if (state == NULL) {
595                               logerr(__func__);
596                               return NULL;
597                     }
598                     TAILQ_INIT(&state->addrs);
599           }
600           return state;
601 }
602 
603 #ifdef ALIAS_ADDR
604 /* Find the next logical aliase address we can use. */
605 static int
ipv4_aliasaddr(struct ipv4_addr * ia,struct ipv4_addr ** repl)606 ipv4_aliasaddr(struct ipv4_addr *ia, struct ipv4_addr **repl)
607 {
608           struct ipv4_state *state;
609           struct ipv4_addr *iap;
610           unsigned int lun;
611           char alias[IF_NAMESIZE];
612 
613           if (ia->alias[0] != '\0')
614                     return 0;
615 
616           lun = 0;
617           state = IPV4_STATE(ia->iface);
618 find_lun:
619           if (if_makealias(alias, IF_NAMESIZE, ia->iface->name, lun) >=
620               IF_NAMESIZE)
621           {
622                     errno = ENOMEM;
623                     return -1;
624           }
625           TAILQ_FOREACH(iap, &state->addrs, next) {
626                     if (iap->alias[0] != '\0' && iap->addr.s_addr == INADDR_ANY) {
627                               /* No address assigned? Lets use it. */
628                               strlcpy(ia->alias, iap->alias, sizeof(ia->alias));
629                               if (repl)
630                                         *repl = iap;
631                               return 1;
632                     }
633                     if (strcmp(iap->alias, alias) == 0)
634                               break;
635           }
636 
637           if (iap != NULL) {
638                     if (lun == UINT_MAX) {
639                               errno = ERANGE;
640                               return -1;
641                     }
642                     lun++;
643                     goto find_lun;
644           }
645 
646           strlcpy(ia->alias, alias, sizeof(ia->alias));
647           return 0;
648 }
649 #endif
650 
651 struct ipv4_addr *
ipv4_addaddr(struct interface * ifp,const struct in_addr * addr,const struct in_addr * mask,const struct in_addr * bcast,uint32_t vltime,uint32_t pltime)652 ipv4_addaddr(struct interface *ifp, const struct in_addr *addr,
653     const struct in_addr *mask, const struct in_addr *bcast,
654     uint32_t vltime, uint32_t pltime)
655 {
656           struct ipv4_state *state;
657           struct ipv4_addr *ia;
658 #ifdef ALIAS_ADDR
659           int replaced, blank;
660           struct ipv4_addr *replaced_ia;
661 #endif
662 
663           if ((state = ipv4_getstate(ifp)) == NULL) {
664                     logerr(__func__);
665                     return NULL;
666           }
667           if (ifp->options->options & DHCPCD_NOALIAS) {
668                     struct ipv4_addr *ian;
669 
670                     TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ian) {
671                               if (ia->addr.s_addr != addr->s_addr)
672                                         ipv4_deladdr(ia, 0);
673                     }
674           }
675 
676           ia = ipv4_iffindaddr(ifp, addr, NULL);
677           if (ia == NULL) {
678                     ia = malloc(sizeof(*ia));
679                     if (ia == NULL) {
680                               logerr(__func__);
681                               return NULL;
682                     }
683                     ia->iface = ifp;
684                     ia->addr = *addr;
685 #ifdef IN_IFF_TENTATIVE
686                     ia->addr_flags = IN_IFF_TENTATIVE;
687 #endif
688                     ia->flags = IPV4_AF_NEW;
689           } else
690                     ia->flags &= ~IPV4_AF_NEW;
691 
692           ia->mask = *mask;
693           ia->brd = *bcast;
694 #ifdef IP_LIFETIME
695           if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND) {
696                     /* We don't want the kernel to expire the address. */
697                     ia->vltime = ia->pltime = DHCP_INFINITE_LIFETIME;
698           } else {
699                     ia->vltime = vltime;
700                     ia->pltime = pltime;
701           }
702 #else
703           UNUSED(vltime);
704           UNUSED(pltime);
705 #endif
706           snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
707               inet_ntoa(*addr), inet_ntocidr(*mask));
708 
709 #ifdef ALIAS_ADDR
710           blank = (ia->alias[0] == '\0');
711           if ((replaced = ipv4_aliasaddr(ia, &replaced_ia)) == -1) {
712                     logerr("%s: ipv4_aliasaddr", ifp->name);
713                     free(ia);
714                     return NULL;
715           }
716           if (blank)
717                     logdebugx("%s: aliased %s", ia->alias, ia->saddr);
718 #endif
719 
720           logdebugx("%s: adding IP address %s %s %s",
721               ifp->name, ia->saddr,
722               ifp->flags & IFF_POINTOPOINT ? "destination" : "broadcast",
723               inet_ntoa(*bcast));
724           if (if_address(RTM_NEWADDR, ia) == -1) {
725                     if (errno != EEXIST)
726                               logerr("%s: if_addaddress",
727                                   __func__);
728                     if (ia->flags & IPV4_AF_NEW)
729                               free(ia);
730                     return NULL;
731           }
732 
733 #ifdef ALIAS_ADDR
734           if (replaced) {
735                     TAILQ_REMOVE(&state->addrs, replaced_ia, next);
736                     free(replaced_ia);
737           }
738 #endif
739 
740           if (ia->flags & IPV4_AF_NEW)
741                     TAILQ_INSERT_TAIL(&state->addrs, ia, next);
742           return ia;
743 }
744 
745 static int
ipv4_daddaddr(struct interface * ifp,const struct dhcp_lease * lease)746 ipv4_daddaddr(struct interface *ifp, const struct dhcp_lease *lease)
747 {
748           struct dhcp_state *state;
749           struct ipv4_addr *ia;
750 
751           ia = ipv4_addaddr(ifp, &lease->addr, &lease->mask, &lease->brd,
752               lease->leasetime, lease->rebindtime);
753           if (ia == NULL)
754                     return -1;
755 
756           state = D_STATE(ifp);
757           state->added = STATE_ADDED;
758           state->addr = ia;
759           return 0;
760 }
761 
762 struct ipv4_addr *
ipv4_applyaddr(void * arg)763 ipv4_applyaddr(void *arg)
764 {
765           struct interface *ifp = arg;
766           struct dhcp_state *state = D_STATE(ifp);
767           struct dhcp_lease *lease;
768           struct if_options *ifo = ifp->options;
769           struct ipv4_addr *ia;
770 
771           if (state == NULL)
772                     return NULL;
773 
774           lease = &state->lease;
775           if (state->new == NULL) {
776                     if ((ifo->options & (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
777                         (DHCPCD_EXITING | DHCPCD_PERSISTENT))
778                     {
779                               if (state->added) {
780                                         delete_address(ifp);
781                                         rt_build(ifp->ctx, AF_INET);
782 #ifdef ARP
783                                         /* Announce the preferred address to
784                                          * kick ARP caches. */
785                                         arp_announceaddr(ifp->ctx,&lease->addr);
786 #endif
787                               }
788                               script_runreason(ifp, state->reason);
789                     } else
790                               rt_build(ifp->ctx, AF_INET);
791                     return NULL;
792           }
793 
794           ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
795           /* If the netmask or broadcast is different, re-add the addresss.
796            * If IP addresses do not have lifetimes, there is a very real chance
797            * that re-adding them will scrub the subnet route temporarily
798            * which is a bad thing, so avoid it. */
799           if (ia != NULL &&
800               ia->mask.s_addr == lease->mask.s_addr &&
801               ia->brd.s_addr == lease->brd.s_addr)
802           {
803 #ifndef IP_LIFETIME
804                     logdebugx("%s: IP address %s already exists",
805                         ifp->name, ia->saddr);
806 #endif
807           } else {
808 #ifdef __linux__
809                     /* Linux does not change netmask/broadcast address
810                      * for re-added addresses, so we need to delete the old one
811                      * first. */
812                     if (ia != NULL)
813                               ipv4_deladdr(ia, 0);
814 #endif
815 #ifndef IP_LIFETIME
816                     if (ipv4_daddaddr(ifp, lease) == -1 && errno != EEXIST)
817                               return NULL;
818 #endif
819           }
820 #ifdef IP_LIFETIME
821           if (ipv4_daddaddr(ifp, lease) == -1 && errno != EEXIST)
822                     return NULL;
823 #endif
824 
825           ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
826           if (ia == NULL) {
827                     logerrx("%s: added address vanished", ifp->name);
828                     return NULL;
829           }
830 #if defined(ARP) && defined(IN_IFF_NOTUSEABLE)
831           if (ia->addr_flags & IN_IFF_NOTUSEABLE)
832                     return NULL;
833 #endif
834 
835           /* Delete the old address if different */
836           if (state->addr &&
837               state->addr->addr.s_addr != lease->addr.s_addr &&
838               ipv4_iffindaddr(ifp, &lease->addr, NULL))
839                     delete_address(ifp);
840 
841           state->addr = ia;
842           state->added = STATE_ADDED;
843 
844           rt_build(ifp->ctx, AF_INET);
845 
846 #ifdef ARP
847           arp_announceaddr(ifp->ctx, &state->addr->addr);
848 #endif
849 
850           if (state->state == DHS_BOUND) {
851                     script_runreason(ifp, state->reason);
852                     dhcpcd_daemonise(ifp->ctx);
853           }
854           return ia;
855 }
856 
857 void
ipv4_markaddrsstale(struct interface * ifp)858 ipv4_markaddrsstale(struct interface *ifp)
859 {
860           struct ipv4_state *state;
861           struct ipv4_addr *ia;
862 
863           state = IPV4_STATE(ifp);
864           if (state == NULL)
865                     return;
866 
867           TAILQ_FOREACH(ia, &state->addrs, next) {
868                     ia->flags |= IPV4_AF_STALE;
869           }
870 }
871 
872 void
ipv4_deletestaleaddrs(struct interface * ifp)873 ipv4_deletestaleaddrs(struct interface *ifp)
874 {
875           struct ipv4_state *state;
876           struct ipv4_addr *ia, *ia1;
877 
878           state = IPV4_STATE(ifp);
879           if (state == NULL)
880                     return;
881 
882           TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ia1) {
883                     if (!(ia->flags & IPV4_AF_STALE))
884                               continue;
885                     ipv4_handleifa(ifp->ctx, RTM_DELADDR,
886                         ifp->ctx->ifaces, ifp->name,
887                         &ia->addr, &ia->mask, &ia->brd, 0, getpid());
888           }
889 }
890 
891 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 * mask,const struct in_addr * brd,int addrflags,pid_t pid)892 ipv4_handleifa(struct dhcpcd_ctx *ctx,
893     int cmd, struct if_head *ifs, const char *ifname,
894     const struct in_addr *addr, const struct in_addr *mask,
895     const struct in_addr *brd, int addrflags, pid_t pid)
896 {
897           struct interface *ifp;
898           struct ipv4_state *state;
899           struct ipv4_addr *ia;
900           bool ia_is_new;
901 
902 #if 0
903           char sbrdbuf[INET_ADDRSTRLEN];
904           const char *sbrd;
905 
906           if (brd)
907                     sbrd = inet_ntop(AF_INET, brd, sbrdbuf, sizeof(sbrdbuf));
908           else
909                     sbrd = NULL;
910           logdebugx("%s: %s %s/%d %s %d", ifname,
911               cmd == RTM_NEWADDR ? "RTM_NEWADDR" :
912               cmd == RTM_DELADDR ? "RTM_DELADDR" : "???",
913               inet_ntoa(*addr), inet_ntocidr(*mask), sbrd, addrflags);
914 #endif
915 
916           if (ifs == NULL)
917                     ifs = ctx->ifaces;
918           if (ifs == NULL) {
919                     errno = ESRCH;
920                     return;
921           }
922           if ((ifp = if_find(ifs, ifname)) == NULL)
923                     return;
924           if ((state = ipv4_getstate(ifp)) == NULL) {
925                     errno = ENOENT;
926                     return;
927           }
928 
929           ia = ipv4_iffindaddr(ifp, addr, NULL);
930           switch (cmd) {
931           case RTM_NEWADDR:
932                     if (ia == NULL) {
933                               if ((ia = malloc(sizeof(*ia))) == NULL) {
934                                         logerr(__func__);
935                                         return;
936                               }
937                               ia->iface = ifp;
938                               ia->addr = *addr;
939                               ia->mask = *mask;
940                               ia->flags = 0;
941                               ia_is_new = true;
942 #ifdef ALIAS_ADDR
943                               strlcpy(ia->alias, ifname, sizeof(ia->alias));
944 #endif
945                               TAILQ_INSERT_TAIL(&state->addrs, ia, next);
946                     } else
947                               ia_is_new = false;
948                     /* Mask could have changed */
949                     if (ia_is_new ||
950                         (mask->s_addr != INADDR_ANY &&
951                         mask->s_addr != ia->mask.s_addr))
952                     {
953                               ia->mask = *mask;
954                               snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
955                                   inet_ntoa(*addr), inet_ntocidr(*mask));
956                     }
957                     if (brd != NULL)
958                               ia->brd = *brd;
959                     else
960                               ia->brd.s_addr = INADDR_ANY;
961                     ia->addr_flags = addrflags;
962                     ia->flags &= ~IPV4_AF_STALE;
963                     break;
964           case RTM_DELADDR:
965                     if (ia == NULL)
966                               return;
967                     if (mask->s_addr != INADDR_ANY &&
968                         mask->s_addr != ia->mask.s_addr)
969                               return;
970                     TAILQ_REMOVE(&state->addrs, ia, next);
971                     break;
972           default:
973                     return;
974           }
975 
976           if (addr->s_addr != INADDR_ANY && addr->s_addr != INADDR_BROADCAST) {
977                     ia = dhcp_handleifa(cmd, ia, pid);
978 #ifdef IPV4LL
979                     if (ia != NULL)
980                               ipv4ll_handleifa(cmd, ia, pid);
981 #endif
982           }
983 
984           if (cmd == RTM_DELADDR)
985                     free(ia);
986 }
987 
988 void
ipv4_free(struct interface * ifp)989 ipv4_free(struct interface *ifp)
990 {
991           struct ipv4_state *state;
992           struct ipv4_addr *ia;
993 
994           if (ifp == NULL || (state = IPV4_STATE(ifp)) == NULL)
995                     return;
996 
997           while ((ia = TAILQ_FIRST(&state->addrs))) {
998                     TAILQ_REMOVE(&state->addrs, ia, next);
999                     free(ia);
1000           }
1001           free(state);
1002 }
1003