2 * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1982, 1986, 1991, 1993
30 * The Regents of the University of California. All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * @(#)in.c 8.4 (Berkeley) 1/9/95
61 * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.5 2001/08/13 16:26:17 ume Exp $
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/sockio.h>
67 #include <sys/socketvar.h>
68 #include <sys/malloc.h>
70 #include <sys/socket.h>
71 #include <sys/kernel.h>
72 #include <sys/sysctl.h>
73 #include <sys/kern_event.h>
74 #include <sys/syslog.h>
75 #include <sys/mcache.h>
76 #include <kern/zalloc.h>
78 #include <pexpert/pexpert.h>
81 #include <net/if_types.h>
82 #include <net/route.h>
83 #include <net/kpi_protocol.h>
85 #include <netinet/in.h>
86 #include <netinet/in_var.h>
87 #include <netinet/in_pcb.h>
89 #include <netinet/igmp_var.h>
92 #include <netinet/ip_var.h>
94 #include <netinet/tcp.h>
95 #include <netinet/tcp_timer.h>
96 #include <netinet/tcp_var.h>
101 #include <net/pfvar.h>
104 static int in_mask2len(struct in_addr
*);
105 static void in_len2mask(struct in_addr
*, int);
106 static int in_lifaddr_ioctl(struct socket
*, u_long
, caddr_t
,
107 struct ifnet
*, struct proc
*);
109 static void in_socktrim(struct sockaddr_in
*);
110 static int in_ifinit(struct ifnet
*,
111 struct in_ifaddr
*, struct sockaddr_in
*, int);
113 #define IA_HASH_INIT(ia) { \
114 (ia)->ia_hash.tqe_next = (void *)(uintptr_t)-1; \
115 (ia)->ia_hash.tqe_prev = (void *)(uintptr_t)-1; \
118 #define IA_IS_HASHED(ia) \
119 (!((ia)->ia_hash.tqe_next == (void *)(uintptr_t)-1 || \
120 (ia)->ia_hash.tqe_prev == (void *)(uintptr_t)-1))
122 static void in_iahash_remove(struct in_ifaddr
*);
123 static void in_iahash_insert(struct in_ifaddr
*);
124 static void in_iahash_insert_ptp(struct in_ifaddr
*);
125 static struct in_ifaddr
*in_ifaddr_alloc(int);
126 static void in_ifaddr_attached(struct ifaddr
*);
127 static void in_ifaddr_detached(struct ifaddr
*);
128 static void in_ifaddr_free(struct ifaddr
*);
129 static void in_ifaddr_trace(struct ifaddr
*, int);
131 static int subnetsarelocal
= 0;
132 SYSCTL_INT(_net_inet_ip
, OID_AUTO
, subnets_are_local
, CTLFLAG_RW
| CTLFLAG_LOCKED
,
133 &subnetsarelocal
, 0, "");
135 /* Track whether or not the SIOCARPIPLL ioctl has been called */
136 __private_extern__ u_int32_t ipv4_ll_arp_aware
= 0;
138 #define INIFA_TRACE_HIST_SIZE 32 /* size of trace history */
141 __private_extern__
unsigned int inifa_trace_hist_size
= INIFA_TRACE_HIST_SIZE
;
143 struct in_ifaddr_dbg
{
144 struct in_ifaddr inifa
; /* in_ifaddr */
145 struct in_ifaddr inifa_old
; /* saved in_ifaddr */
146 u_int16_t inifa_refhold_cnt
; /* # of IFA_ADDREF */
147 u_int16_t inifa_refrele_cnt
; /* # of IFA_REMREF */
149 * Alloc and free callers.
151 ctrace_t inifa_alloc
;
154 * Circular lists of IFA_ADDREF and IFA_REMREF callers.
156 ctrace_t inifa_refhold
[INIFA_TRACE_HIST_SIZE
];
157 ctrace_t inifa_refrele
[INIFA_TRACE_HIST_SIZE
];
161 TAILQ_ENTRY(in_ifaddr_dbg
) inifa_trash_link
;
164 /* List of trash in_ifaddr entries protected by inifa_trash_lock */
165 static TAILQ_HEAD(, in_ifaddr_dbg
) inifa_trash_head
;
166 static decl_lck_mtx_data(, inifa_trash_lock
);
169 static unsigned int inifa_debug
= 1; /* debugging (enabled) */
171 static unsigned int inifa_debug
; /* debugging (disabled) */
173 static unsigned int inifa_size
; /* size of zone element */
174 static struct zone
*inifa_zone
; /* zone for in_ifaddr */
176 #define INIFA_ZONE_MAX 64 /* maximum elements in zone */
177 #define INIFA_ZONE_NAME "in_ifaddr" /* zone name */
180 * Return 1 if the address is
182 * - unicast or multicast link local
183 * - routed via a link level gateway
184 * - belongs to a directly connected (sub)net
187 inaddr_local(struct in_addr in
)
190 struct sockaddr_in sin
;
193 if (ntohl(in
.s_addr
) == INADDR_LOOPBACK
|| IN_LINKLOCAL(ntohl(in
.s_addr
))) {
195 } else if (ntohl(in
.s_addr
) >= INADDR_UNSPEC_GROUP
&&
196 ntohl(in
.s_addr
) <= INADDR_MAX_LOCAL_GROUP
) {
199 sin
.sin_family
= AF_INET
;
200 sin
.sin_len
= sizeof (sin
);
202 rt
= rtalloc1((struct sockaddr
*)&sin
, 0, 0);
206 if (rt
->rt_gateway
->sa_family
== AF_LINK
||
207 (rt
->rt_ifp
->if_flags
& IFF_LOOPBACK
))
212 local
= in_localaddr(in
);
219 * Return 1 if an internet address is for a ``local'' host
220 * (one to which we have a connection). If subnetsarelocal
221 * is true, this includes other subnets of the local net.
222 * Otherwise, it includes only the directly-connected (sub)nets.
225 in_localaddr(struct in_addr in
)
227 u_int32_t i
= ntohl(in
.s_addr
);
228 struct in_ifaddr
*ia
;
230 if (subnetsarelocal
) {
231 lck_rw_lock_shared(in_ifaddr_rwlock
);
232 for (ia
= in_ifaddrhead
.tqh_first
; ia
;
233 ia
= ia
->ia_link
.tqe_next
) {
234 IFA_LOCK(&ia
->ia_ifa
);
235 if ((i
& ia
->ia_netmask
) == ia
->ia_net
) {
236 IFA_UNLOCK(&ia
->ia_ifa
);
237 lck_rw_done(in_ifaddr_rwlock
);
240 IFA_UNLOCK(&ia
->ia_ifa
);
242 lck_rw_done(in_ifaddr_rwlock
);
244 lck_rw_lock_shared(in_ifaddr_rwlock
);
245 for (ia
= in_ifaddrhead
.tqh_first
; ia
;
246 ia
= ia
->ia_link
.tqe_next
) {
247 IFA_LOCK(&ia
->ia_ifa
);
248 if ((i
& ia
->ia_subnetmask
) == ia
->ia_subnet
) {
249 IFA_UNLOCK(&ia
->ia_ifa
);
250 lck_rw_done(in_ifaddr_rwlock
);
253 IFA_UNLOCK(&ia
->ia_ifa
);
255 lck_rw_done(in_ifaddr_rwlock
);
261 * Determine whether an IP address is in a reserved set of addresses
262 * that may not be forwarded, or whether datagrams to that destination
266 in_canforward(struct in_addr in
)
268 u_int32_t i
= ntohl(in
.s_addr
);
271 if (IN_EXPERIMENTAL(i
) || IN_MULTICAST(i
))
274 net
= i
& IN_CLASSA_NET
;
275 if (net
== 0 || net
== (IN_LOOPBACKNET
<< IN_CLASSA_NSHIFT
))
282 * Trim a mask in a sockaddr
285 in_socktrim(struct sockaddr_in
*ap
)
287 char *cplim
= (char *) &ap
->sin_addr
;
288 char *cp
= (char *) (&ap
->sin_addr
+ 1);
291 while (--cp
>= cplim
)
293 (ap
)->sin_len
= cp
- (char *) (ap
) + 1;
299 in_mask2len(struct in_addr
*mask
)
305 for (x
= 0; x
< sizeof(*mask
); x
++) {
310 if (x
< sizeof(*mask
)) {
311 for (y
= 0; y
< 8; y
++) {
312 if ((p
[x
] & (0x80 >> y
)) == 0)
320 in_len2mask(struct in_addr
*mask
, int len
)
326 bzero(mask
, sizeof(*mask
));
327 for (i
= 0; i
< len
/ 8; i
++)
330 p
[i
] = (0xff00 >> (len
% 8)) & 0xff;
333 static int in_interfaces
; /* number of external internet interfaces */
336 in_domifattach(struct ifnet
*ifp
)
340 if ((error
= proto_plumb(PF_INET
, ifp
)) && error
!= EEXIST
)
341 log(LOG_ERR
, "%s: proto_plumb returned %d if=%s%d\n",
342 __func__
, error
, ifp
->if_name
, ifp
->if_unit
);
348 * Generic internet control operations (ioctl's).
349 * Ifp is 0 if not an interface-specific ioctl.
361 * in_lifaddr_ioctl:???
364 * dlil_plumb_protocol:???
365 * dlil_unplumb_protocol:???
376 struct ifreq
*ifr
= (struct ifreq
*)data
;
377 struct in_ifaddr
*ia
= NULL
, *iap
;
379 struct in_aliasreq
*ifra
= (struct in_aliasreq
*)data
;
380 struct sockaddr_in oldaddr
;
382 int hostIsNew
, maskIsNew
;
383 struct kev_msg ev_msg
;
384 struct kev_in_data in_event_data
;
386 bzero(&in_event_data
, sizeof(struct kev_in_data
));
387 bzero(&ev_msg
, sizeof(struct kev_msg
));
391 if ((error
= proc_suser(p
)) != 0)
397 return in_lifaddr_ioctl(so
, cmd
, data
, ifp
, p
);
401 * Find address for this interface, if it exists.
403 * If an alias address was specified, find that one instead of
404 * the first one on the interface.
407 lck_rw_lock_shared(in_ifaddr_rwlock
);
408 for (iap
= in_ifaddrhead
.tqh_first
; iap
;
409 iap
= iap
->ia_link
.tqe_next
)
410 if (iap
->ia_ifp
== ifp
) {
411 IFA_LOCK(&iap
->ia_ifa
);
412 if (((struct sockaddr_in
*)&ifr
->ifr_addr
)->sin_addr
.s_addr
==
413 iap
->ia_addr
.sin_addr
.s_addr
) {
415 IFA_UNLOCK(&iap
->ia_ifa
);
417 } else if (ia
== NULL
) {
419 if (ifr
->ifr_addr
.sa_family
!= AF_INET
) {
420 IFA_UNLOCK(&iap
->ia_ifa
);
424 IFA_UNLOCK(&iap
->ia_ifa
);
426 /* take a reference on ia before releasing lock */
428 IFA_ADDREF(&ia
->ia_ifa
);
430 lck_rw_done(in_ifaddr_rwlock
);
435 if ((error
= proc_suser(p
)) != 0) {
439 error
= EADDRNOTAVAIL
;
447 error
= EADDRNOTAVAIL
;
450 if (ifra
->ifra_addr
.sin_family
== AF_INET
) {
451 struct in_ifaddr
*oia
;
453 lck_rw_lock_shared(in_ifaddr_rwlock
);
454 for (oia
= ia
; ia
; ia
= ia
->ia_link
.tqe_next
) {
455 IFA_LOCK(&ia
->ia_ifa
);
456 if (ia
->ia_ifp
== ifp
&&
457 ia
->ia_addr
.sin_addr
.s_addr
==
458 ifra
->ifra_addr
.sin_addr
.s_addr
) {
459 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
460 IFA_UNLOCK(&ia
->ia_ifa
);
463 IFA_UNLOCK(&ia
->ia_ifa
);
465 lck_rw_done(in_ifaddr_rwlock
);
467 IFA_REMREF(&oia
->ia_ifa
);
468 if ((ifp
->if_flags
& IFF_POINTOPOINT
)
469 && (cmd
== SIOCAIFADDR
)
470 && (ifra
->ifra_dstaddr
.sin_addr
.s_addr
472 error
= EDESTADDRREQ
;
476 else if (cmd
== SIOCAIFADDR
) {
480 if (cmd
== SIOCDIFADDR
&& ia
== 0) {
481 error
= EADDRNOTAVAIL
;
488 /* socket is NULL if called from in_purgeaddrs() */
489 if (so
!= NULL
&& (so
->so_state
& SS_PRIV
) == 0) {
493 /* in case it's NULL, make sure it came from the kernel */
494 if (so
== NULL
&& p
!= kernproc
) {
499 error
= EADDRNOTAVAIL
;
502 if (ifra
->ifra_addr
.sin_family
!= AF_INET
503 && cmd
== SIOCSIFADDR
) {
508 ia
= in_ifaddr_alloc(M_WAITOK
);
513 ifnet_lock_exclusive(ifp
);
516 /* Hold a reference for this routine */
517 IFA_ADDREF_LOCKED(ifa
);
519 ifa
->ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
520 ifa
->ifa_dstaddr
= (struct sockaddr
*)&ia
->ia_dstaddr
;
521 ifa
->ifa_netmask
= (struct sockaddr
*)&ia
->ia_sockmask
;
522 ia
->ia_sockmask
.sin_len
= 8;
523 if (ifp
->if_flags
& IFF_BROADCAST
) {
524 ia
->ia_broadaddr
.sin_len
= sizeof(ia
->ia_addr
);
525 ia
->ia_broadaddr
.sin_family
= AF_INET
;
528 if (!(ifp
->if_flags
& IFF_LOOPBACK
))
530 /* if_attach_ifa() holds a reference for ifa_link */
531 if_attach_ifa(ifp
, ifa
);
533 * If we have to go through in_ifinit(), make sure
534 * to avoid installing route(s) based on this address
535 * via PFC_IFUP event, before the link resolver (ARP)
538 if (cmd
== SIOCAIFADDR
|| cmd
== SIOCSIFADDR
)
539 ifa
->ifa_debug
|= IFD_NOTREADY
;
541 ifnet_lock_done(ifp
);
542 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
543 /* Hold a reference for ia_link */
545 TAILQ_INSERT_TAIL(&in_ifaddrhead
, ia
, ia_link
);
546 lck_rw_done(in_ifaddr_rwlock
);
547 error
= in_domifattach(ifp
);
548 /* discard error,can be cold with unsupported interfaces */
554 case SIOCPROTOATTACH
:
555 case SIOCPROTODETACH
:
556 if ((error
= proc_suser(p
)) != 0) {
560 error
= EADDRNOTAVAIL
;
566 if ((so
->so_state
& SS_PRIV
) == 0) {
576 if (ia
== (struct in_ifaddr
*)0) {
577 error
= EADDRNOTAVAIL
;
584 ifnet_lock_exclusive(ifp
);
586 ifp
->if_eflags
|= IFEF_AUTOCONFIGURING
;
588 ifp
->if_eflags
&= ~IFEF_AUTOCONFIGURING
;
589 ifnet_lock_done(ifp
);
593 ipv4_ll_arp_aware
= 1;
594 ifnet_lock_exclusive(ifp
);
596 ifp
->if_eflags
|= IFEF_ARPLL
;
598 ifp
->if_eflags
&= ~IFEF_ARPLL
;
599 ifnet_lock_done(ifp
);
603 IFA_LOCK(&ia
->ia_ifa
);
604 *((struct sockaddr_in
*)&ifr
->ifr_addr
) = ia
->ia_addr
;
605 IFA_UNLOCK(&ia
->ia_ifa
);
609 if ((ifp
->if_flags
& IFF_BROADCAST
) == 0) {
613 IFA_LOCK(&ia
->ia_ifa
);
614 *((struct sockaddr_in
*)&ifr
->ifr_dstaddr
) = ia
->ia_broadaddr
;
615 IFA_UNLOCK(&ia
->ia_ifa
);
619 if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0) {
623 IFA_LOCK(&ia
->ia_ifa
);
624 *((struct sockaddr_in
*)&ifr
->ifr_dstaddr
) = ia
->ia_dstaddr
;
625 IFA_UNLOCK(&ia
->ia_ifa
);
629 IFA_LOCK(&ia
->ia_ifa
);
630 *((struct sockaddr_in
*)&ifr
->ifr_addr
) = ia
->ia_sockmask
;
631 IFA_UNLOCK(&ia
->ia_ifa
);
635 if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0) {
639 IFA_LOCK(&ia
->ia_ifa
);
640 oldaddr
= ia
->ia_dstaddr
;
641 ia
->ia_dstaddr
= *(struct sockaddr_in
*)&ifr
->ifr_dstaddr
;
642 if (ia
->ia_dstaddr
.sin_family
== AF_INET
)
643 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
644 IFA_UNLOCK(&ia
->ia_ifa
);
645 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFDSTADDR
, ia
);
646 IFA_LOCK(&ia
->ia_ifa
);
647 if (error
== EOPNOTSUPP
) {
651 ia
->ia_dstaddr
= oldaddr
;
652 IFA_UNLOCK(&ia
->ia_ifa
);
655 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
657 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
658 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
659 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
661 ev_msg
.event_code
= KEV_INET_SIFDSTADDR
;
663 if (ia
->ia_ifa
.ifa_dstaddr
)
664 in_event_data
.ia_dstaddr
=
665 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
667 in_event_data
.ia_dstaddr
.s_addr
= 0;
669 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
670 in_event_data
.ia_net
= ia
->ia_net
;
671 in_event_data
.ia_netmask
= ia
->ia_netmask
;
672 in_event_data
.ia_subnet
= ia
->ia_subnet
;
673 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
674 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
675 IFA_UNLOCK(&ia
->ia_ifa
);
676 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
677 in_event_data
.link_data
.if_family
= ifp
->if_family
;
678 in_event_data
.link_data
.if_unit
= (u_int32_t
) ifp
->if_unit
;
680 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
681 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
682 ev_msg
.dv
[1].data_length
= 0;
684 kev_post_msg(&ev_msg
);
686 lck_mtx_lock(rnh_lock
);
687 IFA_LOCK(&ia
->ia_ifa
);
688 if (ia
->ia_flags
& IFA_ROUTE
) {
689 ia
->ia_ifa
.ifa_dstaddr
= (struct sockaddr
*)&oldaddr
;
690 IFA_UNLOCK(&ia
->ia_ifa
);
691 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
692 IFA_LOCK(&ia
->ia_ifa
);
693 ia
->ia_ifa
.ifa_dstaddr
=
694 (struct sockaddr
*)&ia
->ia_dstaddr
;
695 IFA_UNLOCK(&ia
->ia_ifa
);
696 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
,
699 IFA_UNLOCK(&ia
->ia_ifa
);
701 lck_mtx_unlock(rnh_lock
);
705 if ((ifp
->if_flags
& IFF_BROADCAST
) == 0) {
709 IFA_LOCK(&ia
->ia_ifa
);
710 ia
->ia_broadaddr
= *(struct sockaddr_in
*)&ifr
->ifr_broadaddr
;
712 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
713 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
714 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
716 ev_msg
.event_code
= KEV_INET_SIFBRDADDR
;
718 if (ia
->ia_ifa
.ifa_dstaddr
)
719 in_event_data
.ia_dstaddr
=
720 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
722 in_event_data
.ia_dstaddr
.s_addr
= 0;
724 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
725 in_event_data
.ia_net
= ia
->ia_net
;
726 in_event_data
.ia_netmask
= ia
->ia_netmask
;
727 in_event_data
.ia_subnet
= ia
->ia_subnet
;
728 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
729 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
730 IFA_UNLOCK(&ia
->ia_ifa
);
731 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
732 in_event_data
.link_data
.if_family
= ifp
->if_family
;
733 in_event_data
.link_data
.if_unit
= (u_int32_t
) ifp
->if_unit
;
735 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
736 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
737 ev_msg
.dv
[1].data_length
= 0;
739 kev_post_msg(&ev_msg
);
745 * If this is a new address, the reference count for the
746 * hash table has been taken at creation time above.
748 error
= in_ifinit(ifp
, ia
,
749 (struct sockaddr_in
*)&ifr
->ifr_addr
, 1);
752 (void) pf_ifaddr_hook(ifp
, cmd
);
756 case SIOCPROTOATTACH
:
757 error
= in_domifattach(ifp
);
760 case SIOCPROTODETACH
:
762 * If an IPv4 address is still present, refuse to detach.
764 ifnet_lock_shared(ifp
);
765 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
767 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
773 ifnet_lock_done(ifp
);
779 error
= proto_unplumb(PF_INET
, ifp
);
782 case SIOCSIFNETMASK
: {
785 i
= ifra
->ifra_addr
.sin_addr
.s_addr
;
786 IFA_LOCK(&ia
->ia_ifa
);
787 ia
->ia_subnetmask
= ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
= i
);
788 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
789 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
790 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
792 ev_msg
.event_code
= KEV_INET_SIFNETMASK
;
794 if (ia
->ia_ifa
.ifa_dstaddr
)
795 in_event_data
.ia_dstaddr
=
796 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
798 in_event_data
.ia_dstaddr
.s_addr
= 0;
800 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
801 in_event_data
.ia_net
= ia
->ia_net
;
802 in_event_data
.ia_netmask
= ia
->ia_netmask
;
803 in_event_data
.ia_subnet
= ia
->ia_subnet
;
804 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
805 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
806 IFA_UNLOCK(&ia
->ia_ifa
);
807 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
808 in_event_data
.link_data
.if_family
= ifp
->if_family
;
809 in_event_data
.link_data
.if_unit
= (u_int32_t
) ifp
->if_unit
;
811 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
812 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
813 ev_msg
.dv
[1].data_length
= 0;
815 kev_post_msg(&ev_msg
);
824 IFA_LOCK(&ia
->ia_ifa
);
825 if (ia
->ia_addr
.sin_family
== AF_INET
) {
826 if (ifra
->ifra_addr
.sin_len
== 0) {
827 ifra
->ifra_addr
= ia
->ia_addr
;
829 } else if (ifra
->ifra_addr
.sin_addr
.s_addr
==
830 ia
->ia_addr
.sin_addr
.s_addr
)
833 if (ifra
->ifra_mask
.sin_len
) {
834 IFA_UNLOCK(&ia
->ia_ifa
);
835 in_ifscrub(ifp
, ia
, 0);
836 IFA_LOCK(&ia
->ia_ifa
);
837 ia
->ia_sockmask
= ifra
->ifra_mask
;
839 ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
);
842 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
843 (ifra
->ifra_dstaddr
.sin_family
== AF_INET
)) {
844 IFA_UNLOCK(&ia
->ia_ifa
);
845 in_ifscrub(ifp
, ia
, 0);
846 IFA_LOCK(&ia
->ia_ifa
);
847 ia
->ia_dstaddr
= ifra
->ifra_dstaddr
;
848 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
849 maskIsNew
= 1; /* We lie; but the effect's the same */
851 if (ifra
->ifra_addr
.sin_family
== AF_INET
&&
852 (hostIsNew
|| maskIsNew
)) {
853 IFA_UNLOCK(&ia
->ia_ifa
);
854 error
= in_ifinit(ifp
, ia
, &ifra
->ifra_addr
, 0);
856 IFA_UNLOCK(&ia
->ia_ifa
);
860 (void) pf_ifaddr_hook(ifp
, cmd
);
862 IFA_LOCK(&ia
->ia_ifa
);
863 if ((ifp
->if_flags
& IFF_BROADCAST
) &&
864 (ifra
->ifra_broadaddr
.sin_family
== AF_INET
))
865 ia
->ia_broadaddr
= ifra
->ifra_broadaddr
;
871 if ((error
== 0) || (error
== EEXIST
)) {
872 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
873 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
874 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
877 ev_msg
.event_code
= KEV_INET_NEW_ADDR
;
879 ev_msg
.event_code
= KEV_INET_CHANGED_ADDR
;
881 if (ia
->ia_ifa
.ifa_dstaddr
)
882 in_event_data
.ia_dstaddr
=
883 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
885 in_event_data
.ia_dstaddr
.s_addr
= 0;
887 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
888 in_event_data
.ia_net
= ia
->ia_net
;
889 in_event_data
.ia_netmask
= ia
->ia_netmask
;
890 in_event_data
.ia_subnet
= ia
->ia_subnet
;
891 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
892 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
893 IFA_UNLOCK(&ia
->ia_ifa
);
894 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
895 in_event_data
.link_data
.if_family
= ifp
->if_family
;
896 in_event_data
.link_data
.if_unit
= (u_int32_t
) ifp
->if_unit
;
898 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
899 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
900 ev_msg
.dv
[1].data_length
= 0;
902 kev_post_msg(&ev_msg
);
904 IFA_UNLOCK(&ia
->ia_ifa
);
909 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCDIFADDR
, ia
);
910 if (error
== EOPNOTSUPP
)
916 /* Fill out the kernel event information */
917 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
918 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
919 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
921 ev_msg
.event_code
= KEV_INET_ADDR_DELETED
;
923 IFA_LOCK(&ia
->ia_ifa
);
924 if (ia
->ia_ifa
.ifa_dstaddr
)
925 in_event_data
.ia_dstaddr
=
926 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
928 in_event_data
.ia_dstaddr
.s_addr
= 0;
930 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
931 in_event_data
.ia_net
= ia
->ia_net
;
932 in_event_data
.ia_netmask
= ia
->ia_netmask
;
933 in_event_data
.ia_subnet
= ia
->ia_subnet
;
934 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
935 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
936 IFA_UNLOCK(&ia
->ia_ifa
);
937 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
938 in_event_data
.link_data
.if_family
= ifp
->if_family
;
939 in_event_data
.link_data
.if_unit
= (u_int32_t
) ifp
->if_unit
;
941 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
942 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
943 ev_msg
.dv
[1].data_length
= 0;
946 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
947 /* Release ia_link reference */
949 TAILQ_REMOVE(&in_ifaddrhead
, ia
, ia_link
);
951 if (IA_IS_HASHED(ia
))
952 in_iahash_remove(ia
);
954 lck_rw_done(in_ifaddr_rwlock
);
957 * in_ifscrub kills the interface route.
959 in_ifscrub(ifp
, ia
, 0);
960 ifnet_lock_exclusive(ifp
);
962 /* if_detach_ifa() releases ifa_link reference */
963 if_detach_ifa(ifp
, ifa
);
964 /* Our reference to this address is dropped at the bottom */
968 * If the interface supports multicast, and no address is left,
969 * remove the "all hosts" multicast group from that interface.
971 if ((ifp
->if_flags
& IFF_MULTICAST
) != 0 ||
972 ifp
->if_allhostsinm
!= NULL
) {
974 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
976 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
982 ifnet_lock_done(ifp
);
984 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
985 if (ifa
== NULL
&& ifp
->if_allhostsinm
!= NULL
) {
986 struct in_multi
*inm
= ifp
->if_allhostsinm
;
987 ifp
->if_allhostsinm
= NULL
;
990 /* release the reference for allhostsinm pointer */
993 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
995 ifnet_lock_done(ifp
);
998 /* Post the kernel event */
999 kev_post_msg(&ev_msg
);
1002 * See if there is any IPV4 address left and if so,
1003 * reconfigure KDP to use current primary address.
1005 ifa
= ifa_ifpgetprimary(ifp
, AF_INET
);
1007 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa
);
1008 if (error
== EOPNOTSUPP
)
1011 /* Release reference from ifa_ifpgetprimary() */
1015 (void) pf_ifaddr_hook(ifp
, cmd
);
1022 * Inspiration from tcp_ctloutput() and ip_ctloutput()
1023 * Special ioctl for OpenTransport sockets
1025 struct inpcb
*inp
, *cloned_inp
;
1027 int cloned_fd
= *(int *)data
;
1029 inp
= sotoinpcb(so
);
1034 /* let's make sure it's either -1 or a valid file descriptor */
1035 if (cloned_fd
!= -1) {
1036 struct socket
*cloned_so
;
1037 error2
= file_socket(cloned_fd
, &cloned_so
);
1041 cloned_inp
= sotoinpcb(cloned_so
);
1042 file_drop(cloned_fd
);
1047 if (cloned_inp
== NULL
) {
1048 /* OT always uses IP_PORTRANGE_HIGH */
1049 inp
->inp_flags
&= ~(INP_LOWPORT
);
1050 inp
->inp_flags
|= INP_HIGHPORT
;
1051 /* For UDP, OT allows broadcast by default */
1052 if (so
->so_type
== SOCK_DGRAM
)
1053 so
->so_options
|= SO_BROADCAST
;
1054 /* For TCP we want to see MSG_OOB when receive urgent data */
1055 else if (so
->so_type
== SOCK_STREAM
)
1056 so
->so_options
|= SO_WANTOOBFLAG
;
1058 inp
->inp_ip_tos
= cloned_inp
->inp_ip_tos
;
1059 inp
->inp_ip_ttl
= cloned_inp
->inp_ip_ttl
;
1060 inp
->inp_flags
= cloned_inp
->inp_flags
;
1062 /* Multicast options */
1063 if (cloned_inp
->inp_moptions
!= NULL
) {
1064 struct ip_moptions
*cloned_imo
= cloned_inp
->inp_moptions
;
1065 struct ip_moptions
*imo
= inp
->inp_moptions
;
1069 * No multicast option buffer attached to the pcb;
1072 imo
= ip_allocmoptions(M_WAITOK
);
1077 inp
->inp_moptions
= imo
;
1080 error2
= imo_clone(cloned_imo
, imo
);
1085 #endif /* __APPLE__ */
1092 IFA_REMREF(&ia
->ia_ifa
);
1099 * SIOCGLIFADDR: get first address. (?!?)
1100 * SIOCGLIFADDR with IFLR_PREFIX:
1101 * get first address that matches the specified prefix.
1102 * SIOCALIFADDR: add the specified address.
1103 * SIOCALIFADDR with IFLR_PREFIX:
1104 * EINVAL since we can't deduce hostid part of the address.
1105 * SIOCDLIFADDR: delete the specified address.
1106 * SIOCDLIFADDR with IFLR_PREFIX:
1107 * delete the first address that matches the specified prefix.
1109 * EINVAL on invalid parameters
1110 * EADDRNOTAVAIL on prefix match failed/specified address not found
1111 * other values may be returned from in_ioctl()
1121 struct if_laddrreq
*iflr
= (struct if_laddrreq
*)data
;
1125 if (!data
|| !ifp
) {
1126 panic("invalid argument to in_lifaddr_ioctl");
1132 /* address must be specified on GET with IFLR_PREFIX */
1133 if ((iflr
->flags
& IFLR_PREFIX
) == 0)
1138 /* address must be specified on ADD and DELETE */
1139 if (iflr
->addr
.ss_family
!= AF_INET
)
1141 if (iflr
->addr
.ss_len
!= sizeof(struct sockaddr_in
))
1143 /* XXX need improvement */
1144 if (iflr
->dstaddr
.ss_family
1145 && iflr
->dstaddr
.ss_family
!= AF_INET
)
1147 if (iflr
->dstaddr
.ss_family
1148 && iflr
->dstaddr
.ss_len
!= sizeof(struct sockaddr_in
))
1151 default: /*shouldn't happen*/
1154 if (sizeof(struct in_addr
) * 8 < iflr
->prefixlen
)
1160 struct in_aliasreq ifra
;
1162 if (iflr
->flags
& IFLR_PREFIX
)
1165 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
1166 bzero(&ifra
, sizeof(ifra
));
1167 bcopy(iflr
->iflr_name
, ifra
.ifra_name
,
1168 sizeof(ifra
.ifra_name
));
1170 bcopy(&iflr
->addr
, &ifra
.ifra_addr
, iflr
->addr
.ss_len
);
1172 if (iflr
->dstaddr
.ss_family
) { /*XXX*/
1173 bcopy(&iflr
->dstaddr
, &ifra
.ifra_dstaddr
,
1174 iflr
->dstaddr
.ss_len
);
1177 ifra
.ifra_mask
.sin_family
= AF_INET
;
1178 ifra
.ifra_mask
.sin_len
= sizeof(struct sockaddr_in
);
1179 in_len2mask(&ifra
.ifra_mask
.sin_addr
, iflr
->prefixlen
);
1181 return in_control(so
, SIOCAIFADDR
, (caddr_t
)&ifra
, ifp
, p
);
1186 struct in_ifaddr
*ia
;
1187 struct in_addr mask
, candidate
;
1188 struct in_addr match
= { 0 };
1189 struct sockaddr_in
*sin
;
1192 bzero(&mask
, sizeof(mask
));
1193 if (iflr
->flags
& IFLR_PREFIX
) {
1194 /* lookup a prefix rather than address. */
1195 in_len2mask(&mask
, iflr
->prefixlen
);
1197 sin
= (struct sockaddr_in
*)&iflr
->addr
;
1198 match
.s_addr
= sin
->sin_addr
.s_addr
;
1199 match
.s_addr
&= mask
.s_addr
;
1201 /* if you set extra bits, that's wrong */
1202 if (match
.s_addr
!= sin
->sin_addr
.s_addr
)
1207 if (cmd
== SIOCGLIFADDR
) {
1208 /* on getting an address, take the 1st match */
1211 /* on deleting an address, do exact match */
1212 in_len2mask(&mask
, 32);
1213 sin
= (struct sockaddr_in
*)&iflr
->addr
;
1214 match
.s_addr
= sin
->sin_addr
.s_addr
;
1220 ifnet_lock_shared(ifp
);
1221 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1223 if (ifa
->ifa_addr
->sa_family
!= AF_INET6
) {
1231 candidate
.s_addr
= ((struct sockaddr_in
*)&ifa
->ifa_addr
)->sin_addr
.s_addr
;
1232 candidate
.s_addr
&= mask
.s_addr
;
1234 if (candidate
.s_addr
== match
.s_addr
)
1239 ifnet_lock_done(ifp
);
1241 return EADDRNOTAVAIL
;
1242 ia
= (struct in_ifaddr
*)ifa
;
1244 if (cmd
== SIOCGLIFADDR
) {
1246 /* fill in the if_laddrreq structure */
1247 bcopy(&ia
->ia_addr
, &iflr
->addr
, ia
->ia_addr
.sin_len
);
1249 if ((ifp
->if_flags
& IFF_POINTOPOINT
) != 0) {
1250 bcopy(&ia
->ia_dstaddr
, &iflr
->dstaddr
,
1251 ia
->ia_dstaddr
.sin_len
);
1253 bzero(&iflr
->dstaddr
, sizeof(iflr
->dstaddr
));
1256 in_mask2len(&ia
->ia_sockmask
.sin_addr
);
1258 iflr
->flags
= 0; /*XXX*/
1264 struct in_aliasreq ifra
;
1266 /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
1267 bzero(&ifra
, sizeof(ifra
));
1268 bcopy(iflr
->iflr_name
, ifra
.ifra_name
,
1269 sizeof(ifra
.ifra_name
));
1272 bcopy(&ia
->ia_addr
, &ifra
.ifra_addr
,
1273 ia
->ia_addr
.sin_len
);
1274 if ((ifp
->if_flags
& IFF_POINTOPOINT
) != 0) {
1275 bcopy(&ia
->ia_dstaddr
, &ifra
.ifra_dstaddr
,
1276 ia
->ia_dstaddr
.sin_len
);
1278 bcopy(&ia
->ia_sockmask
, &ifra
.ifra_dstaddr
,
1279 ia
->ia_sockmask
.sin_len
);
1282 return in_control(so
, SIOCDIFADDR
, (caddr_t
)&ifra
,
1288 return EOPNOTSUPP
; /*just for safety*/
1292 * Delete any existing route for an interface.
1295 in_ifscrub(struct ifnet
*ifp
, struct in_ifaddr
*ia
, int locked
)
1297 IFA_LOCK(&ia
->ia_ifa
);
1298 if ((ia
->ia_flags
& IFA_ROUTE
) == 0) {
1299 IFA_UNLOCK(&ia
->ia_ifa
);
1302 IFA_UNLOCK(&ia
->ia_ifa
);
1304 lck_mtx_lock(rnh_lock
);
1305 if (ifp
->if_flags
& (IFF_LOOPBACK
|IFF_POINTOPOINT
))
1306 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
1308 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, 0);
1309 IFA_LOCK(&ia
->ia_ifa
);
1310 ia
->ia_flags
&= ~IFA_ROUTE
;
1311 IFA_UNLOCK(&ia
->ia_ifa
);
1313 lck_mtx_unlock(rnh_lock
);
1317 * Caller must hold in_ifaddr_rwlock as writer.
1320 in_iahash_remove(struct in_ifaddr
*ia
)
1322 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1323 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1325 if (!IA_IS_HASHED(ia
)) {
1326 panic("attempt to remove wrong ia %p from hash table\n", ia
);
1329 TAILQ_REMOVE(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), ia
, ia_hash
);
1331 if (IFA_REMREF_LOCKED(&ia
->ia_ifa
) == NULL
) {
1332 panic("%s: unexpected (missing) refcnt ifa=%p", __func__
,
1339 * Caller must hold in_ifaddr_rwlock as writer.
1342 in_iahash_insert(struct in_ifaddr
*ia
)
1344 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1345 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1347 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1348 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1350 } else if (IA_IS_HASHED(ia
)) {
1351 panic("attempt to double-insert ia %p into hash table\n", ia
);
1354 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), ia
, ia_hash
);
1355 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1359 * Some point to point interfaces that are tunnels
1360 * borrow the address from an underlying interface (e.g.
1361 * VPN server). In order for source address selection logic to
1362 * find the underlying interface first, we add the address
1363 * of borrowing point to point interfaces at the end of the list.
1364 * (see rdar://6733789)
1366 * Caller must hold in_ifaddr_rwlock as writer.
1369 in_iahash_insert_ptp(struct in_ifaddr
*ia
)
1371 struct in_ifaddr
*tmp_ifa
;
1372 struct ifnet
*tmp_ifp
;
1374 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1375 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1377 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1378 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1380 } else if (IA_IS_HASHED(ia
)) {
1381 panic("attempt to double-insert ia %p into hash table\n", ia
);
1384 IFA_UNLOCK(&ia
->ia_ifa
);
1385 TAILQ_FOREACH(tmp_ifa
, INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1387 IFA_LOCK(&tmp_ifa
->ia_ifa
);
1388 /* ia->ia_addr won't change, so check without lock */
1389 if (IA_SIN(tmp_ifa
)->sin_addr
.s_addr
==
1390 ia
->ia_addr
.sin_addr
.s_addr
) {
1391 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1394 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1396 tmp_ifp
= (tmp_ifa
== NULL
) ? NULL
: tmp_ifa
->ia_ifp
;
1398 IFA_LOCK(&ia
->ia_ifa
);
1399 if (tmp_ifp
== NULL
) {
1400 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1403 TAILQ_INSERT_TAIL(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1406 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1410 * Initialize an interface's internet address
1411 * and routing table entry.
1416 struct in_ifaddr
*ia
,
1417 struct sockaddr_in
*sin
,
1420 u_int32_t i
= ntohl(sin
->sin_addr
.s_addr
);
1421 struct sockaddr_in oldaddr
;
1422 int flags
= RTF_UP
, error
;
1423 struct ifaddr
*ifa0
;
1427 /* Take an extra reference for this routine */
1428 IFA_ADDREF(&ia
->ia_ifa
);
1430 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1431 IFA_LOCK(&ia
->ia_ifa
);
1432 oldaddr
= ia
->ia_addr
;
1433 if (IA_IS_HASHED(ia
)) {
1435 in_iahash_remove(ia
);
1438 ia
->ia_addr
.sin_len
= sizeof (*sin
);
1439 if ((ifp
->if_flags
& IFF_POINTOPOINT
))
1440 in_iahash_insert_ptp(ia
);
1442 in_iahash_insert(ia
);
1443 IFA_UNLOCK(&ia
->ia_ifa
);
1444 lck_rw_done(in_ifaddr_rwlock
);
1447 * Give the interface a chance to initialize if this is its first
1448 * address, and to validate the address if necessary. Send down
1449 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es).
1450 * We find the first IPV4 address assigned to it and check if this
1451 * is the same as the one passed into this routine.
1453 ifa0
= ifa_ifpgetprimary(ifp
, AF_INET
);
1454 cmd
= (&ia
->ia_ifa
== ifa0
) ? SIOCSIFADDR
: SIOCAIFADDR
;
1455 error
= ifnet_ioctl(ifp
, PF_INET
, cmd
, ia
);
1456 if (error
== EOPNOTSUPP
)
1459 * If we've just sent down SIOCAIFADDR, send another ioctl down
1460 * for SIOCSIFADDR for the first IPV4 address of the interface,
1461 * because an address change on one of the addresses will result
1462 * in the removal of the previous first IPV4 address. KDP needs
1463 * be reconfigured with the current primary IPV4 address.
1465 if (error
== 0 && cmd
== SIOCAIFADDR
) {
1466 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa0
);
1467 if (error
== EOPNOTSUPP
)
1471 /* Release reference from ifa_ifpgetprimary() */
1475 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1476 IFA_LOCK(&ia
->ia_ifa
);
1477 if (IA_IS_HASHED(ia
))
1478 in_iahash_remove(ia
);
1479 ia
->ia_addr
= oldaddr
;
1481 if ((ifp
->if_flags
& IFF_POINTOPOINT
))
1482 in_iahash_insert_ptp(ia
);
1484 in_iahash_insert(ia
);
1486 IFA_UNLOCK(&ia
->ia_ifa
);
1487 lck_rw_done(in_ifaddr_rwlock
);
1488 /* Release extra reference taken above */
1489 IFA_REMREF(&ia
->ia_ifa
);
1492 lck_mtx_lock(rnh_lock
);
1493 IFA_LOCK(&ia
->ia_ifa
);
1495 * Address has been initialized by the link resolver (ARP)
1496 * via ifnet_ioctl() above; it may now generate route(s).
1498 ia
->ia_ifa
.ifa_debug
&= ~IFD_NOTREADY
;
1500 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&oldaddr
;
1501 IFA_UNLOCK(&ia
->ia_ifa
);
1502 in_ifscrub(ifp
, ia
, 1);
1503 IFA_LOCK(&ia
->ia_ifa
);
1504 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1506 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1508 ia
->ia_netmask
= IN_CLASSA_NET
;
1509 else if (IN_CLASSB(i
))
1510 ia
->ia_netmask
= IN_CLASSB_NET
;
1512 ia
->ia_netmask
= IN_CLASSC_NET
;
1514 * The subnet mask usually includes at least the standard network part,
1515 * but may may be smaller in the case of supernetting.
1516 * If it is set, we believe it.
1518 if (ia
->ia_subnetmask
== 0) {
1519 ia
->ia_subnetmask
= ia
->ia_netmask
;
1520 ia
->ia_sockmask
.sin_addr
.s_addr
= htonl(ia
->ia_subnetmask
);
1522 ia
->ia_netmask
&= ia
->ia_subnetmask
;
1523 ia
->ia_net
= i
& ia
->ia_netmask
;
1524 ia
->ia_subnet
= i
& ia
->ia_subnetmask
;
1525 in_socktrim(&ia
->ia_sockmask
);
1527 * Add route for the network.
1529 ia
->ia_ifa
.ifa_metric
= ifp
->if_metric
;
1530 if (ifp
->if_flags
& IFF_BROADCAST
) {
1531 ia
->ia_broadaddr
.sin_addr
.s_addr
=
1532 htonl(ia
->ia_subnet
| ~ia
->ia_subnetmask
);
1533 ia
->ia_netbroadcast
.s_addr
=
1534 htonl(ia
->ia_net
| ~ ia
->ia_netmask
);
1535 } else if (ifp
->if_flags
& IFF_LOOPBACK
) {
1536 ia
->ia_ifa
.ifa_dstaddr
= ia
->ia_ifa
.ifa_addr
;
1538 } else if (ifp
->if_flags
& IFF_POINTOPOINT
) {
1539 if (ia
->ia_dstaddr
.sin_family
!= AF_INET
) {
1540 IFA_UNLOCK(&ia
->ia_ifa
);
1541 lck_mtx_unlock(rnh_lock
);
1542 /* Release extra reference taken above */
1543 IFA_REMREF(&ia
->ia_ifa
);
1546 ia
->ia_dstaddr
.sin_len
= sizeof (*sin
);
1549 IFA_UNLOCK(&ia
->ia_ifa
);
1550 if ((error
= rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
, flags
)) == 0) {
1551 IFA_LOCK(&ia
->ia_ifa
);
1552 ia
->ia_flags
|= IFA_ROUTE
;
1553 IFA_UNLOCK(&ia
->ia_ifa
);
1555 lck_mtx_unlock(rnh_lock
);
1557 /* XXX check if the subnet route points to the same interface */
1558 if (error
== EEXIST
)
1562 * If the interface supports multicast, join the "all hosts"
1563 * multicast group on that interface.
1565 if (ifp
->if_flags
& IFF_MULTICAST
) {
1566 struct in_addr addr
;
1568 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
1569 addr
.s_addr
= htonl(INADDR_ALLHOSTS_GROUP
);
1570 if (ifp
->if_allhostsinm
== NULL
) {
1571 struct in_multi
*inm
;
1572 inm
= in_addmulti(&addr
, ifp
);
1575 /* keep the reference on inm added by
1576 * in_addmulti above for storing the
1577 * pointer in allhostsinm
1579 ifp
->if_allhostsinm
= inm
;
1581 printf("Failed to add membership to all-hosts multicast address on interface %s%d\n", ifp
->if_name
, ifp
->if_unit
);
1584 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
1587 /* Release extra reference taken above */
1588 IFA_REMREF(&ia
->ia_ifa
);
1594 * Return 1 if the address might be a local broadcast address.
1597 in_broadcast(struct in_addr in
, struct ifnet
*ifp
)
1602 if (in
.s_addr
== INADDR_BROADCAST
|| in
.s_addr
== INADDR_ANY
)
1604 if ((ifp
->if_flags
& IFF_BROADCAST
) == 0)
1606 t
= ntohl(in
.s_addr
);
1608 * Look through the list of addresses for a match
1609 * with a broadcast address.
1611 #define ia ((struct in_ifaddr *)ifa)
1612 ifnet_lock_shared(ifp
);
1613 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1615 if (ifa
->ifa_addr
->sa_family
== AF_INET
&&
1616 (in
.s_addr
== ia
->ia_broadaddr
.sin_addr
.s_addr
||
1617 in
.s_addr
== ia
->ia_netbroadcast
.s_addr
||
1619 * Check for old-style (host 0) broadcast.
1621 t
== ia
->ia_subnet
|| t
== ia
->ia_net
) &&
1623 * Check for an all one subnetmask. These
1624 * only exist when an interface gets a secondary
1627 ia
->ia_subnetmask
!= (u_int32_t
)0xffffffff) {
1629 ifnet_lock_done(ifp
);
1634 ifnet_lock_done(ifp
);
1640 in_purgeaddrs(struct ifnet
*ifp
)
1642 struct ifaddr
**ifap
;
1646 * Be nice, and try the civilized way first. If we can't get
1647 * rid of them this way, then do it the rough way. We must
1648 * only get here during detach time, after the ifnet has been
1649 * removed from the global list and arrays.
1651 err
= ifnet_get_address_list_family_internal(ifp
, &ifap
, AF_INET
, 1,
1653 if (err
== 0 && ifap
!= NULL
) {
1654 for (i
= 0; ifap
[i
] != NULL
; i
++) {
1655 struct ifaliasreq ifr
;
1659 bzero(&ifr
, sizeof (ifr
));
1661 ifr
.ifra_addr
= *ifa
->ifa_addr
;
1662 if (ifa
->ifa_dstaddr
!= NULL
)
1663 ifr
.ifra_broadaddr
= *ifa
->ifa_dstaddr
;
1665 err
= in_control(NULL
, SIOCDIFADDR
, (caddr_t
)&ifr
, ifp
,
1667 /* if we lost the race, ignore it */
1668 if (err
== EADDRNOTAVAIL
)
1671 char s_addr
[MAX_IPv4_STR_LEN
];
1672 char s_dstaddr
[MAX_IPv4_STR_LEN
];
1673 struct in_addr
*s
, *d
;
1676 s
= &((struct sockaddr_in
*)
1677 ifa
->ifa_addr
)->sin_addr
;
1678 d
= &((struct sockaddr_in
*)
1679 ifa
->ifa_dstaddr
)->sin_addr
;
1680 (void) inet_ntop(AF_INET
, &s
->s_addr
, s_addr
,
1682 (void) inet_ntop(AF_INET
, &d
->s_addr
, s_dstaddr
,
1683 sizeof (s_dstaddr
));
1686 printf("%s: SIOCDIFADDR ifp=%p ifa_addr=%s "
1687 "ifa_dstaddr=%s (err=%d)\n", __func__
, ifp
,
1688 s_addr
, s_dstaddr
, err
);
1691 ifnet_free_address_list(ifap
);
1692 } else if (err
!= 0 && err
!= ENXIO
) {
1693 printf("%s: error retrieving list of AF_INET addresses for "
1694 "ifp=%p (err=%d)\n", __func__
, ifp
, err
);
1698 int inet_aton(char *cp
, struct in_addr
*pin
);
1700 inet_aton(char * cp
, struct in_addr
* pin
)
1702 u_char
* b
= (unsigned char *)pin
;
1706 for (p
= cp
, i
= 0; i
< 4; i
++) {
1707 u_int32_t l
= strtoul(p
, 0, 0);
1712 if (i
< 3 && p
== NULL
)
1719 int inet_ntoa2(struct in_addr
* pin
, char * cp
, const int len
);
1720 int inet_ntoa2(struct in_addr
* pin
, char * cp
, const int len
)
1724 /* address is in network byte order */
1725 ret
= snprintf(cp
, len
, "%u.%u.%u.%u", pin
->s_addr
& 0xFF,
1726 (pin
->s_addr
>> 8) & 0xFF, (pin
->s_addr
>> 16) & 0xFF,
1727 (pin
->s_addr
>> 24) & 0xFF);
1729 return ret
< len
? TRUE
: FALSE
;
1733 * Called as part of ip_init
1736 in_ifaddr_init(void)
1740 PE_parse_boot_argn("ifa_debug", &inifa_debug
, sizeof (inifa_debug
));
1742 inifa_size
= (inifa_debug
== 0) ? sizeof (struct in_ifaddr
) :
1743 sizeof (struct in_ifaddr_dbg
);
1745 inifa_zone
= zinit(inifa_size
, INIFA_ZONE_MAX
* inifa_size
,
1746 0, INIFA_ZONE_NAME
);
1747 if (inifa_zone
== NULL
) {
1748 panic("%s: failed allocating %s", __func__
, INIFA_ZONE_NAME
);
1751 zone_change(inifa_zone
, Z_EXPAND
, TRUE
);
1752 zone_change(inifa_zone
, Z_CALLERACCT
, FALSE
);
1754 lck_mtx_init(&inifa_trash_lock
, ifa_mtx_grp
, ifa_mtx_attr
);
1755 TAILQ_INIT(&inifa_trash_head
);
1758 static struct in_ifaddr
*
1759 in_ifaddr_alloc(int how
)
1761 struct in_ifaddr
*inifa
;
1763 inifa
= (how
== M_WAITOK
) ? zalloc(inifa_zone
) :
1764 zalloc_noblock(inifa_zone
);
1765 if (inifa
!= NULL
) {
1766 bzero(inifa
, inifa_size
);
1767 inifa
->ia_ifa
.ifa_free
= in_ifaddr_free
;
1768 inifa
->ia_ifa
.ifa_debug
|= IFD_ALLOC
;
1769 ifa_lock_init(&inifa
->ia_ifa
);
1770 if (inifa_debug
!= 0) {
1771 struct in_ifaddr_dbg
*inifa_dbg
=
1772 (struct in_ifaddr_dbg
*)inifa
;
1773 inifa
->ia_ifa
.ifa_debug
|= IFD_DEBUG
;
1774 inifa
->ia_ifa
.ifa_trace
= in_ifaddr_trace
;
1775 inifa
->ia_ifa
.ifa_attached
= in_ifaddr_attached
;
1776 inifa
->ia_ifa
.ifa_detached
= in_ifaddr_detached
;
1777 ctrace_record(&inifa_dbg
->inifa_alloc
);
1784 in_ifaddr_free(struct ifaddr
*ifa
)
1786 IFA_LOCK_ASSERT_HELD(ifa
);
1788 if (ifa
->ifa_refcnt
!= 0) {
1789 panic("%s: ifa %p bad ref cnt", __func__
, ifa
);
1791 } if (!(ifa
->ifa_debug
& IFD_ALLOC
)) {
1792 panic("%s: ifa %p cannot be freed", __func__
, ifa
);
1795 if (ifa
->ifa_debug
& IFD_DEBUG
) {
1796 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
1797 ctrace_record(&inifa_dbg
->inifa_free
);
1798 bcopy(&inifa_dbg
->inifa
, &inifa_dbg
->inifa_old
,
1799 sizeof (struct in_ifaddr
));
1800 if (ifa
->ifa_debug
& IFD_TRASHED
) {
1801 /* Become a regular mutex, just in case */
1802 IFA_CONVERT_LOCK(ifa
);
1803 lck_mtx_lock(&inifa_trash_lock
);
1804 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
,
1806 lck_mtx_unlock(&inifa_trash_lock
);
1807 ifa
->ifa_debug
&= ~IFD_TRASHED
;
1811 ifa_lock_destroy(ifa
);
1812 bzero(ifa
, sizeof (struct in_ifaddr
));
1813 zfree(inifa_zone
, ifa
);
1817 in_ifaddr_attached(struct ifaddr
*ifa
)
1819 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
1821 IFA_LOCK_ASSERT_HELD(ifa
);
1823 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
1824 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
1827 if (ifa
->ifa_debug
& IFD_TRASHED
) {
1828 /* Become a regular mutex, just in case */
1829 IFA_CONVERT_LOCK(ifa
);
1830 lck_mtx_lock(&inifa_trash_lock
);
1831 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
1832 lck_mtx_unlock(&inifa_trash_lock
);
1833 ifa
->ifa_debug
&= ~IFD_TRASHED
;
1838 in_ifaddr_detached(struct ifaddr
*ifa
)
1840 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
1842 IFA_LOCK_ASSERT_HELD(ifa
);
1844 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
1845 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
1847 } else if (ifa
->ifa_debug
& IFD_TRASHED
) {
1848 panic("%s: ifa %p is already in trash list", __func__
, ifa
);
1851 ifa
->ifa_debug
|= IFD_TRASHED
;
1852 /* Become a regular mutex, just in case */
1853 IFA_CONVERT_LOCK(ifa
);
1854 lck_mtx_lock(&inifa_trash_lock
);
1855 TAILQ_INSERT_TAIL(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
1856 lck_mtx_unlock(&inifa_trash_lock
);
1860 in_ifaddr_trace(struct ifaddr
*ifa
, int refhold
)
1862 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
1867 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
1868 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
1872 cnt
= &inifa_dbg
->inifa_refhold_cnt
;
1873 tr
= inifa_dbg
->inifa_refhold
;
1875 cnt
= &inifa_dbg
->inifa_refrele_cnt
;
1876 tr
= inifa_dbg
->inifa_refrele
;
1879 idx
= atomic_add_16_ov(cnt
, 1) % INIFA_TRACE_HIST_SIZE
;
1880 ctrace_record(&tr
[idx
]);