2 * Copyright (c) 2000-2016 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
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/sockio.h>
66 #include <sys/socketvar.h>
67 #include <sys/malloc.h>
69 #include <sys/socket.h>
70 #include <sys/kernel.h>
71 #include <sys/sysctl.h>
72 #include <sys/kern_event.h>
73 #include <sys/syslog.h>
74 #include <sys/mcache.h>
75 #include <sys/protosw.h>
78 #include <kern/zalloc.h>
79 #include <pexpert/pexpert.h>
82 #include <net/if_types.h>
83 #include <net/route.h>
84 #include <net/kpi_protocol.h>
87 #include <net/pfvar.h>
90 #include <netinet/in.h>
91 #include <netinet/in_var.h>
92 #include <netinet/in_pcb.h>
93 #include <netinet/igmp_var.h>
94 #include <netinet/ip_var.h>
95 #include <netinet/tcp.h>
96 #include <netinet/tcp_timer.h>
97 #include <netinet/tcp_var.h>
99 static int inctl_associd(struct socket
*, u_long
, caddr_t
);
100 static int inctl_connid(struct socket
*, u_long
, caddr_t
);
101 static int inctl_conninfo(struct socket
*, u_long
, caddr_t
);
102 static int inctl_autoaddr(struct ifnet
*, struct ifreq
*);
103 static int inctl_arpipll(struct ifnet
*, struct ifreq
*);
104 static int inctl_setrouter(struct ifnet
*, struct ifreq
*);
105 static int inctl_ifaddr(struct ifnet
*, struct in_ifaddr
*, u_long
,
107 static int inctl_ifdstaddr(struct ifnet
*, struct in_ifaddr
*, u_long
,
109 static int inctl_ifbrdaddr(struct ifnet
*, struct in_ifaddr
*, u_long
,
111 static int inctl_ifnetmask(struct ifnet
*, struct in_ifaddr
*, u_long
,
114 static void in_socktrim(struct sockaddr_in
*);
115 static int in_ifinit(struct ifnet
*, struct in_ifaddr
*,
116 struct sockaddr_in
*, int);
118 #define IA_HASH_INIT(ia) { \
119 (ia)->ia_hash.tqe_next = (void *)(uintptr_t)-1; \
120 (ia)->ia_hash.tqe_prev = (void *)(uintptr_t)-1; \
123 #define IA_IS_HASHED(ia) \
124 (!((ia)->ia_hash.tqe_next == (void *)(uintptr_t)-1 || \
125 (ia)->ia_hash.tqe_prev == (void *)(uintptr_t)-1))
127 static void in_iahash_remove(struct in_ifaddr
*);
128 static void in_iahash_insert(struct in_ifaddr
*);
129 static void in_iahash_insert_ptp(struct in_ifaddr
*);
130 static struct in_ifaddr
*in_ifaddr_alloc(int);
131 static void in_ifaddr_attached(struct ifaddr
*);
132 static void in_ifaddr_detached(struct ifaddr
*);
133 static void in_ifaddr_free(struct ifaddr
*);
134 static void in_ifaddr_trace(struct ifaddr
*, int);
136 static int in_getassocids(struct socket
*, uint32_t *, user_addr_t
);
137 static int in_getconnids(struct socket
*, sae_associd_t
, uint32_t *, user_addr_t
);
138 static int in_getconninfo(struct socket
*, sae_connid_t
, uint32_t *,
139 uint32_t *, int32_t *, user_addr_t
, socklen_t
*, user_addr_t
, socklen_t
*,
140 uint32_t *, user_addr_t
, uint32_t *);
142 static int subnetsarelocal
= 0;
143 SYSCTL_INT(_net_inet_ip
, OID_AUTO
, subnets_are_local
,
144 CTLFLAG_RW
| CTLFLAG_LOCKED
, &subnetsarelocal
, 0, "");
146 /* Track whether or not the SIOCARPIPLL ioctl has been called */
147 u_int32_t ipv4_ll_arp_aware
= 0;
149 #define INIFA_TRACE_HIST_SIZE 32 /* size of trace history */
152 __private_extern__
unsigned int inifa_trace_hist_size
= INIFA_TRACE_HIST_SIZE
;
154 struct in_ifaddr_dbg
{
155 struct in_ifaddr inifa
; /* in_ifaddr */
156 struct in_ifaddr inifa_old
; /* saved in_ifaddr */
157 u_int16_t inifa_refhold_cnt
; /* # of IFA_ADDREF */
158 u_int16_t inifa_refrele_cnt
; /* # of IFA_REMREF */
160 * Alloc and free callers.
162 ctrace_t inifa_alloc
;
165 * Circular lists of IFA_ADDREF and IFA_REMREF callers.
167 ctrace_t inifa_refhold
[INIFA_TRACE_HIST_SIZE
];
168 ctrace_t inifa_refrele
[INIFA_TRACE_HIST_SIZE
];
172 TAILQ_ENTRY(in_ifaddr_dbg
) inifa_trash_link
;
175 /* List of trash in_ifaddr entries protected by inifa_trash_lock */
176 static TAILQ_HEAD(, in_ifaddr_dbg
) inifa_trash_head
;
177 static decl_lck_mtx_data(, inifa_trash_lock
);
180 static unsigned int inifa_debug
= 1; /* debugging (enabled) */
182 static unsigned int inifa_debug
; /* debugging (disabled) */
184 static unsigned int inifa_size
; /* size of zone element */
185 static struct zone
*inifa_zone
; /* zone for in_ifaddr */
187 #define INIFA_ZONE_MAX 64 /* maximum elements in zone */
188 #define INIFA_ZONE_NAME "in_ifaddr" /* zone name */
190 static const unsigned int in_extra_size
= sizeof (struct in_ifextra
);
191 static const unsigned int in_extra_bufsize
= in_extra_size
+
192 sizeof (void *) + sizeof (uint64_t);
195 * Return 1 if the address is
197 * - unicast or multicast link local
198 * - routed via a link level gateway
199 * - belongs to a directly connected (sub)net
202 inaddr_local(struct in_addr in
)
205 struct sockaddr_in sin
;
208 if (ntohl(in
.s_addr
) == INADDR_LOOPBACK
||
209 IN_LINKLOCAL(ntohl(in
.s_addr
))) {
211 } else if (ntohl(in
.s_addr
) >= INADDR_UNSPEC_GROUP
&&
212 ntohl(in
.s_addr
) <= INADDR_MAX_LOCAL_GROUP
) {
215 sin
.sin_family
= AF_INET
;
216 sin
.sin_len
= sizeof (sin
);
218 rt
= rtalloc1((struct sockaddr
*)&sin
, 0, 0);
222 if (rt
->rt_gateway
->sa_family
== AF_LINK
||
223 (rt
->rt_ifp
->if_flags
& IFF_LOOPBACK
))
228 local
= in_localaddr(in
);
235 * Return 1 if an internet address is for a ``local'' host
236 * (one to which we have a connection). If subnetsarelocal
237 * is true, this includes other subnets of the local net,
238 * otherwise, it includes the directly-connected (sub)nets.
239 * The IPv4 link local prefix 169.254/16 is also included.
242 in_localaddr(struct in_addr in
)
244 u_int32_t i
= ntohl(in
.s_addr
);
245 struct in_ifaddr
*ia
;
250 if (subnetsarelocal
) {
251 lck_rw_lock_shared(in_ifaddr_rwlock
);
252 for (ia
= in_ifaddrhead
.tqh_first
; ia
!= NULL
;
253 ia
= ia
->ia_link
.tqe_next
) {
254 IFA_LOCK(&ia
->ia_ifa
);
255 if ((i
& ia
->ia_netmask
) == ia
->ia_net
) {
256 IFA_UNLOCK(&ia
->ia_ifa
);
257 lck_rw_done(in_ifaddr_rwlock
);
260 IFA_UNLOCK(&ia
->ia_ifa
);
262 lck_rw_done(in_ifaddr_rwlock
);
264 lck_rw_lock_shared(in_ifaddr_rwlock
);
265 for (ia
= in_ifaddrhead
.tqh_first
; ia
!= NULL
;
266 ia
= ia
->ia_link
.tqe_next
) {
267 IFA_LOCK(&ia
->ia_ifa
);
268 if ((i
& ia
->ia_subnetmask
) == ia
->ia_subnet
) {
269 IFA_UNLOCK(&ia
->ia_ifa
);
270 lck_rw_done(in_ifaddr_rwlock
);
273 IFA_UNLOCK(&ia
->ia_ifa
);
275 lck_rw_done(in_ifaddr_rwlock
);
281 * Determine whether an IP address is in a reserved set of addresses
282 * that may not be forwarded, or whether datagrams to that destination
286 in_canforward(struct in_addr in
)
288 u_int32_t i
= ntohl(in
.s_addr
);
291 if (IN_EXPERIMENTAL(i
) || IN_MULTICAST(i
))
294 net
= i
& IN_CLASSA_NET
;
295 if (net
== 0 || net
== (IN_LOOPBACKNET
<< IN_CLASSA_NSHIFT
))
302 * Trim a mask in a sockaddr
305 in_socktrim(struct sockaddr_in
*ap
)
307 char *cplim
= (char *)&ap
->sin_addr
;
308 char *cp
= (char *)(&ap
->sin_addr
+ 1);
311 while (--cp
>= cplim
)
313 (ap
)->sin_len
= cp
- (char *)(ap
) + 1;
318 static int in_interfaces
; /* number of external internet interfaces */
321 in_domifattach(struct ifnet
*ifp
)
327 if ((error
= proto_plumb(PF_INET
, ifp
)) && error
!= EEXIST
) {
328 log(LOG_ERR
, "%s: proto_plumb returned %d if=%s\n",
329 __func__
, error
, if_name(ifp
));
330 } else if (error
== 0 && ifp
->if_inetdata
== NULL
) {
332 struct in_ifextra
*ext
;
335 if ((ext
= (struct in_ifextra
*)_MALLOC(in_extra_bufsize
,
336 M_IFADDR
, M_WAITOK
|M_ZERO
)) == NULL
) {
338 errorx
= proto_unplumb(PF_INET
, ifp
);
341 "%s: proto_unplumb returned %d if=%s%d\n",
342 __func__
, errorx
, ifp
->if_name
,
348 /* Align on 64-bit boundary */
349 base
= (void *)P2ROUNDUP((intptr_t)ext
+ sizeof (uint64_t),
351 VERIFY(((intptr_t)base
+ in_extra_size
) <=
352 ((intptr_t)ext
+ in_extra_bufsize
));
353 pbuf
= (void **)((intptr_t)base
- sizeof (void *));
355 ifp
->if_inetdata
= base
;
356 VERIFY(IS_P2ALIGNED(ifp
->if_inetdata
, sizeof (uint64_t)));
359 if (error
== 0 && ifp
->if_inetdata
!= NULL
) {
361 * Since the structure is never freed, we need to
362 * zero out its contents to avoid reusing stale data.
363 * A little redundant with allocation above, but it
364 * keeps the code simpler for all cases.
366 bzero(ifp
->if_inetdata
, in_extra_size
);
371 static __attribute__((noinline
)) int
372 inctl_associd(struct socket
*so
, u_long cmd
, caddr_t data
)
376 struct so_aidreq32 a32
;
377 struct so_aidreq64 a64
;
383 case SIOCGASSOCIDS32
: /* struct so_aidreq32 */
384 bcopy(data
, &u
.a32
, sizeof (u
.a32
));
385 error
= in_getassocids(so
, &u
.a32
.sar_cnt
, u
.a32
.sar_aidp
);
387 bcopy(&u
.a32
, data
, sizeof (u
.a32
));
390 case SIOCGASSOCIDS64
: /* struct so_aidreq64 */
391 bcopy(data
, &u
.a64
, sizeof (u
.a64
));
392 error
= in_getassocids(so
, &u
.a64
.sar_cnt
, u
.a64
.sar_aidp
);
394 bcopy(&u
.a64
, data
, sizeof (u
.a64
));
405 static __attribute__((noinline
)) int
406 inctl_connid(struct socket
*so
, u_long cmd
, caddr_t data
)
410 struct so_cidreq32 c32
;
411 struct so_cidreq64 c64
;
417 case SIOCGCONNIDS32
: /* struct so_cidreq32 */
418 bcopy(data
, &u
.c32
, sizeof (u
.c32
));
419 error
= in_getconnids(so
, u
.c32
.scr_aid
, &u
.c32
.scr_cnt
,
422 bcopy(&u
.c32
, data
, sizeof (u
.c32
));
425 case SIOCGCONNIDS64
: /* struct so_cidreq64 */
426 bcopy(data
, &u
.c64
, sizeof (u
.c64
));
427 error
= in_getconnids(so
, u
.c64
.scr_aid
, &u
.c64
.scr_cnt
,
430 bcopy(&u
.c64
, data
, sizeof (u
.c64
));
441 static __attribute__((noinline
)) int
442 inctl_conninfo(struct socket
*so
, u_long cmd
, caddr_t data
)
446 struct so_cinforeq32 ci32
;
447 struct so_cinforeq64 ci64
;
453 case SIOCGCONNINFO32
: /* struct so_cinforeq32 */
454 bcopy(data
, &u
.ci32
, sizeof (u
.ci32
));
455 error
= in_getconninfo(so
, u
.ci32
.scir_cid
, &u
.ci32
.scir_flags
,
456 &u
.ci32
.scir_ifindex
, &u
.ci32
.scir_error
, u
.ci32
.scir_src
,
457 &u
.ci32
.scir_src_len
, u
.ci32
.scir_dst
, &u
.ci32
.scir_dst_len
,
458 &u
.ci32
.scir_aux_type
, u
.ci32
.scir_aux_data
,
459 &u
.ci32
.scir_aux_len
);
461 bcopy(&u
.ci32
, data
, sizeof (u
.ci32
));
464 case SIOCGCONNINFO64
: /* struct so_cinforeq64 */
465 bcopy(data
, &u
.ci64
, sizeof (u
.ci64
));
466 error
= in_getconninfo(so
, u
.ci64
.scir_cid
, &u
.ci64
.scir_flags
,
467 &u
.ci64
.scir_ifindex
, &u
.ci64
.scir_error
, u
.ci64
.scir_src
,
468 &u
.ci64
.scir_src_len
, u
.ci64
.scir_dst
, &u
.ci64
.scir_dst_len
,
469 &u
.ci64
.scir_aux_type
, u
.ci64
.scir_aux_data
,
470 &u
.ci64
.scir_aux_len
);
472 bcopy(&u
.ci64
, data
, sizeof (u
.ci64
));
484 * Caller passes in the ioctl data pointer directly via "ifr", with the
485 * expectation that this routine always uses bcopy() or other byte-aligned
488 static __attribute__((noinline
)) int
489 inctl_autoaddr(struct ifnet
*ifp
, struct ifreq
*ifr
)
491 int error
= 0, intval
;
495 bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
));
497 ifnet_lock_exclusive(ifp
);
500 * An interface in IPv4 router mode implies that it
501 * is configured with a static IP address and should
502 * not act as a DHCP client; prevent SIOCAUTOADDR from
503 * being set in that mode.
505 if (ifp
->if_eflags
& IFEF_IPV4_ROUTER
) {
506 intval
= 0; /* be safe; clear flag if set */
509 ifp
->if_eflags
|= IFEF_AUTOCONFIGURING
;
513 ifp
->if_eflags
&= ~IFEF_AUTOCONFIGURING
;
514 ifnet_lock_done(ifp
);
520 * Caller passes in the ioctl data pointer directly via "ifr", with the
521 * expectation that this routine always uses bcopy() or other byte-aligned
524 static __attribute__((noinline
)) int
525 inctl_arpipll(struct ifnet
*ifp
, struct ifreq
*ifr
)
527 int error
= 0, intval
;
531 bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
));
532 ipv4_ll_arp_aware
= 1;
534 ifnet_lock_exclusive(ifp
);
537 * An interface in IPv4 router mode implies that it
538 * is configured with a static IP address and should
539 * not have to deal with IPv4 Link-Local Address;
540 * prevent SIOCARPIPLL from being set in that mode.
542 if (ifp
->if_eflags
& IFEF_IPV4_ROUTER
) {
543 intval
= 0; /* be safe; clear flag if set */
546 ifp
->if_eflags
|= IFEF_ARPLL
;
550 ifp
->if_eflags
&= ~IFEF_ARPLL
;
551 ifnet_lock_done(ifp
);
557 * Handle SIOCSETROUTERMODE to set or clear the IPv4 router mode flag on
558 * the interface. When in this mode, IPv4 Link-Local Address support is
559 * disabled in ARP, and DHCP client support is disabled in IP input; turning
560 * any of them on would cause an error to be returned. Entering or exiting
561 * this mode will result in the removal of IPv4 addresses currently configured
564 * Caller passes in the ioctl data pointer directly via "ifr", with the
565 * expectation that this routine always uses bcopy() or other byte-aligned
568 static __attribute__((noinline
)) int
569 inctl_setrouter(struct ifnet
*ifp
, struct ifreq
*ifr
)
571 int error
= 0, intval
;
575 /* Router mode isn't valid for loopback */
576 if (ifp
->if_flags
& IFF_LOOPBACK
)
579 bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
));
581 ifnet_lock_exclusive(ifp
);
583 ifp
->if_eflags
|= IFEF_IPV4_ROUTER
;
584 ifp
->if_eflags
&= ~(IFEF_ARPLL
| IFEF_AUTOCONFIGURING
);
586 ifp
->if_eflags
&= ~IFEF_IPV4_ROUTER
;
588 ifnet_lock_done(ifp
);
590 /* purge all IPv4 addresses configured on this interface */
597 * Caller passes in the ioctl data pointer directly via "ifr", with the
598 * expectation that this routine always uses bcopy() or other byte-aligned
601 static __attribute__((noinline
)) int
602 inctl_ifaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
605 struct kev_in_data in_event_data
;
606 struct kev_msg ev_msg
;
607 struct sockaddr_in addr
;
613 bzero(&in_event_data
, sizeof (struct kev_in_data
));
614 bzero(&ev_msg
, sizeof (struct kev_msg
));
617 case SIOCGIFADDR
: /* struct ifreq */
619 error
= EADDRNOTAVAIL
;
622 IFA_LOCK(&ia
->ia_ifa
);
623 bcopy(&ia
->ia_addr
, &ifr
->ifr_addr
, sizeof (addr
));
624 IFA_UNLOCK(&ia
->ia_ifa
);
627 case SIOCSIFADDR
: /* struct ifreq */
629 bcopy(&ifr
->ifr_addr
, &addr
, sizeof (addr
));
631 * If this is a new address, the reference count for the
632 * hash table has been taken at creation time above.
634 error
= in_ifinit(ifp
, ia
, &addr
, 1);
636 (void) ifnet_notify_address(ifp
, AF_INET
);
640 case SIOCAIFADDR
: { /* struct {if,in_}aliasreq */
641 struct in_aliasreq
*ifra
= (struct in_aliasreq
*)ifr
;
642 struct sockaddr_in broadaddr
, mask
;
643 int hostIsNew
, maskIsNew
;
646 bcopy(&ifra
->ifra_addr
, &addr
, sizeof (addr
));
647 bcopy(&ifra
->ifra_broadaddr
, &broadaddr
, sizeof (broadaddr
));
648 bcopy(&ifra
->ifra_mask
, &mask
, sizeof (mask
));
654 IFA_LOCK(&ia
->ia_ifa
);
655 if (ia
->ia_addr
.sin_family
== AF_INET
) {
656 if (addr
.sin_len
== 0) {
659 } else if (addr
.sin_addr
.s_addr
==
660 ia
->ia_addr
.sin_addr
.s_addr
) {
665 IFA_UNLOCK(&ia
->ia_ifa
);
666 in_ifscrub(ifp
, ia
, 0);
667 IFA_LOCK(&ia
->ia_ifa
);
668 ia
->ia_sockmask
= mask
;
670 ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
);
673 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
674 (broadaddr
.sin_family
== AF_INET
)) {
675 IFA_UNLOCK(&ia
->ia_ifa
);
676 in_ifscrub(ifp
, ia
, 0);
677 IFA_LOCK(&ia
->ia_ifa
);
678 ia
->ia_dstaddr
= broadaddr
;
679 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
680 maskIsNew
= 1; /* We lie; but the effect's the same */
682 if (addr
.sin_family
== AF_INET
&& (hostIsNew
|| maskIsNew
)) {
683 IFA_UNLOCK(&ia
->ia_ifa
);
684 error
= in_ifinit(ifp
, ia
, &addr
, 0);
686 IFA_UNLOCK(&ia
->ia_ifa
);
689 (void) ifnet_notify_address(ifp
, AF_INET
);
691 IFA_LOCK(&ia
->ia_ifa
);
692 if ((ifp
->if_flags
& IFF_BROADCAST
) &&
693 (broadaddr
.sin_family
== AF_INET
))
694 ia
->ia_broadaddr
= broadaddr
;
699 if ((error
== 0) || (error
== EEXIST
)) {
700 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
701 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
702 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
705 ev_msg
.event_code
= KEV_INET_NEW_ADDR
;
707 ev_msg
.event_code
= KEV_INET_CHANGED_ADDR
;
709 if (ia
->ia_ifa
.ifa_dstaddr
) {
710 in_event_data
.ia_dstaddr
=
711 ((struct sockaddr_in
*)(void *)ia
->
712 ia_ifa
.ifa_dstaddr
)->sin_addr
;
714 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
716 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
717 in_event_data
.ia_net
= ia
->ia_net
;
718 in_event_data
.ia_netmask
= ia
->ia_netmask
;
719 in_event_data
.ia_subnet
= ia
->ia_subnet
;
720 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
721 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
722 IFA_UNLOCK(&ia
->ia_ifa
);
723 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
724 ifp
->if_name
, IFNAMSIZ
);
725 in_event_data
.link_data
.if_family
= ifp
->if_family
;
726 in_event_data
.link_data
.if_unit
= ifp
->if_unit
;
728 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
729 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
730 ev_msg
.dv
[1].data_length
= 0;
732 dlil_post_complete_msg(ifp
, &ev_msg
);
734 IFA_UNLOCK(&ia
->ia_ifa
);
739 case SIOCDIFADDR
: /* struct ifreq */
741 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCDIFADDR
, ia
);
742 if (error
== EOPNOTSUPP
)
747 /* Fill out the kernel event information */
748 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
749 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
750 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
752 ev_msg
.event_code
= KEV_INET_ADDR_DELETED
;
754 IFA_LOCK(&ia
->ia_ifa
);
755 if (ia
->ia_ifa
.ifa_dstaddr
) {
756 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
757 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
759 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
761 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
762 in_event_data
.ia_net
= ia
->ia_net
;
763 in_event_data
.ia_netmask
= ia
->ia_netmask
;
764 in_event_data
.ia_subnet
= ia
->ia_subnet
;
765 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
766 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
767 IFA_UNLOCK(&ia
->ia_ifa
);
768 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
769 ifp
->if_name
, IFNAMSIZ
);
770 in_event_data
.link_data
.if_family
= ifp
->if_family
;
771 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
773 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
774 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
775 ev_msg
.dv
[1].data_length
= 0;
778 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
779 /* Release ia_link reference */
781 TAILQ_REMOVE(&in_ifaddrhead
, ia
, ia_link
);
783 if (IA_IS_HASHED(ia
))
784 in_iahash_remove(ia
);
786 lck_rw_done(in_ifaddr_rwlock
);
789 * in_ifscrub kills the interface route.
791 in_ifscrub(ifp
, ia
, 0);
792 ifnet_lock_exclusive(ifp
);
794 /* if_detach_ifa() releases ifa_link reference */
795 if_detach_ifa(ifp
, ifa
);
796 /* Our reference to this address is dropped at the bottom */
799 /* invalidate route caches */
800 routegenid_inet_update();
803 * If the interface supports multicast, and no address is left,
804 * remove the "all hosts" multicast group from that interface.
806 if ((ifp
->if_flags
& IFF_MULTICAST
) ||
807 ifp
->if_allhostsinm
!= NULL
) {
809 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
811 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
817 ifnet_lock_done(ifp
);
819 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
820 if (ifa
== NULL
&& ifp
->if_allhostsinm
!= NULL
) {
821 struct in_multi
*inm
= ifp
->if_allhostsinm
;
822 ifp
->if_allhostsinm
= NULL
;
825 /* release the reference for allhostsinm */
828 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
830 ifnet_lock_done(ifp
);
833 /* Post the kernel event */
834 dlil_post_complete_msg(ifp
, &ev_msg
);
837 * See if there is any IPV4 address left and if so,
838 * reconfigure KDP to use current primary address.
840 ifa
= ifa_ifpgetprimary(ifp
, AF_INET
);
843 * NOTE: SIOCSIFADDR is defined with struct ifreq
844 * as parameter, but here we are sending it down
845 * to the interface with a pointer to struct ifaddr,
846 * for legacy reasons.
848 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa
);
849 if (error
== EOPNOTSUPP
)
852 /* Release reference from ifa_ifpgetprimary() */
855 (void) ifnet_notify_address(ifp
, AF_INET
);
867 * Caller passes in the ioctl data pointer directly via "ifr", with the
868 * expectation that this routine always uses bcopy() or other byte-aligned
871 static __attribute__((noinline
)) int
872 inctl_ifdstaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
875 struct kev_in_data in_event_data
;
876 struct kev_msg ev_msg
;
877 struct sockaddr_in dstaddr
;
882 if (!(ifp
->if_flags
& IFF_POINTOPOINT
))
885 bzero(&in_event_data
, sizeof (struct kev_in_data
));
886 bzero(&ev_msg
, sizeof (struct kev_msg
));
889 case SIOCGIFDSTADDR
: /* struct ifreq */
891 error
= EADDRNOTAVAIL
;
894 IFA_LOCK(&ia
->ia_ifa
);
895 bcopy(&ia
->ia_dstaddr
, &ifr
->ifr_dstaddr
, sizeof (dstaddr
));
896 IFA_UNLOCK(&ia
->ia_ifa
);
899 case SIOCSIFDSTADDR
: /* struct ifreq */
901 IFA_LOCK(&ia
->ia_ifa
);
902 dstaddr
= ia
->ia_dstaddr
;
903 bcopy(&ifr
->ifr_dstaddr
, &ia
->ia_dstaddr
, sizeof (dstaddr
));
904 if (ia
->ia_dstaddr
.sin_family
== AF_INET
)
905 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
906 IFA_UNLOCK(&ia
->ia_ifa
);
908 * NOTE: SIOCSIFDSTADDR is defined with struct ifreq
909 * as parameter, but here we are sending it down
910 * to the interface with a pointer to struct ifaddr,
911 * for legacy reasons.
913 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFDSTADDR
, ia
);
914 IFA_LOCK(&ia
->ia_ifa
);
915 if (error
== EOPNOTSUPP
)
918 ia
->ia_dstaddr
= dstaddr
;
919 IFA_UNLOCK(&ia
->ia_ifa
);
922 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
924 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
925 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
926 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
928 ev_msg
.event_code
= KEV_INET_SIFDSTADDR
;
930 if (ia
->ia_ifa
.ifa_dstaddr
) {
931 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
932 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
934 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
937 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
938 in_event_data
.ia_net
= ia
->ia_net
;
939 in_event_data
.ia_netmask
= ia
->ia_netmask
;
940 in_event_data
.ia_subnet
= ia
->ia_subnet
;
941 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
942 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
943 IFA_UNLOCK(&ia
->ia_ifa
);
944 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
945 ifp
->if_name
, IFNAMSIZ
);
946 in_event_data
.link_data
.if_family
= ifp
->if_family
;
947 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
949 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
950 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
951 ev_msg
.dv
[1].data_length
= 0;
953 dlil_post_complete_msg(ifp
, &ev_msg
);
955 lck_mtx_lock(rnh_lock
);
956 IFA_LOCK(&ia
->ia_ifa
);
957 if (ia
->ia_flags
& IFA_ROUTE
) {
958 ia
->ia_ifa
.ifa_dstaddr
= (struct sockaddr
*)&dstaddr
;
959 IFA_UNLOCK(&ia
->ia_ifa
);
960 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
961 IFA_LOCK(&ia
->ia_ifa
);
962 ia
->ia_ifa
.ifa_dstaddr
=
963 (struct sockaddr
*)&ia
->ia_dstaddr
;
964 IFA_UNLOCK(&ia
->ia_ifa
);
965 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
,
968 IFA_UNLOCK(&ia
->ia_ifa
);
970 lck_mtx_unlock(rnh_lock
);
984 * Caller passes in the ioctl data pointer directly via "ifr", with the
985 * expectation that this routine always uses bcopy() or other byte-aligned
988 static __attribute__((noinline
)) int
989 inctl_ifbrdaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
992 struct kev_in_data in_event_data
;
993 struct kev_msg ev_msg
;
999 return (EADDRNOTAVAIL
);
1001 if (!(ifp
->if_flags
& IFF_BROADCAST
))
1004 bzero(&in_event_data
, sizeof (struct kev_in_data
));
1005 bzero(&ev_msg
, sizeof (struct kev_msg
));
1008 case SIOCGIFBRDADDR
: /* struct ifreq */
1009 IFA_LOCK(&ia
->ia_ifa
);
1010 bcopy(&ia
->ia_broadaddr
, &ifr
->ifr_broadaddr
,
1011 sizeof (struct sockaddr_in
));
1012 IFA_UNLOCK(&ia
->ia_ifa
);
1015 case SIOCSIFBRDADDR
: /* struct ifreq */
1016 IFA_LOCK(&ia
->ia_ifa
);
1017 bcopy(&ifr
->ifr_broadaddr
, &ia
->ia_broadaddr
,
1018 sizeof (struct sockaddr_in
));
1020 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
1021 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
1022 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
1024 ev_msg
.event_code
= KEV_INET_SIFBRDADDR
;
1026 if (ia
->ia_ifa
.ifa_dstaddr
) {
1027 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
1028 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
1030 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
1032 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
1033 in_event_data
.ia_net
= ia
->ia_net
;
1034 in_event_data
.ia_netmask
= ia
->ia_netmask
;
1035 in_event_data
.ia_subnet
= ia
->ia_subnet
;
1036 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
1037 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
1038 IFA_UNLOCK(&ia
->ia_ifa
);
1039 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
1040 ifp
->if_name
, IFNAMSIZ
);
1041 in_event_data
.link_data
.if_family
= ifp
->if_family
;
1042 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
1044 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
1045 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
1046 ev_msg
.dv
[1].data_length
= 0;
1048 dlil_post_complete_msg(ifp
, &ev_msg
);
1060 * Caller passes in the ioctl data pointer directly via "ifr", with the
1061 * expectation that this routine always uses bcopy() or other byte-aligned
1064 static __attribute__((noinline
)) int
1065 inctl_ifnetmask(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
1068 struct kev_in_data in_event_data
;
1069 struct kev_msg ev_msg
;
1070 struct sockaddr_in mask
;
1073 VERIFY(ifp
!= NULL
);
1075 bzero(&in_event_data
, sizeof (struct kev_in_data
));
1076 bzero(&ev_msg
, sizeof (struct kev_msg
));
1079 case SIOCGIFNETMASK
: /* struct ifreq */
1081 error
= EADDRNOTAVAIL
;
1084 IFA_LOCK(&ia
->ia_ifa
);
1085 bcopy(&ia
->ia_sockmask
, &ifr
->ifr_addr
, sizeof (mask
));
1086 IFA_UNLOCK(&ia
->ia_ifa
);
1089 case SIOCSIFNETMASK
: { /* struct ifreq */
1092 bcopy(&ifr
->ifr_addr
, &mask
, sizeof (mask
));
1093 i
= mask
.sin_addr
.s_addr
;
1096 IFA_LOCK(&ia
->ia_ifa
);
1097 ia
->ia_subnetmask
= ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
= i
);
1098 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
1099 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
1100 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
1102 ev_msg
.event_code
= KEV_INET_SIFNETMASK
;
1104 if (ia
->ia_ifa
.ifa_dstaddr
) {
1105 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
1106 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
1108 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
1110 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
1111 in_event_data
.ia_net
= ia
->ia_net
;
1112 in_event_data
.ia_netmask
= ia
->ia_netmask
;
1113 in_event_data
.ia_subnet
= ia
->ia_subnet
;
1114 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
1115 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
1116 IFA_UNLOCK(&ia
->ia_ifa
);
1117 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
1118 ifp
->if_name
, IFNAMSIZ
);
1119 in_event_data
.link_data
.if_family
= ifp
->if_family
;
1120 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
1122 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
1123 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
1124 ev_msg
.dv
[1].data_length
= 0;
1126 dlil_post_complete_msg(ifp
, &ev_msg
);
1139 * Generic INET control operations (ioctl's).
1141 * ifp is NULL if not an interface-specific ioctl.
1143 * Most of the routines called to handle the ioctls would end up being
1144 * tail-call optimized, which unfortunately causes this routine to
1145 * consume too much stack space; this is the reason for the "noinline"
1146 * attribute used on those routines.
1148 * If called directly from within the networking stack (as opposed to via
1149 * pru_control), the socket parameter may be NULL.
1152 in_control(struct socket
*so
, u_long cmd
, caddr_t data
, struct ifnet
*ifp
,
1155 struct ifreq
*ifr
= (struct ifreq
*)(void *)data
;
1156 struct sockaddr_in addr
, dstaddr
;
1157 struct sockaddr_in sin
, *sa
= NULL
;
1158 boolean_t privileged
= (proc_suser(p
) == 0);
1159 boolean_t so_unlocked
= FALSE
;
1160 struct in_ifaddr
*ia
= NULL
;
1164 /* In case it's NULL, make sure it came from the kernel */
1165 VERIFY(so
!= NULL
|| p
== kernproc
);
1168 * ioctls which don't require ifp, but require socket.
1171 case SIOCGASSOCIDS32
: /* struct so_aidreq32 */
1172 case SIOCGASSOCIDS64
: /* struct so_aidreq64 */
1173 return (inctl_associd(so
, cmd
, data
));
1176 case SIOCGCONNIDS32
: /* struct so_cidreq32 */
1177 case SIOCGCONNIDS64
: /* struct so_cidreq64 */
1178 return (inctl_connid(so
, cmd
, data
));
1181 case SIOCGCONNINFO32
: /* struct so_cinforeq32 */
1182 case SIOCGCONNINFO64
: /* struct so_cinforeq64 */
1183 return (inctl_conninfo(so
, cmd
, data
));
1188 * The rest of ioctls require ifp; reject if we don't have one;
1189 * return ENXIO to be consistent with ifioctl().
1195 * ioctls which require ifp but not interface address.
1198 case SIOCAUTOADDR
: /* struct ifreq */
1201 return (inctl_autoaddr(ifp
, ifr
));
1204 case SIOCARPIPLL
: /* struct ifreq */
1207 return (inctl_arpipll(ifp
, ifr
));
1210 case SIOCSETROUTERMODE
: /* struct ifreq */
1213 return (inctl_setrouter(ifp
, ifr
));
1216 case SIOCPROTOATTACH
: /* struct ifreq */
1219 return (in_domifattach(ifp
));
1222 case SIOCPROTODETACH
: /* struct ifreq */
1227 * If an IPv4 address is still present, refuse to detach.
1229 ifnet_lock_shared(ifp
);
1230 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1232 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
1238 ifnet_lock_done(ifp
);
1239 return ((ifa
== NULL
) ? proto_unplumb(PF_INET
, ifp
) : EBUSY
);
1244 * ioctls which require interface address; obtain sockaddr_in.
1247 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1250 bcopy(&((struct in_aliasreq
*)(void *)data
)->ifra_addr
,
1251 &sin
, sizeof (sin
));
1255 case SIOCDIFADDR
: /* struct ifreq */
1256 case SIOCSIFADDR
: /* struct ifreq */
1257 case SIOCSIFDSTADDR
: /* struct ifreq */
1258 case SIOCSIFNETMASK
: /* struct ifreq */
1259 case SIOCSIFBRDADDR
: /* struct ifreq */
1263 case SIOCGIFADDR
: /* struct ifreq */
1264 case SIOCGIFDSTADDR
: /* struct ifreq */
1265 case SIOCGIFNETMASK
: /* struct ifreq */
1266 case SIOCGIFBRDADDR
: /* struct ifreq */
1267 bcopy(&ifr
->ifr_addr
, &sin
, sizeof (sin
));
1273 * Find address for this interface, if it exists.
1275 * If an alias address was specified, find that one instead of
1276 * the first one on the interface, if possible.
1280 struct in_ifaddr
*iap
;
1283 * Any failures from this point on must take into account
1284 * a non-NULL "ia" with an outstanding reference count, and
1285 * therefore requires IFA_REMREF. Jump to "done" label
1286 * instead of calling return if "ia" is valid.
1288 lck_rw_lock_shared(in_ifaddr_rwlock
);
1289 TAILQ_FOREACH(iap
, INADDR_HASH(sa
->sin_addr
.s_addr
), ia_hash
) {
1290 IFA_LOCK(&iap
->ia_ifa
);
1291 if (iap
->ia_ifp
== ifp
&&
1292 iap
->ia_addr
.sin_addr
.s_addr
==
1293 sa
->sin_addr
.s_addr
) {
1295 IFA_UNLOCK(&iap
->ia_ifa
);
1298 IFA_UNLOCK(&iap
->ia_ifa
);
1300 /* take a reference on ia before releasing lock */
1302 IFA_ADDREF(&ia
->ia_ifa
);
1303 lck_rw_done(in_ifaddr_rwlock
);
1306 ifnet_lock_shared(ifp
);
1307 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1309 IFA_LOCK(&iap
->ia_ifa
);
1310 if (iap
->ia_addr
.sin_family
== AF_INET
) {
1312 IFA_UNLOCK(&iap
->ia_ifa
);
1315 IFA_UNLOCK(&iap
->ia_ifa
);
1317 /* take a reference on ia before releasing lock */
1319 IFA_ADDREF(&ia
->ia_ifa
);
1320 ifnet_lock_done(ifp
);
1325 * Unlock the socket since ifnet_ioctl() may be invoked by
1326 * one of the ioctl handlers below. Socket will be re-locked
1327 * prior to returning.
1330 socket_unlock(so
, 0);
1335 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1336 case SIOCDIFADDR
: /* struct ifreq */
1337 if (cmd
== SIOCAIFADDR
) {
1338 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1339 ifra_addr
, &addr
, sizeof (addr
));
1340 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1341 ifra_dstaddr
, &dstaddr
, sizeof (dstaddr
));
1343 VERIFY(cmd
== SIOCDIFADDR
);
1344 bcopy(&((struct ifreq
*)(void *)data
)->ifr_addr
,
1345 &addr
, sizeof (addr
));
1346 bzero(&dstaddr
, sizeof (dstaddr
));
1349 if (addr
.sin_family
== AF_INET
) {
1350 struct in_ifaddr
*oia
;
1352 lck_rw_lock_shared(in_ifaddr_rwlock
);
1353 for (oia
= ia
; ia
; ia
= ia
->ia_link
.tqe_next
) {
1354 IFA_LOCK(&ia
->ia_ifa
);
1355 if (ia
->ia_ifp
== ifp
&&
1356 ia
->ia_addr
.sin_addr
.s_addr
==
1357 addr
.sin_addr
.s_addr
) {
1358 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1359 IFA_UNLOCK(&ia
->ia_ifa
);
1362 IFA_UNLOCK(&ia
->ia_ifa
);
1364 lck_rw_done(in_ifaddr_rwlock
);
1366 IFA_REMREF(&oia
->ia_ifa
);
1367 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
1368 (cmd
== SIOCAIFADDR
) &&
1369 (dstaddr
.sin_addr
.s_addr
== INADDR_ANY
)) {
1370 error
= EDESTADDRREQ
;
1373 } else if (cmd
== SIOCAIFADDR
) {
1377 if (cmd
== SIOCDIFADDR
&& ia
== NULL
) {
1378 error
= EADDRNOTAVAIL
;
1382 case SIOCSIFADDR
: /* struct ifreq */
1383 case SIOCSIFDSTADDR
: /* struct ifreq */
1384 case SIOCSIFNETMASK
: /* struct ifreq */
1385 if (cmd
== SIOCAIFADDR
) {
1386 /* fell thru from above; just repeat it */
1387 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1388 ifra_addr
, &addr
, sizeof (addr
));
1390 VERIFY(cmd
== SIOCDIFADDR
|| cmd
== SIOCSIFADDR
||
1391 cmd
== SIOCSIFNETMASK
|| cmd
== SIOCSIFDSTADDR
);
1392 bcopy(&((struct ifreq
*)(void *)data
)->ifr_addr
,
1393 &addr
, sizeof (addr
));
1396 if (addr
.sin_family
!= AF_INET
&& cmd
== SIOCSIFADDR
) {
1401 ia
= in_ifaddr_alloc(M_WAITOK
);
1406 ifnet_lock_exclusive(ifp
);
1409 /* Hold a reference for this routine */
1410 IFA_ADDREF_LOCKED(ifa
);
1412 ifa
->ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1413 ifa
->ifa_dstaddr
= (struct sockaddr
*)&ia
->ia_dstaddr
;
1414 ifa
->ifa_netmask
= (struct sockaddr
*)&ia
->ia_sockmask
;
1415 ia
->ia_sockmask
.sin_len
= 8;
1416 if (ifp
->if_flags
& IFF_BROADCAST
) {
1417 ia
->ia_broadaddr
.sin_len
= sizeof (ia
->ia_addr
);
1418 ia
->ia_broadaddr
.sin_family
= AF_INET
;
1421 if (!(ifp
->if_flags
& IFF_LOOPBACK
))
1423 /* if_attach_ifa() holds a reference for ifa_link */
1424 if_attach_ifa(ifp
, ifa
);
1426 * If we have to go through in_ifinit(), make sure
1427 * to avoid installing route(s) based on this address
1428 * via PFC_IFUP event, before the link resolver (ARP)
1431 if (cmd
== SIOCAIFADDR
|| cmd
== SIOCSIFADDR
)
1432 ifa
->ifa_debug
|= IFD_NOTREADY
;
1434 ifnet_lock_done(ifp
);
1435 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1436 /* Hold a reference for ia_link */
1438 TAILQ_INSERT_TAIL(&in_ifaddrhead
, ia
, ia_link
);
1439 lck_rw_done(in_ifaddr_rwlock
);
1441 (void) in_domifattach(ifp
);
1448 case SIOCGIFDSTADDR
: /* struct ifreq */
1449 case SIOCSIFDSTADDR
: /* struct ifreq */
1450 error
= inctl_ifdstaddr(ifp
, ia
, cmd
, ifr
);
1453 case SIOCGIFBRDADDR
: /* struct ifreq */
1454 case SIOCSIFBRDADDR
: /* struct ifreq */
1455 error
= inctl_ifbrdaddr(ifp
, ia
, cmd
, ifr
);
1458 case SIOCGIFNETMASK
: /* struct ifreq */
1459 case SIOCSIFNETMASK
: /* struct ifreq */
1460 error
= inctl_ifnetmask(ifp
, ia
, cmd
, ifr
);
1463 case SIOCGIFADDR
: /* struct ifreq */
1464 case SIOCSIFADDR
: /* struct ifreq */
1465 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1466 case SIOCDIFADDR
: /* struct ifreq */
1467 error
= inctl_ifaddr(ifp
, ia
, cmd
, ifr
);
1476 IFA_REMREF(&ia
->ia_ifa
);
1484 * Delete any existing route for an interface.
1487 in_ifscrub(struct ifnet
*ifp
, struct in_ifaddr
*ia
, int locked
)
1489 IFA_LOCK(&ia
->ia_ifa
);
1490 if ((ia
->ia_flags
& IFA_ROUTE
) == 0) {
1491 IFA_UNLOCK(&ia
->ia_ifa
);
1494 IFA_UNLOCK(&ia
->ia_ifa
);
1496 lck_mtx_lock(rnh_lock
);
1497 if (ifp
->if_flags
& (IFF_LOOPBACK
|IFF_POINTOPOINT
))
1498 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
1500 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, 0);
1501 IFA_LOCK(&ia
->ia_ifa
);
1502 ia
->ia_flags
&= ~IFA_ROUTE
;
1503 IFA_UNLOCK(&ia
->ia_ifa
);
1505 lck_mtx_unlock(rnh_lock
);
1509 * Caller must hold in_ifaddr_rwlock as writer.
1512 in_iahash_remove(struct in_ifaddr
*ia
)
1514 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1515 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1517 if (!IA_IS_HASHED(ia
)) {
1518 panic("attempt to remove wrong ia %p from hash table\n", ia
);
1521 TAILQ_REMOVE(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), ia
, ia_hash
);
1523 if (IFA_REMREF_LOCKED(&ia
->ia_ifa
) == NULL
) {
1524 panic("%s: unexpected (missing) refcnt ifa=%p", __func__
,
1531 * Caller must hold in_ifaddr_rwlock as writer.
1534 in_iahash_insert(struct in_ifaddr
*ia
)
1536 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1537 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1539 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1540 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1542 } else if (IA_IS_HASHED(ia
)) {
1543 panic("attempt to double-insert ia %p into hash table\n", ia
);
1546 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1548 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1552 * Some point to point interfaces that are tunnels borrow the address from
1553 * an underlying interface (e.g. VPN server). In order for source address
1554 * selection logic to find the underlying interface first, we add the address
1555 * of borrowing point to point interfaces at the end of the list.
1556 * (see rdar://6733789)
1558 * Caller must hold in_ifaddr_rwlock as writer.
1561 in_iahash_insert_ptp(struct in_ifaddr
*ia
)
1563 struct in_ifaddr
*tmp_ifa
;
1564 struct ifnet
*tmp_ifp
;
1566 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1567 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1569 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1570 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1572 } else if (IA_IS_HASHED(ia
)) {
1573 panic("attempt to double-insert ia %p into hash table\n", ia
);
1576 IFA_UNLOCK(&ia
->ia_ifa
);
1577 TAILQ_FOREACH(tmp_ifa
, INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1579 IFA_LOCK(&tmp_ifa
->ia_ifa
);
1580 /* ia->ia_addr won't change, so check without lock */
1581 if (IA_SIN(tmp_ifa
)->sin_addr
.s_addr
==
1582 ia
->ia_addr
.sin_addr
.s_addr
) {
1583 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1586 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1588 tmp_ifp
= (tmp_ifa
== NULL
) ? NULL
: tmp_ifa
->ia_ifp
;
1590 IFA_LOCK(&ia
->ia_ifa
);
1591 if (tmp_ifp
== NULL
) {
1592 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1595 TAILQ_INSERT_TAIL(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1598 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1602 * Initialize an interface's internet address
1603 * and routing table entry.
1606 in_ifinit(struct ifnet
*ifp
, struct in_ifaddr
*ia
, struct sockaddr_in
*sin
,
1609 u_int32_t i
= ntohl(sin
->sin_addr
.s_addr
);
1610 struct sockaddr_in oldaddr
;
1611 int flags
= RTF_UP
, error
;
1612 struct ifaddr
*ifa0
;
1616 /* Take an extra reference for this routine */
1617 IFA_ADDREF(&ia
->ia_ifa
);
1619 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1620 IFA_LOCK(&ia
->ia_ifa
);
1621 oldaddr
= ia
->ia_addr
;
1622 if (IA_IS_HASHED(ia
)) {
1624 in_iahash_remove(ia
);
1628 * Interface addresses should not contain port or sin_zero information.
1630 SIN(&ia
->ia_addr
)->sin_family
= AF_INET
;
1631 SIN(&ia
->ia_addr
)->sin_len
= sizeof (struct sockaddr_in
);
1632 SIN(&ia
->ia_addr
)->sin_port
= 0;
1633 bzero(&SIN(&ia
->ia_addr
)->sin_zero
, sizeof (sin
->sin_zero
));
1634 if ((ifp
->if_flags
& IFF_POINTOPOINT
))
1635 in_iahash_insert_ptp(ia
);
1637 in_iahash_insert(ia
);
1638 IFA_UNLOCK(&ia
->ia_ifa
);
1639 lck_rw_done(in_ifaddr_rwlock
);
1642 * Give the interface a chance to initialize if this is its first
1643 * address, and to validate the address if necessary. Send down
1644 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es).
1645 * We find the first IPV4 address assigned to it and check if this
1646 * is the same as the one passed into this routine.
1648 ifa0
= ifa_ifpgetprimary(ifp
, AF_INET
);
1649 cmd
= (&ia
->ia_ifa
== ifa0
) ? SIOCSIFADDR
: SIOCAIFADDR
;
1650 error
= ifnet_ioctl(ifp
, PF_INET
, cmd
, ia
);
1651 if (error
== EOPNOTSUPP
)
1654 * If we've just sent down SIOCAIFADDR, send another ioctl down
1655 * for SIOCSIFADDR for the first IPV4 address of the interface,
1656 * because an address change on one of the addresses will result
1657 * in the removal of the previous first IPV4 address. KDP needs
1658 * be reconfigured with the current primary IPV4 address.
1660 if (error
== 0 && cmd
== SIOCAIFADDR
) {
1662 * NOTE: SIOCSIFADDR is defined with struct ifreq
1663 * as parameter, but here we are sending it down
1664 * to the interface with a pointer to struct ifaddr,
1665 * for legacy reasons.
1667 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa0
);
1668 if (error
== EOPNOTSUPP
)
1672 /* Release reference from ifa_ifpgetprimary() */
1676 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1677 IFA_LOCK(&ia
->ia_ifa
);
1678 if (IA_IS_HASHED(ia
))
1679 in_iahash_remove(ia
);
1680 ia
->ia_addr
= oldaddr
;
1682 if ((ifp
->if_flags
& IFF_POINTOPOINT
))
1683 in_iahash_insert_ptp(ia
);
1685 in_iahash_insert(ia
);
1687 IFA_UNLOCK(&ia
->ia_ifa
);
1688 lck_rw_done(in_ifaddr_rwlock
);
1689 /* Release extra reference taken above */
1690 IFA_REMREF(&ia
->ia_ifa
);
1693 lck_mtx_lock(rnh_lock
);
1694 IFA_LOCK(&ia
->ia_ifa
);
1696 * Address has been initialized by the link resolver (ARP)
1697 * via ifnet_ioctl() above; it may now generate route(s).
1699 ia
->ia_ifa
.ifa_debug
&= ~IFD_NOTREADY
;
1701 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&oldaddr
;
1702 IFA_UNLOCK(&ia
->ia_ifa
);
1703 in_ifscrub(ifp
, ia
, 1);
1704 IFA_LOCK(&ia
->ia_ifa
);
1705 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1707 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1709 ia
->ia_netmask
= IN_CLASSA_NET
;
1710 else if (IN_CLASSB(i
))
1711 ia
->ia_netmask
= IN_CLASSB_NET
;
1713 ia
->ia_netmask
= IN_CLASSC_NET
;
1715 * The subnet mask usually includes at least the standard network part,
1716 * but may may be smaller in the case of supernetting.
1717 * If it is set, we believe it.
1719 if (ia
->ia_subnetmask
== 0) {
1720 ia
->ia_subnetmask
= ia
->ia_netmask
;
1721 ia
->ia_sockmask
.sin_addr
.s_addr
= htonl(ia
->ia_subnetmask
);
1723 ia
->ia_netmask
&= ia
->ia_subnetmask
;
1724 ia
->ia_net
= i
& ia
->ia_netmask
;
1725 ia
->ia_subnet
= i
& ia
->ia_subnetmask
;
1726 in_socktrim(&ia
->ia_sockmask
);
1728 * Add route for the network.
1730 ia
->ia_ifa
.ifa_metric
= ifp
->if_metric
;
1731 if (ifp
->if_flags
& IFF_BROADCAST
) {
1732 ia
->ia_broadaddr
.sin_addr
.s_addr
=
1733 htonl(ia
->ia_subnet
| ~ia
->ia_subnetmask
);
1734 ia
->ia_netbroadcast
.s_addr
=
1735 htonl(ia
->ia_net
| ~ ia
->ia_netmask
);
1736 } else if (ifp
->if_flags
& IFF_LOOPBACK
) {
1737 ia
->ia_ifa
.ifa_dstaddr
= ia
->ia_ifa
.ifa_addr
;
1739 } else if (ifp
->if_flags
& IFF_POINTOPOINT
) {
1740 if (ia
->ia_dstaddr
.sin_family
!= AF_INET
) {
1741 IFA_UNLOCK(&ia
->ia_ifa
);
1742 lck_mtx_unlock(rnh_lock
);
1743 /* Release extra reference taken above */
1744 IFA_REMREF(&ia
->ia_ifa
);
1747 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
1750 IFA_UNLOCK(&ia
->ia_ifa
);
1752 if ((error
= rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
, flags
)) == 0) {
1753 IFA_LOCK(&ia
->ia_ifa
);
1754 ia
->ia_flags
|= IFA_ROUTE
;
1755 IFA_UNLOCK(&ia
->ia_ifa
);
1757 lck_mtx_unlock(rnh_lock
);
1759 /* XXX check if the subnet route points to the same interface */
1760 if (error
== EEXIST
)
1764 * If the interface supports multicast, join the "all hosts"
1765 * multicast group on that interface.
1767 if (ifp
->if_flags
& IFF_MULTICAST
) {
1768 struct in_addr addr
;
1770 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
1771 addr
.s_addr
= htonl(INADDR_ALLHOSTS_GROUP
);
1772 if (ifp
->if_allhostsinm
== NULL
) {
1773 struct in_multi
*inm
;
1774 inm
= in_addmulti(&addr
, ifp
);
1778 * Keep the reference on inm added by
1779 * in_addmulti above for storing the
1780 * pointer in allhostsinm.
1782 ifp
->if_allhostsinm
= inm
;
1784 printf("%s: failed to add membership to "
1785 "all-hosts multicast address on %s\n",
1786 __func__
, if_name(ifp
));
1789 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
1792 /* Release extra reference taken above */
1793 IFA_REMREF(&ia
->ia_ifa
);
1796 /* invalidate route caches */
1797 routegenid_inet_update();
1804 * Return TRUE if the address might be a local broadcast address.
1807 in_broadcast(struct in_addr in
, struct ifnet
*ifp
)
1812 if (in
.s_addr
== INADDR_BROADCAST
|| in
.s_addr
== INADDR_ANY
)
1814 if (!(ifp
->if_flags
& IFF_BROADCAST
))
1816 t
= ntohl(in
.s_addr
);
1819 * Look through the list of addresses for a match
1820 * with a broadcast address.
1822 #define ia ((struct in_ifaddr *)ifa)
1823 ifnet_lock_shared(ifp
);
1824 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1826 if (ifa
->ifa_addr
->sa_family
== AF_INET
&&
1827 (in
.s_addr
== ia
->ia_broadaddr
.sin_addr
.s_addr
||
1828 in
.s_addr
== ia
->ia_netbroadcast
.s_addr
||
1830 * Check for old-style (host 0) broadcast.
1832 t
== ia
->ia_subnet
|| t
== ia
->ia_net
) &&
1834 * Check for an all one subnetmask. These
1835 * only exist when an interface gets a secondary
1838 ia
->ia_subnetmask
!= (u_int32_t
)0xffffffff) {
1840 ifnet_lock_done(ifp
);
1845 ifnet_lock_done(ifp
);
1851 in_purgeaddrs(struct ifnet
*ifp
)
1853 struct ifaddr
**ifap
;
1856 VERIFY(ifp
!= NULL
);
1859 * Be nice, and try the civilized way first. If we can't get
1860 * rid of them this way, then do it the rough way. We must
1861 * only get here during detach time, after the ifnet has been
1862 * removed from the global list and arrays.
1864 err
= ifnet_get_address_list_family_internal(ifp
, &ifap
, AF_INET
, 1,
1866 if (err
== 0 && ifap
!= NULL
) {
1869 bzero(&ifr
, sizeof (ifr
));
1870 (void) snprintf(ifr
.ifr_name
, sizeof (ifr
.ifr_name
),
1871 "%s", if_name(ifp
));
1873 for (i
= 0; ifap
[i
] != NULL
; i
++) {
1878 bcopy(ifa
->ifa_addr
, &ifr
.ifr_addr
,
1879 sizeof (struct sockaddr_in
));
1881 err
= in_control(NULL
, SIOCDIFADDR
, (caddr_t
)&ifr
, ifp
,
1883 /* if we lost the race, ignore it */
1884 if (err
== EADDRNOTAVAIL
)
1887 char s_addr
[MAX_IPv4_STR_LEN
];
1888 char s_dstaddr
[MAX_IPv4_STR_LEN
];
1889 struct in_addr
*s
, *d
;
1892 s
= &((struct sockaddr_in
*)
1893 (void *)ifa
->ifa_addr
)->sin_addr
;
1894 d
= &((struct sockaddr_in
*)
1895 (void *)ifa
->ifa_dstaddr
)->sin_addr
;
1896 (void) inet_ntop(AF_INET
, &s
->s_addr
, s_addr
,
1898 (void) inet_ntop(AF_INET
, &d
->s_addr
, s_dstaddr
,
1899 sizeof (s_dstaddr
));
1902 printf("%s: SIOCDIFADDR ifp=%s ifa_addr=%s "
1903 "ifa_dstaddr=%s (err=%d)\n", __func__
,
1904 ifp
->if_xname
, s_addr
, s_dstaddr
, err
);
1907 ifnet_free_address_list(ifap
);
1908 } else if (err
!= 0 && err
!= ENXIO
) {
1909 printf("%s: error retrieving list of AF_INET addresses for "
1910 "ifp=%s (err=%d)\n", __func__
, ifp
->if_xname
, err
);
1915 * Select endpoint address(es). For now just take the first matching
1916 * address and discard the rest, if present.
1919 in_selectaddrs(int af
, struct sockaddr_list
**src_sl
,
1920 struct sockaddr_entry
**src_se
, struct sockaddr_list
**dst_sl
,
1921 struct sockaddr_entry
**dst_se
)
1923 struct sockaddr_entry
*se
= NULL
;
1924 struct sockaddr_entry
*tse
= NULL
;
1927 VERIFY(src_sl
!= NULL
&& dst_sl
!= NULL
&& *dst_sl
!= NULL
);
1928 VERIFY(src_se
!= NULL
&& dst_se
!= NULL
);
1930 *src_se
= *dst_se
= NULL
;
1932 /* pick a source address, if available */
1933 if (*src_sl
!= NULL
) {
1934 TAILQ_FOREACH(se
, &(*src_sl
)->sl_head
, se_link
) {
1935 VERIFY(se
->se_addr
!= NULL
);
1937 * Take the first source address, or the first
1938 * one with matching address family.
1940 if (af
== AF_UNSPEC
|| se
->se_addr
->sa_family
== af
) {
1941 sockaddrlist_remove(*src_sl
, se
);
1946 /* get rid of the rest */
1947 TAILQ_FOREACH_SAFE(se
, &(*src_sl
)->sl_head
, se_link
, tse
) {
1948 sockaddrlist_remove(*src_sl
, se
);
1949 sockaddrentry_free(se
);
1951 if (*src_se
!= NULL
) {
1952 /* insert the first src address back in */
1953 sockaddrlist_insert(*src_sl
, *src_se
);
1954 VERIFY((*src_sl
)->sl_cnt
== 1);
1955 /* destination address must be of this family */
1956 af
= (*src_se
)->se_addr
->sa_family
;
1958 /* no usable source address with matching family */
1959 VERIFY(af
!= AF_UNSPEC
);
1960 error
= EAFNOSUPPORT
;
1964 /* pick a (matching) destination address */
1965 TAILQ_FOREACH(se
, &(*dst_sl
)->sl_head
, se_link
) {
1966 VERIFY(se
->se_addr
!= NULL
);
1968 * Take the first destination address; if source is specified,
1969 * find one which uses the same address family.
1971 if (af
== AF_UNSPEC
|| se
->se_addr
->sa_family
== af
) {
1972 sockaddrlist_remove(*dst_sl
, se
);
1977 /* get rid of the rest */
1978 TAILQ_FOREACH_SAFE(se
, &(*dst_sl
)->sl_head
, se_link
, tse
) {
1979 sockaddrlist_remove(*dst_sl
, se
);
1980 sockaddrentry_free(se
);
1982 if (*dst_se
!= NULL
) {
1983 /* insert the first dst address back in */
1984 sockaddrlist_insert(*dst_sl
, *dst_se
);
1985 VERIFY((*dst_sl
)->sl_cnt
== 1);
1987 /* source and destination address families don't match */
1988 error
= EAFNOSUPPORT
;
1992 af
= (*dst_se
)->se_addr
->sa_family
;
1993 VERIFY(*src_se
== NULL
|| (*src_se
)->se_addr
->sa_family
== af
);
1995 /* verify address length */
1998 if ((*dst_se
)->se_addr
->sa_len
!=
1999 sizeof (struct sockaddr_in
)) {
2000 error
= EAFNOSUPPORT
;
2006 if ((*dst_se
)->se_addr
->sa_len
!=
2007 sizeof (struct sockaddr_in6
)) {
2008 error
= EAFNOSUPPORT
;
2014 error
= EAFNOSUPPORT
;
2018 /* if source address is specified, length must match destination */
2019 if (*src_se
!= NULL
&& (*src_se
)->se_addr
->sa_len
!=
2020 (*dst_se
)->se_addr
->sa_len
) {
2021 error
= EAFNOSUPPORT
;
2029 * Called as part of ip_init
2032 in_ifaddr_init(void)
2036 PE_parse_boot_argn("ifa_debug", &inifa_debug
, sizeof (inifa_debug
));
2038 inifa_size
= (inifa_debug
== 0) ? sizeof (struct in_ifaddr
) :
2039 sizeof (struct in_ifaddr_dbg
);
2041 inifa_zone
= zinit(inifa_size
, INIFA_ZONE_MAX
* inifa_size
,
2042 0, INIFA_ZONE_NAME
);
2043 if (inifa_zone
== NULL
) {
2044 panic("%s: failed allocating %s", __func__
, INIFA_ZONE_NAME
);
2047 zone_change(inifa_zone
, Z_EXPAND
, TRUE
);
2048 zone_change(inifa_zone
, Z_CALLERACCT
, FALSE
);
2050 lck_mtx_init(&inifa_trash_lock
, ifa_mtx_grp
, ifa_mtx_attr
);
2051 TAILQ_INIT(&inifa_trash_head
);
2054 static struct in_ifaddr
*
2055 in_ifaddr_alloc(int how
)
2057 struct in_ifaddr
*inifa
;
2059 inifa
= (how
== M_WAITOK
) ? zalloc(inifa_zone
) :
2060 zalloc_noblock(inifa_zone
);
2061 if (inifa
!= NULL
) {
2062 bzero(inifa
, inifa_size
);
2063 inifa
->ia_ifa
.ifa_free
= in_ifaddr_free
;
2064 inifa
->ia_ifa
.ifa_debug
|= IFD_ALLOC
;
2065 ifa_lock_init(&inifa
->ia_ifa
);
2066 if (inifa_debug
!= 0) {
2067 struct in_ifaddr_dbg
*inifa_dbg
=
2068 (struct in_ifaddr_dbg
*)inifa
;
2069 inifa
->ia_ifa
.ifa_debug
|= IFD_DEBUG
;
2070 inifa
->ia_ifa
.ifa_trace
= in_ifaddr_trace
;
2071 inifa
->ia_ifa
.ifa_attached
= in_ifaddr_attached
;
2072 inifa
->ia_ifa
.ifa_detached
= in_ifaddr_detached
;
2073 ctrace_record(&inifa_dbg
->inifa_alloc
);
2080 in_ifaddr_free(struct ifaddr
*ifa
)
2082 IFA_LOCK_ASSERT_HELD(ifa
);
2084 if (ifa
->ifa_refcnt
!= 0) {
2085 panic("%s: ifa %p bad ref cnt", __func__
, ifa
);
2087 } if (!(ifa
->ifa_debug
& IFD_ALLOC
)) {
2088 panic("%s: ifa %p cannot be freed", __func__
, ifa
);
2091 if (ifa
->ifa_debug
& IFD_DEBUG
) {
2092 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2093 ctrace_record(&inifa_dbg
->inifa_free
);
2094 bcopy(&inifa_dbg
->inifa
, &inifa_dbg
->inifa_old
,
2095 sizeof (struct in_ifaddr
));
2096 if (ifa
->ifa_debug
& IFD_TRASHED
) {
2097 /* Become a regular mutex, just in case */
2098 IFA_CONVERT_LOCK(ifa
);
2099 lck_mtx_lock(&inifa_trash_lock
);
2100 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
,
2102 lck_mtx_unlock(&inifa_trash_lock
);
2103 ifa
->ifa_debug
&= ~IFD_TRASHED
;
2107 ifa_lock_destroy(ifa
);
2108 bzero(ifa
, sizeof (struct in_ifaddr
));
2109 zfree(inifa_zone
, ifa
);
2113 in_ifaddr_attached(struct ifaddr
*ifa
)
2115 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2117 IFA_LOCK_ASSERT_HELD(ifa
);
2119 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2120 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2123 if (ifa
->ifa_debug
& IFD_TRASHED
) {
2124 /* Become a regular mutex, just in case */
2125 IFA_CONVERT_LOCK(ifa
);
2126 lck_mtx_lock(&inifa_trash_lock
);
2127 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
2128 lck_mtx_unlock(&inifa_trash_lock
);
2129 ifa
->ifa_debug
&= ~IFD_TRASHED
;
2134 in_ifaddr_detached(struct ifaddr
*ifa
)
2136 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2138 IFA_LOCK_ASSERT_HELD(ifa
);
2140 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2141 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2143 } else if (ifa
->ifa_debug
& IFD_TRASHED
) {
2144 panic("%s: ifa %p is already in trash list", __func__
, ifa
);
2147 ifa
->ifa_debug
|= IFD_TRASHED
;
2148 /* Become a regular mutex, just in case */
2149 IFA_CONVERT_LOCK(ifa
);
2150 lck_mtx_lock(&inifa_trash_lock
);
2151 TAILQ_INSERT_TAIL(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
2152 lck_mtx_unlock(&inifa_trash_lock
);
2156 in_ifaddr_trace(struct ifaddr
*ifa
, int refhold
)
2158 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2163 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2164 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2168 cnt
= &inifa_dbg
->inifa_refhold_cnt
;
2169 tr
= inifa_dbg
->inifa_refhold
;
2171 cnt
= &inifa_dbg
->inifa_refrele_cnt
;
2172 tr
= inifa_dbg
->inifa_refrele
;
2175 idx
= atomic_add_16_ov(cnt
, 1) % INIFA_TRACE_HIST_SIZE
;
2176 ctrace_record(&tr
[idx
]);
2180 * Handle SIOCGASSOCIDS ioctl for PF_INET domain.
2183 in_getassocids(struct socket
*so
, uint32_t *cnt
, user_addr_t aidp
)
2185 struct inpcb
*inp
= sotoinpcb(so
);
2188 if (inp
== NULL
|| inp
->inp_state
== INPCB_STATE_DEAD
)
2191 /* INPCB has no concept of association */
2192 aid
= SAE_ASSOCID_ANY
;
2195 /* just asking how many there are? */
2196 if (aidp
== USER_ADDR_NULL
)
2199 return (copyout(&aid
, aidp
, sizeof (aid
)));
2203 * Handle SIOCGCONNIDS ioctl for PF_INET domain.
2206 in_getconnids(struct socket
*so
, sae_associd_t aid
, uint32_t *cnt
,
2209 struct inpcb
*inp
= sotoinpcb(so
);
2212 if (inp
== NULL
|| inp
->inp_state
== INPCB_STATE_DEAD
)
2215 if (aid
!= SAE_ASSOCID_ANY
&& aid
!= SAE_ASSOCID_ALL
)
2218 /* if connected, return 1 connection count */
2219 *cnt
= ((so
->so_state
& SS_ISCONNECTED
) ? 1 : 0);
2221 /* just asking how many there are? */
2222 if (cidp
== USER_ADDR_NULL
)
2225 /* if INPCB is connected, assign it connid 1 */
2226 cid
= ((*cnt
!= 0) ? 1 : SAE_CONNID_ANY
);
2228 return (copyout(&cid
, cidp
, sizeof (cid
)));
2232 * Handle SIOCGCONNINFO ioctl for PF_INET domain.
2235 in_getconninfo(struct socket
*so
, sae_connid_t cid
, uint32_t *flags
,
2236 uint32_t *ifindex
, int32_t *soerror
, user_addr_t src
, socklen_t
*src_len
,
2237 user_addr_t dst
, socklen_t
*dst_len
, uint32_t *aux_type
,
2238 user_addr_t aux_data
, uint32_t *aux_len
)
2240 #pragma unused(aux_data)
2241 struct inpcb
*inp
= sotoinpcb(so
);
2242 struct sockaddr_in sin
;
2243 struct ifnet
*ifp
= NULL
;
2245 u_int32_t copy_len
= 0;
2248 * Don't test for INPCB_STATE_DEAD since this may be called
2249 * after SOF_PCBCLEARING is set, e.g. after tcp_close().
2256 if (cid
!= SAE_CONNID_ANY
&& cid
!= SAE_CONNID_ALL
&& cid
!= 1) {
2261 ifp
= inp
->inp_last_outifp
;
2262 *ifindex
= ((ifp
!= NULL
) ? ifp
->if_index
: 0);
2263 *soerror
= so
->so_error
;
2265 if (so
->so_state
& SS_ISCONNECTED
)
2266 *flags
|= (CIF_CONNECTED
| CIF_PREFERRED
);
2267 if (inp
->inp_flags
& INP_BOUND_IF
)
2268 *flags
|= CIF_BOUND_IF
;
2269 if (!(inp
->inp_flags
& INP_INADDR_ANY
))
2270 *flags
|= CIF_BOUND_IP
;
2271 if (!(inp
->inp_flags
& INP_ANONPORT
))
2272 *flags
|= CIF_BOUND_PORT
;
2274 bzero(&sin
, sizeof (sin
));
2275 sin
.sin_len
= sizeof (sin
);
2276 sin
.sin_family
= AF_INET
;
2278 /* source address and port */
2279 sin
.sin_port
= inp
->inp_lport
;
2280 sin
.sin_addr
.s_addr
= inp
->inp_laddr
.s_addr
;
2281 if (*src_len
== 0) {
2282 *src_len
= sin
.sin_len
;
2284 if (src
!= USER_ADDR_NULL
) {
2285 copy_len
= min(*src_len
, sizeof (sin
));
2286 error
= copyout(&sin
, src
, copy_len
);
2289 *src_len
= copy_len
;
2293 /* destination address and port */
2294 sin
.sin_port
= inp
->inp_fport
;
2295 sin
.sin_addr
.s_addr
= inp
->inp_faddr
.s_addr
;
2296 if (*dst_len
== 0) {
2297 *dst_len
= sin
.sin_len
;
2299 if (dst
!= USER_ADDR_NULL
) {
2300 copy_len
= min(*dst_len
, sizeof (sin
));
2301 error
= copyout(&sin
, dst
, copy_len
);
2304 *dst_len
= copy_len
;
2310 if (SOCK_PROTO(so
) == IPPROTO_TCP
) {
2311 struct conninfo_tcp tcp_ci
;
2313 *aux_type
= CIAUX_TCP
;
2314 if (*aux_len
== 0) {
2315 *aux_len
= sizeof (tcp_ci
);
2317 if (aux_data
!= USER_ADDR_NULL
) {
2318 copy_len
= min(*aux_len
, sizeof (tcp_ci
));
2319 bzero(&tcp_ci
, sizeof (tcp_ci
));
2320 tcp_getconninfo(so
, &tcp_ci
);
2321 error
= copyout(&tcp_ci
, aux_data
, copy_len
);
2324 *aux_len
= copy_len
;