2 * Copyright (c) 2000-2013 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_lifaddr(struct ifnet
*, u_long
, struct if_laddrreq
*);
108 static int inctl_ifdstaddr(struct ifnet
*, struct in_ifaddr
*, u_long
,
110 static int inctl_ifbrdaddr(struct ifnet
*, struct in_ifaddr
*, u_long
,
112 static int inctl_ifnetmask(struct ifnet
*, struct in_ifaddr
*, u_long
,
115 static int in_mask2len(struct in_addr
*);
116 static void in_len2mask(struct in_addr
*, int);
117 static void in_socktrim(struct sockaddr_in
*);
118 static int in_ifinit(struct ifnet
*, struct in_ifaddr
*,
119 struct sockaddr_in
*, int);
121 #define IA_HASH_INIT(ia) { \
122 (ia)->ia_hash.tqe_next = (void *)(uintptr_t)-1; \
123 (ia)->ia_hash.tqe_prev = (void *)(uintptr_t)-1; \
126 #define IA_IS_HASHED(ia) \
127 (!((ia)->ia_hash.tqe_next == (void *)(uintptr_t)-1 || \
128 (ia)->ia_hash.tqe_prev == (void *)(uintptr_t)-1))
130 static void in_iahash_remove(struct in_ifaddr
*);
131 static void in_iahash_insert(struct in_ifaddr
*);
132 static void in_iahash_insert_ptp(struct in_ifaddr
*);
133 static struct in_ifaddr
*in_ifaddr_alloc(int);
134 static void in_ifaddr_attached(struct ifaddr
*);
135 static void in_ifaddr_detached(struct ifaddr
*);
136 static void in_ifaddr_free(struct ifaddr
*);
137 static void in_ifaddr_trace(struct ifaddr
*, int);
139 static int in_getassocids(struct socket
*, uint32_t *, user_addr_t
);
140 static int in_getconnids(struct socket
*, associd_t
, uint32_t *, user_addr_t
);
141 static int in_getconninfo(struct socket
*, connid_t
, uint32_t *,
142 uint32_t *, int32_t *, user_addr_t
, socklen_t
*, user_addr_t
, socklen_t
*,
143 uint32_t *, user_addr_t
, uint32_t *);
145 static int subnetsarelocal
= 0;
146 SYSCTL_INT(_net_inet_ip
, OID_AUTO
, subnets_are_local
,
147 CTLFLAG_RW
| CTLFLAG_LOCKED
, &subnetsarelocal
, 0, "");
149 /* Track whether or not the SIOCARPIPLL ioctl has been called */
150 u_int32_t ipv4_ll_arp_aware
= 0;
152 #define INIFA_TRACE_HIST_SIZE 32 /* size of trace history */
155 __private_extern__
unsigned int inifa_trace_hist_size
= INIFA_TRACE_HIST_SIZE
;
157 struct in_ifaddr_dbg
{
158 struct in_ifaddr inifa
; /* in_ifaddr */
159 struct in_ifaddr inifa_old
; /* saved in_ifaddr */
160 u_int16_t inifa_refhold_cnt
; /* # of IFA_ADDREF */
161 u_int16_t inifa_refrele_cnt
; /* # of IFA_REMREF */
163 * Alloc and free callers.
165 ctrace_t inifa_alloc
;
168 * Circular lists of IFA_ADDREF and IFA_REMREF callers.
170 ctrace_t inifa_refhold
[INIFA_TRACE_HIST_SIZE
];
171 ctrace_t inifa_refrele
[INIFA_TRACE_HIST_SIZE
];
175 TAILQ_ENTRY(in_ifaddr_dbg
) inifa_trash_link
;
178 /* List of trash in_ifaddr entries protected by inifa_trash_lock */
179 static TAILQ_HEAD(, in_ifaddr_dbg
) inifa_trash_head
;
180 static decl_lck_mtx_data(, inifa_trash_lock
);
183 static unsigned int inifa_debug
= 1; /* debugging (enabled) */
185 static unsigned int inifa_debug
; /* debugging (disabled) */
187 static unsigned int inifa_size
; /* size of zone element */
188 static struct zone
*inifa_zone
; /* zone for in_ifaddr */
190 #define INIFA_ZONE_MAX 64 /* maximum elements in zone */
191 #define INIFA_ZONE_NAME "in_ifaddr" /* zone name */
194 * Return 1 if the address is
196 * - unicast or multicast link local
197 * - routed via a link level gateway
198 * - belongs to a directly connected (sub)net
201 inaddr_local(struct in_addr in
)
204 struct sockaddr_in sin
;
207 if (ntohl(in
.s_addr
) == INADDR_LOOPBACK
||
208 IN_LINKLOCAL(ntohl(in
.s_addr
))) {
210 } else if (ntohl(in
.s_addr
) >= INADDR_UNSPEC_GROUP
&&
211 ntohl(in
.s_addr
) <= INADDR_MAX_LOCAL_GROUP
) {
214 sin
.sin_family
= AF_INET
;
215 sin
.sin_len
= sizeof (sin
);
217 rt
= rtalloc1((struct sockaddr
*)&sin
, 0, 0);
221 if (rt
->rt_gateway
->sa_family
== AF_LINK
||
222 (rt
->rt_ifp
->if_flags
& IFF_LOOPBACK
))
227 local
= in_localaddr(in
);
234 * Return 1 if an internet address is for a ``local'' host
235 * (one to which we have a connection). If subnetsarelocal
236 * is true, this includes other subnets of the local net.
237 * Otherwise, it includes only the directly-connected (sub)nets.
240 in_localaddr(struct in_addr in
)
242 u_int32_t i
= ntohl(in
.s_addr
);
243 struct in_ifaddr
*ia
;
245 if (subnetsarelocal
) {
246 lck_rw_lock_shared(in_ifaddr_rwlock
);
247 for (ia
= in_ifaddrhead
.tqh_first
; ia
!= NULL
;
248 ia
= ia
->ia_link
.tqe_next
) {
249 IFA_LOCK(&ia
->ia_ifa
);
250 if ((i
& ia
->ia_netmask
) == ia
->ia_net
) {
251 IFA_UNLOCK(&ia
->ia_ifa
);
252 lck_rw_done(in_ifaddr_rwlock
);
255 IFA_UNLOCK(&ia
->ia_ifa
);
257 lck_rw_done(in_ifaddr_rwlock
);
259 lck_rw_lock_shared(in_ifaddr_rwlock
);
260 for (ia
= in_ifaddrhead
.tqh_first
; ia
!= NULL
;
261 ia
= ia
->ia_link
.tqe_next
) {
262 IFA_LOCK(&ia
->ia_ifa
);
263 if ((i
& ia
->ia_subnetmask
) == ia
->ia_subnet
) {
264 IFA_UNLOCK(&ia
->ia_ifa
);
265 lck_rw_done(in_ifaddr_rwlock
);
268 IFA_UNLOCK(&ia
->ia_ifa
);
270 lck_rw_done(in_ifaddr_rwlock
);
276 * Determine whether an IP address is in a reserved set of addresses
277 * that may not be forwarded, or whether datagrams to that destination
281 in_canforward(struct in_addr in
)
283 u_int32_t i
= ntohl(in
.s_addr
);
286 if (IN_EXPERIMENTAL(i
) || IN_MULTICAST(i
))
289 net
= i
& IN_CLASSA_NET
;
290 if (net
== 0 || net
== (IN_LOOPBACKNET
<< IN_CLASSA_NSHIFT
))
297 * Trim a mask in a sockaddr
300 in_socktrim(struct sockaddr_in
*ap
)
302 char *cplim
= (char *)&ap
->sin_addr
;
303 char *cp
= (char *)(&ap
->sin_addr
+ 1);
306 while (--cp
>= cplim
)
308 (ap
)->sin_len
= cp
- (char *)(ap
) + 1;
314 in_mask2len(struct in_addr
*mask
)
320 for (x
= 0; x
< sizeof (*mask
); x
++) {
325 if (x
< sizeof (*mask
)) {
326 for (y
= 0; y
< 8; y
++) {
327 if ((p
[x
] & (0x80 >> y
)) == 0)
335 in_len2mask(struct in_addr
*mask
, int len
)
341 bzero(mask
, sizeof(*mask
));
342 for (i
= 0; i
< len
/ 8; i
++)
345 p
[i
] = (0xff00 >> (len
% 8)) & 0xff;
348 static int in_interfaces
; /* number of external internet interfaces */
351 in_domifattach(struct ifnet
*ifp
)
357 if ((error
= proto_plumb(PF_INET
, ifp
)) && error
!= EEXIST
)
358 log(LOG_ERR
, "%s: proto_plumb returned %d if=%s\n",
359 __func__
, error
, if_name(ifp
));
364 static __attribute__((noinline
)) int
365 inctl_associd(struct socket
*so
, u_long cmd
, caddr_t data
)
369 struct so_aidreq32 a32
;
370 struct so_aidreq64 a64
;
376 case SIOCGASSOCIDS32
: /* struct so_aidreq32 */
377 bcopy(data
, &u
.a32
, sizeof (u
.a32
));
378 error
= in_getassocids(so
, &u
.a32
.sar_cnt
, u
.a32
.sar_aidp
);
380 bcopy(&u
.a32
, data
, sizeof (u
.a32
));
383 case SIOCGASSOCIDS64
: /* struct so_aidreq64 */
384 bcopy(data
, &u
.a64
, sizeof (u
.a64
));
385 error
= in_getassocids(so
, &u
.a64
.sar_cnt
, u
.a64
.sar_aidp
);
387 bcopy(&u
.a64
, data
, sizeof (u
.a64
));
398 static __attribute__((noinline
)) int
399 inctl_connid(struct socket
*so
, u_long cmd
, caddr_t data
)
403 struct so_cidreq32 c32
;
404 struct so_cidreq64 c64
;
410 case SIOCGCONNIDS32
: /* struct so_cidreq32 */
411 bcopy(data
, &u
.c32
, sizeof (u
.c32
));
412 error
= in_getconnids(so
, u
.c32
.scr_aid
, &u
.c32
.scr_cnt
,
415 bcopy(&u
.c32
, data
, sizeof (u
.c32
));
418 case SIOCGCONNIDS64
: /* struct so_cidreq64 */
419 bcopy(data
, &u
.c64
, sizeof (u
.c64
));
420 error
= in_getconnids(so
, u
.c64
.scr_aid
, &u
.c64
.scr_cnt
,
423 bcopy(&u
.c64
, data
, sizeof (u
.c64
));
434 static __attribute__((noinline
)) int
435 inctl_conninfo(struct socket
*so
, u_long cmd
, caddr_t data
)
439 struct so_cinforeq32 ci32
;
440 struct so_cinforeq64 ci64
;
446 case SIOCGCONNINFO32
: /* struct so_cinforeq32 */
447 bcopy(data
, &u
.ci32
, sizeof (u
.ci32
));
448 error
= in_getconninfo(so
, u
.ci32
.scir_cid
, &u
.ci32
.scir_flags
,
449 &u
.ci32
.scir_ifindex
, &u
.ci32
.scir_error
, u
.ci32
.scir_src
,
450 &u
.ci32
.scir_src_len
, u
.ci32
.scir_dst
, &u
.ci32
.scir_dst_len
,
451 &u
.ci32
.scir_aux_type
, u
.ci32
.scir_aux_data
,
452 &u
.ci32
.scir_aux_len
);
454 bcopy(&u
.ci32
, data
, sizeof (u
.ci32
));
457 case SIOCGCONNINFO64
: /* struct so_cinforeq64 */
458 bcopy(data
, &u
.ci64
, sizeof (u
.ci64
));
459 error
= in_getconninfo(so
, u
.ci64
.scir_cid
, &u
.ci64
.scir_flags
,
460 &u
.ci64
.scir_ifindex
, &u
.ci64
.scir_error
, u
.ci64
.scir_src
,
461 &u
.ci64
.scir_src_len
, u
.ci64
.scir_dst
, &u
.ci64
.scir_dst_len
,
462 &u
.ci64
.scir_aux_type
, u
.ci64
.scir_aux_data
,
463 &u
.ci64
.scir_aux_len
);
465 bcopy(&u
.ci64
, data
, sizeof (u
.ci64
));
477 * Caller passes in the ioctl data pointer directly via "ifr", with the
478 * expectation that this routine always uses bcopy() or other byte-aligned
481 static __attribute__((noinline
)) int
482 inctl_autoaddr(struct ifnet
*ifp
, struct ifreq
*ifr
)
484 int error
= 0, intval
;
488 bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
));
490 ifnet_lock_exclusive(ifp
);
493 * An interface in IPv4 router mode implies that it
494 * is configured with a static IP address and should
495 * not act as a DHCP client; prevent SIOCAUTOADDR from
496 * being set in that mode.
498 if (ifp
->if_eflags
& IFEF_IPV4_ROUTER
) {
499 intval
= 0; /* be safe; clear flag if set */
502 ifp
->if_eflags
|= IFEF_AUTOCONFIGURING
;
506 ifp
->if_eflags
&= ~IFEF_AUTOCONFIGURING
;
507 ifnet_lock_done(ifp
);
513 * Caller passes in the ioctl data pointer directly via "ifr", with the
514 * expectation that this routine always uses bcopy() or other byte-aligned
517 static __attribute__((noinline
)) int
518 inctl_arpipll(struct ifnet
*ifp
, struct ifreq
*ifr
)
520 int error
= 0, intval
;
524 bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
));
525 ipv4_ll_arp_aware
= 1;
527 ifnet_lock_exclusive(ifp
);
530 * An interface in IPv4 router mode implies that it
531 * is configured with a static IP address and should
532 * not have to deal with IPv4 Link-Local Address;
533 * prevent SIOCARPIPLL from being set in that mode.
535 if (ifp
->if_eflags
& IFEF_IPV4_ROUTER
) {
536 intval
= 0; /* be safe; clear flag if set */
539 ifp
->if_eflags
|= IFEF_ARPLL
;
543 ifp
->if_eflags
&= ~IFEF_ARPLL
;
544 ifnet_lock_done(ifp
);
550 * Handle SIOCSETROUTERMODE to set or clear the IPv4 router mode flag on
551 * the interface. When in this mode, IPv4 Link-Local Address support is
552 * disabled in ARP, and DHCP client support is disabled in IP input; turning
553 * any of them on would cause an error to be returned. Entering or exiting
554 * this mode will result in the removal of IPv4 addresses currently configured
557 * Caller passes in the ioctl data pointer directly via "ifr", with the
558 * expectation that this routine always uses bcopy() or other byte-aligned
561 static __attribute__((noinline
)) int
562 inctl_setrouter(struct ifnet
*ifp
, struct ifreq
*ifr
)
564 int error
= 0, intval
;
568 /* Router mode isn't valid for loopback */
569 if (ifp
->if_flags
& IFF_LOOPBACK
)
572 bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
));
574 ifnet_lock_exclusive(ifp
);
576 ifp
->if_eflags
|= IFEF_IPV4_ROUTER
;
577 ifp
->if_eflags
&= ~(IFEF_ARPLL
| IFEF_AUTOCONFIGURING
);
579 ifp
->if_eflags
&= ~IFEF_IPV4_ROUTER
;
581 ifnet_lock_done(ifp
);
583 /* purge all IPv4 addresses configured on this interface */
590 * Caller passes in the ioctl data pointer directly via "ifr", with the
591 * expectation that this routine always uses bcopy() or other byte-aligned
594 static __attribute__((noinline
)) int
595 inctl_ifaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
598 struct kev_in_data in_event_data
;
599 struct kev_msg ev_msg
;
600 struct sockaddr_in addr
;
606 bzero(&in_event_data
, sizeof (struct kev_in_data
));
607 bzero(&ev_msg
, sizeof (struct kev_msg
));
610 case SIOCGIFADDR
: /* struct ifreq */
612 error
= EADDRNOTAVAIL
;
615 IFA_LOCK(&ia
->ia_ifa
);
616 bcopy(&ia
->ia_addr
, &ifr
->ifr_addr
, sizeof (addr
));
617 IFA_UNLOCK(&ia
->ia_ifa
);
620 case SIOCSIFADDR
: /* struct ifreq */
622 bcopy(&ifr
->ifr_addr
, &addr
, sizeof (addr
));
624 * If this is a new address, the reference count for the
625 * hash table has been taken at creation time above.
627 error
= in_ifinit(ifp
, ia
, &addr
, 1);
629 (void) ifnet_notify_address(ifp
, AF_INET
);
633 case SIOCAIFADDR
: { /* struct {if,in_}aliasreq */
634 struct in_aliasreq
*ifra
= (struct in_aliasreq
*)ifr
;
635 struct sockaddr_in broadaddr
, mask
;
636 int hostIsNew
, maskIsNew
;
639 bcopy(&ifra
->ifra_addr
, &addr
, sizeof (addr
));
640 bcopy(&ifra
->ifra_broadaddr
, &broadaddr
, sizeof (broadaddr
));
641 bcopy(&ifra
->ifra_mask
, &mask
, sizeof (mask
));
647 IFA_LOCK(&ia
->ia_ifa
);
648 if (ia
->ia_addr
.sin_family
== AF_INET
) {
649 if (addr
.sin_len
== 0) {
652 } else if (addr
.sin_addr
.s_addr
==
653 ia
->ia_addr
.sin_addr
.s_addr
) {
658 IFA_UNLOCK(&ia
->ia_ifa
);
659 in_ifscrub(ifp
, ia
, 0);
660 IFA_LOCK(&ia
->ia_ifa
);
661 ia
->ia_sockmask
= mask
;
663 ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
);
666 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
667 (broadaddr
.sin_family
== AF_INET
)) {
668 IFA_UNLOCK(&ia
->ia_ifa
);
669 in_ifscrub(ifp
, ia
, 0);
670 IFA_LOCK(&ia
->ia_ifa
);
671 ia
->ia_dstaddr
= broadaddr
;
672 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
673 maskIsNew
= 1; /* We lie; but the effect's the same */
675 if (addr
.sin_family
== AF_INET
&& (hostIsNew
|| maskIsNew
)) {
676 IFA_UNLOCK(&ia
->ia_ifa
);
677 error
= in_ifinit(ifp
, ia
, &addr
, 0);
679 IFA_UNLOCK(&ia
->ia_ifa
);
682 (void) ifnet_notify_address(ifp
, AF_INET
);
684 IFA_LOCK(&ia
->ia_ifa
);
685 if ((ifp
->if_flags
& IFF_BROADCAST
) &&
686 (broadaddr
.sin_family
== AF_INET
))
687 ia
->ia_broadaddr
= broadaddr
;
692 if ((error
== 0) || (error
== EEXIST
)) {
693 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
694 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
695 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
698 ev_msg
.event_code
= KEV_INET_NEW_ADDR
;
700 ev_msg
.event_code
= KEV_INET_CHANGED_ADDR
;
702 if (ia
->ia_ifa
.ifa_dstaddr
) {
703 in_event_data
.ia_dstaddr
=
704 ((struct sockaddr_in
*)(void *)ia
->
705 ia_ifa
.ifa_dstaddr
)->sin_addr
;
707 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
709 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
710 in_event_data
.ia_net
= ia
->ia_net
;
711 in_event_data
.ia_netmask
= ia
->ia_netmask
;
712 in_event_data
.ia_subnet
= ia
->ia_subnet
;
713 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
714 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
715 IFA_UNLOCK(&ia
->ia_ifa
);
716 (void) strncpy(&in_event_data
.link_data
.if_name
[0],
717 ifp
->if_name
, IFNAMSIZ
);
718 in_event_data
.link_data
.if_family
= ifp
->if_family
;
719 in_event_data
.link_data
.if_unit
= ifp
->if_unit
;
721 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
722 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
723 ev_msg
.dv
[1].data_length
= 0;
725 kev_post_msg(&ev_msg
);
727 IFA_UNLOCK(&ia
->ia_ifa
);
732 case SIOCDIFADDR
: /* struct ifreq */
734 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCDIFADDR
, ia
);
735 if (error
== EOPNOTSUPP
)
740 /* Fill out the kernel event information */
741 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
742 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
743 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
745 ev_msg
.event_code
= KEV_INET_ADDR_DELETED
;
747 IFA_LOCK(&ia
->ia_ifa
);
748 if (ia
->ia_ifa
.ifa_dstaddr
) {
749 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
750 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
752 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
754 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
755 in_event_data
.ia_net
= ia
->ia_net
;
756 in_event_data
.ia_netmask
= ia
->ia_netmask
;
757 in_event_data
.ia_subnet
= ia
->ia_subnet
;
758 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
759 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
760 IFA_UNLOCK(&ia
->ia_ifa
);
761 (void) strncpy(&in_event_data
.link_data
.if_name
[0],
762 ifp
->if_name
, IFNAMSIZ
);
763 in_event_data
.link_data
.if_family
= ifp
->if_family
;
764 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
766 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
767 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
768 ev_msg
.dv
[1].data_length
= 0;
771 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
772 /* Release ia_link reference */
774 TAILQ_REMOVE(&in_ifaddrhead
, ia
, ia_link
);
776 if (IA_IS_HASHED(ia
))
777 in_iahash_remove(ia
);
779 lck_rw_done(in_ifaddr_rwlock
);
782 * in_ifscrub kills the interface route.
784 in_ifscrub(ifp
, ia
, 0);
785 ifnet_lock_exclusive(ifp
);
787 /* if_detach_ifa() releases ifa_link reference */
788 if_detach_ifa(ifp
, ifa
);
789 /* Our reference to this address is dropped at the bottom */
792 /* invalidate route caches */
793 routegenid_inet_update();
796 * If the interface supports multicast, and no address is left,
797 * remove the "all hosts" multicast group from that interface.
799 if ((ifp
->if_flags
& IFF_MULTICAST
) ||
800 ifp
->if_allhostsinm
!= NULL
) {
802 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
804 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
810 ifnet_lock_done(ifp
);
812 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
813 if (ifa
== NULL
&& ifp
->if_allhostsinm
!= NULL
) {
814 struct in_multi
*inm
= ifp
->if_allhostsinm
;
815 ifp
->if_allhostsinm
= NULL
;
818 /* release the reference for allhostsinm */
821 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
823 ifnet_lock_done(ifp
);
826 /* Post the kernel event */
827 kev_post_msg(&ev_msg
);
830 * See if there is any IPV4 address left and if so,
831 * reconfigure KDP to use current primary address.
833 ifa
= ifa_ifpgetprimary(ifp
, AF_INET
);
836 * NOTE: SIOCSIFADDR is defined with struct ifreq
837 * as parameter, but here we are sending it down
838 * to the interface with a pointer to struct ifaddr,
839 * for legacy reasons.
841 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa
);
842 if (error
== EOPNOTSUPP
)
845 /* Release reference from ifa_ifpgetprimary() */
848 (void) ifnet_notify_address(ifp
, AF_INET
);
860 * Caller passes in the ioctl data pointer directly via "ifr", with the
861 * expectation that this routine always uses bcopy() or other byte-aligned
864 static __attribute__((noinline
)) int
865 inctl_ifdstaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
868 struct kev_in_data in_event_data
;
869 struct kev_msg ev_msg
;
870 struct sockaddr_in dstaddr
;
875 if (!(ifp
->if_flags
& IFF_POINTOPOINT
))
878 bzero(&in_event_data
, sizeof (struct kev_in_data
));
879 bzero(&ev_msg
, sizeof (struct kev_msg
));
882 case SIOCGIFDSTADDR
: /* struct ifreq */
884 error
= EADDRNOTAVAIL
;
887 IFA_LOCK(&ia
->ia_ifa
);
888 bcopy(&ia
->ia_dstaddr
, &ifr
->ifr_dstaddr
, sizeof (dstaddr
));
889 IFA_UNLOCK(&ia
->ia_ifa
);
892 case SIOCSIFDSTADDR
: /* struct ifreq */
894 IFA_LOCK(&ia
->ia_ifa
);
895 dstaddr
= ia
->ia_dstaddr
;
896 bcopy(&ifr
->ifr_dstaddr
, &ia
->ia_dstaddr
, sizeof (dstaddr
));
897 if (ia
->ia_dstaddr
.sin_family
== AF_INET
)
898 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
899 IFA_UNLOCK(&ia
->ia_ifa
);
901 * NOTE: SIOCSIFDSTADDR is defined with struct ifreq
902 * as parameter, but here we are sending it down
903 * to the interface with a pointer to struct ifaddr,
904 * for legacy reasons.
906 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFDSTADDR
, ia
);
907 IFA_LOCK(&ia
->ia_ifa
);
908 if (error
== EOPNOTSUPP
)
911 ia
->ia_dstaddr
= dstaddr
;
912 IFA_UNLOCK(&ia
->ia_ifa
);
915 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
917 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
918 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
919 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
921 ev_msg
.event_code
= KEV_INET_SIFDSTADDR
;
923 if (ia
->ia_ifa
.ifa_dstaddr
) {
924 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
925 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
927 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
930 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
931 in_event_data
.ia_net
= ia
->ia_net
;
932 in_event_data
.ia_netmask
= ia
->ia_netmask
;
933 in_event_data
.ia_subnet
= ia
->ia_subnet
;
934 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
935 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
936 IFA_UNLOCK(&ia
->ia_ifa
);
937 (void) strncpy(&in_event_data
.link_data
.if_name
[0],
938 ifp
->if_name
, IFNAMSIZ
);
939 in_event_data
.link_data
.if_family
= ifp
->if_family
;
940 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
942 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
943 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
944 ev_msg
.dv
[1].data_length
= 0;
946 kev_post_msg(&ev_msg
);
948 lck_mtx_lock(rnh_lock
);
949 IFA_LOCK(&ia
->ia_ifa
);
950 if (ia
->ia_flags
& IFA_ROUTE
) {
951 ia
->ia_ifa
.ifa_dstaddr
= (struct sockaddr
*)&dstaddr
;
952 IFA_UNLOCK(&ia
->ia_ifa
);
953 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
954 IFA_LOCK(&ia
->ia_ifa
);
955 ia
->ia_ifa
.ifa_dstaddr
=
956 (struct sockaddr
*)&ia
->ia_dstaddr
;
957 IFA_UNLOCK(&ia
->ia_ifa
);
958 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
,
961 IFA_UNLOCK(&ia
->ia_ifa
);
963 lck_mtx_unlock(rnh_lock
);
977 * Caller passes in the ioctl data pointer directly via "ifr", with the
978 * expectation that this routine always uses bcopy() or other byte-aligned
981 static __attribute__((noinline
)) int
982 inctl_ifbrdaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
985 struct kev_in_data in_event_data
;
986 struct kev_msg ev_msg
;
992 return (EADDRNOTAVAIL
);
994 if (!(ifp
->if_flags
& IFF_BROADCAST
))
997 bzero(&in_event_data
, sizeof (struct kev_in_data
));
998 bzero(&ev_msg
, sizeof (struct kev_msg
));
1001 case SIOCGIFBRDADDR
: /* struct ifreq */
1002 IFA_LOCK(&ia
->ia_ifa
);
1003 bcopy(&ia
->ia_broadaddr
, &ifr
->ifr_broadaddr
,
1004 sizeof (struct sockaddr_in
));
1005 IFA_UNLOCK(&ia
->ia_ifa
);
1008 case SIOCSIFBRDADDR
: /* struct ifreq */
1009 IFA_LOCK(&ia
->ia_ifa
);
1010 bcopy(&ifr
->ifr_broadaddr
, &ia
->ia_broadaddr
,
1011 sizeof (struct sockaddr_in
));
1013 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
1014 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
1015 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
1017 ev_msg
.event_code
= KEV_INET_SIFBRDADDR
;
1019 if (ia
->ia_ifa
.ifa_dstaddr
) {
1020 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
1021 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
1023 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
1025 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
1026 in_event_data
.ia_net
= ia
->ia_net
;
1027 in_event_data
.ia_netmask
= ia
->ia_netmask
;
1028 in_event_data
.ia_subnet
= ia
->ia_subnet
;
1029 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
1030 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
1031 IFA_UNLOCK(&ia
->ia_ifa
);
1032 (void) strncpy(&in_event_data
.link_data
.if_name
[0],
1033 ifp
->if_name
, IFNAMSIZ
);
1034 in_event_data
.link_data
.if_family
= ifp
->if_family
;
1035 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
1037 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
1038 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
1039 ev_msg
.dv
[1].data_length
= 0;
1041 kev_post_msg(&ev_msg
);
1053 * Caller passes in the ioctl data pointer directly via "ifr", with the
1054 * expectation that this routine always uses bcopy() or other byte-aligned
1057 static __attribute__((noinline
)) int
1058 inctl_ifnetmask(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
1061 struct kev_in_data in_event_data
;
1062 struct kev_msg ev_msg
;
1063 struct sockaddr_in mask
;
1066 VERIFY(ifp
!= NULL
);
1068 bzero(&in_event_data
, sizeof (struct kev_in_data
));
1069 bzero(&ev_msg
, sizeof (struct kev_msg
));
1072 case SIOCGIFNETMASK
: /* struct ifreq */
1074 error
= EADDRNOTAVAIL
;
1077 IFA_LOCK(&ia
->ia_ifa
);
1078 bcopy(&ia
->ia_sockmask
, &ifr
->ifr_addr
, sizeof (mask
));
1079 IFA_UNLOCK(&ia
->ia_ifa
);
1082 case SIOCSIFNETMASK
: { /* struct ifreq */
1085 bcopy(&ifr
->ifr_addr
, &mask
, sizeof (mask
));
1086 i
= mask
.sin_addr
.s_addr
;
1089 IFA_LOCK(&ia
->ia_ifa
);
1090 ia
->ia_subnetmask
= ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
= i
);
1091 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
1092 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
1093 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
1095 ev_msg
.event_code
= KEV_INET_SIFNETMASK
;
1097 if (ia
->ia_ifa
.ifa_dstaddr
) {
1098 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
1099 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
1101 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
1103 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
1104 in_event_data
.ia_net
= ia
->ia_net
;
1105 in_event_data
.ia_netmask
= ia
->ia_netmask
;
1106 in_event_data
.ia_subnet
= ia
->ia_subnet
;
1107 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
1108 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
1109 IFA_UNLOCK(&ia
->ia_ifa
);
1110 (void) strncpy(&in_event_data
.link_data
.if_name
[0],
1111 ifp
->if_name
, IFNAMSIZ
);
1112 in_event_data
.link_data
.if_family
= ifp
->if_family
;
1113 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
1115 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
1116 ev_msg
.dv
[0].data_length
= sizeof (struct kev_in_data
);
1117 ev_msg
.dv
[1].data_length
= 0;
1119 kev_post_msg(&ev_msg
);
1132 * Generic INET control operations (ioctl's).
1134 * ifp is NULL if not an interface-specific ioctl.
1136 * Most of the routines called to handle the ioctls would end up being
1137 * tail-call optimized, which unfortunately causes this routine to
1138 * consume too much stack space; this is the reason for the "noinline"
1139 * attribute used on those routines.
1141 * If called directly from within the networking stack (as opposed to via
1142 * pru_control), the socket parameter may be NULL.
1145 in_control(struct socket
*so
, u_long cmd
, caddr_t data
, struct ifnet
*ifp
,
1148 struct ifreq
*ifr
= (struct ifreq
*)(void *)data
;
1149 struct sockaddr_in addr
, dstaddr
;
1150 struct sockaddr_in sin
, *sa
= NULL
;
1151 boolean_t privileged
= (proc_suser(p
) == 0);
1152 boolean_t so_unlocked
= FALSE
;
1153 struct in_ifaddr
*ia
= NULL
;
1157 /* In case it's NULL, make sure it came from the kernel */
1158 VERIFY(so
!= NULL
|| p
== kernproc
);
1161 * ioctls which don't require ifp, but require socket.
1164 case SIOCGASSOCIDS32
: /* struct so_aidreq32 */
1165 case SIOCGASSOCIDS64
: /* struct so_aidreq64 */
1166 return (inctl_associd(so
, cmd
, data
));
1169 case SIOCGCONNIDS32
: /* struct so_cidreq32 */
1170 case SIOCGCONNIDS64
: /* struct so_cidreq64 */
1171 return (inctl_connid(so
, cmd
, data
));
1174 case SIOCGCONNINFO32
: /* struct so_cinforeq32 */
1175 case SIOCGCONNINFO64
: /* struct so_cinforeq64 */
1176 return (inctl_conninfo(so
, cmd
, data
));
1181 * The rest of ioctls require ifp; reject if we don't have one;
1182 * return ENXIO to be consistent with ifioctl().
1188 * ioctls which require ifp but not interface address.
1191 case SIOCAUTOADDR
: /* struct ifreq */
1194 return (inctl_autoaddr(ifp
, ifr
));
1197 case SIOCARPIPLL
: /* struct ifreq */
1200 return (inctl_arpipll(ifp
, ifr
));
1203 case SIOCSETROUTERMODE
: /* struct ifreq */
1206 return (inctl_setrouter(ifp
, ifr
));
1209 case SIOCPROTOATTACH
: /* struct ifreq */
1212 return (in_domifattach(ifp
));
1215 case SIOCPROTODETACH
: /* struct ifreq */
1220 * If an IPv4 address is still present, refuse to detach.
1222 ifnet_lock_shared(ifp
);
1223 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1225 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
1231 ifnet_lock_done(ifp
);
1232 return ((ifa
== NULL
) ? proto_unplumb(PF_INET
, ifp
) : EBUSY
);
1235 case SIOCALIFADDR
: /* struct if_laddrreq */
1236 case SIOCDLIFADDR
: /* struct if_laddrreq */
1240 case SIOCGLIFADDR
: { /* struct if_laddrreq */
1241 struct if_laddrreq iflr
;
1243 bcopy(data
, &iflr
, sizeof (iflr
));
1244 error
= inctl_lifaddr(ifp
, cmd
, &iflr
);
1245 bcopy(&iflr
, data
, sizeof (iflr
));
1252 * ioctls which require interface address; obtain sockaddr_in.
1255 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1258 bcopy(&((struct in_aliasreq
*)(void *)data
)->ifra_addr
,
1259 &sin
, sizeof (sin
));
1263 case SIOCDIFADDR
: /* struct ifreq */
1264 case SIOCSIFADDR
: /* struct ifreq */
1265 case SIOCSIFDSTADDR
: /* struct ifreq */
1266 case SIOCSIFNETMASK
: /* struct ifreq */
1267 case SIOCSIFBRDADDR
: /* struct ifreq */
1271 case SIOCGIFADDR
: /* struct ifreq */
1272 case SIOCGIFDSTADDR
: /* struct ifreq */
1273 case SIOCGIFNETMASK
: /* struct ifreq */
1274 case SIOCGIFBRDADDR
: /* struct ifreq */
1275 bcopy(&ifr
->ifr_addr
, &sin
, sizeof (sin
));
1281 * Find address for this interface, if it exists.
1283 * If an alias address was specified, find that one instead of
1284 * the first one on the interface, if possible.
1288 struct in_ifaddr
*iap
;
1291 * Any failures from this point on must take into account
1292 * a non-NULL "ia" with an outstanding reference count, and
1293 * therefore requires IFA_REMREF. Jump to "done" label
1294 * instead of calling return if "ia" is valid.
1296 lck_rw_lock_shared(in_ifaddr_rwlock
);
1297 TAILQ_FOREACH(iap
, INADDR_HASH(sa
->sin_addr
.s_addr
), ia_hash
) {
1298 IFA_LOCK(&iap
->ia_ifa
);
1299 if (iap
->ia_ifp
== ifp
&&
1300 iap
->ia_addr
.sin_addr
.s_addr
==
1301 sa
->sin_addr
.s_addr
) {
1303 IFA_UNLOCK(&iap
->ia_ifa
);
1306 IFA_UNLOCK(&iap
->ia_ifa
);
1308 /* take a reference on ia before releasing lock */
1310 IFA_ADDREF(&ia
->ia_ifa
);
1311 lck_rw_done(in_ifaddr_rwlock
);
1314 ifnet_lock_shared(ifp
);
1315 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1317 IFA_LOCK(&iap
->ia_ifa
);
1318 if (iap
->ia_addr
.sin_family
== AF_INET
) {
1320 IFA_UNLOCK(&iap
->ia_ifa
);
1323 IFA_UNLOCK(&iap
->ia_ifa
);
1325 /* take a reference on ia before releasing lock */
1327 IFA_ADDREF(&ia
->ia_ifa
);
1328 ifnet_lock_done(ifp
);
1333 * Unlock the socket since ifnet_ioctl() may be invoked by
1334 * one of the ioctl handlers below. Socket will be re-locked
1335 * prior to returning.
1338 socket_unlock(so
, 0);
1343 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1344 case SIOCDIFADDR
: /* struct ifreq */
1345 if (cmd
== SIOCAIFADDR
) {
1346 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1347 ifra_addr
, &addr
, sizeof (addr
));
1348 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1349 ifra_dstaddr
, &dstaddr
, sizeof (dstaddr
));
1351 VERIFY(cmd
== SIOCDIFADDR
);
1352 bcopy(&((struct ifreq
*)(void *)data
)->ifr_addr
,
1353 &addr
, sizeof (addr
));
1354 bzero(&dstaddr
, sizeof (dstaddr
));
1357 if (addr
.sin_family
== AF_INET
) {
1358 struct in_ifaddr
*oia
;
1360 lck_rw_lock_shared(in_ifaddr_rwlock
);
1361 for (oia
= ia
; ia
; ia
= ia
->ia_link
.tqe_next
) {
1362 IFA_LOCK(&ia
->ia_ifa
);
1363 if (ia
->ia_ifp
== ifp
&&
1364 ia
->ia_addr
.sin_addr
.s_addr
==
1365 addr
.sin_addr
.s_addr
) {
1366 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1367 IFA_UNLOCK(&ia
->ia_ifa
);
1370 IFA_UNLOCK(&ia
->ia_ifa
);
1372 lck_rw_done(in_ifaddr_rwlock
);
1374 IFA_REMREF(&oia
->ia_ifa
);
1375 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
1376 (cmd
== SIOCAIFADDR
) &&
1377 (dstaddr
.sin_addr
.s_addr
== INADDR_ANY
)) {
1378 error
= EDESTADDRREQ
;
1381 } else if (cmd
== SIOCAIFADDR
) {
1385 if (cmd
== SIOCDIFADDR
&& ia
== NULL
) {
1386 error
= EADDRNOTAVAIL
;
1390 case SIOCSIFADDR
: /* struct ifreq */
1391 case SIOCSIFDSTADDR
: /* struct ifreq */
1392 case SIOCSIFNETMASK
: /* struct ifreq */
1393 if (cmd
== SIOCAIFADDR
) {
1394 /* fell thru from above; just repeat it */
1395 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1396 ifra_addr
, &addr
, sizeof (addr
));
1398 VERIFY(cmd
== SIOCDIFADDR
|| cmd
== SIOCSIFADDR
||
1399 cmd
== SIOCSIFNETMASK
|| cmd
== SIOCSIFDSTADDR
);
1400 bcopy(&((struct ifreq
*)(void *)data
)->ifr_addr
,
1401 &addr
, sizeof (addr
));
1404 if (addr
.sin_family
!= AF_INET
&& cmd
== SIOCSIFADDR
) {
1409 ia
= in_ifaddr_alloc(M_WAITOK
);
1414 ifnet_lock_exclusive(ifp
);
1417 /* Hold a reference for this routine */
1418 IFA_ADDREF_LOCKED(ifa
);
1420 ifa
->ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1421 ifa
->ifa_dstaddr
= (struct sockaddr
*)&ia
->ia_dstaddr
;
1422 ifa
->ifa_netmask
= (struct sockaddr
*)&ia
->ia_sockmask
;
1423 ia
->ia_sockmask
.sin_len
= 8;
1424 if (ifp
->if_flags
& IFF_BROADCAST
) {
1425 ia
->ia_broadaddr
.sin_len
= sizeof (ia
->ia_addr
);
1426 ia
->ia_broadaddr
.sin_family
= AF_INET
;
1429 if (!(ifp
->if_flags
& IFF_LOOPBACK
))
1431 /* if_attach_ifa() holds a reference for ifa_link */
1432 if_attach_ifa(ifp
, ifa
);
1434 * If we have to go through in_ifinit(), make sure
1435 * to avoid installing route(s) based on this address
1436 * via PFC_IFUP event, before the link resolver (ARP)
1439 if (cmd
== SIOCAIFADDR
|| cmd
== SIOCSIFADDR
)
1440 ifa
->ifa_debug
|= IFD_NOTREADY
;
1442 ifnet_lock_done(ifp
);
1443 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1444 /* Hold a reference for ia_link */
1446 TAILQ_INSERT_TAIL(&in_ifaddrhead
, ia
, ia_link
);
1447 lck_rw_done(in_ifaddr_rwlock
);
1449 (void) in_domifattach(ifp
);
1456 case SIOCGIFDSTADDR
: /* struct ifreq */
1457 case SIOCSIFDSTADDR
: /* struct ifreq */
1458 error
= inctl_ifdstaddr(ifp
, ia
, cmd
, ifr
);
1461 case SIOCGIFBRDADDR
: /* struct ifreq */
1462 case SIOCSIFBRDADDR
: /* struct ifreq */
1463 error
= inctl_ifbrdaddr(ifp
, ia
, cmd
, ifr
);
1466 case SIOCGIFNETMASK
: /* struct ifreq */
1467 case SIOCSIFNETMASK
: /* struct ifreq */
1468 error
= inctl_ifnetmask(ifp
, ia
, cmd
, ifr
);
1471 case SIOCGIFADDR
: /* struct ifreq */
1472 case SIOCSIFADDR
: /* struct ifreq */
1473 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1474 case SIOCDIFADDR
: /* struct ifreq */
1475 error
= inctl_ifaddr(ifp
, ia
, cmd
, ifr
);
1484 IFA_REMREF(&ia
->ia_ifa
);
1493 * SIOCGLIFADDR: get first address. (?!?)
1494 * SIOCGLIFADDR with IFLR_PREFIX:
1495 * get first address that matches the specified prefix.
1496 * SIOCALIFADDR: add the specified address.
1497 * SIOCALIFADDR with IFLR_PREFIX:
1498 * EINVAL since we can't deduce hostid part of the address.
1499 * SIOCDLIFADDR: delete the specified address.
1500 * SIOCDLIFADDR with IFLR_PREFIX:
1501 * delete the first address that matches the specified prefix.
1503 * EINVAL on invalid parameters
1504 * EADDRNOTAVAIL on prefix match failed/specified address not found
1505 * other values may be returned from in_ioctl()
1507 static __attribute__((noinline
)) int
1508 inctl_lifaddr(struct ifnet
*ifp
, u_long cmd
, struct if_laddrreq
*iflr
)
1512 VERIFY(ifp
!= NULL
);
1516 /* address must be specified on GET with IFLR_PREFIX */
1517 if (!(iflr
->flags
& IFLR_PREFIX
))
1522 /* address must be specified on ADD and DELETE */
1523 if (iflr
->addr
.ss_family
!= AF_INET
)
1525 if (iflr
->addr
.ss_len
!= sizeof (struct sockaddr_in
))
1527 /* XXX need improvement */
1528 if (iflr
->dstaddr
.ss_family
&&
1529 iflr
->dstaddr
.ss_family
!= AF_INET
)
1531 if (iflr
->dstaddr
.ss_family
&&
1532 iflr
->dstaddr
.ss_len
!= sizeof (struct sockaddr_in
))
1536 /* shouldn't happen */
1540 if (sizeof (struct in_addr
) * 8 < iflr
->prefixlen
)
1544 case SIOCALIFADDR
: {
1545 struct in_aliasreq ifra
;
1547 if (iflr
->flags
& IFLR_PREFIX
)
1550 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR). */
1551 bzero(&ifra
, sizeof (ifra
));
1552 bcopy(iflr
->iflr_name
, ifra
.ifra_name
, sizeof (ifra
.ifra_name
));
1553 bcopy(&iflr
->addr
, &ifra
.ifra_addr
, iflr
->addr
.ss_len
);
1554 if (iflr
->dstaddr
.ss_family
) { /* XXX */
1555 bcopy(&iflr
->dstaddr
, &ifra
.ifra_dstaddr
,
1556 sizeof (struct sockaddr_in
));
1558 ifra
.ifra_mask
.sin_family
= AF_INET
;
1559 ifra
.ifra_mask
.sin_len
= sizeof (struct sockaddr_in
);
1560 in_len2mask(&ifra
.ifra_mask
.sin_addr
, iflr
->prefixlen
);
1562 return (in_control(NULL
, SIOCAIFADDR
, (caddr_t
)&ifra
,
1567 case SIOCDLIFADDR
: {
1568 struct in_ifaddr
*ia
;
1569 struct in_addr mask
, candidate
;
1570 struct in_addr match
= { 0 };
1571 struct sockaddr_in
*sin
;
1574 bzero(&mask
, sizeof(mask
));
1575 if (iflr
->flags
& IFLR_PREFIX
) {
1576 /* lookup a prefix rather than address. */
1577 in_len2mask(&mask
, iflr
->prefixlen
);
1579 sin
= (struct sockaddr_in
*)&iflr
->addr
;
1580 match
.s_addr
= sin
->sin_addr
.s_addr
;
1581 match
.s_addr
&= mask
.s_addr
;
1583 /* if you set extra bits, that's wrong */
1584 if (match
.s_addr
!= sin
->sin_addr
.s_addr
)
1589 if (cmd
== SIOCGLIFADDR
) {
1590 /* on getting an address, take the 1st match */
1593 /* on deleting an address, do exact match */
1594 in_len2mask(&mask
, 32);
1595 sin
= (struct sockaddr_in
*)&iflr
->addr
;
1596 match
.s_addr
= sin
->sin_addr
.s_addr
;
1602 ifnet_lock_shared(ifp
);
1603 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1605 if (ifa
->ifa_addr
->sa_family
!= AF_INET6
) {
1613 candidate
.s_addr
= SIN(&ifa
->ifa_addr
)->sin_addr
.s_addr
;
1614 candidate
.s_addr
&= mask
.s_addr
;
1616 if (candidate
.s_addr
== match
.s_addr
)
1621 ifnet_lock_done(ifp
);
1623 return (EADDRNOTAVAIL
);
1624 ia
= (struct in_ifaddr
*)ifa
;
1626 if (cmd
== SIOCGLIFADDR
) {
1628 /* fill in the if_laddrreq structure */
1629 bcopy(&ia
->ia_addr
, &iflr
->addr
, ia
->ia_addr
.sin_len
);
1631 if ((ifp
->if_flags
& IFF_POINTOPOINT
) != 0) {
1632 bcopy(&ia
->ia_dstaddr
, &iflr
->dstaddr
,
1633 ia
->ia_dstaddr
.sin_len
);
1635 bzero(&iflr
->dstaddr
, sizeof(iflr
->dstaddr
));
1638 in_mask2len(&ia
->ia_sockmask
.sin_addr
);
1639 iflr
->flags
= 0; /* XXX */
1647 /* fill ifreq and do ioctl(SIOCDIFADDR) */
1648 bzero(&ifr
, sizeof (ifr
));
1649 bcopy(iflr
->iflr_name
, ifr
.ifr_name
,
1650 sizeof (ifr
.ifr_name
));
1652 bcopy(&ia
->ia_addr
, &ifr
.ifr_addr
,
1653 sizeof (struct sockaddr_in
));
1656 return (in_control(NULL
, SIOCDIFADDR
, (caddr_t
)&ifr
,
1662 return (EOPNOTSUPP
); /* just for safety */
1666 * Delete any existing route for an interface.
1669 in_ifscrub(struct ifnet
*ifp
, struct in_ifaddr
*ia
, int locked
)
1671 IFA_LOCK(&ia
->ia_ifa
);
1672 if ((ia
->ia_flags
& IFA_ROUTE
) == 0) {
1673 IFA_UNLOCK(&ia
->ia_ifa
);
1676 IFA_UNLOCK(&ia
->ia_ifa
);
1678 lck_mtx_lock(rnh_lock
);
1679 if (ifp
->if_flags
& (IFF_LOOPBACK
|IFF_POINTOPOINT
))
1680 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
1682 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, 0);
1683 IFA_LOCK(&ia
->ia_ifa
);
1684 ia
->ia_flags
&= ~IFA_ROUTE
;
1685 IFA_UNLOCK(&ia
->ia_ifa
);
1687 lck_mtx_unlock(rnh_lock
);
1691 * Caller must hold in_ifaddr_rwlock as writer.
1694 in_iahash_remove(struct in_ifaddr
*ia
)
1696 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1697 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1699 if (!IA_IS_HASHED(ia
)) {
1700 panic("attempt to remove wrong ia %p from hash table\n", ia
);
1703 TAILQ_REMOVE(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), ia
, ia_hash
);
1705 if (IFA_REMREF_LOCKED(&ia
->ia_ifa
) == NULL
) {
1706 panic("%s: unexpected (missing) refcnt ifa=%p", __func__
,
1713 * Caller must hold in_ifaddr_rwlock as writer.
1716 in_iahash_insert(struct in_ifaddr
*ia
)
1718 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1719 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1721 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1722 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1724 } else if (IA_IS_HASHED(ia
)) {
1725 panic("attempt to double-insert ia %p into hash table\n", ia
);
1728 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1730 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1734 * Some point to point interfaces that are tunnels borrow the address from
1735 * an underlying interface (e.g. VPN server). In order for source address
1736 * selection logic to find the underlying interface first, we add the address
1737 * of borrowing point to point interfaces at the end of the list.
1738 * (see rdar://6733789)
1740 * Caller must hold in_ifaddr_rwlock as writer.
1743 in_iahash_insert_ptp(struct in_ifaddr
*ia
)
1745 struct in_ifaddr
*tmp_ifa
;
1746 struct ifnet
*tmp_ifp
;
1748 lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1749 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1751 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1752 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1754 } else if (IA_IS_HASHED(ia
)) {
1755 panic("attempt to double-insert ia %p into hash table\n", ia
);
1758 IFA_UNLOCK(&ia
->ia_ifa
);
1759 TAILQ_FOREACH(tmp_ifa
, INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1761 IFA_LOCK(&tmp_ifa
->ia_ifa
);
1762 /* ia->ia_addr won't change, so check without lock */
1763 if (IA_SIN(tmp_ifa
)->sin_addr
.s_addr
==
1764 ia
->ia_addr
.sin_addr
.s_addr
) {
1765 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1768 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1770 tmp_ifp
= (tmp_ifa
== NULL
) ? NULL
: tmp_ifa
->ia_ifp
;
1772 IFA_LOCK(&ia
->ia_ifa
);
1773 if (tmp_ifp
== NULL
) {
1774 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1777 TAILQ_INSERT_TAIL(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1780 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1784 * Initialize an interface's internet address
1785 * and routing table entry.
1788 in_ifinit(struct ifnet
*ifp
, struct in_ifaddr
*ia
, struct sockaddr_in
*sin
,
1791 u_int32_t i
= ntohl(sin
->sin_addr
.s_addr
);
1792 struct sockaddr_in oldaddr
;
1793 int flags
= RTF_UP
, error
;
1794 struct ifaddr
*ifa0
;
1798 /* Take an extra reference for this routine */
1799 IFA_ADDREF(&ia
->ia_ifa
);
1801 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1802 IFA_LOCK(&ia
->ia_ifa
);
1803 oldaddr
= ia
->ia_addr
;
1804 if (IA_IS_HASHED(ia
)) {
1806 in_iahash_remove(ia
);
1810 * Interface addresses should not contain port or sin_zero information.
1812 SIN(&ia
->ia_addr
)->sin_family
= AF_INET
;
1813 SIN(&ia
->ia_addr
)->sin_len
= sizeof (struct sockaddr_in
);
1814 SIN(&ia
->ia_addr
)->sin_port
= 0;
1815 bzero(&SIN(&ia
->ia_addr
)->sin_zero
, sizeof (sin
->sin_zero
));
1816 if ((ifp
->if_flags
& IFF_POINTOPOINT
))
1817 in_iahash_insert_ptp(ia
);
1819 in_iahash_insert(ia
);
1820 IFA_UNLOCK(&ia
->ia_ifa
);
1821 lck_rw_done(in_ifaddr_rwlock
);
1824 * Give the interface a chance to initialize if this is its first
1825 * address, and to validate the address if necessary. Send down
1826 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es).
1827 * We find the first IPV4 address assigned to it and check if this
1828 * is the same as the one passed into this routine.
1830 ifa0
= ifa_ifpgetprimary(ifp
, AF_INET
);
1831 cmd
= (&ia
->ia_ifa
== ifa0
) ? SIOCSIFADDR
: SIOCAIFADDR
;
1832 error
= ifnet_ioctl(ifp
, PF_INET
, cmd
, ia
);
1833 if (error
== EOPNOTSUPP
)
1836 * If we've just sent down SIOCAIFADDR, send another ioctl down
1837 * for SIOCSIFADDR for the first IPV4 address of the interface,
1838 * because an address change on one of the addresses will result
1839 * in the removal of the previous first IPV4 address. KDP needs
1840 * be reconfigured with the current primary IPV4 address.
1842 if (error
== 0 && cmd
== SIOCAIFADDR
) {
1844 * NOTE: SIOCSIFADDR is defined with struct ifreq
1845 * as parameter, but here we are sending it down
1846 * to the interface with a pointer to struct ifaddr,
1847 * for legacy reasons.
1849 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa0
);
1850 if (error
== EOPNOTSUPP
)
1854 /* Release reference from ifa_ifpgetprimary() */
1858 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1859 IFA_LOCK(&ia
->ia_ifa
);
1860 if (IA_IS_HASHED(ia
))
1861 in_iahash_remove(ia
);
1862 ia
->ia_addr
= oldaddr
;
1864 if ((ifp
->if_flags
& IFF_POINTOPOINT
))
1865 in_iahash_insert_ptp(ia
);
1867 in_iahash_insert(ia
);
1869 IFA_UNLOCK(&ia
->ia_ifa
);
1870 lck_rw_done(in_ifaddr_rwlock
);
1871 /* Release extra reference taken above */
1872 IFA_REMREF(&ia
->ia_ifa
);
1875 lck_mtx_lock(rnh_lock
);
1876 IFA_LOCK(&ia
->ia_ifa
);
1878 * Address has been initialized by the link resolver (ARP)
1879 * via ifnet_ioctl() above; it may now generate route(s).
1881 ia
->ia_ifa
.ifa_debug
&= ~IFD_NOTREADY
;
1883 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&oldaddr
;
1884 IFA_UNLOCK(&ia
->ia_ifa
);
1885 in_ifscrub(ifp
, ia
, 1);
1886 IFA_LOCK(&ia
->ia_ifa
);
1887 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1889 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1891 ia
->ia_netmask
= IN_CLASSA_NET
;
1892 else if (IN_CLASSB(i
))
1893 ia
->ia_netmask
= IN_CLASSB_NET
;
1895 ia
->ia_netmask
= IN_CLASSC_NET
;
1897 * The subnet mask usually includes at least the standard network part,
1898 * but may may be smaller in the case of supernetting.
1899 * If it is set, we believe it.
1901 if (ia
->ia_subnetmask
== 0) {
1902 ia
->ia_subnetmask
= ia
->ia_netmask
;
1903 ia
->ia_sockmask
.sin_addr
.s_addr
= htonl(ia
->ia_subnetmask
);
1905 ia
->ia_netmask
&= ia
->ia_subnetmask
;
1906 ia
->ia_net
= i
& ia
->ia_netmask
;
1907 ia
->ia_subnet
= i
& ia
->ia_subnetmask
;
1908 in_socktrim(&ia
->ia_sockmask
);
1910 * Add route for the network.
1912 ia
->ia_ifa
.ifa_metric
= ifp
->if_metric
;
1913 if (ifp
->if_flags
& IFF_BROADCAST
) {
1914 ia
->ia_broadaddr
.sin_addr
.s_addr
=
1915 htonl(ia
->ia_subnet
| ~ia
->ia_subnetmask
);
1916 ia
->ia_netbroadcast
.s_addr
=
1917 htonl(ia
->ia_net
| ~ ia
->ia_netmask
);
1918 } else if (ifp
->if_flags
& IFF_LOOPBACK
) {
1919 ia
->ia_ifa
.ifa_dstaddr
= ia
->ia_ifa
.ifa_addr
;
1921 } else if (ifp
->if_flags
& IFF_POINTOPOINT
) {
1922 if (ia
->ia_dstaddr
.sin_family
!= AF_INET
) {
1923 IFA_UNLOCK(&ia
->ia_ifa
);
1924 lck_mtx_unlock(rnh_lock
);
1925 /* Release extra reference taken above */
1926 IFA_REMREF(&ia
->ia_ifa
);
1929 ia
->ia_dstaddr
.sin_len
= sizeof (struct sockaddr_in
);
1932 IFA_UNLOCK(&ia
->ia_ifa
);
1934 if ((error
= rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
, flags
)) == 0) {
1935 IFA_LOCK(&ia
->ia_ifa
);
1936 ia
->ia_flags
|= IFA_ROUTE
;
1937 IFA_UNLOCK(&ia
->ia_ifa
);
1939 lck_mtx_unlock(rnh_lock
);
1941 /* XXX check if the subnet route points to the same interface */
1942 if (error
== EEXIST
)
1946 * If the interface supports multicast, join the "all hosts"
1947 * multicast group on that interface.
1949 if (ifp
->if_flags
& IFF_MULTICAST
) {
1950 struct in_addr addr
;
1952 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
1953 addr
.s_addr
= htonl(INADDR_ALLHOSTS_GROUP
);
1954 if (ifp
->if_allhostsinm
== NULL
) {
1955 struct in_multi
*inm
;
1956 inm
= in_addmulti(&addr
, ifp
);
1960 * Keep the reference on inm added by
1961 * in_addmulti above for storing the
1962 * pointer in allhostsinm.
1964 ifp
->if_allhostsinm
= inm
;
1966 printf("%s: failed to add membership to "
1967 "all-hosts multicast address on %s\n",
1968 __func__
, if_name(ifp
));
1971 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
1974 /* Release extra reference taken above */
1975 IFA_REMREF(&ia
->ia_ifa
);
1978 /* invalidate route caches */
1979 routegenid_inet_update();
1986 * Return TRUE if the address might be a local broadcast address.
1989 in_broadcast(struct in_addr in
, struct ifnet
*ifp
)
1994 if (in
.s_addr
== INADDR_BROADCAST
|| in
.s_addr
== INADDR_ANY
)
1996 if (!(ifp
->if_flags
& IFF_BROADCAST
))
1998 t
= ntohl(in
.s_addr
);
2001 * Look through the list of addresses for a match
2002 * with a broadcast address.
2004 #define ia ((struct in_ifaddr *)ifa)
2005 ifnet_lock_shared(ifp
);
2006 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
2008 if (ifa
->ifa_addr
->sa_family
== AF_INET
&&
2009 (in
.s_addr
== ia
->ia_broadaddr
.sin_addr
.s_addr
||
2010 in
.s_addr
== ia
->ia_netbroadcast
.s_addr
||
2012 * Check for old-style (host 0) broadcast.
2014 t
== ia
->ia_subnet
|| t
== ia
->ia_net
) &&
2016 * Check for an all one subnetmask. These
2017 * only exist when an interface gets a secondary
2020 ia
->ia_subnetmask
!= (u_int32_t
)0xffffffff) {
2022 ifnet_lock_done(ifp
);
2027 ifnet_lock_done(ifp
);
2033 in_purgeaddrs(struct ifnet
*ifp
)
2035 struct ifaddr
**ifap
;
2038 VERIFY(ifp
!= NULL
);
2041 * Be nice, and try the civilized way first. If we can't get
2042 * rid of them this way, then do it the rough way. We must
2043 * only get here during detach time, after the ifnet has been
2044 * removed from the global list and arrays.
2046 err
= ifnet_get_address_list_family_internal(ifp
, &ifap
, AF_INET
, 1,
2048 if (err
== 0 && ifap
!= NULL
) {
2051 bzero(&ifr
, sizeof (ifr
));
2052 (void) snprintf(ifr
.ifr_name
, sizeof (ifr
.ifr_name
),
2053 "%s", if_name(ifp
));
2055 for (i
= 0; ifap
[i
] != NULL
; i
++) {
2060 bcopy(ifa
->ifa_addr
, &ifr
.ifr_addr
,
2061 sizeof (struct sockaddr_in
));
2063 err
= in_control(NULL
, SIOCDIFADDR
, (caddr_t
)&ifr
, ifp
,
2065 /* if we lost the race, ignore it */
2066 if (err
== EADDRNOTAVAIL
)
2069 char s_addr
[MAX_IPv4_STR_LEN
];
2070 char s_dstaddr
[MAX_IPv4_STR_LEN
];
2071 struct in_addr
*s
, *d
;
2074 s
= &((struct sockaddr_in
*)
2075 (void *)ifa
->ifa_addr
)->sin_addr
;
2076 d
= &((struct sockaddr_in
*)
2077 (void *)ifa
->ifa_dstaddr
)->sin_addr
;
2078 (void) inet_ntop(AF_INET
, &s
->s_addr
, s_addr
,
2080 (void) inet_ntop(AF_INET
, &d
->s_addr
, s_dstaddr
,
2081 sizeof (s_dstaddr
));
2084 printf("%s: SIOCDIFADDR ifp=%s ifa_addr=%s "
2085 "ifa_dstaddr=%s (err=%d)\n", __func__
,
2086 ifp
->if_xname
, s_addr
, s_dstaddr
, err
);
2089 ifnet_free_address_list(ifap
);
2090 } else if (err
!= 0 && err
!= ENXIO
) {
2091 printf("%s: error retrieving list of AF_INET addresses for "
2092 "ifp=%s (err=%d)\n", __func__
, ifp
->if_xname
, err
);
2097 * Select endpoint address(es). For now just take the first matching
2098 * address and discard the rest, if present.
2101 in_selectaddrs(int af
, struct sockaddr_list
**src_sl
,
2102 struct sockaddr_entry
**src_se
, struct sockaddr_list
**dst_sl
,
2103 struct sockaddr_entry
**dst_se
)
2105 struct sockaddr_entry
*se
;
2108 VERIFY(src_sl
!= NULL
&& dst_sl
!= NULL
&& *dst_sl
!= NULL
);
2109 VERIFY(src_se
!= NULL
&& dst_se
!= NULL
);
2111 *src_se
= *dst_se
= NULL
;
2113 /* pick a source address, if available */
2114 if (*src_sl
!= NULL
) {
2115 TAILQ_FOREACH(se
, &(*src_sl
)->sl_head
, se_link
) {
2116 VERIFY(se
->se_addr
!= NULL
);
2118 * Take the first source address, or the first
2119 * one with matching address family.
2121 if (af
== AF_UNSPEC
|| se
->se_addr
->sa_family
== af
) {
2122 sockaddrlist_remove(*src_sl
, se
);
2127 /* get rid of the rest */
2128 TAILQ_FOREACH(se
, &(*src_sl
)->sl_head
, se_link
) {
2129 sockaddrlist_remove(*src_sl
, se
);
2130 sockaddrentry_free(se
);
2132 if (*src_se
!= NULL
) {
2133 /* insert the first src address back in */
2134 sockaddrlist_insert(*src_sl
, *src_se
);
2135 VERIFY((*src_sl
)->sl_cnt
== 1);
2136 /* destination address must be of this family */
2137 af
= (*src_se
)->se_addr
->sa_family
;
2139 /* no usable source address with matching family */
2140 VERIFY(af
!= AF_UNSPEC
);
2141 error
= EAFNOSUPPORT
;
2145 /* pick a (matching) destination address */
2146 TAILQ_FOREACH(se
, &(*dst_sl
)->sl_head
, se_link
) {
2147 VERIFY(se
->se_addr
!= NULL
);
2149 * Take the first destination address; if source is specified,
2150 * find one which uses the same address family.
2152 if (af
== AF_UNSPEC
|| se
->se_addr
->sa_family
== af
) {
2153 sockaddrlist_remove(*dst_sl
, se
);
2158 /* get rid of the rest */
2159 TAILQ_FOREACH(se
, &(*dst_sl
)->sl_head
, se_link
) {
2160 sockaddrlist_remove(*dst_sl
, se
);
2161 sockaddrentry_free(se
);
2163 if (*dst_se
!= NULL
) {
2164 /* insert the first dst address back in */
2165 sockaddrlist_insert(*dst_sl
, *dst_se
);
2166 VERIFY((*dst_sl
)->sl_cnt
== 1);
2168 /* source and destination address families don't match */
2169 error
= EAFNOSUPPORT
;
2173 af
= (*dst_se
)->se_addr
->sa_family
;
2174 VERIFY(*src_se
== NULL
|| (*src_se
)->se_addr
->sa_family
== af
);
2176 /* verify address length */
2179 if ((*dst_se
)->se_addr
->sa_len
!=
2180 sizeof (struct sockaddr_in
)) {
2181 error
= EAFNOSUPPORT
;
2187 if ((*dst_se
)->se_addr
->sa_len
!=
2188 sizeof (struct sockaddr_in6
)) {
2189 error
= EAFNOSUPPORT
;
2195 error
= EAFNOSUPPORT
;
2199 /* if source address is specified, length must match destination */
2200 if (*src_se
!= NULL
&& (*src_se
)->se_addr
->sa_len
!=
2201 (*dst_se
)->se_addr
->sa_len
) {
2202 error
= EAFNOSUPPORT
;
2210 * Called as part of ip_init
2213 in_ifaddr_init(void)
2217 PE_parse_boot_argn("ifa_debug", &inifa_debug
, sizeof (inifa_debug
));
2219 inifa_size
= (inifa_debug
== 0) ? sizeof (struct in_ifaddr
) :
2220 sizeof (struct in_ifaddr_dbg
);
2222 inifa_zone
= zinit(inifa_size
, INIFA_ZONE_MAX
* inifa_size
,
2223 0, INIFA_ZONE_NAME
);
2224 if (inifa_zone
== NULL
) {
2225 panic("%s: failed allocating %s", __func__
, INIFA_ZONE_NAME
);
2228 zone_change(inifa_zone
, Z_EXPAND
, TRUE
);
2229 zone_change(inifa_zone
, Z_CALLERACCT
, FALSE
);
2231 lck_mtx_init(&inifa_trash_lock
, ifa_mtx_grp
, ifa_mtx_attr
);
2232 TAILQ_INIT(&inifa_trash_head
);
2235 static struct in_ifaddr
*
2236 in_ifaddr_alloc(int how
)
2238 struct in_ifaddr
*inifa
;
2240 inifa
= (how
== M_WAITOK
) ? zalloc(inifa_zone
) :
2241 zalloc_noblock(inifa_zone
);
2242 if (inifa
!= NULL
) {
2243 bzero(inifa
, inifa_size
);
2244 inifa
->ia_ifa
.ifa_free
= in_ifaddr_free
;
2245 inifa
->ia_ifa
.ifa_debug
|= IFD_ALLOC
;
2246 ifa_lock_init(&inifa
->ia_ifa
);
2247 if (inifa_debug
!= 0) {
2248 struct in_ifaddr_dbg
*inifa_dbg
=
2249 (struct in_ifaddr_dbg
*)inifa
;
2250 inifa
->ia_ifa
.ifa_debug
|= IFD_DEBUG
;
2251 inifa
->ia_ifa
.ifa_trace
= in_ifaddr_trace
;
2252 inifa
->ia_ifa
.ifa_attached
= in_ifaddr_attached
;
2253 inifa
->ia_ifa
.ifa_detached
= in_ifaddr_detached
;
2254 ctrace_record(&inifa_dbg
->inifa_alloc
);
2261 in_ifaddr_free(struct ifaddr
*ifa
)
2263 IFA_LOCK_ASSERT_HELD(ifa
);
2265 if (ifa
->ifa_refcnt
!= 0) {
2266 panic("%s: ifa %p bad ref cnt", __func__
, ifa
);
2268 } if (!(ifa
->ifa_debug
& IFD_ALLOC
)) {
2269 panic("%s: ifa %p cannot be freed", __func__
, ifa
);
2272 if (ifa
->ifa_debug
& IFD_DEBUG
) {
2273 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2274 ctrace_record(&inifa_dbg
->inifa_free
);
2275 bcopy(&inifa_dbg
->inifa
, &inifa_dbg
->inifa_old
,
2276 sizeof (struct in_ifaddr
));
2277 if (ifa
->ifa_debug
& IFD_TRASHED
) {
2278 /* Become a regular mutex, just in case */
2279 IFA_CONVERT_LOCK(ifa
);
2280 lck_mtx_lock(&inifa_trash_lock
);
2281 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
,
2283 lck_mtx_unlock(&inifa_trash_lock
);
2284 ifa
->ifa_debug
&= ~IFD_TRASHED
;
2288 ifa_lock_destroy(ifa
);
2289 bzero(ifa
, sizeof (struct in_ifaddr
));
2290 zfree(inifa_zone
, ifa
);
2294 in_ifaddr_attached(struct ifaddr
*ifa
)
2296 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2298 IFA_LOCK_ASSERT_HELD(ifa
);
2300 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2301 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2304 if (ifa
->ifa_debug
& IFD_TRASHED
) {
2305 /* Become a regular mutex, just in case */
2306 IFA_CONVERT_LOCK(ifa
);
2307 lck_mtx_lock(&inifa_trash_lock
);
2308 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
2309 lck_mtx_unlock(&inifa_trash_lock
);
2310 ifa
->ifa_debug
&= ~IFD_TRASHED
;
2315 in_ifaddr_detached(struct ifaddr
*ifa
)
2317 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2319 IFA_LOCK_ASSERT_HELD(ifa
);
2321 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2322 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2324 } else if (ifa
->ifa_debug
& IFD_TRASHED
) {
2325 panic("%s: ifa %p is already in trash list", __func__
, ifa
);
2328 ifa
->ifa_debug
|= IFD_TRASHED
;
2329 /* Become a regular mutex, just in case */
2330 IFA_CONVERT_LOCK(ifa
);
2331 lck_mtx_lock(&inifa_trash_lock
);
2332 TAILQ_INSERT_TAIL(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
2333 lck_mtx_unlock(&inifa_trash_lock
);
2337 in_ifaddr_trace(struct ifaddr
*ifa
, int refhold
)
2339 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2344 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2345 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2349 cnt
= &inifa_dbg
->inifa_refhold_cnt
;
2350 tr
= inifa_dbg
->inifa_refhold
;
2352 cnt
= &inifa_dbg
->inifa_refrele_cnt
;
2353 tr
= inifa_dbg
->inifa_refrele
;
2356 idx
= atomic_add_16_ov(cnt
, 1) % INIFA_TRACE_HIST_SIZE
;
2357 ctrace_record(&tr
[idx
]);
2361 * Handle SIOCGASSOCIDS ioctl for PF_INET domain.
2364 in_getassocids(struct socket
*so
, uint32_t *cnt
, user_addr_t aidp
)
2366 struct inpcb
*inp
= sotoinpcb(so
);
2369 if (inp
== NULL
|| inp
->inp_state
== INPCB_STATE_DEAD
)
2372 /* INPCB has no concept of association */
2376 /* just asking how many there are? */
2377 if (aidp
== USER_ADDR_NULL
)
2380 return (copyout(&aid
, aidp
, sizeof (aid
)));
2384 * Handle SIOCGCONNIDS ioctl for PF_INET domain.
2387 in_getconnids(struct socket
*so
, associd_t aid
, uint32_t *cnt
,
2390 struct inpcb
*inp
= sotoinpcb(so
);
2393 if (inp
== NULL
|| inp
->inp_state
== INPCB_STATE_DEAD
)
2396 if (aid
!= ASSOCID_ANY
&& aid
!= ASSOCID_ALL
)
2399 /* if connected, return 1 connection count */
2400 *cnt
= ((so
->so_state
& SS_ISCONNECTED
) ? 1 : 0);
2402 /* just asking how many there are? */
2403 if (cidp
== USER_ADDR_NULL
)
2406 /* if INPCB is connected, assign it connid 1 */
2407 cid
= ((*cnt
!= 0) ? 1 : CONNID_ANY
);
2409 return (copyout(&cid
, cidp
, sizeof (cid
)));
2413 * Handle SIOCGCONNINFO ioctl for PF_INET domain.
2416 in_getconninfo(struct socket
*so
, connid_t cid
, uint32_t *flags
,
2417 uint32_t *ifindex
, int32_t *soerror
, user_addr_t src
, socklen_t
*src_len
,
2418 user_addr_t dst
, socklen_t
*dst_len
, uint32_t *aux_type
,
2419 user_addr_t aux_data
, uint32_t *aux_len
)
2421 #pragma unused(aux_data)
2422 struct inpcb
*inp
= sotoinpcb(so
);
2423 struct sockaddr_in sin
;
2424 struct ifnet
*ifp
= NULL
;
2426 u_int32_t copy_len
= 0;
2429 * Don't test for INPCB_STATE_DEAD since this may be called
2430 * after SOF_PCBCLEARING is set, e.g. after tcp_close().
2437 if (cid
!= CONNID_ANY
&& cid
!= CONNID_ALL
&& cid
!= 1) {
2442 ifp
= inp
->inp_last_outifp
;
2443 *ifindex
= ((ifp
!= NULL
) ? ifp
->if_index
: 0);
2444 *soerror
= so
->so_error
;
2446 if (so
->so_state
& SS_ISCONNECTED
)
2447 *flags
|= (CIF_CONNECTED
| CIF_PREFERRED
);
2448 if (inp
->inp_flags
& INP_BOUND_IF
)
2449 *flags
|= CIF_BOUND_IF
;
2450 if (!(inp
->inp_flags
& INP_INADDR_ANY
))
2451 *flags
|= CIF_BOUND_IP
;
2452 if (!(inp
->inp_flags
& INP_ANONPORT
))
2453 *flags
|= CIF_BOUND_PORT
;
2455 bzero(&sin
, sizeof (sin
));
2456 sin
.sin_len
= sizeof (sin
);
2457 sin
.sin_family
= AF_INET
;
2459 /* source address and port */
2460 sin
.sin_port
= inp
->inp_lport
;
2461 sin
.sin_addr
.s_addr
= inp
->inp_laddr
.s_addr
;
2462 if (*src_len
== 0) {
2463 *src_len
= sin
.sin_len
;
2465 if (src
!= USER_ADDR_NULL
) {
2466 copy_len
= min(*src_len
, sizeof (sin
));
2467 error
= copyout(&sin
, src
, copy_len
);
2470 *src_len
= copy_len
;
2474 /* destination address and port */
2475 sin
.sin_port
= inp
->inp_fport
;
2476 sin
.sin_addr
.s_addr
= inp
->inp_faddr
.s_addr
;
2477 if (*dst_len
== 0) {
2478 *dst_len
= sin
.sin_len
;
2480 if (dst
!= USER_ADDR_NULL
) {
2481 copy_len
= min(*dst_len
, sizeof (sin
));
2482 error
= copyout(&sin
, dst
, copy_len
);
2485 *dst_len
= copy_len
;
2491 if (SOCK_PROTO(so
) == IPPROTO_TCP
) {
2492 struct conninfo_tcp tcp_ci
;
2494 *aux_type
= CIAUX_TCP
;
2495 if (*aux_len
== 0) {
2496 *aux_len
= sizeof (tcp_ci
);
2498 if (aux_data
!= USER_ADDR_NULL
) {
2499 copy_len
= min(*aux_len
, sizeof (tcp_ci
));
2500 bzero(&tcp_ci
, sizeof (tcp_ci
));
2501 tcp_getconninfo(so
, &tcp_ci
);
2502 error
= copyout(&tcp_ci
, aux_data
, copy_len
);
2505 *aux_len
= copy_len
;