2 * Copyright (c) 2000-2014 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
*, associd_t
, uint32_t *, user_addr_t
);
138 static int in_getconninfo(struct socket
*, 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 */
191 * Return 1 if the address is
193 * - unicast or multicast link local
194 * - routed via a link level gateway
195 * - belongs to a directly connected (sub)net
198 inaddr_local(struct in_addr in
)
201 struct sockaddr_in sin
;
204 if (ntohl(in
.s_addr
) == INADDR_LOOPBACK
||
205 IN_LINKLOCAL(ntohl(in
.s_addr
))) {
207 } else if (ntohl(in
.s_addr
) >= INADDR_UNSPEC_GROUP
&&
208 ntohl(in
.s_addr
) <= INADDR_MAX_LOCAL_GROUP
) {
211 sin
.sin_family
= AF_INET
;
212 sin
.sin_len
= sizeof (sin
);
214 rt
= rtalloc1((struct sockaddr
*)&sin
, 0, 0);
218 if (rt
->rt_gateway
->sa_family
== AF_LINK
||
219 (rt
->rt_ifp
->if_flags
& IFF_LOOPBACK
))
224 local
= in_localaddr(in
);
231 * Return 1 if an internet address is for a ``local'' host
232 * (one to which we have a connection). If subnetsarelocal
233 * is true, this includes other subnets of the local net.
234 * Otherwise, it includes only the directly-connected (sub)nets.
237 in_localaddr(struct in_addr in
)
239 u_int32_t i
= ntohl(in
.s_addr
);
240 struct in_ifaddr
*ia
;
242 if (subnetsarelocal
) {
243 lck_rw_lock_shared(in_ifaddr_rwlock
);
244 for (ia
= in_ifaddrhead
.tqh_first
; ia
!= NULL
;
245 ia
= ia
->ia_link
.tqe_next
) {
246 IFA_LOCK(&ia
->ia_ifa
);
247 if ((i
& ia
->ia_netmask
) == ia
->ia_net
) {
248 IFA_UNLOCK(&ia
->ia_ifa
);
249 lck_rw_done(in_ifaddr_rwlock
);
252 IFA_UNLOCK(&ia
->ia_ifa
);
254 lck_rw_done(in_ifaddr_rwlock
);
256 lck_rw_lock_shared(in_ifaddr_rwlock
);
257 for (ia
= in_ifaddrhead
.tqh_first
; ia
!= NULL
;
258 ia
= ia
->ia_link
.tqe_next
) {
259 IFA_LOCK(&ia
->ia_ifa
);
260 if ((i
& ia
->ia_subnetmask
) == ia
->ia_subnet
) {
261 IFA_UNLOCK(&ia
->ia_ifa
);
262 lck_rw_done(in_ifaddr_rwlock
);
265 IFA_UNLOCK(&ia
->ia_ifa
);
267 lck_rw_done(in_ifaddr_rwlock
);
273 * Determine whether an IP address is in a reserved set of addresses
274 * that may not be forwarded, or whether datagrams to that destination
278 in_canforward(struct in_addr in
)
280 u_int32_t i
= ntohl(in
.s_addr
);
283 if (IN_EXPERIMENTAL(i
) || IN_MULTICAST(i
))
286 net
= i
& IN_CLASSA_NET
;
287 if (net
== 0 || net
== (IN_LOOPBACKNET
<< IN_CLASSA_NSHIFT
))
294 * Trim a mask in a sockaddr
297 in_socktrim(struct sockaddr_in
*ap
)
299 char *cplim
= (char *)&ap
->sin_addr
;
300 char *cp
= (char *)(&ap
->sin_addr
+ 1);
303 while (--cp
>= cplim
)
305 (ap
)->sin_len
= cp
- (char *)(ap
) + 1;
310 static int in_interfaces
; /* number of external internet interfaces */
313 in_domifattach(struct ifnet
*ifp
)
319 if ((error
= proto_plumb(PF_INET
, ifp
)) && error
!= EEXIST
)
320 log(LOG_ERR
, "%s: proto_plumb returned %d if=%s\n",
321 __func__
, error
, if_name(ifp
));
326 static __attribute__((noinline
)) int
327 inctl_associd(struct socket
*so
, u_long cmd
, caddr_t data
)
331 struct so_aidreq32 a32
;
332 struct so_aidreq64 a64
;
338 case SIOCGASSOCIDS32
: /* struct so_aidreq32 */
339 bcopy(data
, &u
.a32
, sizeof (u
.a32
));
340 error
= in_getassocids(so
, &u
.a32
.sar_cnt
, u
.a32
.sar_aidp
);
342 bcopy(&u
.a32
, data
, sizeof (u
.a32
));
345 case SIOCGASSOCIDS64
: /* struct so_aidreq64 */
346 bcopy(data
, &u
.a64
, sizeof (u
.a64
));
347 error
= in_getassocids(so
, &u
.a64
.sar_cnt
, u
.a64
.sar_aidp
);
349 bcopy(&u
.a64
, data
, sizeof (u
.a64
));
360 static __attribute__((noinline
)) int
361 inctl_connid(struct socket
*so
, u_long cmd
, caddr_t data
)
365 struct so_cidreq32 c32
;
366 struct so_cidreq64 c64
;
372 case SIOCGCONNIDS32
: /* struct so_cidreq32 */
373 bcopy(data
, &u
.c32
, sizeof (u
.c32
));
374 error
= in_getconnids(so
, u
.c32
.scr_aid
, &u
.c32
.scr_cnt
,
377 bcopy(&u
.c32
, data
, sizeof (u
.c32
));
380 case SIOCGCONNIDS64
: /* struct so_cidreq64 */
381 bcopy(data
, &u
.c64
, sizeof (u
.c64
));
382 error
= in_getconnids(so
, u
.c64
.scr_aid
, &u
.c64
.scr_cnt
,
385 bcopy(&u
.c64
, data
, sizeof (u
.c64
));
396 static __attribute__((noinline
)) int
397 inctl_conninfo(struct socket
*so
, u_long cmd
, caddr_t data
)
401 struct so_cinforeq32 ci32
;
402 struct so_cinforeq64 ci64
;
408 case SIOCGCONNINFO32
: /* struct so_cinforeq32 */
409 bcopy(data
, &u
.ci32
, sizeof (u
.ci32
));
410 error
= in_getconninfo(so
, u
.ci32
.scir_cid
, &u
.ci32
.scir_flags
,
411 &u
.ci32
.scir_ifindex
, &u
.ci32
.scir_error
, u
.ci32
.scir_src
,
412 &u
.ci32
.scir_src_len
, u
.ci32
.scir_dst
, &u
.ci32
.scir_dst_len
,
413 &u
.ci32
.scir_aux_type
, u
.ci32
.scir_aux_data
,
414 &u
.ci32
.scir_aux_len
);
416 bcopy(&u
.ci32
, data
, sizeof (u
.ci32
));
419 case SIOCGCONNINFO64
: /* struct so_cinforeq64 */
420 bcopy(data
, &u
.ci64
, sizeof (u
.ci64
));
421 error
= in_getconninfo(so
, u
.ci64
.scir_cid
, &u
.ci64
.scir_flags
,
422 &u
.ci64
.scir_ifindex
, &u
.ci64
.scir_error
, u
.ci64
.scir_src
,
423 &u
.ci64
.scir_src_len
, u
.ci64
.scir_dst
, &u
.ci64
.scir_dst_len
,
424 &u
.ci64
.scir_aux_type
, u
.ci64
.scir_aux_data
,
425 &u
.ci64
.scir_aux_len
);
427 bcopy(&u
.ci64
, data
, sizeof (u
.ci64
));
439 * Caller passes in the ioctl data pointer directly via "ifr", with the
440 * expectation that this routine always uses bcopy() or other byte-aligned
443 static __attribute__((noinline
)) int
444 inctl_autoaddr(struct ifnet
*ifp
, struct ifreq
*ifr
)
446 int error
= 0, intval
;
450 bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
));
452 ifnet_lock_exclusive(ifp
);
455 * An interface in IPv4 router mode implies that it
456 * is configured with a static IP address and should
457 * not act as a DHCP client; prevent SIOCAUTOADDR from
458 * being set in that mode.
460 if (ifp
->if_eflags
& IFEF_IPV4_ROUTER
) {
461 intval
= 0; /* be safe; clear flag if set */
464 ifp
->if_eflags
|= IFEF_AUTOCONFIGURING
;
468 ifp
->if_eflags
&= ~IFEF_AUTOCONFIGURING
;
469 ifnet_lock_done(ifp
);
475 * Caller passes in the ioctl data pointer directly via "ifr", with the
476 * expectation that this routine always uses bcopy() or other byte-aligned
479 static __attribute__((noinline
)) int
480 inctl_arpipll(struct ifnet
*ifp
, struct ifreq
*ifr
)
482 int error
= 0, intval
;
486 bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
));
487 ipv4_ll_arp_aware
= 1;
489 ifnet_lock_exclusive(ifp
);
492 * An interface in IPv4 router mode implies that it
493 * is configured with a static IP address and should
494 * not have to deal with IPv4 Link-Local Address;
495 * prevent SIOCARPIPLL from being set in that mode.
497 if (ifp
->if_eflags
& IFEF_IPV4_ROUTER
) {
498 intval
= 0; /* be safe; clear flag if set */
501 ifp
->if_eflags
|= IFEF_ARPLL
;
505 ifp
->if_eflags
&= ~IFEF_ARPLL
;
506 ifnet_lock_done(ifp
);
512 * Handle SIOCSETROUTERMODE to set or clear the IPv4 router mode flag on
513 * the interface. When in this mode, IPv4 Link-Local Address support is
514 * disabled in ARP, and DHCP client support is disabled in IP input; turning
515 * any of them on would cause an error to be returned. Entering or exiting
516 * this mode will result in the removal of IPv4 addresses currently configured
519 * Caller passes in the ioctl data pointer directly via "ifr", with the
520 * expectation that this routine always uses bcopy() or other byte-aligned
523 static __attribute__((noinline
)) int
524 inctl_setrouter(struct ifnet
*ifp
, struct ifreq
*ifr
)
526 int error
= 0, intval
;
530 /* Router mode isn't valid for loopback */
531 if (ifp
->if_flags
& IFF_LOOPBACK
)
534 bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
));
536 ifnet_lock_exclusive(ifp
);
538 ifp
->if_eflags
|= IFEF_IPV4_ROUTER
;
539 ifp
->if_eflags
&= ~(IFEF_ARPLL
| IFEF_AUTOCONFIGURING
);
541 ifp
->if_eflags
&= ~IFEF_IPV4_ROUTER
;
543 ifnet_lock_done(ifp
);
545 /* purge all IPv4 addresses configured on this interface */
552 * Caller passes in the ioctl data pointer directly via "ifr", with the
553 * expectation that this routine always uses bcopy() or other byte-aligned
556 static __attribute__((noinline
)) int
557 inctl_ifaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
560 struct kev_in_data in_event_data
;
561 struct kev_msg ev_msg
;
562 struct sockaddr_in addr
;
568 bzero(&in_event_data
, sizeof (struct kev_in_data
));
569 bzero(&ev_msg
, sizeof (struct kev_msg
));
572 case SIOCGIFADDR
: /* struct ifreq */
574 error
= EADDRNOTAVAIL
;
577 IFA_LOCK(&ia
->ia_ifa
);
578 bcopy(&ia
->ia_addr
, &ifr
->ifr_addr
, sizeof (addr
));
579 IFA_UNLOCK(&ia
->ia_ifa
);
582 case SIOCSIFADDR
: /* struct ifreq */
584 bcopy(&ifr
->ifr_addr
, &addr
, sizeof (addr
));
586 * If this is a new address, the reference count for the
587 * hash table has been taken at creation time above.
589 error
= in_ifinit(ifp
, ia
, &addr
, 1);
591 (void) ifnet_notify_address(ifp
, AF_INET
);
595 case SIOCAIFADDR
: { /* struct {if,in_}aliasreq */
596 struct in_aliasreq
*ifra
= (struct in_aliasreq
*)ifr
;
597 struct sockaddr_in broadaddr
, mask
;
598 int hostIsNew
, maskIsNew
;
601 bcopy(&ifra
->ifra_addr
, &addr
, sizeof (addr
));
602 bcopy(&ifra
->ifra_broadaddr
, &broadaddr
, sizeof (broadaddr
));
603 bcopy(&ifra
->ifra_mask
, &mask
, sizeof (mask
));
609 IFA_LOCK(&ia
->ia_ifa
);
610 if (ia
->ia_addr
.sin_family
== AF_INET
) {
611 if (addr
.sin_len
== 0) {
614 } else if (addr
.sin_addr
.s_addr
==
615 ia
->ia_addr
.sin_addr
.s_addr
) {
620 IFA_UNLOCK(&ia
->ia_ifa
);
621 in_ifscrub(ifp
, ia
, 0);
622 IFA_LOCK(&ia
->ia_ifa
);
623 ia
->ia_sockmask
= mask
;
625 ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
);
628 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
629 (broadaddr
.sin_family
== AF_INET
)) {
630 IFA_UNLOCK(&ia
->ia_ifa
);
631 in_ifscrub(ifp
, ia
, 0);
632 IFA_LOCK(&ia
->ia_ifa
);
633 ia
->ia_dstaddr
= broadaddr
;
634 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
635 maskIsNew
= 1; /* We lie; but the effect's the same */
637 if (addr
.sin_family
== AF_INET
&& (hostIsNew
|| maskIsNew
)) {
638 IFA_UNLOCK(&ia
->ia_ifa
);
639 error
= in_ifinit(ifp
, ia
, &addr
, 0);
641 IFA_UNLOCK(&ia
->ia_ifa
);
644 (void) ifnet_notify_address(ifp
, AF_INET
);
646 IFA_LOCK(&ia
->ia_ifa
);
647 if ((ifp
->if_flags
& IFF_BROADCAST
) &&
648 (broadaddr
.sin_family
== AF_INET
))
649 ia
->ia_broadaddr
= broadaddr
;
654 if ((error
== 0) || (error
== EEXIST
)) {
655 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
656 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
657 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
660 ev_msg
.event_code
= KEV_INET_NEW_ADDR
;
662 ev_msg
.event_code
= KEV_INET_CHANGED_ADDR
;
664 if (ia
->ia_ifa
.ifa_dstaddr
) {
665 in_event_data
.ia_dstaddr
=
666 ((struct sockaddr_in
*)(void *)ia
->
667 ia_ifa
.ifa_dstaddr
)->sin_addr
;
669 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
671 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
672 in_event_data
.ia_net
= ia
->ia_net
;
673 in_event_data
.ia_netmask
= ia
->ia_netmask
;
674 in_event_data
.ia_subnet
= ia
->ia_subnet
;
675 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
676 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
677 IFA_UNLOCK(&ia
->ia_ifa
);
678 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
679 ifp
->if_name
, IFNAMSIZ
);
680 in_event_data
.link_data
.if_family
= ifp
->if_family
;
681 in_event_data
.link_data
.if_unit
= ifp
->if_unit
;
683 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
684 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
685 ev_msg
.dv
[1].data_length
= 0;
687 kev_post_msg(&ev_msg
);
689 IFA_UNLOCK(&ia
->ia_ifa
);
694 case SIOCDIFADDR
: /* struct ifreq */
696 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCDIFADDR
, ia
);
697 if (error
== EOPNOTSUPP
)
702 /* Fill out the kernel event information */
703 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
704 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
705 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
707 ev_msg
.event_code
= KEV_INET_ADDR_DELETED
;
709 IFA_LOCK(&ia
->ia_ifa
);
710 if (ia
->ia_ifa
.ifa_dstaddr
) {
711 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
712 (void *)ia
->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
= (u_int32_t
)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;
733 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
734 /* Release ia_link reference */
736 TAILQ_REMOVE(&in_ifaddrhead
, ia
, ia_link
);
738 if (IA_IS_HASHED(ia
))
739 in_iahash_remove(ia
);
741 lck_rw_done(in_ifaddr_rwlock
);
744 * in_ifscrub kills the interface route.
746 in_ifscrub(ifp
, ia
, 0);
747 ifnet_lock_exclusive(ifp
);
749 /* if_detach_ifa() releases ifa_link reference */
750 if_detach_ifa(ifp
, ifa
);
751 /* Our reference to this address is dropped at the bottom */
754 /* invalidate route caches */
755 routegenid_inet_update();
758 * If the interface supports multicast, and no address is left,
759 * remove the "all hosts" multicast group from that interface.
761 if ((ifp
->if_flags
& IFF_MULTICAST
) ||
762 ifp
->if_allhostsinm
!= NULL
) {
764 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
766 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
772 ifnet_lock_done(ifp
);
774 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
775 if (ifa
== NULL
&& ifp
->if_allhostsinm
!= NULL
) {
776 struct in_multi
*inm
= ifp
->if_allhostsinm
;
777 ifp
->if_allhostsinm
= NULL
;
780 /* release the reference for allhostsinm */
783 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
785 ifnet_lock_done(ifp
);
788 /* Post the kernel event */
789 kev_post_msg(&ev_msg
);
792 * See if there is any IPV4 address left and if so,
793 * reconfigure KDP to use current primary address.
795 ifa
= ifa_ifpgetprimary(ifp
, AF_INET
);
798 * NOTE: SIOCSIFADDR is defined with struct ifreq
799 * as parameter, but here we are sending it down
800 * to the interface with a pointer to struct ifaddr,
801 * for legacy reasons.
803 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa
);
804 if (error
== EOPNOTSUPP
)
807 /* Release reference from ifa_ifpgetprimary() */
810 (void) ifnet_notify_address(ifp
, AF_INET
);
822 * Caller passes in the ioctl data pointer directly via "ifr", with the
823 * expectation that this routine always uses bcopy() or other byte-aligned
826 static __attribute__((noinline
)) int
827 inctl_ifdstaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
830 struct kev_in_data in_event_data
;
831 struct kev_msg ev_msg
;
832 struct sockaddr_in dstaddr
;
837 if (!(ifp
->if_flags
& IFF_POINTOPOINT
))
840 bzero(&in_event_data
, sizeof (struct kev_in_data
));
841 bzero(&ev_msg
, sizeof (struct kev_msg
));
844 case SIOCGIFDSTADDR
: /* struct ifreq */
846 error
= EADDRNOTAVAIL
;
849 IFA_LOCK(&ia
->ia_ifa
);
850 bcopy(&ia
->ia_dstaddr
, &ifr
->ifr_dstaddr
, sizeof (dstaddr
));
851 IFA_UNLOCK(&ia
->ia_ifa
);
854 case SIOCSIFDSTADDR
: /* struct ifreq */
856 IFA_LOCK(&ia
->ia_ifa
);
857 dstaddr
= ia
->ia_dstaddr
;
858 bcopy(&ifr
->ifr_dstaddr
, &ia
->ia_dstaddr
, sizeof (dstaddr
));
859 if (ia
->ia_dstaddr
.sin_family
== AF_INET
)
860 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
861 IFA_UNLOCK(&ia
->ia_ifa
);
863 * NOTE: SIOCSIFDSTADDR is defined with struct ifreq
864 * as parameter, but here we are sending it down
865 * to the interface with a pointer to struct ifaddr,
866 * for legacy reasons.
868 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFDSTADDR
, ia
);
869 IFA_LOCK(&ia
->ia_ifa
);
870 if (error
== EOPNOTSUPP
)
873 ia
->ia_dstaddr
= dstaddr
;
874 IFA_UNLOCK(&ia
->ia_ifa
);
877 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
879 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
880 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
881 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
883 ev_msg
.event_code
= KEV_INET_SIFDSTADDR
;
885 if (ia
->ia_ifa
.ifa_dstaddr
) {
886 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
887 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
889 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
892 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
893 in_event_data
.ia_net
= ia
->ia_net
;
894 in_event_data
.ia_netmask
= ia
->ia_netmask
;
895 in_event_data
.ia_subnet
= ia
->ia_subnet
;
896 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
897 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
898 IFA_UNLOCK(&ia
->ia_ifa
);
899 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
900 ifp
->if_name
, IFNAMSIZ
);
901 in_event_data
.link_data
.if_family
= ifp
->if_family
;
902 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
904 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
905 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
906 ev_msg
.dv
[1].data_length
= 0;
908 kev_post_msg(&ev_msg
);
910 lck_mtx_lock(rnh_lock
);
911 IFA_LOCK(&ia
->ia_ifa
);
912 if (ia
->ia_flags
& IFA_ROUTE
) {
913 ia
->ia_ifa
.ifa_dstaddr
= (struct sockaddr
*)&dstaddr
;
914 IFA_UNLOCK(&ia
->ia_ifa
);
915 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
916 IFA_LOCK(&ia
->ia_ifa
);
917 ia
->ia_ifa
.ifa_dstaddr
=
918 (struct sockaddr
*)&ia
->ia_dstaddr
;
919 IFA_UNLOCK(&ia
->ia_ifa
);
920 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
,
923 IFA_UNLOCK(&ia
->ia_ifa
);
925 lck_mtx_unlock(rnh_lock
);
939 * Caller passes in the ioctl data pointer directly via "ifr", with the
940 * expectation that this routine always uses bcopy() or other byte-aligned
943 static __attribute__((noinline
)) int
944 inctl_ifbrdaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
947 struct kev_in_data in_event_data
;
948 struct kev_msg ev_msg
;
954 return (EADDRNOTAVAIL
);
956 if (!(ifp
->if_flags
& IFF_BROADCAST
))
959 bzero(&in_event_data
, sizeof (struct kev_in_data
));
960 bzero(&ev_msg
, sizeof (struct kev_msg
));
963 case SIOCGIFBRDADDR
: /* struct ifreq */
964 IFA_LOCK(&ia
->ia_ifa
);
965 bcopy(&ia
->ia_broadaddr
, &ifr
->ifr_broadaddr
,
966 sizeof (struct sockaddr_in
));
967 IFA_UNLOCK(&ia
->ia_ifa
);
970 case SIOCSIFBRDADDR
: /* struct ifreq */
971 IFA_LOCK(&ia
->ia_ifa
);
972 bcopy(&ifr
->ifr_broadaddr
, &ia
->ia_broadaddr
,
973 sizeof (struct sockaddr_in
));
975 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
976 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
977 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
979 ev_msg
.event_code
= KEV_INET_SIFBRDADDR
;
981 if (ia
->ia_ifa
.ifa_dstaddr
) {
982 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
983 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
985 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
987 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
988 in_event_data
.ia_net
= ia
->ia_net
;
989 in_event_data
.ia_netmask
= ia
->ia_netmask
;
990 in_event_data
.ia_subnet
= ia
->ia_subnet
;
991 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
992 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
993 IFA_UNLOCK(&ia
->ia_ifa
);
994 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
995 ifp
->if_name
, IFNAMSIZ
);
996 in_event_data
.link_data
.if_family
= ifp
->if_family
;
997 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
999 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
1000 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
1001 ev_msg
.dv
[1].data_length
= 0;
1003 kev_post_msg(&ev_msg
);
1015 * Caller passes in the ioctl data pointer directly via "ifr", with the
1016 * expectation that this routine always uses bcopy() or other byte-aligned
1019 static __attribute__((noinline
)) int
1020 inctl_ifnetmask(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
1023 struct kev_in_data in_event_data
;
1024 struct kev_msg ev_msg
;
1025 struct sockaddr_in mask
;
1028 VERIFY(ifp
!= NULL
);
1030 bzero(&in_event_data
, sizeof (struct kev_in_data
));
1031 bzero(&ev_msg
, sizeof (struct kev_msg
));
1034 case SIOCGIFNETMASK
: /* struct ifreq */
1036 error
= EADDRNOTAVAIL
;
1039 IFA_LOCK(&ia
->ia_ifa
);
1040 bcopy(&ia
->ia_sockmask
, &ifr
->ifr_addr
, sizeof (mask
));
1041 IFA_UNLOCK(&ia
->ia_ifa
);
1044 case SIOCSIFNETMASK
: { /* struct ifreq */
1047 bcopy(&ifr
->ifr_addr
, &mask
, sizeof (mask
));
1048 i
= mask
.sin_addr
.s_addr
;
1051 IFA_LOCK(&ia
->ia_ifa
);
1052 ia
->ia_subnetmask
= ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
= i
);
1053 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
1054 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
1055 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
1057 ev_msg
.event_code
= KEV_INET_SIFNETMASK
;
1059 if (ia
->ia_ifa
.ifa_dstaddr
) {
1060 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
1061 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
1063 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
1065 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
1066 in_event_data
.ia_net
= ia
->ia_net
;
1067 in_event_data
.ia_netmask
= ia
->ia_netmask
;
1068 in_event_data
.ia_subnet
= ia
->ia_subnet
;
1069 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
1070 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
1071 IFA_UNLOCK(&ia
->ia_ifa
);
1072 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
1073 ifp
->if_name
, IFNAMSIZ
);
1074 in_event_data
.link_data
.if_family
= ifp
->if_family
;
1075 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
1077 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
1078 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
1079 ev_msg
.dv
[1].data_length
= 0;
1081 kev_post_msg(&ev_msg
);
1094 * Generic INET control operations (ioctl's).
1096 * ifp is NULL if not an interface-specific ioctl.
1098 * Most of the routines called to handle the ioctls would end up being
1099 * tail-call optimized, which unfortunately causes this routine to
1100 * consume too much stack space; this is the reason for the "noinline"
1101 * attribute used on those routines.
1103 * If called directly from within the networking stack (as opposed to via
1104 * pru_control), the socket parameter may be NULL.
1107 in_control(struct socket
*so
, u_long cmd
, caddr_t data
, struct ifnet
*ifp
,
1110 struct ifreq
*ifr
= (struct ifreq
*)(void *)data
;
1111 struct sockaddr_in addr
, dstaddr
;
1112 struct sockaddr_in sin
, *sa
= NULL
;
1113 boolean_t privileged
= (proc_suser(p
) == 0);
1114 boolean_t so_unlocked
= FALSE
;
1115 struct in_ifaddr
*ia
= NULL
;
1119 /* In case it's NULL, make sure it came from the kernel */
1120 VERIFY(so
!= NULL
|| p
== kernproc
);
1123 * ioctls which don't require ifp, but require socket.
1126 case SIOCGASSOCIDS32
: /* struct so_aidreq32 */
1127 case SIOCGASSOCIDS64
: /* struct so_aidreq64 */
1128 return (inctl_associd(so
, cmd
, data
));
1131 case SIOCGCONNIDS32
: /* struct so_cidreq32 */
1132 case SIOCGCONNIDS64
: /* struct so_cidreq64 */
1133 return (inctl_connid(so
, cmd
, data
));
1136 case SIOCGCONNINFO32
: /* struct so_cinforeq32 */
1137 case SIOCGCONNINFO64
: /* struct so_cinforeq64 */
1138 return (inctl_conninfo(so
, cmd
, data
));
1143 * The rest of ioctls require ifp; reject if we don't have one;
1144 * return ENXIO to be consistent with ifioctl().
1150 * ioctls which require ifp but not interface address.
1153 case SIOCAUTOADDR
: /* struct ifreq */
1156 return (inctl_autoaddr(ifp
, ifr
));
1159 case SIOCARPIPLL
: /* struct ifreq */
1162 return (inctl_arpipll(ifp
, ifr
));
1165 case SIOCSETROUTERMODE
: /* struct ifreq */
1168 return (inctl_setrouter(ifp
, ifr
));
1171 case SIOCPROTOATTACH
: /* struct ifreq */
1174 return (in_domifattach(ifp
));
1177 case SIOCPROTODETACH
: /* struct ifreq */
1182 * If an IPv4 address is still present, refuse to detach.
1184 ifnet_lock_shared(ifp
);
1185 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1187 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
1193 ifnet_lock_done(ifp
);
1194 return ((ifa
== NULL
) ? proto_unplumb(PF_INET
, ifp
) : EBUSY
);
1199 * ioctls which require interface address; obtain sockaddr_in.
1202 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1205 bcopy(&((struct in_aliasreq
*)(void *)data
)->ifra_addr
,
1206 &sin
, sizeof (sin
));
1210 case SIOCDIFADDR
: /* struct ifreq */
1211 case SIOCSIFADDR
: /* struct ifreq */
1212 case SIOCSIFDSTADDR
: /* struct ifreq */
1213 case SIOCSIFNETMASK
: /* struct ifreq */
1214 case SIOCSIFBRDADDR
: /* struct ifreq */
1218 case SIOCGIFADDR
: /* struct ifreq */
1219 case SIOCGIFDSTADDR
: /* struct ifreq */
1220 case SIOCGIFNETMASK
: /* struct ifreq */
1221 case SIOCGIFBRDADDR
: /* struct ifreq */
1222 bcopy(&ifr
->ifr_addr
, &sin
, sizeof (sin
));
1228 * Find address for this interface, if it exists.
1230 * If an alias address was specified, find that one instead of
1231 * the first one on the interface, if possible.
1235 struct in_ifaddr
*iap
;
1238 * Any failures from this point on must take into account
1239 * a non-NULL "ia" with an outstanding reference count, and
1240 * therefore requires IFA_REMREF. Jump to "done" label
1241 * instead of calling return if "ia" is valid.
1243 lck_rw_lock_shared(in_ifaddr_rwlock
);
1244 TAILQ_FOREACH(iap
, INADDR_HASH(sa
->sin_addr
.s_addr
), ia_hash
) {
1245 IFA_LOCK(&iap
->ia_ifa
);
1246 if (iap
->ia_ifp
== ifp
&&
1247 iap
->ia_addr
.sin_addr
.s_addr
==
1248 sa
->sin_addr
.s_addr
) {
1250 IFA_UNLOCK(&iap
->ia_ifa
);
1253 IFA_UNLOCK(&iap
->ia_ifa
);
1255 /* take a reference on ia before releasing lock */
1257 IFA_ADDREF(&ia
->ia_ifa
);
1258 lck_rw_done(in_ifaddr_rwlock
);
1261 ifnet_lock_shared(ifp
);
1262 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1264 IFA_LOCK(&iap
->ia_ifa
);
1265 if (iap
->ia_addr
.sin_family
== AF_INET
) {
1267 IFA_UNLOCK(&iap
->ia_ifa
);
1270 IFA_UNLOCK(&iap
->ia_ifa
);
1272 /* take a reference on ia before releasing lock */
1274 IFA_ADDREF(&ia
->ia_ifa
);
1275 ifnet_lock_done(ifp
);
1280 * Unlock the socket since ifnet_ioctl() may be invoked by
1281 * one of the ioctl handlers below. Socket will be re-locked
1282 * prior to returning.
1285 socket_unlock(so
, 0);
1290 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1291 case SIOCDIFADDR
: /* struct ifreq */
1292 if (cmd
== SIOCAIFADDR
) {
1293 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1294 ifra_addr
, &addr
, sizeof (addr
));
1295 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1296 ifra_dstaddr
, &dstaddr
, sizeof (dstaddr
));
1298 VERIFY(cmd
== SIOCDIFADDR
);
1299 bcopy(&((struct ifreq
*)(void *)data
)->ifr_addr
,
1300 &addr
, sizeof (addr
));
1301 bzero(&dstaddr
, sizeof (dstaddr
));
1304 if (addr
.sin_family
== AF_INET
) {
1305 struct in_ifaddr
*oia
;
1307 lck_rw_lock_shared(in_ifaddr_rwlock
);
1308 for (oia
= ia
; ia
; ia
= ia
->ia_link
.tqe_next
) {
1309 IFA_LOCK(&ia
->ia_ifa
);
1310 if (ia
->ia_ifp
== ifp
&&
1311 ia
->ia_addr
.sin_addr
.s_addr
==
1312 addr
.sin_addr
.s_addr
) {
1313 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1314 IFA_UNLOCK(&ia
->ia_ifa
);
1317 IFA_UNLOCK(&ia
->ia_ifa
);
1319 lck_rw_done(in_ifaddr_rwlock
);
1321 IFA_REMREF(&oia
->ia_ifa
);
1322 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
1323 (cmd
== SIOCAIFADDR
) &&
1324 (dstaddr
.sin_addr
.s_addr
== INADDR_ANY
)) {
1325 error
= EDESTADDRREQ
;
1328 } else if (cmd
== SIOCAIFADDR
) {
1332 if (cmd
== SIOCDIFADDR
&& ia
== NULL
) {
1333 error
= EADDRNOTAVAIL
;
1337 case SIOCSIFADDR
: /* struct ifreq */
1338 case SIOCSIFDSTADDR
: /* struct ifreq */
1339 case SIOCSIFNETMASK
: /* struct ifreq */
1340 if (cmd
== SIOCAIFADDR
) {
1341 /* fell thru from above; just repeat it */
1342 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1343 ifra_addr
, &addr
, sizeof (addr
));
1345 VERIFY(cmd
== SIOCDIFADDR
|| cmd
== SIOCSIFADDR
||
1346 cmd
== SIOCSIFNETMASK
|| cmd
== SIOCSIFDSTADDR
);
1347 bcopy(&((struct ifreq
*)(void *)data
)->ifr_addr
,
1348 &addr
, sizeof (addr
));
1351 if (addr
.sin_family
!= AF_INET
&& cmd
== SIOCSIFADDR
) {
1356 ia
= in_ifaddr_alloc(M_WAITOK
);
1361 ifnet_lock_exclusive(ifp
);
1364 /* Hold a reference for this routine */
1365 IFA_ADDREF_LOCKED(ifa
);
1367 ifa
->ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1368 ifa
->ifa_dstaddr
= (struct sockaddr
*)&ia
->ia_dstaddr
;
1369 ifa
->ifa_netmask
= (struct sockaddr
*)&ia
->ia_sockmask
;
1370 ia
->ia_sockmask
.sin_len
= 8;
1371 if (ifp
->if_flags
& IFF_BROADCAST
) {
1372 ia
->ia_broadaddr
.sin_len
= sizeof (ia
->ia_addr
);
1373 ia
->ia_broadaddr
.sin_family
= AF_INET
;
1376 if (!(ifp
->if_flags
& IFF_LOOPBACK
))
1378 /* if_attach_ifa() holds a reference for ifa_link */
1379 if_attach_ifa(ifp
, ifa
);
1381 * If we have to go through in_ifinit(), make sure
1382 * to avoid installing route(s) based on this address
1383 * via PFC_IFUP event, before the link resolver (ARP)
1386 if (cmd
== SIOCAIFADDR
|| cmd
== SIOCSIFADDR
)
1387 ifa
->ifa_debug
|= IFD_NOTREADY
;
1389 ifnet_lock_done(ifp
);
1390 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1391 /* Hold a reference for ia_link */
1393 TAILQ_INSERT_TAIL(&in_ifaddrhead
, ia
, ia_link
);
1394 lck_rw_done(in_ifaddr_rwlock
);
1396 (void) in_domifattach(ifp
);
1403 case SIOCGIFDSTADDR
: /* struct ifreq */
1404 case SIOCSIFDSTADDR
: /* struct ifreq */
1405 error
= inctl_ifdstaddr(ifp
, ia
, cmd
, ifr
);
1408 case SIOCGIFBRDADDR
: /* struct ifreq */
1409 case SIOCSIFBRDADDR
: /* struct ifreq */
1410 error
= inctl_ifbrdaddr(ifp
, ia
, cmd
, ifr
);
1413 case SIOCGIFNETMASK
: /* struct ifreq */
1414 case SIOCSIFNETMASK
: /* struct ifreq */
1415 error
= inctl_ifnetmask(ifp
, ia
, cmd
, ifr
);
1418 case SIOCGIFADDR
: /* struct ifreq */
1419 case SIOCSIFADDR
: /* struct ifreq */
1420 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1421 case SIOCDIFADDR
: /* struct ifreq */
1422 error
= inctl_ifaddr(ifp
, ia
, cmd
, ifr
);
1431 IFA_REMREF(&ia
->ia_ifa
);
1439 * Delete any existing route for an interface.
1442 in_ifscrub(struct ifnet
*ifp
, struct in_ifaddr
*ia
, int locked
)
1444 IFA_LOCK(&ia
->ia_ifa
);
1445 if ((ia
->ia_flags
& IFA_ROUTE
) == 0) {
1446 IFA_UNLOCK(&ia
->ia_ifa
);
1449 IFA_UNLOCK(&ia
->ia_ifa
);
1451 lck_mtx_lock(rnh_lock
);
1452 if (ifp
->if_flags
& (IFF_LOOPBACK
|IFF_POINTOPOINT
))
1453 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
1455 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, 0);
1456 IFA_LOCK(&ia
->ia_ifa
);
1457 ia
->ia_flags
&= ~IFA_ROUTE
;
1458 IFA_UNLOCK(&ia
->ia_ifa
);
1460 lck_mtx_unlock(rnh_lock
);
1464 * Caller must hold in_ifaddr_rwlock as writer.
1467 in_iahash_remove(struct in_ifaddr
*ia
)
1469 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1470 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1472 if (!IA_IS_HASHED(ia
)) {
1473 panic("attempt to remove wrong ia %p from hash table\n", ia
);
1476 TAILQ_REMOVE(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), ia
, ia_hash
);
1478 if (IFA_REMREF_LOCKED(&ia
->ia_ifa
) == NULL
) {
1479 panic("%s: unexpected (missing) refcnt ifa=%p", __func__
,
1486 * Caller must hold in_ifaddr_rwlock as writer.
1489 in_iahash_insert(struct in_ifaddr
*ia
)
1491 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1492 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1494 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1495 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1497 } else if (IA_IS_HASHED(ia
)) {
1498 panic("attempt to double-insert ia %p into hash table\n", ia
);
1501 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1503 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1507 * Some point to point interfaces that are tunnels borrow the address from
1508 * an underlying interface (e.g. VPN server). In order for source address
1509 * selection logic to find the underlying interface first, we add the address
1510 * of borrowing point to point interfaces at the end of the list.
1511 * (see rdar://6733789)
1513 * Caller must hold in_ifaddr_rwlock as writer.
1516 in_iahash_insert_ptp(struct in_ifaddr
*ia
)
1518 struct in_ifaddr
*tmp_ifa
;
1519 struct ifnet
*tmp_ifp
;
1521 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1522 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1524 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1525 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1527 } else if (IA_IS_HASHED(ia
)) {
1528 panic("attempt to double-insert ia %p into hash table\n", ia
);
1531 IFA_UNLOCK(&ia
->ia_ifa
);
1532 TAILQ_FOREACH(tmp_ifa
, INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1534 IFA_LOCK(&tmp_ifa
->ia_ifa
);
1535 /* ia->ia_addr won't change, so check without lock */
1536 if (IA_SIN(tmp_ifa
)->sin_addr
.s_addr
==
1537 ia
->ia_addr
.sin_addr
.s_addr
) {
1538 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1541 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1543 tmp_ifp
= (tmp_ifa
== NULL
) ? NULL
: tmp_ifa
->ia_ifp
;
1545 IFA_LOCK(&ia
->ia_ifa
);
1546 if (tmp_ifp
== NULL
) {
1547 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1550 TAILQ_INSERT_TAIL(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1553 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1557 * Initialize an interface's internet address
1558 * and routing table entry.
1561 in_ifinit(struct ifnet
*ifp
, struct in_ifaddr
*ia
, struct sockaddr_in
*sin
,
1564 u_int32_t i
= ntohl(sin
->sin_addr
.s_addr
);
1565 struct sockaddr_in oldaddr
;
1566 int flags
= RTF_UP
, error
;
1567 struct ifaddr
*ifa0
;
1571 /* Take an extra reference for this routine */
1572 IFA_ADDREF(&ia
->ia_ifa
);
1574 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1575 IFA_LOCK(&ia
->ia_ifa
);
1576 oldaddr
= ia
->ia_addr
;
1577 if (IA_IS_HASHED(ia
)) {
1579 in_iahash_remove(ia
);
1583 * Interface addresses should not contain port or sin_zero information.
1585 SIN(&ia
->ia_addr
)->sin_family
= AF_INET
;
1586 SIN(&ia
->ia_addr
)->sin_len
= sizeof (struct sockaddr_in
);
1587 SIN(&ia
->ia_addr
)->sin_port
= 0;
1588 bzero(&SIN(&ia
->ia_addr
)->sin_zero
, sizeof (sin
->sin_zero
));
1589 if ((ifp
->if_flags
& IFF_POINTOPOINT
))
1590 in_iahash_insert_ptp(ia
);
1592 in_iahash_insert(ia
);
1593 IFA_UNLOCK(&ia
->ia_ifa
);
1594 lck_rw_done(in_ifaddr_rwlock
);
1597 * Give the interface a chance to initialize if this is its first
1598 * address, and to validate the address if necessary. Send down
1599 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es).
1600 * We find the first IPV4 address assigned to it and check if this
1601 * is the same as the one passed into this routine.
1603 ifa0
= ifa_ifpgetprimary(ifp
, AF_INET
);
1604 cmd
= (&ia
->ia_ifa
== ifa0
) ? SIOCSIFADDR
: SIOCAIFADDR
;
1605 error
= ifnet_ioctl(ifp
, PF_INET
, cmd
, ia
);
1606 if (error
== EOPNOTSUPP
)
1609 * If we've just sent down SIOCAIFADDR, send another ioctl down
1610 * for SIOCSIFADDR for the first IPV4 address of the interface,
1611 * because an address change on one of the addresses will result
1612 * in the removal of the previous first IPV4 address. KDP needs
1613 * be reconfigured with the current primary IPV4 address.
1615 if (error
== 0 && cmd
== SIOCAIFADDR
) {
1617 * NOTE: SIOCSIFADDR is defined with struct ifreq
1618 * as parameter, but here we are sending it down
1619 * to the interface with a pointer to struct ifaddr,
1620 * for legacy reasons.
1622 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa0
);
1623 if (error
== EOPNOTSUPP
)
1627 /* Release reference from ifa_ifpgetprimary() */
1631 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1632 IFA_LOCK(&ia
->ia_ifa
);
1633 if (IA_IS_HASHED(ia
))
1634 in_iahash_remove(ia
);
1635 ia
->ia_addr
= oldaddr
;
1637 if ((ifp
->if_flags
& IFF_POINTOPOINT
))
1638 in_iahash_insert_ptp(ia
);
1640 in_iahash_insert(ia
);
1642 IFA_UNLOCK(&ia
->ia_ifa
);
1643 lck_rw_done(in_ifaddr_rwlock
);
1644 /* Release extra reference taken above */
1645 IFA_REMREF(&ia
->ia_ifa
);
1648 lck_mtx_lock(rnh_lock
);
1649 IFA_LOCK(&ia
->ia_ifa
);
1651 * Address has been initialized by the link resolver (ARP)
1652 * via ifnet_ioctl() above; it may now generate route(s).
1654 ia
->ia_ifa
.ifa_debug
&= ~IFD_NOTREADY
;
1656 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&oldaddr
;
1657 IFA_UNLOCK(&ia
->ia_ifa
);
1658 in_ifscrub(ifp
, ia
, 1);
1659 IFA_LOCK(&ia
->ia_ifa
);
1660 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1662 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1664 ia
->ia_netmask
= IN_CLASSA_NET
;
1665 else if (IN_CLASSB(i
))
1666 ia
->ia_netmask
= IN_CLASSB_NET
;
1668 ia
->ia_netmask
= IN_CLASSC_NET
;
1670 * The subnet mask usually includes at least the standard network part,
1671 * but may may be smaller in the case of supernetting.
1672 * If it is set, we believe it.
1674 if (ia
->ia_subnetmask
== 0) {
1675 ia
->ia_subnetmask
= ia
->ia_netmask
;
1676 ia
->ia_sockmask
.sin_addr
.s_addr
= htonl(ia
->ia_subnetmask
);
1678 ia
->ia_netmask
&= ia
->ia_subnetmask
;
1679 ia
->ia_net
= i
& ia
->ia_netmask
;
1680 ia
->ia_subnet
= i
& ia
->ia_subnetmask
;
1681 in_socktrim(&ia
->ia_sockmask
);
1683 * Add route for the network.
1685 ia
->ia_ifa
.ifa_metric
= ifp
->if_metric
;
1686 if (ifp
->if_flags
& IFF_BROADCAST
) {
1687 ia
->ia_broadaddr
.sin_addr
.s_addr
=
1688 htonl(ia
->ia_subnet
| ~ia
->ia_subnetmask
);
1689 ia
->ia_netbroadcast
.s_addr
=
1690 htonl(ia
->ia_net
| ~ ia
->ia_netmask
);
1691 } else if (ifp
->if_flags
& IFF_LOOPBACK
) {
1692 ia
->ia_ifa
.ifa_dstaddr
= ia
->ia_ifa
.ifa_addr
;
1694 } else if (ifp
->if_flags
& IFF_POINTOPOINT
) {
1695 if (ia
->ia_dstaddr
.sin_family
!= AF_INET
) {
1696 IFA_UNLOCK(&ia
->ia_ifa
);
1697 lck_mtx_unlock(rnh_lock
);
1698 /* Release extra reference taken above */
1699 IFA_REMREF(&ia
->ia_ifa
);
1702 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
1705 IFA_UNLOCK(&ia
->ia_ifa
);
1707 if ((error
= rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
, flags
)) == 0) {
1708 IFA_LOCK(&ia
->ia_ifa
);
1709 ia
->ia_flags
|= IFA_ROUTE
;
1710 IFA_UNLOCK(&ia
->ia_ifa
);
1712 lck_mtx_unlock(rnh_lock
);
1714 /* XXX check if the subnet route points to the same interface */
1715 if (error
== EEXIST
)
1719 * If the interface supports multicast, join the "all hosts"
1720 * multicast group on that interface.
1722 if (ifp
->if_flags
& IFF_MULTICAST
) {
1723 struct in_addr addr
;
1725 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
1726 addr
.s_addr
= htonl(INADDR_ALLHOSTS_GROUP
);
1727 if (ifp
->if_allhostsinm
== NULL
) {
1728 struct in_multi
*inm
;
1729 inm
= in_addmulti(&addr
, ifp
);
1733 * Keep the reference on inm added by
1734 * in_addmulti above for storing the
1735 * pointer in allhostsinm.
1737 ifp
->if_allhostsinm
= inm
;
1739 printf("%s: failed to add membership to "
1740 "all-hosts multicast address on %s\n",
1741 __func__
, if_name(ifp
));
1744 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
1747 /* Release extra reference taken above */
1748 IFA_REMREF(&ia
->ia_ifa
);
1751 /* invalidate route caches */
1752 routegenid_inet_update();
1759 * Return TRUE if the address might be a local broadcast address.
1762 in_broadcast(struct in_addr in
, struct ifnet
*ifp
)
1767 if (in
.s_addr
== INADDR_BROADCAST
|| in
.s_addr
== INADDR_ANY
)
1769 if (!(ifp
->if_flags
& IFF_BROADCAST
))
1771 t
= ntohl(in
.s_addr
);
1774 * Look through the list of addresses for a match
1775 * with a broadcast address.
1777 #define ia ((struct in_ifaddr *)ifa)
1778 ifnet_lock_shared(ifp
);
1779 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1781 if (ifa
->ifa_addr
->sa_family
== AF_INET
&&
1782 (in
.s_addr
== ia
->ia_broadaddr
.sin_addr
.s_addr
||
1783 in
.s_addr
== ia
->ia_netbroadcast
.s_addr
||
1785 * Check for old-style (host 0) broadcast.
1787 t
== ia
->ia_subnet
|| t
== ia
->ia_net
) &&
1789 * Check for an all one subnetmask. These
1790 * only exist when an interface gets a secondary
1793 ia
->ia_subnetmask
!= (u_int32_t
)0xffffffff) {
1795 ifnet_lock_done(ifp
);
1800 ifnet_lock_done(ifp
);
1806 in_purgeaddrs(struct ifnet
*ifp
)
1808 struct ifaddr
**ifap
;
1811 VERIFY(ifp
!= NULL
);
1814 * Be nice, and try the civilized way first. If we can't get
1815 * rid of them this way, then do it the rough way. We must
1816 * only get here during detach time, after the ifnet has been
1817 * removed from the global list and arrays.
1819 err
= ifnet_get_address_list_family_internal(ifp
, &ifap
, AF_INET
, 1,
1821 if (err
== 0 && ifap
!= NULL
) {
1824 bzero(&ifr
, sizeof (ifr
));
1825 (void) snprintf(ifr
.ifr_name
, sizeof (ifr
.ifr_name
),
1826 "%s", if_name(ifp
));
1828 for (i
= 0; ifap
[i
] != NULL
; i
++) {
1833 bcopy(ifa
->ifa_addr
, &ifr
.ifr_addr
,
1834 sizeof (struct sockaddr_in
));
1836 err
= in_control(NULL
, SIOCDIFADDR
, (caddr_t
)&ifr
, ifp
,
1838 /* if we lost the race, ignore it */
1839 if (err
== EADDRNOTAVAIL
)
1842 char s_addr
[MAX_IPv4_STR_LEN
];
1843 char s_dstaddr
[MAX_IPv4_STR_LEN
];
1844 struct in_addr
*s
, *d
;
1847 s
= &((struct sockaddr_in
*)
1848 (void *)ifa
->ifa_addr
)->sin_addr
;
1849 d
= &((struct sockaddr_in
*)
1850 (void *)ifa
->ifa_dstaddr
)->sin_addr
;
1851 (void) inet_ntop(AF_INET
, &s
->s_addr
, s_addr
,
1853 (void) inet_ntop(AF_INET
, &d
->s_addr
, s_dstaddr
,
1854 sizeof (s_dstaddr
));
1857 printf("%s: SIOCDIFADDR ifp=%s ifa_addr=%s "
1858 "ifa_dstaddr=%s (err=%d)\n", __func__
,
1859 ifp
->if_xname
, s_addr
, s_dstaddr
, err
);
1862 ifnet_free_address_list(ifap
);
1863 } else if (err
!= 0 && err
!= ENXIO
) {
1864 printf("%s: error retrieving list of AF_INET addresses for "
1865 "ifp=%s (err=%d)\n", __func__
, ifp
->if_xname
, err
);
1870 * Select endpoint address(es). For now just take the first matching
1871 * address and discard the rest, if present.
1874 in_selectaddrs(int af
, struct sockaddr_list
**src_sl
,
1875 struct sockaddr_entry
**src_se
, struct sockaddr_list
**dst_sl
,
1876 struct sockaddr_entry
**dst_se
)
1878 struct sockaddr_entry
*se
;
1881 VERIFY(src_sl
!= NULL
&& dst_sl
!= NULL
&& *dst_sl
!= NULL
);
1882 VERIFY(src_se
!= NULL
&& dst_se
!= NULL
);
1884 *src_se
= *dst_se
= NULL
;
1886 /* pick a source address, if available */
1887 if (*src_sl
!= NULL
) {
1888 TAILQ_FOREACH(se
, &(*src_sl
)->sl_head
, se_link
) {
1889 VERIFY(se
->se_addr
!= NULL
);
1891 * Take the first source address, or the first
1892 * one with matching address family.
1894 if (af
== AF_UNSPEC
|| se
->se_addr
->sa_family
== af
) {
1895 sockaddrlist_remove(*src_sl
, se
);
1900 /* get rid of the rest */
1901 TAILQ_FOREACH(se
, &(*src_sl
)->sl_head
, se_link
) {
1902 sockaddrlist_remove(*src_sl
, se
);
1903 sockaddrentry_free(se
);
1905 if (*src_se
!= NULL
) {
1906 /* insert the first src address back in */
1907 sockaddrlist_insert(*src_sl
, *src_se
);
1908 VERIFY((*src_sl
)->sl_cnt
== 1);
1909 /* destination address must be of this family */
1910 af
= (*src_se
)->se_addr
->sa_family
;
1912 /* no usable source address with matching family */
1913 VERIFY(af
!= AF_UNSPEC
);
1914 error
= EAFNOSUPPORT
;
1918 /* pick a (matching) destination address */
1919 TAILQ_FOREACH(se
, &(*dst_sl
)->sl_head
, se_link
) {
1920 VERIFY(se
->se_addr
!= NULL
);
1922 * Take the first destination address; if source is specified,
1923 * find one which uses the same address family.
1925 if (af
== AF_UNSPEC
|| se
->se_addr
->sa_family
== af
) {
1926 sockaddrlist_remove(*dst_sl
, se
);
1931 /* get rid of the rest */
1932 TAILQ_FOREACH(se
, &(*dst_sl
)->sl_head
, se_link
) {
1933 sockaddrlist_remove(*dst_sl
, se
);
1934 sockaddrentry_free(se
);
1936 if (*dst_se
!= NULL
) {
1937 /* insert the first dst address back in */
1938 sockaddrlist_insert(*dst_sl
, *dst_se
);
1939 VERIFY((*dst_sl
)->sl_cnt
== 1);
1941 /* source and destination address families don't match */
1942 error
= EAFNOSUPPORT
;
1946 af
= (*dst_se
)->se_addr
->sa_family
;
1947 VERIFY(*src_se
== NULL
|| (*src_se
)->se_addr
->sa_family
== af
);
1949 /* verify address length */
1952 if ((*dst_se
)->se_addr
->sa_len
!=
1953 sizeof (struct sockaddr_in
)) {
1954 error
= EAFNOSUPPORT
;
1960 if ((*dst_se
)->se_addr
->sa_len
!=
1961 sizeof (struct sockaddr_in6
)) {
1962 error
= EAFNOSUPPORT
;
1968 error
= EAFNOSUPPORT
;
1972 /* if source address is specified, length must match destination */
1973 if (*src_se
!= NULL
&& (*src_se
)->se_addr
->sa_len
!=
1974 (*dst_se
)->se_addr
->sa_len
) {
1975 error
= EAFNOSUPPORT
;
1983 * Called as part of ip_init
1986 in_ifaddr_init(void)
1990 PE_parse_boot_argn("ifa_debug", &inifa_debug
, sizeof (inifa_debug
));
1992 inifa_size
= (inifa_debug
== 0) ? sizeof (struct in_ifaddr
) :
1993 sizeof (struct in_ifaddr_dbg
);
1995 inifa_zone
= zinit(inifa_size
, INIFA_ZONE_MAX
* inifa_size
,
1996 0, INIFA_ZONE_NAME
);
1997 if (inifa_zone
== NULL
) {
1998 panic("%s: failed allocating %s", __func__
, INIFA_ZONE_NAME
);
2001 zone_change(inifa_zone
, Z_EXPAND
, TRUE
);
2002 zone_change(inifa_zone
, Z_CALLERACCT
, FALSE
);
2004 lck_mtx_init(&inifa_trash_lock
, ifa_mtx_grp
, ifa_mtx_attr
);
2005 TAILQ_INIT(&inifa_trash_head
);
2008 static struct in_ifaddr
*
2009 in_ifaddr_alloc(int how
)
2011 struct in_ifaddr
*inifa
;
2013 inifa
= (how
== M_WAITOK
) ? zalloc(inifa_zone
) :
2014 zalloc_noblock(inifa_zone
);
2015 if (inifa
!= NULL
) {
2016 bzero(inifa
, inifa_size
);
2017 inifa
->ia_ifa
.ifa_free
= in_ifaddr_free
;
2018 inifa
->ia_ifa
.ifa_debug
|= IFD_ALLOC
;
2019 ifa_lock_init(&inifa
->ia_ifa
);
2020 if (inifa_debug
!= 0) {
2021 struct in_ifaddr_dbg
*inifa_dbg
=
2022 (struct in_ifaddr_dbg
*)inifa
;
2023 inifa
->ia_ifa
.ifa_debug
|= IFD_DEBUG
;
2024 inifa
->ia_ifa
.ifa_trace
= in_ifaddr_trace
;
2025 inifa
->ia_ifa
.ifa_attached
= in_ifaddr_attached
;
2026 inifa
->ia_ifa
.ifa_detached
= in_ifaddr_detached
;
2027 ctrace_record(&inifa_dbg
->inifa_alloc
);
2034 in_ifaddr_free(struct ifaddr
*ifa
)
2036 IFA_LOCK_ASSERT_HELD(ifa
);
2038 if (ifa
->ifa_refcnt
!= 0) {
2039 panic("%s: ifa %p bad ref cnt", __func__
, ifa
);
2041 } if (!(ifa
->ifa_debug
& IFD_ALLOC
)) {
2042 panic("%s: ifa %p cannot be freed", __func__
, ifa
);
2045 if (ifa
->ifa_debug
& IFD_DEBUG
) {
2046 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2047 ctrace_record(&inifa_dbg
->inifa_free
);
2048 bcopy(&inifa_dbg
->inifa
, &inifa_dbg
->inifa_old
,
2049 sizeof (struct in_ifaddr
));
2050 if (ifa
->ifa_debug
& IFD_TRASHED
) {
2051 /* Become a regular mutex, just in case */
2052 IFA_CONVERT_LOCK(ifa
);
2053 lck_mtx_lock(&inifa_trash_lock
);
2054 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
,
2056 lck_mtx_unlock(&inifa_trash_lock
);
2057 ifa
->ifa_debug
&= ~IFD_TRASHED
;
2061 ifa_lock_destroy(ifa
);
2062 bzero(ifa
, sizeof (struct in_ifaddr
));
2063 zfree(inifa_zone
, ifa
);
2067 in_ifaddr_attached(struct ifaddr
*ifa
)
2069 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2071 IFA_LOCK_ASSERT_HELD(ifa
);
2073 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2074 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2077 if (ifa
->ifa_debug
& IFD_TRASHED
) {
2078 /* Become a regular mutex, just in case */
2079 IFA_CONVERT_LOCK(ifa
);
2080 lck_mtx_lock(&inifa_trash_lock
);
2081 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
2082 lck_mtx_unlock(&inifa_trash_lock
);
2083 ifa
->ifa_debug
&= ~IFD_TRASHED
;
2088 in_ifaddr_detached(struct ifaddr
*ifa
)
2090 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2092 IFA_LOCK_ASSERT_HELD(ifa
);
2094 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2095 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2097 } else if (ifa
->ifa_debug
& IFD_TRASHED
) {
2098 panic("%s: ifa %p is already in trash list", __func__
, ifa
);
2101 ifa
->ifa_debug
|= IFD_TRASHED
;
2102 /* Become a regular mutex, just in case */
2103 IFA_CONVERT_LOCK(ifa
);
2104 lck_mtx_lock(&inifa_trash_lock
);
2105 TAILQ_INSERT_TAIL(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
2106 lck_mtx_unlock(&inifa_trash_lock
);
2110 in_ifaddr_trace(struct ifaddr
*ifa
, int refhold
)
2112 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2117 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2118 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2122 cnt
= &inifa_dbg
->inifa_refhold_cnt
;
2123 tr
= inifa_dbg
->inifa_refhold
;
2125 cnt
= &inifa_dbg
->inifa_refrele_cnt
;
2126 tr
= inifa_dbg
->inifa_refrele
;
2129 idx
= atomic_add_16_ov(cnt
, 1) % INIFA_TRACE_HIST_SIZE
;
2130 ctrace_record(&tr
[idx
]);
2134 * Handle SIOCGASSOCIDS ioctl for PF_INET domain.
2137 in_getassocids(struct socket
*so
, uint32_t *cnt
, user_addr_t aidp
)
2139 struct inpcb
*inp
= sotoinpcb(so
);
2142 if (inp
== NULL
|| inp
->inp_state
== INPCB_STATE_DEAD
)
2145 /* INPCB has no concept of association */
2149 /* just asking how many there are? */
2150 if (aidp
== USER_ADDR_NULL
)
2153 return (copyout(&aid
, aidp
, sizeof (aid
)));
2157 * Handle SIOCGCONNIDS ioctl for PF_INET domain.
2160 in_getconnids(struct socket
*so
, associd_t aid
, uint32_t *cnt
,
2163 struct inpcb
*inp
= sotoinpcb(so
);
2166 if (inp
== NULL
|| inp
->inp_state
== INPCB_STATE_DEAD
)
2169 if (aid
!= ASSOCID_ANY
&& aid
!= ASSOCID_ALL
)
2172 /* if connected, return 1 connection count */
2173 *cnt
= ((so
->so_state
& SS_ISCONNECTED
) ? 1 : 0);
2175 /* just asking how many there are? */
2176 if (cidp
== USER_ADDR_NULL
)
2179 /* if INPCB is connected, assign it connid 1 */
2180 cid
= ((*cnt
!= 0) ? 1 : CONNID_ANY
);
2182 return (copyout(&cid
, cidp
, sizeof (cid
)));
2186 * Handle SIOCGCONNINFO ioctl for PF_INET domain.
2189 in_getconninfo(struct socket
*so
, connid_t cid
, uint32_t *flags
,
2190 uint32_t *ifindex
, int32_t *soerror
, user_addr_t src
, socklen_t
*src_len
,
2191 user_addr_t dst
, socklen_t
*dst_len
, uint32_t *aux_type
,
2192 user_addr_t aux_data
, uint32_t *aux_len
)
2194 #pragma unused(aux_data)
2195 struct inpcb
*inp
= sotoinpcb(so
);
2196 struct sockaddr_in sin
;
2197 struct ifnet
*ifp
= NULL
;
2199 u_int32_t copy_len
= 0;
2202 * Don't test for INPCB_STATE_DEAD since this may be called
2203 * after SOF_PCBCLEARING is set, e.g. after tcp_close().
2210 if (cid
!= CONNID_ANY
&& cid
!= CONNID_ALL
&& cid
!= 1) {
2215 ifp
= inp
->inp_last_outifp
;
2216 *ifindex
= ((ifp
!= NULL
) ? ifp
->if_index
: 0);
2217 *soerror
= so
->so_error
;
2219 if (so
->so_state
& SS_ISCONNECTED
)
2220 *flags
|= (CIF_CONNECTED
| CIF_PREFERRED
);
2221 if (inp
->inp_flags
& INP_BOUND_IF
)
2222 *flags
|= CIF_BOUND_IF
;
2223 if (!(inp
->inp_flags
& INP_INADDR_ANY
))
2224 *flags
|= CIF_BOUND_IP
;
2225 if (!(inp
->inp_flags
& INP_ANONPORT
))
2226 *flags
|= CIF_BOUND_PORT
;
2228 bzero(&sin
, sizeof (sin
));
2229 sin
.sin_len
= sizeof (sin
);
2230 sin
.sin_family
= AF_INET
;
2232 /* source address and port */
2233 sin
.sin_port
= inp
->inp_lport
;
2234 sin
.sin_addr
.s_addr
= inp
->inp_laddr
.s_addr
;
2235 if (*src_len
== 0) {
2236 *src_len
= sin
.sin_len
;
2238 if (src
!= USER_ADDR_NULL
) {
2239 copy_len
= min(*src_len
, sizeof (sin
));
2240 error
= copyout(&sin
, src
, copy_len
);
2243 *src_len
= copy_len
;
2247 /* destination address and port */
2248 sin
.sin_port
= inp
->inp_fport
;
2249 sin
.sin_addr
.s_addr
= inp
->inp_faddr
.s_addr
;
2250 if (*dst_len
== 0) {
2251 *dst_len
= sin
.sin_len
;
2253 if (dst
!= USER_ADDR_NULL
) {
2254 copy_len
= min(*dst_len
, sizeof (sin
));
2255 error
= copyout(&sin
, dst
, copy_len
);
2258 *dst_len
= copy_len
;
2264 if (SOCK_PROTO(so
) == IPPROTO_TCP
) {
2265 struct conninfo_tcp tcp_ci
;
2267 *aux_type
= CIAUX_TCP
;
2268 if (*aux_len
== 0) {
2269 *aux_len
= sizeof (tcp_ci
);
2271 if (aux_data
!= USER_ADDR_NULL
) {
2272 copy_len
= min(*aux_len
, sizeof (tcp_ci
));
2273 bzero(&tcp_ci
, sizeof (tcp_ci
));
2274 tcp_getconninfo(so
, &tcp_ci
);
2275 error
= copyout(&tcp_ci
, aux_data
, copy_len
);
2278 *aux_len
= copy_len
;