1 /* SPDX-License-Identifier: BSD-2-Clause */
3 * dhcpcd - DHCP client daemon
4 * Copyright (c) 2006-2019 Roy Marples <roy@marples.name>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
29 #include <sys/socket.h>
30 #include <sys/types.h>
32 #include <arpa/inet.h>
34 #include <net/route.h>
35 #include <netinet/if_ether.h>
36 #include <netinet/in.h>
53 #include "if-options.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
69 inet_ntocidr(struct in_addr address
)
72 uint32_t mask
= htonl(address
.s_addr
);
82 inet_cidrtoaddr(int cidr
, struct in_addr
*addr
)
86 if (cidr
< 1 || cidr
> 32) {
90 ocets
= (cidr
+ 7) / NBBY
;
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);
103 ipv4_getnetmask(uint32_t addr
)
112 return ntohl(IN_CLASSA_NET
);
114 return ntohl(IN_CLASSB_NET
);
116 return ntohl(IN_CLASSC_NET
);
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
);
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
))
140 ipv4_iffindlladdr(struct interface
*ifp
)
142 struct ipv4_state
*state
;
143 struct ipv4_addr
*ap
;
145 state
= IPV4_STATE(ifp
);
147 TAILQ_FOREACH(ap
, &state
->addrs
, next
) {
148 if (IN_LINKLOCAL(htonl(ap
->addr
.s_addr
)))
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
);
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
))
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
);
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
);
201 ipv4_hasaddr(const struct interface
*ifp
)
203 const struct dhcp_state
*dstate
;
206 if (IPV4LL_STATE_RUNNING(ifp
))
210 dstate
= D_CSTATE(ifp
);
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
;
230 /* If one has a lease and the other not, it takes precedence. */
231 if (sis
->new && !tis
->new)
233 if (!sis
->new && tis
->new)
235 /* Always prefer proper leases */
236 if (!(sis
->added
& STATE_FAKE
) && (tis
->added
& STATE_FAKE
))
238 if ((sis
->added
& STATE_FAKE
) && !(tis
->added
& STATE_FAKE
))
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))
245 if (!IS_DHCP(sis
->new) && IS_DHCP(tis
->new))
252 inet_dhcproutes(rb_tree_t
*routes
, struct interface
*ifp
, bool *have_default
)
254 const struct dhcp_state
*state
;
256 struct rt
*rt
, *r
= NULL
;
261 state
= D_CSTATE(ifp
);
262 if (state
== NULL
|| state
->state
!= DHS_BOUND
|| !state
->added
)
265 /* An address does have to exist. */
268 rb_tree_init(&nroutes
, &rt_compare_proto_ops
);
270 /* First, add a subnet route. */
271 if (state
->addr
->mask
.s_addr
!= INADDR_ANY
273 /* BSD adds a route in this instance */
274 && state
->addr
->mask
.s_addr
!= INADDR_BROADCAST
277 if ((rt
= rt_new(ifp
)) == NULL
)
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
))
295 if ((rt
= rt_new0(ifp
->ctx
)) == NULL
)
297 memcpy(rt
, r
, sizeof(*rt
));
299 rt
->rt_dflags
= RTDF_STATIC
;
300 rt_proto_add(&nroutes
, rt
);
303 if (dhcp_get_routes(&nroutes
, ifp
) == -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
)
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
);
325 while ((rt
= RB_TREE_MIN(&nroutes
)) != NULL
) {
326 rb_tree_remove_node(&nroutes
, rt
);
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
) {
335 if (rt_is_default(rt
))
336 *have_default
= true;
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. */
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
;
356 /* Don't add a host route for these interfaces. */
357 if (ifp
->flags
& (IFF_LOOPBACK
| IFF_POINTOPOINT
))
360 rb_tree_init(&troutes
, &rt_compare_proto_ops
);
362 RB_TREE_FOREACH(rt
, routes
) {
363 if (rt
->rt_dest
.sa_family
!= AF_INET
)
365 if (!sa_is_unspecified(&rt
->rt_dest
) ||
366 sa_is_unspecified(&rt
->rt_gateway
))
368 gateway
= satosin(&rt
->rt_gateway
);
369 /* Scan for a route to match */
370 RB_TREE_FOREACH(rth
, routes
) {
374 if (sa_cmp(&rth
->rt_dest
, &rt
->rt_gateway
) == 0)
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
++)
393 if ((state
= D_CSTATE(ifp
)) == NULL
)
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 "
406 sa_addrtop(&rt
->rt_gateway
,
409 gateway
->sin_addr
.s_addr
= INADDR_ANY
;
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",
420 sa_addrtop(&rt
->rt_gateway
, buf
, sizeof(buf
)));
423 if ((rth
= rt_new(ifp
)) == NULL
)
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
);
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
);
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
) {
460 if (inet_dhcproutes(routes
, ifp
, &have_default
) == -1)
463 if (ipv4ll_subnetroute(routes
, ifp
) == -1)
466 if (inet_routerhostroute(routes
, ifp
) == -1)
471 /* If there is no default route, see if we can use an IPv4LL one. */
475 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
477 ipv4ll_defaultroute(routes
, ifp
) == 1)
486 ipv4_deladdr(struct ipv4_addr
*addr
, int keeparp
)
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
);
497 errno
!= EADDRNOTAVAIL
&& errno
!= ESRCH
&&
498 errno
!= ENXIO
&& errno
!= ENODEV
)
499 logerr("%s: %s", addr
->iface
->name
, __func__
);
503 arp_freeaddr(addr
->iface
, &addr
->addr
);
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
);
517 if (dstate
&& dstate
->addr
== ap
) {
529 delete_address(struct interface
*ifp
)
532 struct if_options
*ifo
;
533 struct dhcp_state
*state
;
535 state
= D_STATE(ifp
);
537 /* The lease could have been added, but the address deleted
539 if (state
->addr
== NULL
||
540 ifo
->options
& DHCPCD_INFORM
||
541 (ifo
->options
& DHCPCD_STATIC
&& ifo
->req_addr
.s_addr
== 0))
544 arp_freeaddr(ifp
, &state
->addr
->addr
);
546 r
= ipv4_deladdr(state
->addr
, 0);
551 ipv4_getstate(struct interface
*ifp
)
553 struct ipv4_state
*state
;
555 state
= IPV4_STATE(ifp
);
557 ifp
->if_data
[IF_DATA_IPV4
] = malloc(sizeof(*state
));
558 state
= IPV4_STATE(ifp
);
563 TAILQ_INIT(&state
->addrs
);
564 state
->buffer_size
= state
->buffer_len
= state
->buffer_pos
= 0;
565 state
->buffer
= NULL
;
571 /* Find the next logical aliase address we can use. */
573 ipv4_aliasaddr(struct ipv4_addr
*ia
, struct ipv4_addr
**repl
)
575 struct ipv4_state
*state
;
576 struct ipv4_addr
*iap
;
578 char alias
[IF_NAMESIZE
];
580 if (ia
->alias
[0] != '\0')
584 state
= IPV4_STATE(ia
->iface
);
586 if (if_makealias(alias
, IF_NAMESIZE
, ia
->iface
->name
, lun
) >=
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
));
600 if (strcmp(iap
->alias
, alias
) == 0)
605 if (lun
== UINT_MAX
) {
613 strlcpy(ia
->alias
, alias
, sizeof(ia
->alias
));
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
;
628 struct ipv4_addr
*replaced_ia
;
631 if ((state
= ipv4_getstate(ifp
)) == 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
)
644 ia
= ipv4_iffindaddr(ifp
, addr
, NULL
);
646 ia
= malloc(sizeof(*ia
));
653 #ifdef IN_IFF_TENTATIVE
654 ia
->addr_flags
= IN_IFF_TENTATIVE
;
668 snprintf(ia
->saddr
, sizeof(ia
->saddr
), "%s/%d",
669 inet_ntoa(*addr
), inet_ntocidr(*mask
));
672 blank
= (ia
->alias
[0] == '\0');
673 if ((replaced
= ipv4_aliasaddr(ia
, &replaced_ia
)) == -1) {
674 logerr("%s: ipv4_aliasaddr", ifp
->name
);
679 logdebugx("%s: aliased %s", ia
->alias
, ia
->saddr
);
682 logdebugx("%s: adding IP address %s %s %s",
683 ifp
->name
, ia
->saddr
,
684 ifp
->flags
& IFF_POINTOPOINT
? "destination" : "broadcast",
686 if (if_address(RTM_NEWADDR
, ia
) == -1) {
688 logerr("%s: if_addaddress",
696 TAILQ_REMOVE(&state
->addrs
, replaced_ia
, next
);
702 TAILQ_INSERT_TAIL(&state
->addrs
, ia
, next
);
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
);
717 state
= D_STATE(ifp
);
718 state
->added
= STATE_ADDED
;
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
;
735 lease
= &state
->lease
;
736 if (state
->new == NULL
) {
737 if ((ifo
->options
& (DHCPCD_EXITING
| DHCPCD_PERSISTENT
)) !=
738 (DHCPCD_EXITING
| DHCPCD_PERSISTENT
))
742 rt_build(ifp
->ctx
, AF_INET
);
744 /* Announce the preferred address to
745 * kick ARP caches. */
746 if (!(ifp
->flags
& IFF_NOARP
))
747 arp_announceaddr(ifp
->ctx
,&lease
->addr
);
750 script_runreason(ifp
, state
->reason
);
752 rt_build(ifp
->ctx
, AF_INET
);
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. */
762 ia
->mask
.s_addr
== lease
->mask
.s_addr
&&
763 ia
->brd
.s_addr
== lease
->brd
.s_addr
)
766 logdebugx("%s: IP address %s already exists",
767 ifp
->name
, ia
->saddr
);
771 /* Linux does not change netmask/broadcast address
772 * for re-added addresses, so we need to delete the old one
778 if (ipv4_daddaddr(ifp
, lease
) == -1 && errno
!= EEXIST
)
783 if (ipv4_daddaddr(ifp
, lease
) == -1 && errno
!= EEXIST
)
787 ia
= ipv4_iffindaddr(ifp
, &lease
->addr
, NULL
);
789 logerrx("%s: added address vanished", ifp
->name
);
792 #if defined(ARP) && defined(IN_IFF_NOTUSEABLE)
793 if (ia
->addr_flags
& IN_IFF_NOTUSEABLE
)
797 /* Delete the old address if different */
799 state
->addr
->addr
.s_addr
!= lease
->addr
.s_addr
&&
800 ipv4_iffindaddr(ifp
, &lease
->addr
, NULL
))
804 state
->added
= STATE_ADDED
;
806 rt_build(ifp
->ctx
, AF_INET
);
809 if (!(ifp
->flags
& IFF_NOARP
))
810 arp_announceaddr(ifp
->ctx
, &state
->addr
->addr
);
813 if (state
->state
== DHS_BOUND
) {
814 script_runreason(ifp
, state
->reason
);
815 dhcpcd_daemonise(ifp
->ctx
);
820 ipv4_markaddrsstale(struct interface
*ifp
)
822 struct ipv4_state
*state
;
823 struct ipv4_addr
*ia
;
825 state
= IPV4_STATE(ifp
);
829 TAILQ_FOREACH(ia
, &state
->addrs
, next
) {
830 ia
->flags
|= IPV4_AF_STALE
;
835 ipv4_deletestaleaddrs(struct interface
*ifp
)
837 struct ipv4_state
*state
;
838 struct ipv4_addr
*ia
, *ia1
;
840 state
= IPV4_STATE(ifp
);
844 TAILQ_FOREACH_SAFE(ia
, &state
->addrs
, next
, ia1
) {
845 if (!(ia
->flags
& IPV4_AF_STALE
))
847 ipv4_handleifa(ifp
->ctx
, RTM_DELADDR
,
848 ifp
->ctx
->ifaces
, ifp
->name
,
849 &ia
->addr
, &ia
->mask
, &ia
->brd
, 0, getpid());
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
;
865 char sbrdbuf
[INET_ADDRSTRLEN
];
869 sbrd
= inet_ntop(AF_INET
, brd
, sbrdbuf
, sizeof(sbrdbuf
));
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
);
884 if ((ifp
= if_find(ifs
, ifname
)) == NULL
)
886 if ((state
= ipv4_getstate(ifp
)) == NULL
) {
891 ia
= ipv4_iffindaddr(ifp
, addr
, NULL
);
895 if ((ia
= malloc(sizeof(*ia
))) == NULL
) {
905 strlcpy(ia
->alias
, ifname
, sizeof(ia
->alias
));
907 TAILQ_INSERT_TAIL(&state
->addrs
, ia
, next
);
910 /* Mask could have changed */
912 (mask
->s_addr
!= INADDR_ANY
&&
913 mask
->s_addr
!= ia
->mask
.s_addr
))
916 snprintf(ia
->saddr
, sizeof(ia
->saddr
), "%s/%d",
917 inet_ntoa(*addr
), inet_ntocidr(*mask
));
922 ia
->brd
.s_addr
= INADDR_ANY
;
923 ia
->addr_flags
= addrflags
;
924 ia
->flags
&= ~IPV4_AF_STALE
;
929 if (mask
->s_addr
!= INADDR_ANY
&&
930 mask
->s_addr
!= ia
->mask
.s_addr
)
932 TAILQ_REMOVE(&state
->addrs
, ia
, next
);
938 if (addr
->s_addr
!= INADDR_ANY
&& addr
->s_addr
!= INADDR_BROADCAST
) {
939 dhcp_handleifa(cmd
, ia
, pid
);
941 ipv4ll_handleifa(cmd
, ia
, pid
);
945 if (cmd
== RTM_DELADDR
)
950 ipv4_free(struct interface
*ifp
)
952 struct ipv4_state
*state
;
953 struct ipv4_addr
*ia
;
956 state
= IPV4_STATE(ifp
);
958 while ((ia
= TAILQ_FIRST(&state
->addrs
))) {
959 TAILQ_REMOVE(&state
->addrs
, ia
, next
);