2  * Copyright (c) 2000-2015 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29  * Copyright (c) 1982, 1986, 1991, 1993 
  30  *      The Regents of the University of California.  All rights reserved. 
  32  * Redistribution and use in source and binary forms, with or without 
  33  * modification, are permitted provided that the following conditions 
  35  * 1. Redistributions of source code must retain the above copyright 
  36  *    notice, this list of conditions and the following disclaimer. 
  37  * 2. Redistributions in binary form must reproduce the above copyright 
  38  *    notice, this list of conditions and the following disclaimer in the 
  39  *    documentation and/or other materials provided with the distribution. 
  40  * 3. All advertising materials mentioning features or use of this software 
  41  *    must display the following acknowledgement: 
  42  *      This product includes software developed by the University of 
  43  *      California, Berkeley and its contributors. 
  44  * 4. Neither the name of the University nor the names of its contributors 
  45  *    may be used to endorse or promote products derived from this software 
  46  *    without specific prior written permission. 
  48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  60  *      @(#)in.c        8.4 (Berkeley) 1/9/95 
  63 #include <sys/param.h> 
  64 #include <sys/systm.h> 
  65 #include <sys/sockio.h> 
  66 #include <sys/socketvar.h> 
  67 #include <sys/malloc.h> 
  69 #include <sys/socket.h> 
  70 #include <sys/kernel.h> 
  71 #include <sys/sysctl.h> 
  72 #include <sys/kern_event.h> 
  73 #include <sys/syslog.h> 
  74 #include <sys/mcache.h> 
  75 #include <sys/protosw.h> 
  78 #include <kern/zalloc.h> 
  79 #include <pexpert/pexpert.h> 
  82 #include <net/if_types.h> 
  83 #include <net/route.h> 
  84 #include <net/kpi_protocol.h> 
  87 #include <net/pfvar.h> 
  90 #include <netinet/in.h> 
  91 #include <netinet/in_var.h> 
  92 #include <netinet/in_pcb.h> 
  93 #include <netinet/igmp_var.h> 
  94 #include <netinet/ip_var.h> 
  95 #include <netinet/tcp.h> 
  96 #include <netinet/tcp_timer.h> 
  97 #include <netinet/tcp_var.h> 
  99 static int inctl_associd(struct socket 
*, u_long
, caddr_t
); 
 100 static int inctl_connid(struct socket 
*, u_long
, caddr_t
); 
 101 static int inctl_conninfo(struct socket 
*, u_long
, caddr_t
); 
 102 static int inctl_autoaddr(struct ifnet 
*, struct ifreq 
*); 
 103 static int inctl_arpipll(struct ifnet 
*, struct ifreq 
*); 
 104 static int inctl_setrouter(struct ifnet 
*, struct ifreq 
*); 
 105 static int inctl_ifaddr(struct ifnet 
*, struct in_ifaddr 
*, u_long
, 
 107 static int inctl_ifdstaddr(struct ifnet 
*, struct in_ifaddr 
*, u_long
, 
 109 static int inctl_ifbrdaddr(struct ifnet 
*, struct in_ifaddr 
*, u_long
, 
 111 static int inctl_ifnetmask(struct ifnet 
*, struct in_ifaddr 
*, u_long
, 
 114 static void in_socktrim(struct sockaddr_in 
*); 
 115 static int in_ifinit(struct ifnet 
*, struct in_ifaddr 
*, 
 116     struct sockaddr_in 
*, int); 
 118 #define IA_HASH_INIT(ia) {                                      \ 
 119         (ia)->ia_hash.tqe_next = (void *)(uintptr_t)-1;         \ 
 120         (ia)->ia_hash.tqe_prev = (void *)(uintptr_t)-1;         \ 
 123 #define IA_IS_HASHED(ia)                                        \ 
 124         (!((ia)->ia_hash.tqe_next == (void *)(uintptr_t)-1 ||   \ 
 125         (ia)->ia_hash.tqe_prev == (void *)(uintptr_t)-1)) 
 127 static void in_iahash_remove(struct in_ifaddr 
*); 
 128 static void in_iahash_insert(struct in_ifaddr 
*); 
 129 static void in_iahash_insert_ptp(struct in_ifaddr 
*); 
 130 static struct in_ifaddr 
*in_ifaddr_alloc(int); 
 131 static void in_ifaddr_attached(struct ifaddr 
*); 
 132 static void in_ifaddr_detached(struct ifaddr 
*); 
 133 static void in_ifaddr_free(struct ifaddr 
*); 
 134 static void in_ifaddr_trace(struct ifaddr 
*, int); 
 136 static int in_getassocids(struct socket 
*, uint32_t *, user_addr_t
); 
 137 static int in_getconnids(struct socket 
*, sae_associd_t
, uint32_t *, user_addr_t
); 
 138 static int in_getconninfo(struct socket 
*, sae_connid_t
, uint32_t *, 
 139     uint32_t *, int32_t *, user_addr_t
, socklen_t 
*, user_addr_t
, socklen_t 
*, 
 140     uint32_t *, user_addr_t
, uint32_t *); 
 142 static int subnetsarelocal 
= 0; 
 143 SYSCTL_INT(_net_inet_ip
, OID_AUTO
, subnets_are_local
, 
 144         CTLFLAG_RW 
| CTLFLAG_LOCKED
, &subnetsarelocal
, 0, ""); 
 146 /* Track whether or not the SIOCARPIPLL ioctl has been called */ 
 147 u_int32_t ipv4_ll_arp_aware 
= 0; 
 149 #define INIFA_TRACE_HIST_SIZE   32      /* size of trace history */ 
 152 __private_extern__ 
unsigned int inifa_trace_hist_size 
= INIFA_TRACE_HIST_SIZE
; 
 154 struct in_ifaddr_dbg 
{ 
 155         struct in_ifaddr        inifa
;                  /* in_ifaddr */ 
 156         struct in_ifaddr        inifa_old
;              /* saved in_ifaddr */ 
 157         u_int16_t               inifa_refhold_cnt
;      /* # of IFA_ADDREF */ 
 158         u_int16_t               inifa_refrele_cnt
;      /* # of IFA_REMREF */ 
 160          * Alloc and free callers. 
 162         ctrace_t                inifa_alloc
; 
 165          * Circular lists of IFA_ADDREF and IFA_REMREF callers. 
 167         ctrace_t                inifa_refhold
[INIFA_TRACE_HIST_SIZE
]; 
 168         ctrace_t                inifa_refrele
[INIFA_TRACE_HIST_SIZE
]; 
 172         TAILQ_ENTRY(in_ifaddr_dbg
) inifa_trash_link
; 
 175 /* List of trash in_ifaddr entries protected by inifa_trash_lock */ 
 176 static TAILQ_HEAD(, in_ifaddr_dbg
) inifa_trash_head
; 
 177 static decl_lck_mtx_data(, inifa_trash_lock
); 
 180 static unsigned int inifa_debug 
= 1;            /* debugging (enabled) */ 
 182 static unsigned int inifa_debug
;                /* debugging (disabled) */ 
 184 static unsigned int inifa_size
;                 /* size of zone element */ 
 185 static struct zone 
*inifa_zone
;                 /* zone for in_ifaddr */ 
 187 #define INIFA_ZONE_MAX          64              /* maximum elements in zone */ 
 188 #define INIFA_ZONE_NAME         "in_ifaddr"     /* zone name */ 
 190 static const unsigned int in_extra_size 
= sizeof (struct in_ifextra
); 
 191 static const unsigned int in_extra_bufsize 
= in_extra_size 
+ 
 192     sizeof (void *) + sizeof (uint64_t); 
 195  * Return 1 if the address is 
 197  * - unicast or multicast link local 
 198  * - routed via a link level gateway 
 199  * - belongs to a directly connected (sub)net 
 202 inaddr_local(struct in_addr in
) 
 205         struct sockaddr_in sin
; 
 208         if (ntohl(in
.s_addr
) == INADDR_LOOPBACK 
|| 
 209             IN_LINKLOCAL(ntohl(in
.s_addr
))) { 
 211         } else if (ntohl(in
.s_addr
) >= INADDR_UNSPEC_GROUP 
&& 
 212             ntohl(in
.s_addr
) <= INADDR_MAX_LOCAL_GROUP
) { 
 215                 sin
.sin_family 
= AF_INET
; 
 216                 sin
.sin_len 
= sizeof (sin
); 
 218                 rt 
= rtalloc1((struct sockaddr 
*)&sin
, 0, 0); 
 222                         if (rt
->rt_gateway
->sa_family 
== AF_LINK 
|| 
 223                             (rt
->rt_ifp
->if_flags 
& IFF_LOOPBACK
)) 
 228                         local 
= in_localaddr(in
); 
 235  * Return 1 if an internet address is for a ``local'' host 
 236  * (one to which we have a connection).  If subnetsarelocal 
 237  * is true, this includes other subnets of the local net. 
 238  * Otherwise, it includes only the directly-connected (sub)nets. 
 241 in_localaddr(struct in_addr in
) 
 243         u_int32_t i 
= ntohl(in
.s_addr
); 
 244         struct in_ifaddr 
*ia
; 
 246         if (subnetsarelocal
) { 
 247                 lck_rw_lock_shared(in_ifaddr_rwlock
); 
 248                 for (ia 
= in_ifaddrhead
.tqh_first
; ia 
!= NULL
; 
 249                     ia 
= ia
->ia_link
.tqe_next
) { 
 250                         IFA_LOCK(&ia
->ia_ifa
); 
 251                         if ((i 
& ia
->ia_netmask
) == ia
->ia_net
) { 
 252                                 IFA_UNLOCK(&ia
->ia_ifa
); 
 253                                 lck_rw_done(in_ifaddr_rwlock
); 
 256                         IFA_UNLOCK(&ia
->ia_ifa
); 
 258                 lck_rw_done(in_ifaddr_rwlock
); 
 260                 lck_rw_lock_shared(in_ifaddr_rwlock
); 
 261                 for (ia 
= in_ifaddrhead
.tqh_first
; ia 
!= NULL
; 
 262                     ia 
= ia
->ia_link
.tqe_next
) { 
 263                         IFA_LOCK(&ia
->ia_ifa
); 
 264                         if ((i 
& ia
->ia_subnetmask
) == ia
->ia_subnet
) { 
 265                                 IFA_UNLOCK(&ia
->ia_ifa
); 
 266                                 lck_rw_done(in_ifaddr_rwlock
); 
 269                         IFA_UNLOCK(&ia
->ia_ifa
); 
 271                 lck_rw_done(in_ifaddr_rwlock
); 
 277  * Determine whether an IP address is in a reserved set of addresses 
 278  * that may not be forwarded, or whether datagrams to that destination 
 282 in_canforward(struct in_addr in
) 
 284         u_int32_t i 
= ntohl(in
.s_addr
); 
 287         if (IN_EXPERIMENTAL(i
) || IN_MULTICAST(i
)) 
 290                 net 
= i 
& IN_CLASSA_NET
; 
 291                 if (net 
== 0 || net 
== (IN_LOOPBACKNET 
<< IN_CLASSA_NSHIFT
)) 
 298  * Trim a mask in a sockaddr 
 301 in_socktrim(struct sockaddr_in 
*ap
) 
 303         char *cplim 
= (char *)&ap
->sin_addr
; 
 304         char *cp 
= (char *)(&ap
->sin_addr 
+ 1); 
 307         while (--cp 
>= cplim
) 
 309                         (ap
)->sin_len 
= cp 
- (char *)(ap
) + 1; 
 314 static int in_interfaces
;       /* number of external internet interfaces */ 
 317 in_domifattach(struct ifnet 
*ifp
) 
 323         if ((error 
= proto_plumb(PF_INET
, ifp
)) && error 
!= EEXIST
) { 
 324                 log(LOG_ERR
, "%s: proto_plumb returned %d if=%s\n", 
 325                     __func__
, error
, if_name(ifp
)); 
 326         } else if (error 
== 0 && ifp
->if_inetdata 
== NULL
) { 
 328                 struct in_ifextra 
*ext
; 
 331                 if ((ext 
= (struct in_ifextra 
*)_MALLOC(in_extra_bufsize
, 
 332                     M_IFADDR
, M_WAITOK
|M_ZERO
)) == NULL
) { 
 334                         errorx 
= proto_unplumb(PF_INET
, ifp
); 
 337                                     "%s: proto_unplumb returned %d if=%s%d\n", 
 338                                     __func__
, errorx
, ifp
->if_name
, 
 344                 /* Align on 64-bit boundary */ 
 345                 base 
= (void *)P2ROUNDUP((intptr_t)ext 
+ sizeof (uint64_t), 
 347                 VERIFY(((intptr_t)base 
+ in_extra_size
) <= 
 348                     ((intptr_t)ext 
+ in_extra_bufsize
)); 
 349                 pbuf 
= (void **)((intptr_t)base 
- sizeof (void *)); 
 351                 ifp
->if_inetdata 
= base
; 
 352                 VERIFY(IS_P2ALIGNED(ifp
->if_inetdata
, sizeof (uint64_t))); 
 355         if (error 
== 0 && ifp
->if_inetdata 
!= NULL
) { 
 357                  * Since the structure is never freed, we need to 
 358                  * zero out its contents to avoid reusing stale data. 
 359                  * A little redundant with allocation above, but it 
 360                  * keeps the code simpler for all cases. 
 362                 bzero(ifp
->if_inetdata
, in_extra_size
); 
 367 static __attribute__((noinline
)) int 
 368 inctl_associd(struct socket 
*so
, u_long cmd
, caddr_t data
) 
 372                 struct so_aidreq32 a32
; 
 373                 struct so_aidreq64 a64
; 
 379         case SIOCGASSOCIDS32
:           /* struct so_aidreq32 */ 
 380                 bcopy(data
, &u
.a32
, sizeof (u
.a32
)); 
 381                 error 
= in_getassocids(so
, &u
.a32
.sar_cnt
, u
.a32
.sar_aidp
); 
 383                         bcopy(&u
.a32
, data
, sizeof (u
.a32
)); 
 386         case SIOCGASSOCIDS64
:           /* struct so_aidreq64 */ 
 387                 bcopy(data
, &u
.a64
, sizeof (u
.a64
)); 
 388                 error 
= in_getassocids(so
, &u
.a64
.sar_cnt
, u
.a64
.sar_aidp
); 
 390                         bcopy(&u
.a64
, data
, sizeof (u
.a64
)); 
 401 static __attribute__((noinline
)) int 
 402 inctl_connid(struct socket 
*so
, u_long cmd
, caddr_t data
) 
 406                 struct so_cidreq32 c32
; 
 407                 struct so_cidreq64 c64
; 
 413         case SIOCGCONNIDS32
:            /* struct so_cidreq32 */ 
 414                 bcopy(data
, &u
.c32
, sizeof (u
.c32
)); 
 415                 error 
= in_getconnids(so
, u
.c32
.scr_aid
, &u
.c32
.scr_cnt
, 
 418                         bcopy(&u
.c32
, data
, sizeof (u
.c32
)); 
 421         case SIOCGCONNIDS64
:            /* struct so_cidreq64 */ 
 422                 bcopy(data
, &u
.c64
, sizeof (u
.c64
)); 
 423                 error 
= in_getconnids(so
, u
.c64
.scr_aid
, &u
.c64
.scr_cnt
, 
 426                         bcopy(&u
.c64
, data
, sizeof (u
.c64
)); 
 437 static __attribute__((noinline
)) int 
 438 inctl_conninfo(struct socket 
*so
, u_long cmd
, caddr_t data
) 
 442                 struct so_cinforeq32 ci32
; 
 443                 struct so_cinforeq64 ci64
; 
 449         case SIOCGCONNINFO32
:           /* struct so_cinforeq32 */ 
 450                 bcopy(data
, &u
.ci32
, sizeof (u
.ci32
)); 
 451                 error 
= in_getconninfo(so
, u
.ci32
.scir_cid
, &u
.ci32
.scir_flags
, 
 452                     &u
.ci32
.scir_ifindex
, &u
.ci32
.scir_error
, u
.ci32
.scir_src
, 
 453                     &u
.ci32
.scir_src_len
, u
.ci32
.scir_dst
, &u
.ci32
.scir_dst_len
, 
 454                     &u
.ci32
.scir_aux_type
, u
.ci32
.scir_aux_data
, 
 455                     &u
.ci32
.scir_aux_len
); 
 457                         bcopy(&u
.ci32
, data
, sizeof (u
.ci32
)); 
 460         case SIOCGCONNINFO64
:           /* struct so_cinforeq64 */ 
 461                 bcopy(data
, &u
.ci64
, sizeof (u
.ci64
)); 
 462                 error 
= in_getconninfo(so
, u
.ci64
.scir_cid
, &u
.ci64
.scir_flags
, 
 463                     &u
.ci64
.scir_ifindex
, &u
.ci64
.scir_error
, u
.ci64
.scir_src
, 
 464                     &u
.ci64
.scir_src_len
, u
.ci64
.scir_dst
, &u
.ci64
.scir_dst_len
, 
 465                     &u
.ci64
.scir_aux_type
, u
.ci64
.scir_aux_data
, 
 466                     &u
.ci64
.scir_aux_len
); 
 468                         bcopy(&u
.ci64
, data
, sizeof (u
.ci64
)); 
 480  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 481  * expectation that this routine always uses bcopy() or other byte-aligned 
 484 static __attribute__((noinline
)) int 
 485 inctl_autoaddr(struct ifnet 
*ifp
, struct ifreq 
*ifr
) 
 487         int error 
= 0, intval
; 
 491         bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
)); 
 493         ifnet_lock_exclusive(ifp
); 
 496                  * An interface in IPv4 router mode implies that it 
 497                  * is configured with a static IP address and should 
 498                  * not act as a DHCP client; prevent SIOCAUTOADDR from 
 499                  * being set in that mode. 
 501                 if (ifp
->if_eflags 
& IFEF_IPV4_ROUTER
) { 
 502                         intval 
= 0;     /* be safe; clear flag if set */ 
 505                         ifp
->if_eflags 
|= IFEF_AUTOCONFIGURING
; 
 509                 ifp
->if_eflags 
&= ~IFEF_AUTOCONFIGURING
; 
 510         ifnet_lock_done(ifp
); 
 516  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 517  * expectation that this routine always uses bcopy() or other byte-aligned 
 520 static __attribute__((noinline
)) int 
 521 inctl_arpipll(struct ifnet 
*ifp
, struct ifreq 
*ifr
) 
 523         int error 
= 0, intval
; 
 527         bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
)); 
 528         ipv4_ll_arp_aware 
= 1; 
 530         ifnet_lock_exclusive(ifp
); 
 533                  * An interface in IPv4 router mode implies that it 
 534                  * is configured with a static IP address and should 
 535                  * not have to deal with IPv4 Link-Local Address; 
 536                  * prevent SIOCARPIPLL from being set in that mode. 
 538                 if (ifp
->if_eflags 
& IFEF_IPV4_ROUTER
) { 
 539                         intval 
= 0;     /* be safe; clear flag if set */ 
 542                         ifp
->if_eflags 
|= IFEF_ARPLL
; 
 546                 ifp
->if_eflags 
&= ~IFEF_ARPLL
; 
 547         ifnet_lock_done(ifp
); 
 553  * Handle SIOCSETROUTERMODE to set or clear the IPv4 router mode flag on 
 554  * the interface.  When in this mode, IPv4 Link-Local Address support is 
 555  * disabled in ARP, and DHCP client support is disabled in IP input; turning 
 556  * any of them on would cause an error to be returned.  Entering or exiting 
 557  * this mode will result in the removal of IPv4 addresses currently configured 
 560  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 561  * expectation that this routine always uses bcopy() or other byte-aligned 
 564 static __attribute__((noinline
)) int 
 565 inctl_setrouter(struct ifnet 
*ifp
, struct ifreq 
*ifr
) 
 567         int error 
= 0, intval
; 
 571         /* Router mode isn't valid for loopback */ 
 572         if (ifp
->if_flags 
& IFF_LOOPBACK
) 
 575         bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
)); 
 577         ifnet_lock_exclusive(ifp
); 
 579                 ifp
->if_eflags 
|= IFEF_IPV4_ROUTER
; 
 580                 ifp
->if_eflags 
&= ~(IFEF_ARPLL 
| IFEF_AUTOCONFIGURING
); 
 582                 ifp
->if_eflags 
&= ~IFEF_IPV4_ROUTER
; 
 584         ifnet_lock_done(ifp
); 
 586         /* purge all IPv4 addresses configured on this interface */ 
 593  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 594  * expectation that this routine always uses bcopy() or other byte-aligned 
 597 static __attribute__((noinline
)) int 
 598 inctl_ifaddr(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, u_long cmd
, 
 601         struct kev_in_data in_event_data
; 
 602         struct kev_msg ev_msg
; 
 603         struct sockaddr_in addr
; 
 609         bzero(&in_event_data
, sizeof (struct kev_in_data
)); 
 610         bzero(&ev_msg
, sizeof (struct kev_msg
)); 
 613         case SIOCGIFADDR
:               /* struct ifreq */ 
 615                         error 
= EADDRNOTAVAIL
; 
 618                 IFA_LOCK(&ia
->ia_ifa
); 
 619                 bcopy(&ia
->ia_addr
, &ifr
->ifr_addr
, sizeof (addr
)); 
 620                 IFA_UNLOCK(&ia
->ia_ifa
); 
 623         case SIOCSIFADDR
:               /* struct ifreq */ 
 625                 bcopy(&ifr
->ifr_addr
, &addr
, sizeof (addr
)); 
 627                  * If this is a new address, the reference count for the 
 628                  * hash table has been taken at creation time above. 
 630                 error 
= in_ifinit(ifp
, ia
, &addr
, 1); 
 632                         (void) ifnet_notify_address(ifp
, AF_INET
); 
 636         case SIOCAIFADDR
: {             /* struct {if,in_}aliasreq */ 
 637                 struct in_aliasreq 
*ifra 
= (struct in_aliasreq 
*)ifr
; 
 638                 struct sockaddr_in broadaddr
, mask
; 
 639                 int hostIsNew
, maskIsNew
; 
 642                 bcopy(&ifra
->ifra_addr
, &addr
, sizeof (addr
)); 
 643                 bcopy(&ifra
->ifra_broadaddr
, &broadaddr
, sizeof (broadaddr
)); 
 644                 bcopy(&ifra
->ifra_mask
, &mask
, sizeof (mask
)); 
 650                 IFA_LOCK(&ia
->ia_ifa
); 
 651                 if (ia
->ia_addr
.sin_family 
== AF_INET
) { 
 652                         if (addr
.sin_len 
== 0) { 
 655                         } else if (addr
.sin_addr
.s_addr 
== 
 656                             ia
->ia_addr
.sin_addr
.s_addr
) { 
 661                         IFA_UNLOCK(&ia
->ia_ifa
); 
 662                         in_ifscrub(ifp
, ia
, 0); 
 663                         IFA_LOCK(&ia
->ia_ifa
); 
 664                         ia
->ia_sockmask 
= mask
; 
 666                             ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
); 
 669                 if ((ifp
->if_flags 
& IFF_POINTOPOINT
) && 
 670                     (broadaddr
.sin_family 
== AF_INET
)) { 
 671                         IFA_UNLOCK(&ia
->ia_ifa
); 
 672                         in_ifscrub(ifp
, ia
, 0); 
 673                         IFA_LOCK(&ia
->ia_ifa
); 
 674                         ia
->ia_dstaddr 
= broadaddr
; 
 675                         ia
->ia_dstaddr
.sin_len 
= sizeof (struct sockaddr_in
); 
 676                         maskIsNew  
= 1; /* We lie; but the effect's the same */ 
 678                 if (addr
.sin_family 
== AF_INET 
&& (hostIsNew 
|| maskIsNew
)) { 
 679                         IFA_UNLOCK(&ia
->ia_ifa
); 
 680                         error 
= in_ifinit(ifp
, ia
, &addr
, 0); 
 682                         IFA_UNLOCK(&ia
->ia_ifa
); 
 685                         (void) ifnet_notify_address(ifp
, AF_INET
); 
 687                 IFA_LOCK(&ia
->ia_ifa
); 
 688                 if ((ifp
->if_flags 
& IFF_BROADCAST
) && 
 689                     (broadaddr
.sin_family 
== AF_INET
)) 
 690                         ia
->ia_broadaddr 
= broadaddr
; 
 695                 if ((error 
== 0) || (error 
== EEXIST
)) { 
 696                         ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
 697                         ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
 698                         ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
 701                                 ev_msg
.event_code 
= KEV_INET_NEW_ADDR
; 
 703                                 ev_msg
.event_code 
= KEV_INET_CHANGED_ADDR
; 
 705                         if (ia
->ia_ifa
.ifa_dstaddr
) { 
 706                                 in_event_data
.ia_dstaddr 
= 
 707                                     ((struct sockaddr_in 
*)(void *)ia
-> 
 708                                     ia_ifa
.ifa_dstaddr
)->sin_addr
; 
 710                                 in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
 712                         in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
 713                         in_event_data
.ia_net            
= ia
->ia_net
; 
 714                         in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
 715                         in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
 716                         in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
 717                         in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
 718                         IFA_UNLOCK(&ia
->ia_ifa
); 
 719                         (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
 720                             ifp
->if_name
, IFNAMSIZ
); 
 721                         in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
 722                         in_event_data
.link_data
.if_unit 
= ifp
->if_unit
; 
 724                         ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
 725                         ev_msg
.dv
[0].data_length 
= sizeof (struct kev_in_data
); 
 726                         ev_msg
.dv
[1].data_length 
= 0; 
 728                         kev_post_msg(&ev_msg
); 
 730                         IFA_UNLOCK(&ia
->ia_ifa
); 
 735         case SIOCDIFADDR
:               /* struct ifreq */ 
 737                 error 
= ifnet_ioctl(ifp
, PF_INET
, SIOCDIFADDR
, ia
); 
 738                 if (error 
== EOPNOTSUPP
) 
 743                 /* Fill out the kernel event information */ 
 744                 ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
 745                 ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
 746                 ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
 748                 ev_msg
.event_code       
= KEV_INET_ADDR_DELETED
; 
 750                 IFA_LOCK(&ia
->ia_ifa
); 
 751                 if (ia
->ia_ifa
.ifa_dstaddr
) { 
 752                         in_event_data
.ia_dstaddr 
= ((struct sockaddr_in 
*) 
 753                             (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
; 
 755                         in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
 757                 in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
 758                 in_event_data
.ia_net            
= ia
->ia_net
; 
 759                 in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
 760                 in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
 761                 in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
 762                 in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
 763                 IFA_UNLOCK(&ia
->ia_ifa
); 
 764                 (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
 765                     ifp
->if_name
, IFNAMSIZ
); 
 766                 in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
 767                 in_event_data
.link_data
.if_unit  
= (u_int32_t
)ifp
->if_unit
; 
 769                 ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
 770                 ev_msg
.dv
[0].data_length 
= sizeof(struct kev_in_data
); 
 771                 ev_msg
.dv
[1].data_length 
= 0; 
 774                 lck_rw_lock_exclusive(in_ifaddr_rwlock
); 
 775                 /* Release ia_link reference */ 
 777                 TAILQ_REMOVE(&in_ifaddrhead
, ia
, ia_link
); 
 779                 if (IA_IS_HASHED(ia
)) 
 780                         in_iahash_remove(ia
); 
 782                 lck_rw_done(in_ifaddr_rwlock
); 
 785                  * in_ifscrub kills the interface route. 
 787                 in_ifscrub(ifp
, ia
, 0); 
 788                 ifnet_lock_exclusive(ifp
); 
 790                 /* if_detach_ifa() releases ifa_link reference */ 
 791                 if_detach_ifa(ifp
, ifa
); 
 792                 /* Our reference to this address is dropped at the bottom */ 
 795                 /* invalidate route caches */ 
 796                 routegenid_inet_update(); 
 799                  * If the interface supports multicast, and no address is left, 
 800                  * remove the "all hosts" multicast group from that interface. 
 802                 if ((ifp
->if_flags 
& IFF_MULTICAST
) || 
 803                     ifp
->if_allhostsinm 
!= NULL
) { 
 805                         TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) { 
 807                                 if (ifa
->ifa_addr
->sa_family 
== AF_INET
) { 
 813                         ifnet_lock_done(ifp
); 
 815                         lck_mtx_lock(&ifp
->if_addrconfig_lock
); 
 816                         if (ifa 
== NULL 
&& ifp
->if_allhostsinm 
!= NULL
) { 
 817                                 struct in_multi 
*inm 
= ifp
->if_allhostsinm
; 
 818                                 ifp
->if_allhostsinm 
= NULL
; 
 821                                 /* release the reference for allhostsinm */ 
 824                         lck_mtx_unlock(&ifp
->if_addrconfig_lock
); 
 826                         ifnet_lock_done(ifp
); 
 829                 /* Post the kernel event */ 
 830                 kev_post_msg(&ev_msg
); 
 833                  * See if there is any IPV4 address left and if so, 
 834                  * reconfigure KDP to use current primary address. 
 836                 ifa 
= ifa_ifpgetprimary(ifp
, AF_INET
); 
 839                          * NOTE: SIOCSIFADDR is defined with struct ifreq 
 840                          * as parameter, but here we are sending it down 
 841                          * to the interface with a pointer to struct ifaddr, 
 842                          * for legacy reasons. 
 844                         error 
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa
); 
 845                         if (error 
== EOPNOTSUPP
) 
 848                         /* Release reference from ifa_ifpgetprimary() */ 
 851                 (void) ifnet_notify_address(ifp
, AF_INET
); 
 863  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 864  * expectation that this routine always uses bcopy() or other byte-aligned 
 867 static __attribute__((noinline
)) int 
 868 inctl_ifdstaddr(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, u_long cmd
, 
 871         struct kev_in_data in_event_data
; 
 872         struct kev_msg ev_msg
; 
 873         struct sockaddr_in dstaddr
; 
 878         if (!(ifp
->if_flags 
& IFF_POINTOPOINT
)) 
 881         bzero(&in_event_data
, sizeof (struct kev_in_data
)); 
 882         bzero(&ev_msg
, sizeof (struct kev_msg
)); 
 885         case SIOCGIFDSTADDR
:            /* struct ifreq */ 
 887                         error 
= EADDRNOTAVAIL
; 
 890                 IFA_LOCK(&ia
->ia_ifa
); 
 891                 bcopy(&ia
->ia_dstaddr
, &ifr
->ifr_dstaddr
, sizeof (dstaddr
)); 
 892                 IFA_UNLOCK(&ia
->ia_ifa
); 
 895         case SIOCSIFDSTADDR
:            /* struct ifreq */ 
 897                 IFA_LOCK(&ia
->ia_ifa
); 
 898                 dstaddr 
= ia
->ia_dstaddr
; 
 899                 bcopy(&ifr
->ifr_dstaddr
, &ia
->ia_dstaddr
, sizeof (dstaddr
)); 
 900                 if (ia
->ia_dstaddr
.sin_family 
== AF_INET
) 
 901                         ia
->ia_dstaddr
.sin_len 
= sizeof (struct sockaddr_in
); 
 902                 IFA_UNLOCK(&ia
->ia_ifa
); 
 904                  * NOTE: SIOCSIFDSTADDR is defined with struct ifreq 
 905                  * as parameter, but here we are sending it down 
 906                  * to the interface with a pointer to struct ifaddr, 
 907                  * for legacy reasons. 
 909                 error 
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFDSTADDR
, ia
); 
 910                 IFA_LOCK(&ia
->ia_ifa
); 
 911                 if (error 
== EOPNOTSUPP
) 
 914                         ia
->ia_dstaddr 
= dstaddr
; 
 915                         IFA_UNLOCK(&ia
->ia_ifa
); 
 918                 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
 920                 ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
 921                 ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
 922                 ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
 924                 ev_msg
.event_code       
= KEV_INET_SIFDSTADDR
; 
 926                 if (ia
->ia_ifa
.ifa_dstaddr
) { 
 927                         in_event_data
.ia_dstaddr 
= ((struct sockaddr_in 
*) 
 928                             (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
; 
 930                         in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
 933                 in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
 934                 in_event_data
.ia_net            
= ia
->ia_net
; 
 935                 in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
 936                 in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
 937                 in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
 938                 in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
 939                 IFA_UNLOCK(&ia
->ia_ifa
); 
 940                 (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
 941                     ifp
->if_name
, IFNAMSIZ
); 
 942                 in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
 943                 in_event_data
.link_data
.if_unit  
= (u_int32_t
)ifp
->if_unit
; 
 945                 ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
 946                 ev_msg
.dv
[0].data_length 
= sizeof (struct kev_in_data
); 
 947                 ev_msg
.dv
[1].data_length 
= 0; 
 949                 kev_post_msg(&ev_msg
); 
 951                 lck_mtx_lock(rnh_lock
); 
 952                 IFA_LOCK(&ia
->ia_ifa
); 
 953                 if (ia
->ia_flags 
& IFA_ROUTE
) { 
 954                         ia
->ia_ifa
.ifa_dstaddr 
= (struct sockaddr 
*)&dstaddr
; 
 955                         IFA_UNLOCK(&ia
->ia_ifa
); 
 956                         rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
); 
 957                         IFA_LOCK(&ia
->ia_ifa
); 
 958                         ia
->ia_ifa
.ifa_dstaddr 
= 
 959                             (struct sockaddr 
*)&ia
->ia_dstaddr
; 
 960                         IFA_UNLOCK(&ia
->ia_ifa
); 
 961                         rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
, 
 964                         IFA_UNLOCK(&ia
->ia_ifa
); 
 966                 lck_mtx_unlock(rnh_lock
); 
 980  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 981  * expectation that this routine always uses bcopy() or other byte-aligned 
 984 static __attribute__((noinline
)) int 
 985 inctl_ifbrdaddr(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, u_long cmd
, 
 988         struct kev_in_data in_event_data
; 
 989         struct kev_msg ev_msg
; 
 995                 return (EADDRNOTAVAIL
); 
 997         if (!(ifp
->if_flags 
& IFF_BROADCAST
)) 
1000         bzero(&in_event_data
, sizeof (struct kev_in_data
)); 
1001         bzero(&ev_msg
, sizeof (struct kev_msg
)); 
1004         case SIOCGIFBRDADDR
:            /* struct ifreq */ 
1005                 IFA_LOCK(&ia
->ia_ifa
); 
1006                 bcopy(&ia
->ia_broadaddr
, &ifr
->ifr_broadaddr
, 
1007                     sizeof (struct sockaddr_in
)); 
1008                 IFA_UNLOCK(&ia
->ia_ifa
); 
1011         case SIOCSIFBRDADDR
:            /* struct ifreq */ 
1012                 IFA_LOCK(&ia
->ia_ifa
); 
1013                 bcopy(&ifr
->ifr_broadaddr
, &ia
->ia_broadaddr
, 
1014                     sizeof (struct sockaddr_in
)); 
1016                 ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
1017                 ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
1018                 ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
1020                 ev_msg
.event_code 
= KEV_INET_SIFBRDADDR
; 
1022                 if (ia
->ia_ifa
.ifa_dstaddr
) { 
1023                         in_event_data
.ia_dstaddr 
= ((struct sockaddr_in 
*) 
1024                             (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
; 
1026                         in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
1028                 in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
1029                 in_event_data
.ia_net            
= ia
->ia_net
; 
1030                 in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
1031                 in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
1032                 in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
1033                 in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
1034                 IFA_UNLOCK(&ia
->ia_ifa
); 
1035                 (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
1036                     ifp
->if_name
, IFNAMSIZ
); 
1037                 in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
1038                 in_event_data
.link_data
.if_unit  
= (u_int32_t
)ifp
->if_unit
; 
1040                 ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
1041                 ev_msg
.dv
[0].data_length 
= sizeof (struct kev_in_data
); 
1042                 ev_msg
.dv
[1].data_length 
= 0; 
1044                 kev_post_msg(&ev_msg
); 
1056  * Caller passes in the ioctl data pointer directly via "ifr", with the 
1057  * expectation that this routine always uses bcopy() or other byte-aligned 
1060 static __attribute__((noinline
)) int 
1061 inctl_ifnetmask(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, u_long cmd
, 
1064         struct kev_in_data in_event_data
; 
1065         struct kev_msg ev_msg
; 
1066         struct sockaddr_in mask
; 
1069         VERIFY(ifp 
!= NULL
); 
1071         bzero(&in_event_data
, sizeof (struct kev_in_data
)); 
1072         bzero(&ev_msg
, sizeof (struct kev_msg
)); 
1075         case SIOCGIFNETMASK
:            /* struct ifreq */ 
1077                         error 
= EADDRNOTAVAIL
; 
1080                 IFA_LOCK(&ia
->ia_ifa
); 
1081                 bcopy(&ia
->ia_sockmask
, &ifr
->ifr_addr
, sizeof (mask
)); 
1082                 IFA_UNLOCK(&ia
->ia_ifa
); 
1085         case SIOCSIFNETMASK
: {          /* struct ifreq */ 
1088                 bcopy(&ifr
->ifr_addr
, &mask
, sizeof (mask
)); 
1089                 i 
= mask
.sin_addr
.s_addr
; 
1092                 IFA_LOCK(&ia
->ia_ifa
); 
1093                 ia
->ia_subnetmask 
= ntohl(ia
->ia_sockmask
.sin_addr
.s_addr 
= i
); 
1094                 ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
1095                 ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
1096                 ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
1098                 ev_msg
.event_code 
= KEV_INET_SIFNETMASK
; 
1100                 if (ia
->ia_ifa
.ifa_dstaddr
) { 
1101                         in_event_data
.ia_dstaddr 
= ((struct sockaddr_in 
*) 
1102                             (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
; 
1104                         in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
1106                 in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
1107                 in_event_data
.ia_net            
= ia
->ia_net
; 
1108                 in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
1109                 in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
1110                 in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
1111                 in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
1112                 IFA_UNLOCK(&ia
->ia_ifa
); 
1113                 (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
1114                     ifp
->if_name
, IFNAMSIZ
); 
1115                 in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
1116                 in_event_data
.link_data
.if_unit  
= (u_int32_t
)ifp
->if_unit
; 
1118                 ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
1119                 ev_msg
.dv
[0].data_length 
= sizeof (struct kev_in_data
); 
1120                 ev_msg
.dv
[1].data_length 
= 0; 
1122                 kev_post_msg(&ev_msg
); 
1135  * Generic INET control operations (ioctl's). 
1137  * ifp is NULL if not an interface-specific ioctl. 
1139  * Most of the routines called to handle the ioctls would end up being 
1140  * tail-call optimized, which unfortunately causes this routine to 
1141  * consume too much stack space; this is the reason for the "noinline" 
1142  * attribute used on those routines. 
1144  * If called directly from within the networking stack (as opposed to via 
1145  * pru_control), the socket parameter may be NULL. 
1148 in_control(struct socket 
*so
, u_long cmd
, caddr_t data
, struct ifnet 
*ifp
, 
1151         struct ifreq 
*ifr 
= (struct ifreq 
*)(void *)data
; 
1152         struct sockaddr_in addr
, dstaddr
; 
1153         struct sockaddr_in sin
, *sa 
= NULL
; 
1154         boolean_t privileged 
= (proc_suser(p
) == 0); 
1155         boolean_t so_unlocked 
= FALSE
; 
1156         struct in_ifaddr 
*ia 
= NULL
; 
1160         /* In case it's NULL, make sure it came from the kernel */ 
1161         VERIFY(so 
!= NULL 
|| p 
== kernproc
); 
1164          * ioctls which don't require ifp, but require socket. 
1167         case SIOCGASSOCIDS32
:           /* struct so_aidreq32 */ 
1168         case SIOCGASSOCIDS64
:           /* struct so_aidreq64 */ 
1169                 return (inctl_associd(so
, cmd
, data
)); 
1172         case SIOCGCONNIDS32
:            /* struct so_cidreq32 */ 
1173         case SIOCGCONNIDS64
:            /* struct so_cidreq64 */ 
1174                 return (inctl_connid(so
, cmd
, data
)); 
1177         case SIOCGCONNINFO32
:           /* struct so_cinforeq32 */ 
1178         case SIOCGCONNINFO64
:           /* struct so_cinforeq64 */ 
1179                 return (inctl_conninfo(so
, cmd
, data
)); 
1184          * The rest of ioctls require ifp; reject if we don't have one; 
1185          * return ENXIO to be consistent with ifioctl(). 
1191          * ioctls which require ifp but not interface address. 
1194         case SIOCAUTOADDR
:              /* struct ifreq */ 
1197                 return (inctl_autoaddr(ifp
, ifr
)); 
1200         case SIOCARPIPLL
:               /* struct ifreq */ 
1203                 return (inctl_arpipll(ifp
, ifr
)); 
1206         case SIOCSETROUTERMODE
:         /* struct ifreq */ 
1209                 return (inctl_setrouter(ifp
, ifr
)); 
1212         case SIOCPROTOATTACH
:           /* struct ifreq */ 
1215                 return (in_domifattach(ifp
)); 
1218         case SIOCPROTODETACH
:           /* struct ifreq */ 
1223                  * If an IPv4 address is still present, refuse to detach. 
1225                 ifnet_lock_shared(ifp
); 
1226                 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) { 
1228                         if (ifa
->ifa_addr
->sa_family 
== AF_INET
) { 
1234                 ifnet_lock_done(ifp
); 
1235                 return ((ifa 
== NULL
) ? proto_unplumb(PF_INET
, ifp
) : EBUSY
); 
1240          * ioctls which require interface address; obtain sockaddr_in. 
1243         case SIOCAIFADDR
:               /* struct {if,in_}aliasreq */ 
1246                 bcopy(&((struct in_aliasreq 
*)(void *)data
)->ifra_addr
, 
1247                     &sin
, sizeof (sin
)); 
1251         case SIOCDIFADDR
:               /* struct ifreq */ 
1252         case SIOCSIFADDR
:               /* struct ifreq */ 
1253         case SIOCSIFDSTADDR
:            /* struct ifreq */ 
1254         case SIOCSIFNETMASK
:            /* struct ifreq */ 
1255         case SIOCSIFBRDADDR
:            /* struct ifreq */ 
1259         case SIOCGIFADDR
:               /* struct ifreq */ 
1260         case SIOCGIFDSTADDR
:            /* struct ifreq */ 
1261         case SIOCGIFNETMASK
:            /* struct ifreq */ 
1262         case SIOCGIFBRDADDR
:            /* struct ifreq */ 
1263                 bcopy(&ifr
->ifr_addr
, &sin
, sizeof (sin
)); 
1269          * Find address for this interface, if it exists. 
1271          * If an alias address was specified, find that one instead of 
1272          * the first one on the interface, if possible. 
1276                 struct in_ifaddr 
*iap
; 
1279                  * Any failures from this point on must take into account 
1280                  * a non-NULL "ia" with an outstanding reference count, and 
1281                  * therefore requires IFA_REMREF.  Jump to "done" label 
1282                  * instead of calling return if "ia" is valid. 
1284                 lck_rw_lock_shared(in_ifaddr_rwlock
); 
1285                 TAILQ_FOREACH(iap
, INADDR_HASH(sa
->sin_addr
.s_addr
), ia_hash
) { 
1286                         IFA_LOCK(&iap
->ia_ifa
); 
1287                         if (iap
->ia_ifp 
== ifp 
&& 
1288                             iap
->ia_addr
.sin_addr
.s_addr 
== 
1289                             sa
->sin_addr
.s_addr
) { 
1291                                 IFA_UNLOCK(&iap
->ia_ifa
); 
1294                         IFA_UNLOCK(&iap
->ia_ifa
); 
1296                 /* take a reference on ia before releasing lock */ 
1298                         IFA_ADDREF(&ia
->ia_ifa
); 
1299                 lck_rw_done(in_ifaddr_rwlock
); 
1302                         ifnet_lock_shared(ifp
); 
1303                         TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) { 
1305                                 IFA_LOCK(&iap
->ia_ifa
); 
1306                                 if (iap
->ia_addr
.sin_family 
== AF_INET
) { 
1308                                         IFA_UNLOCK(&iap
->ia_ifa
); 
1311                                 IFA_UNLOCK(&iap
->ia_ifa
); 
1313                         /* take a reference on ia before releasing lock */ 
1315                                 IFA_ADDREF(&ia
->ia_ifa
); 
1316                         ifnet_lock_done(ifp
); 
1321          * Unlock the socket since ifnet_ioctl() may be invoked by 
1322          * one of the ioctl handlers below.  Socket will be re-locked 
1323          * prior to returning. 
1326                 socket_unlock(so
, 0); 
1331         case SIOCAIFADDR
:               /* struct {if,in_}aliasreq */ 
1332         case SIOCDIFADDR
:               /* struct ifreq */ 
1333                 if (cmd 
== SIOCAIFADDR
) { 
1334                         bcopy(&((struct in_aliasreq 
*)(void *)data
)-> 
1335                             ifra_addr
, &addr
, sizeof (addr
)); 
1336                         bcopy(&((struct in_aliasreq 
*)(void *)data
)-> 
1337                             ifra_dstaddr
, &dstaddr
, sizeof (dstaddr
)); 
1339                         VERIFY(cmd 
== SIOCDIFADDR
); 
1340                         bcopy(&((struct ifreq 
*)(void *)data
)->ifr_addr
, 
1341                             &addr
, sizeof (addr
)); 
1342                         bzero(&dstaddr
, sizeof (dstaddr
)); 
1345                 if (addr
.sin_family 
== AF_INET
) { 
1346                         struct in_ifaddr 
*oia
; 
1348                         lck_rw_lock_shared(in_ifaddr_rwlock
); 
1349                         for (oia 
= ia
; ia
; ia 
= ia
->ia_link
.tqe_next
) { 
1350                                 IFA_LOCK(&ia
->ia_ifa
); 
1351                                 if (ia
->ia_ifp 
== ifp 
&& 
1352                                     ia
->ia_addr
.sin_addr
.s_addr 
== 
1353                                     addr
.sin_addr
.s_addr
) { 
1354                                         IFA_ADDREF_LOCKED(&ia
->ia_ifa
); 
1355                                         IFA_UNLOCK(&ia
->ia_ifa
); 
1358                                 IFA_UNLOCK(&ia
->ia_ifa
); 
1360                         lck_rw_done(in_ifaddr_rwlock
); 
1362                                 IFA_REMREF(&oia
->ia_ifa
); 
1363                         if ((ifp
->if_flags 
& IFF_POINTOPOINT
) && 
1364                             (cmd 
== SIOCAIFADDR
) && 
1365                             (dstaddr
.sin_addr
.s_addr 
== INADDR_ANY
)) { 
1366                                 error 
= EDESTADDRREQ
; 
1369                 } else if (cmd 
== SIOCAIFADDR
) { 
1373                 if (cmd 
== SIOCDIFADDR 
&& ia 
== NULL
) { 
1374                         error 
= EADDRNOTAVAIL
; 
1378         case SIOCSIFADDR
:               /* struct ifreq */ 
1379         case SIOCSIFDSTADDR
:            /* struct ifreq */ 
1380         case SIOCSIFNETMASK
:            /* struct ifreq */ 
1381                 if (cmd 
== SIOCAIFADDR
) { 
1382                         /* fell thru from above; just repeat it */ 
1383                         bcopy(&((struct in_aliasreq 
*)(void *)data
)-> 
1384                             ifra_addr
, &addr
, sizeof (addr
)); 
1386                         VERIFY(cmd 
== SIOCDIFADDR 
|| cmd 
== SIOCSIFADDR 
|| 
1387                             cmd 
== SIOCSIFNETMASK 
|| cmd 
== SIOCSIFDSTADDR
); 
1388                         bcopy(&((struct ifreq 
*)(void *)data
)->ifr_addr
, 
1389                             &addr
, sizeof (addr
)); 
1392                 if (addr
.sin_family 
!= AF_INET 
&& cmd 
== SIOCSIFADDR
) { 
1397                         ia 
= in_ifaddr_alloc(M_WAITOK
); 
1402                         ifnet_lock_exclusive(ifp
); 
1405                         /* Hold a reference for this routine */ 
1406                         IFA_ADDREF_LOCKED(ifa
); 
1408                         ifa
->ifa_addr 
= (struct sockaddr 
*)&ia
->ia_addr
; 
1409                         ifa
->ifa_dstaddr 
= (struct sockaddr 
*)&ia
->ia_dstaddr
; 
1410                         ifa
->ifa_netmask 
= (struct sockaddr 
*)&ia
->ia_sockmask
; 
1411                         ia
->ia_sockmask
.sin_len 
= 8; 
1412                         if (ifp
->if_flags 
& IFF_BROADCAST
) { 
1413                                 ia
->ia_broadaddr
.sin_len 
= sizeof (ia
->ia_addr
); 
1414                                 ia
->ia_broadaddr
.sin_family 
= AF_INET
; 
1417                         if (!(ifp
->if_flags 
& IFF_LOOPBACK
)) 
1419                         /* if_attach_ifa() holds a reference for ifa_link */ 
1420                         if_attach_ifa(ifp
, ifa
); 
1422                          * If we have to go through in_ifinit(), make sure 
1423                          * to avoid installing route(s) based on this address 
1424                          * via PFC_IFUP event, before the link resolver (ARP) 
1427                         if (cmd 
== SIOCAIFADDR 
|| cmd 
== SIOCSIFADDR
) 
1428                                 ifa
->ifa_debug 
|= IFD_NOTREADY
; 
1430                         ifnet_lock_done(ifp
); 
1431                         lck_rw_lock_exclusive(in_ifaddr_rwlock
); 
1432                         /* Hold a reference for ia_link */ 
1434                         TAILQ_INSERT_TAIL(&in_ifaddrhead
, ia
, ia_link
); 
1435                         lck_rw_done(in_ifaddr_rwlock
); 
1437                         (void) in_domifattach(ifp
); 
1444         case SIOCGIFDSTADDR
:            /* struct ifreq */ 
1445         case SIOCSIFDSTADDR
:            /* struct ifreq */ 
1446                 error 
= inctl_ifdstaddr(ifp
, ia
, cmd
, ifr
); 
1449         case SIOCGIFBRDADDR
:            /* struct ifreq */ 
1450         case SIOCSIFBRDADDR
:            /* struct ifreq */ 
1451                 error 
= inctl_ifbrdaddr(ifp
, ia
, cmd
, ifr
); 
1454         case SIOCGIFNETMASK
:            /* struct ifreq */ 
1455         case SIOCSIFNETMASK
:            /* struct ifreq */ 
1456                 error 
= inctl_ifnetmask(ifp
, ia
, cmd
, ifr
); 
1459         case SIOCGIFADDR
:               /* struct ifreq */ 
1460         case SIOCSIFADDR
:               /* struct ifreq */ 
1461         case SIOCAIFADDR
:               /* struct {if,in_}aliasreq */ 
1462         case SIOCDIFADDR
:               /* struct ifreq */ 
1463                 error 
= inctl_ifaddr(ifp
, ia
, cmd
, ifr
); 
1472                 IFA_REMREF(&ia
->ia_ifa
); 
1480  * Delete any existing route for an interface. 
1483 in_ifscrub(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, int locked
) 
1485         IFA_LOCK(&ia
->ia_ifa
); 
1486         if ((ia
->ia_flags 
& IFA_ROUTE
) == 0) { 
1487                 IFA_UNLOCK(&ia
->ia_ifa
); 
1490         IFA_UNLOCK(&ia
->ia_ifa
); 
1492                 lck_mtx_lock(rnh_lock
); 
1493         if (ifp
->if_flags 
& (IFF_LOOPBACK
|IFF_POINTOPOINT
)) 
1494                 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
); 
1496                 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, 0); 
1497         IFA_LOCK(&ia
->ia_ifa
); 
1498         ia
->ia_flags 
&= ~IFA_ROUTE
; 
1499         IFA_UNLOCK(&ia
->ia_ifa
); 
1501                 lck_mtx_unlock(rnh_lock
); 
1505  * Caller must hold in_ifaddr_rwlock as writer. 
1508 in_iahash_remove(struct in_ifaddr 
*ia
) 
1510         lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
); 
1511         IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
1513         if (!IA_IS_HASHED(ia
)) { 
1514                 panic("attempt to remove wrong ia %p from hash table\n", ia
); 
1517         TAILQ_REMOVE(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), ia
, ia_hash
); 
1519         if (IFA_REMREF_LOCKED(&ia
->ia_ifa
) == NULL
) { 
1520                 panic("%s: unexpected (missing) refcnt ifa=%p", __func__
, 
1527  * Caller must hold in_ifaddr_rwlock as writer. 
1530 in_iahash_insert(struct in_ifaddr 
*ia
) 
1532         lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
); 
1533         IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
1535         if (ia
->ia_addr
.sin_family 
!= AF_INET
) { 
1536                 panic("attempt to insert wrong ia %p into hash table\n", ia
); 
1538         } else if (IA_IS_HASHED(ia
)) { 
1539                 panic("attempt to double-insert ia %p into hash table\n", ia
); 
1542         TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), 
1544         IFA_ADDREF_LOCKED(&ia
->ia_ifa
); 
1548  * Some point to point interfaces that are tunnels borrow the address from 
1549  * an underlying interface (e.g. VPN server). In order for source address 
1550  * selection logic to find the underlying interface first, we add the address 
1551  * of borrowing point to point interfaces at the end of the list. 
1552  * (see rdar://6733789) 
1554  * Caller must hold in_ifaddr_rwlock as writer. 
1557 in_iahash_insert_ptp(struct in_ifaddr 
*ia
) 
1559         struct in_ifaddr 
*tmp_ifa
; 
1560         struct ifnet 
*tmp_ifp
; 
1562         lck_rw_assert(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
); 
1563         IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
1565         if (ia
->ia_addr
.sin_family 
!= AF_INET
) { 
1566                 panic("attempt to insert wrong ia %p into hash table\n", ia
); 
1568         } else if (IA_IS_HASHED(ia
)) { 
1569                 panic("attempt to double-insert ia %p into hash table\n", ia
); 
1572         IFA_UNLOCK(&ia
->ia_ifa
); 
1573         TAILQ_FOREACH(tmp_ifa
, INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), 
1575                 IFA_LOCK(&tmp_ifa
->ia_ifa
); 
1576                 /* ia->ia_addr won't change, so check without lock */ 
1577                 if (IA_SIN(tmp_ifa
)->sin_addr
.s_addr 
== 
1578                     ia
->ia_addr
.sin_addr
.s_addr
) { 
1579                         IFA_UNLOCK(&tmp_ifa
->ia_ifa
); 
1582                 IFA_UNLOCK(&tmp_ifa
->ia_ifa
); 
1584         tmp_ifp 
= (tmp_ifa 
== NULL
) ? NULL 
: tmp_ifa
->ia_ifp
; 
1586         IFA_LOCK(&ia
->ia_ifa
); 
1587         if (tmp_ifp 
== NULL
) { 
1588                 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), 
1591                 TAILQ_INSERT_TAIL(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), 
1594         IFA_ADDREF_LOCKED(&ia
->ia_ifa
); 
1598  * Initialize an interface's internet address 
1599  * and routing table entry. 
1602 in_ifinit(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, struct sockaddr_in 
*sin
, 
1605         u_int32_t i 
= ntohl(sin
->sin_addr
.s_addr
); 
1606         struct sockaddr_in oldaddr
; 
1607         int flags 
= RTF_UP
, error
; 
1608         struct ifaddr 
*ifa0
; 
1612         /* Take an extra reference for this routine */ 
1613         IFA_ADDREF(&ia
->ia_ifa
); 
1615         lck_rw_lock_exclusive(in_ifaddr_rwlock
); 
1616         IFA_LOCK(&ia
->ia_ifa
); 
1617         oldaddr 
= ia
->ia_addr
; 
1618         if (IA_IS_HASHED(ia
)) { 
1620                 in_iahash_remove(ia
); 
1624          * Interface addresses should not contain port or sin_zero information. 
1626         SIN(&ia
->ia_addr
)->sin_family 
= AF_INET
; 
1627         SIN(&ia
->ia_addr
)->sin_len 
= sizeof (struct sockaddr_in
); 
1628         SIN(&ia
->ia_addr
)->sin_port 
= 0; 
1629         bzero(&SIN(&ia
->ia_addr
)->sin_zero
, sizeof (sin
->sin_zero
)); 
1630         if ((ifp
->if_flags 
& IFF_POINTOPOINT
)) 
1631                 in_iahash_insert_ptp(ia
); 
1633                 in_iahash_insert(ia
); 
1634         IFA_UNLOCK(&ia
->ia_ifa
); 
1635         lck_rw_done(in_ifaddr_rwlock
); 
1638          * Give the interface a chance to initialize if this is its first 
1639          * address, and to validate the address if necessary.  Send down 
1640          * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es). 
1641          * We find the first IPV4 address assigned to it and check if this 
1642          * is the same as the one passed into this routine. 
1644         ifa0 
= ifa_ifpgetprimary(ifp
, AF_INET
); 
1645         cmd 
= (&ia
->ia_ifa 
== ifa0
) ? SIOCSIFADDR 
: SIOCAIFADDR
; 
1646         error 
= ifnet_ioctl(ifp
, PF_INET
, cmd
, ia
); 
1647         if (error 
== EOPNOTSUPP
) 
1650          * If we've just sent down SIOCAIFADDR, send another ioctl down 
1651          * for SIOCSIFADDR for the first IPV4 address of the interface, 
1652          * because an address change on one of the addresses will result 
1653          * in the removal of the previous first IPV4 address.  KDP needs 
1654          * be reconfigured with the current primary IPV4 address. 
1656         if (error 
== 0 && cmd 
== SIOCAIFADDR
) { 
1658                  * NOTE: SIOCSIFADDR is defined with struct ifreq 
1659                  * as parameter, but here we are sending it down 
1660                  * to the interface with a pointer to struct ifaddr, 
1661                  * for legacy reasons. 
1663                 error 
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa0
); 
1664                 if (error 
== EOPNOTSUPP
) 
1668         /* Release reference from ifa_ifpgetprimary() */ 
1672                 lck_rw_lock_exclusive(in_ifaddr_rwlock
); 
1673                 IFA_LOCK(&ia
->ia_ifa
); 
1674                 if (IA_IS_HASHED(ia
)) 
1675                         in_iahash_remove(ia
); 
1676                 ia
->ia_addr 
= oldaddr
; 
1678                         if ((ifp
->if_flags 
& IFF_POINTOPOINT
)) 
1679                                 in_iahash_insert_ptp(ia
); 
1681                                 in_iahash_insert(ia
); 
1683                 IFA_UNLOCK(&ia
->ia_ifa
); 
1684                 lck_rw_done(in_ifaddr_rwlock
); 
1685                 /* Release extra reference taken above */ 
1686                 IFA_REMREF(&ia
->ia_ifa
); 
1689         lck_mtx_lock(rnh_lock
); 
1690         IFA_LOCK(&ia
->ia_ifa
); 
1692          * Address has been initialized by the link resolver (ARP) 
1693          * via ifnet_ioctl() above; it may now generate route(s). 
1695         ia
->ia_ifa
.ifa_debug 
&= ~IFD_NOTREADY
; 
1697                 ia
->ia_ifa
.ifa_addr 
= (struct sockaddr 
*)&oldaddr
; 
1698                 IFA_UNLOCK(&ia
->ia_ifa
); 
1699                 in_ifscrub(ifp
, ia
, 1); 
1700                 IFA_LOCK(&ia
->ia_ifa
); 
1701                 ia
->ia_ifa
.ifa_addr 
= (struct sockaddr 
*)&ia
->ia_addr
; 
1703         IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
1705                 ia
->ia_netmask 
= IN_CLASSA_NET
; 
1706         else if (IN_CLASSB(i
)) 
1707                 ia
->ia_netmask 
= IN_CLASSB_NET
; 
1709                 ia
->ia_netmask 
= IN_CLASSC_NET
; 
1711          * The subnet mask usually includes at least the standard network part, 
1712          * but may may be smaller in the case of supernetting. 
1713          * If it is set, we believe it. 
1715         if (ia
->ia_subnetmask 
== 0) { 
1716                 ia
->ia_subnetmask 
= ia
->ia_netmask
; 
1717                 ia
->ia_sockmask
.sin_addr
.s_addr 
= htonl(ia
->ia_subnetmask
); 
1719                 ia
->ia_netmask 
&= ia
->ia_subnetmask
; 
1720         ia
->ia_net 
= i 
& ia
->ia_netmask
; 
1721         ia
->ia_subnet 
= i 
& ia
->ia_subnetmask
; 
1722         in_socktrim(&ia
->ia_sockmask
); 
1724          * Add route for the network. 
1726         ia
->ia_ifa
.ifa_metric 
= ifp
->if_metric
; 
1727         if (ifp
->if_flags 
& IFF_BROADCAST
) { 
1728                 ia
->ia_broadaddr
.sin_addr
.s_addr 
= 
1729                     htonl(ia
->ia_subnet 
| ~ia
->ia_subnetmask
); 
1730                 ia
->ia_netbroadcast
.s_addr 
= 
1731                     htonl(ia
->ia_net 
| ~ ia
->ia_netmask
); 
1732         } else if (ifp
->if_flags 
& IFF_LOOPBACK
) { 
1733                 ia
->ia_ifa
.ifa_dstaddr 
= ia
->ia_ifa
.ifa_addr
; 
1735         } else if (ifp
->if_flags 
& IFF_POINTOPOINT
) { 
1736                 if (ia
->ia_dstaddr
.sin_family 
!= AF_INET
) { 
1737                         IFA_UNLOCK(&ia
->ia_ifa
); 
1738                         lck_mtx_unlock(rnh_lock
); 
1739                         /* Release extra reference taken above */ 
1740                         IFA_REMREF(&ia
->ia_ifa
); 
1743                 ia
->ia_dstaddr
.sin_len 
= sizeof (struct sockaddr_in
); 
1746         IFA_UNLOCK(&ia
->ia_ifa
); 
1748         if ((error 
= rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
, flags
)) == 0) { 
1749                 IFA_LOCK(&ia
->ia_ifa
); 
1750                 ia
->ia_flags 
|= IFA_ROUTE
; 
1751                 IFA_UNLOCK(&ia
->ia_ifa
); 
1753         lck_mtx_unlock(rnh_lock
); 
1755         /* XXX check if the subnet route points to the same interface */ 
1756         if (error 
== EEXIST
) 
1760          * If the interface supports multicast, join the "all hosts" 
1761          * multicast group on that interface. 
1763         if (ifp
->if_flags 
& IFF_MULTICAST
) { 
1764                 struct in_addr addr
; 
1766                 lck_mtx_lock(&ifp
->if_addrconfig_lock
); 
1767                 addr
.s_addr 
= htonl(INADDR_ALLHOSTS_GROUP
); 
1768                 if (ifp
->if_allhostsinm 
== NULL
) { 
1769                         struct in_multi 
*inm
; 
1770                         inm 
= in_addmulti(&addr
, ifp
); 
1774                                  * Keep the reference on inm added by 
1775                                  * in_addmulti above for storing the 
1776                                  * pointer in allhostsinm. 
1778                                 ifp
->if_allhostsinm 
= inm
; 
1780                                 printf("%s: failed to add membership to " 
1781                                     "all-hosts multicast address on %s\n", 
1782                                     __func__
, if_name(ifp
)); 
1785                 lck_mtx_unlock(&ifp
->if_addrconfig_lock
); 
1788         /* Release extra reference taken above */ 
1789         IFA_REMREF(&ia
->ia_ifa
); 
1792                 /* invalidate route caches */ 
1793                 routegenid_inet_update(); 
1800  * Return TRUE if the address might be a local broadcast address. 
1803 in_broadcast(struct in_addr in
, struct ifnet 
*ifp
) 
1808         if (in
.s_addr 
== INADDR_BROADCAST 
|| in
.s_addr 
== INADDR_ANY
) 
1810         if (!(ifp
->if_flags 
& IFF_BROADCAST
)) 
1812         t 
= ntohl(in
.s_addr
); 
1815          * Look through the list of addresses for a match 
1816          * with a broadcast address. 
1818 #define ia ((struct in_ifaddr *)ifa) 
1819         ifnet_lock_shared(ifp
); 
1820         TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) { 
1822                 if (ifa
->ifa_addr
->sa_family 
== AF_INET 
&& 
1823                     (in
.s_addr 
== ia
->ia_broadaddr
.sin_addr
.s_addr 
|| 
1824                      in
.s_addr 
== ia
->ia_netbroadcast
.s_addr 
|| 
1826                       * Check for old-style (host 0) broadcast. 
1828                      t 
== ia
->ia_subnet 
|| t 
== ia
->ia_net
) && 
1830                       * Check for an all one subnetmask. These 
1831                       * only exist when an interface gets a secondary 
1834                      ia
->ia_subnetmask 
!= (u_int32_t
)0xffffffff) { 
1836                         ifnet_lock_done(ifp
); 
1841         ifnet_lock_done(ifp
); 
1847 in_purgeaddrs(struct ifnet 
*ifp
) 
1849         struct ifaddr 
**ifap
; 
1852         VERIFY(ifp 
!= NULL
); 
1855          * Be nice, and try the civilized way first.  If we can't get 
1856          * rid of them this way, then do it the rough way.  We must 
1857          * only get here during detach time, after the ifnet has been 
1858          * removed from the global list and arrays. 
1860         err 
= ifnet_get_address_list_family_internal(ifp
, &ifap
, AF_INET
, 1, 
1862         if (err 
== 0 && ifap 
!= NULL
) { 
1865                 bzero(&ifr
, sizeof (ifr
)); 
1866                 (void) snprintf(ifr
.ifr_name
, sizeof (ifr
.ifr_name
), 
1867                     "%s", if_name(ifp
)); 
1869                 for (i 
= 0; ifap
[i
] != NULL
; i
++) { 
1874                         bcopy(ifa
->ifa_addr
, &ifr
.ifr_addr
, 
1875                             sizeof (struct sockaddr_in
)); 
1877                         err 
= in_control(NULL
, SIOCDIFADDR
, (caddr_t
)&ifr
, ifp
, 
1879                         /* if we lost the race, ignore it */ 
1880                         if (err 
== EADDRNOTAVAIL
) 
1883                                 char s_addr
[MAX_IPv4_STR_LEN
]; 
1884                                 char s_dstaddr
[MAX_IPv4_STR_LEN
]; 
1885                                 struct in_addr 
*s
, *d
; 
1888                                 s 
= &((struct sockaddr_in 
*) 
1889                                     (void *)ifa
->ifa_addr
)->sin_addr
; 
1890                                 d 
= &((struct sockaddr_in 
*) 
1891                                     (void *)ifa
->ifa_dstaddr
)->sin_addr
; 
1892                                 (void) inet_ntop(AF_INET
, &s
->s_addr
, s_addr
, 
1894                                 (void) inet_ntop(AF_INET
, &d
->s_addr
, s_dstaddr
, 
1895                                     sizeof (s_dstaddr
)); 
1898                                 printf("%s: SIOCDIFADDR ifp=%s ifa_addr=%s " 
1899                                     "ifa_dstaddr=%s (err=%d)\n", __func__
, 
1900                                     ifp
->if_xname
, s_addr
, s_dstaddr
, err
); 
1903                 ifnet_free_address_list(ifap
); 
1904         } else if (err 
!= 0 && err 
!= ENXIO
) { 
1905                 printf("%s: error retrieving list of AF_INET addresses for " 
1906                     "ifp=%s (err=%d)\n", __func__
, ifp
->if_xname
, err
); 
1911  * Select endpoint address(es).  For now just take the first matching 
1912  * address and discard the rest, if present. 
1915 in_selectaddrs(int af
, struct sockaddr_list 
**src_sl
, 
1916     struct sockaddr_entry 
**src_se
, struct sockaddr_list 
**dst_sl
, 
1917     struct sockaddr_entry 
**dst_se
) 
1919         struct sockaddr_entry 
*se
; 
1922         VERIFY(src_sl 
!= NULL 
&& dst_sl 
!= NULL 
&& *dst_sl 
!= NULL
); 
1923         VERIFY(src_se 
!= NULL 
&& dst_se 
!= NULL
); 
1925         *src_se 
= *dst_se 
= NULL
; 
1927         /* pick a source address, if available */ 
1928         if (*src_sl 
!= NULL
) { 
1929                 TAILQ_FOREACH(se
, &(*src_sl
)->sl_head
, se_link
) { 
1930                         VERIFY(se
->se_addr 
!= NULL
); 
1932                          * Take the first source address, or the first 
1933                          * one with matching address family. 
1935                         if (af 
== AF_UNSPEC 
|| se
->se_addr
->sa_family 
== af
) { 
1936                                 sockaddrlist_remove(*src_sl
, se
); 
1941                 /* get rid of the rest */ 
1942                 TAILQ_FOREACH(se
, &(*src_sl
)->sl_head
, se_link
) { 
1943                         sockaddrlist_remove(*src_sl
, se
); 
1944                         sockaddrentry_free(se
); 
1946                 if (*src_se 
!= NULL
) { 
1947                         /* insert the first src address back in */ 
1948                         sockaddrlist_insert(*src_sl
, *src_se
); 
1949                         VERIFY((*src_sl
)->sl_cnt 
== 1); 
1950                         /* destination address must be of this family */ 
1951                         af 
= (*src_se
)->se_addr
->sa_family
; 
1953                         /* no usable source address with matching family */ 
1954                         VERIFY(af 
!= AF_UNSPEC
); 
1955                         error 
= EAFNOSUPPORT
; 
1959         /* pick a (matching) destination address */ 
1960         TAILQ_FOREACH(se
, &(*dst_sl
)->sl_head
, se_link
) { 
1961                 VERIFY(se
->se_addr 
!= NULL
); 
1963                  * Take the first destination address; if source is specified, 
1964                  * find one which uses the same address family. 
1966                 if (af 
== AF_UNSPEC 
|| se
->se_addr
->sa_family 
== af
) { 
1967                         sockaddrlist_remove(*dst_sl
, se
); 
1972         /* get rid of the rest */ 
1973         TAILQ_FOREACH(se
, &(*dst_sl
)->sl_head
, se_link
) { 
1974                 sockaddrlist_remove(*dst_sl
, se
); 
1975                 sockaddrentry_free(se
); 
1977         if (*dst_se 
!= NULL
) { 
1978                 /* insert the first dst address back in */ 
1979                 sockaddrlist_insert(*dst_sl
, *dst_se
); 
1980                 VERIFY((*dst_sl
)->sl_cnt 
== 1); 
1982                 /* source and destination address families don't match */ 
1983                 error 
= EAFNOSUPPORT
; 
1987         af 
= (*dst_se
)->se_addr
->sa_family
; 
1988         VERIFY(*src_se 
== NULL 
|| (*src_se
)->se_addr
->sa_family 
== af
); 
1990         /* verify address length */ 
1993                 if ((*dst_se
)->se_addr
->sa_len 
!= 
1994                     sizeof (struct sockaddr_in
)) { 
1995                         error 
= EAFNOSUPPORT
; 
2001                 if ((*dst_se
)->se_addr
->sa_len 
!= 
2002                     sizeof (struct sockaddr_in6
)) { 
2003                         error 
= EAFNOSUPPORT
; 
2009                 error 
= EAFNOSUPPORT
; 
2013         /* if source address is specified, length must match destination */ 
2014         if (*src_se 
!= NULL 
&& (*src_se
)->se_addr
->sa_len 
!= 
2015             (*dst_se
)->se_addr
->sa_len
) { 
2016                 error 
= EAFNOSUPPORT
; 
2024  * Called as part of ip_init 
2027 in_ifaddr_init(void) 
2031         PE_parse_boot_argn("ifa_debug", &inifa_debug
, sizeof (inifa_debug
)); 
2033         inifa_size 
= (inifa_debug 
== 0) ? sizeof (struct in_ifaddr
) : 
2034             sizeof (struct in_ifaddr_dbg
); 
2036         inifa_zone 
= zinit(inifa_size
, INIFA_ZONE_MAX 
* inifa_size
, 
2037             0, INIFA_ZONE_NAME
); 
2038         if (inifa_zone 
== NULL
) { 
2039                 panic("%s: failed allocating %s", __func__
, INIFA_ZONE_NAME
); 
2042         zone_change(inifa_zone
, Z_EXPAND
, TRUE
); 
2043         zone_change(inifa_zone
, Z_CALLERACCT
, FALSE
); 
2045         lck_mtx_init(&inifa_trash_lock
, ifa_mtx_grp
, ifa_mtx_attr
); 
2046         TAILQ_INIT(&inifa_trash_head
); 
2049 static struct in_ifaddr 
* 
2050 in_ifaddr_alloc(int how
) 
2052         struct in_ifaddr 
*inifa
; 
2054         inifa 
= (how 
== M_WAITOK
) ? zalloc(inifa_zone
) : 
2055             zalloc_noblock(inifa_zone
); 
2056         if (inifa 
!= NULL
) { 
2057                 bzero(inifa
, inifa_size
); 
2058                 inifa
->ia_ifa
.ifa_free 
= in_ifaddr_free
; 
2059                 inifa
->ia_ifa
.ifa_debug 
|= IFD_ALLOC
; 
2060                 ifa_lock_init(&inifa
->ia_ifa
); 
2061                 if (inifa_debug 
!= 0) { 
2062                         struct in_ifaddr_dbg 
*inifa_dbg 
= 
2063                             (struct in_ifaddr_dbg 
*)inifa
; 
2064                         inifa
->ia_ifa
.ifa_debug 
|= IFD_DEBUG
; 
2065                         inifa
->ia_ifa
.ifa_trace 
= in_ifaddr_trace
; 
2066                         inifa
->ia_ifa
.ifa_attached 
= in_ifaddr_attached
; 
2067                         inifa
->ia_ifa
.ifa_detached 
= in_ifaddr_detached
; 
2068                         ctrace_record(&inifa_dbg
->inifa_alloc
); 
2075 in_ifaddr_free(struct ifaddr 
*ifa
) 
2077         IFA_LOCK_ASSERT_HELD(ifa
); 
2079         if (ifa
->ifa_refcnt 
!= 0) { 
2080                 panic("%s: ifa %p bad ref cnt", __func__
, ifa
); 
2082         } if (!(ifa
->ifa_debug 
& IFD_ALLOC
)) { 
2083                 panic("%s: ifa %p cannot be freed", __func__
, ifa
); 
2086         if (ifa
->ifa_debug 
& IFD_DEBUG
) { 
2087                 struct in_ifaddr_dbg 
*inifa_dbg 
= (struct in_ifaddr_dbg 
*)ifa
; 
2088                 ctrace_record(&inifa_dbg
->inifa_free
); 
2089                 bcopy(&inifa_dbg
->inifa
, &inifa_dbg
->inifa_old
, 
2090                     sizeof (struct in_ifaddr
)); 
2091                 if (ifa
->ifa_debug 
& IFD_TRASHED
) { 
2092                         /* Become a regular mutex, just in case */ 
2093                         IFA_CONVERT_LOCK(ifa
); 
2094                         lck_mtx_lock(&inifa_trash_lock
); 
2095                         TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
, 
2097                         lck_mtx_unlock(&inifa_trash_lock
); 
2098                         ifa
->ifa_debug 
&= ~IFD_TRASHED
; 
2102         ifa_lock_destroy(ifa
); 
2103         bzero(ifa
, sizeof (struct in_ifaddr
)); 
2104         zfree(inifa_zone
, ifa
); 
2108 in_ifaddr_attached(struct ifaddr 
*ifa
) 
2110         struct in_ifaddr_dbg 
*inifa_dbg 
= (struct in_ifaddr_dbg 
*)ifa
; 
2112         IFA_LOCK_ASSERT_HELD(ifa
); 
2114         if (!(ifa
->ifa_debug 
& IFD_DEBUG
)) { 
2115                 panic("%s: ifa %p has no debug structure", __func__
, ifa
); 
2118         if (ifa
->ifa_debug 
& IFD_TRASHED
) { 
2119                 /* Become a regular mutex, just in case */ 
2120                 IFA_CONVERT_LOCK(ifa
); 
2121                 lck_mtx_lock(&inifa_trash_lock
); 
2122                 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
); 
2123                 lck_mtx_unlock(&inifa_trash_lock
); 
2124                 ifa
->ifa_debug 
&= ~IFD_TRASHED
; 
2129 in_ifaddr_detached(struct ifaddr 
*ifa
) 
2131         struct in_ifaddr_dbg 
*inifa_dbg 
= (struct in_ifaddr_dbg 
*)ifa
; 
2133         IFA_LOCK_ASSERT_HELD(ifa
); 
2135         if (!(ifa
->ifa_debug 
& IFD_DEBUG
)) { 
2136                 panic("%s: ifa %p has no debug structure", __func__
, ifa
); 
2138         } else if (ifa
->ifa_debug 
& IFD_TRASHED
) { 
2139                 panic("%s: ifa %p is already in trash list", __func__
, ifa
); 
2142         ifa
->ifa_debug 
|= IFD_TRASHED
; 
2143         /* Become a regular mutex, just in case */ 
2144         IFA_CONVERT_LOCK(ifa
); 
2145         lck_mtx_lock(&inifa_trash_lock
); 
2146         TAILQ_INSERT_TAIL(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
); 
2147         lck_mtx_unlock(&inifa_trash_lock
); 
2151 in_ifaddr_trace(struct ifaddr 
*ifa
, int refhold
) 
2153         struct in_ifaddr_dbg 
*inifa_dbg 
= (struct in_ifaddr_dbg 
*)ifa
; 
2158         if (!(ifa
->ifa_debug 
& IFD_DEBUG
)) { 
2159                 panic("%s: ifa %p has no debug structure", __func__
, ifa
); 
2163                 cnt 
= &inifa_dbg
->inifa_refhold_cnt
; 
2164                 tr 
= inifa_dbg
->inifa_refhold
; 
2166                 cnt 
= &inifa_dbg
->inifa_refrele_cnt
; 
2167                 tr 
= inifa_dbg
->inifa_refrele
; 
2170         idx 
= atomic_add_16_ov(cnt
, 1) % INIFA_TRACE_HIST_SIZE
; 
2171         ctrace_record(&tr
[idx
]); 
2175  * Handle SIOCGASSOCIDS ioctl for PF_INET domain. 
2178 in_getassocids(struct socket 
*so
, uint32_t *cnt
, user_addr_t aidp
) 
2180         struct inpcb 
*inp 
= sotoinpcb(so
); 
2183         if (inp 
== NULL 
|| inp
->inp_state 
== INPCB_STATE_DEAD
) 
2186         /* INPCB has no concept of association */ 
2187         aid 
= SAE_ASSOCID_ANY
; 
2190         /* just asking how many there are? */ 
2191         if (aidp 
== USER_ADDR_NULL
) 
2194         return (copyout(&aid
, aidp
, sizeof (aid
))); 
2198  * Handle SIOCGCONNIDS ioctl for PF_INET domain. 
2201 in_getconnids(struct socket 
*so
, sae_associd_t aid
, uint32_t *cnt
, 
2204         struct inpcb 
*inp 
= sotoinpcb(so
); 
2207         if (inp 
== NULL 
|| inp
->inp_state 
== INPCB_STATE_DEAD
) 
2210         if (aid 
!= SAE_ASSOCID_ANY 
&& aid 
!= SAE_ASSOCID_ALL
) 
2213         /* if connected, return 1 connection count */ 
2214         *cnt 
= ((so
->so_state 
& SS_ISCONNECTED
) ? 1 : 0); 
2216         /* just asking how many there are? */ 
2217         if (cidp 
== USER_ADDR_NULL
) 
2220         /* if INPCB is connected, assign it connid 1 */ 
2221         cid 
= ((*cnt 
!= 0) ? 1 : SAE_CONNID_ANY
); 
2223         return (copyout(&cid
, cidp
, sizeof (cid
))); 
2227  * Handle SIOCGCONNINFO ioctl for PF_INET domain. 
2230 in_getconninfo(struct socket 
*so
, sae_connid_t cid
, uint32_t *flags
, 
2231     uint32_t *ifindex
, int32_t *soerror
, user_addr_t src
, socklen_t 
*src_len
, 
2232     user_addr_t dst
, socklen_t 
*dst_len
, uint32_t *aux_type
, 
2233     user_addr_t aux_data
, uint32_t *aux_len
) 
2235 #pragma unused(aux_data) 
2236         struct inpcb 
*inp 
= sotoinpcb(so
); 
2237         struct sockaddr_in sin
; 
2238         struct ifnet 
*ifp 
= NULL
; 
2240         u_int32_t copy_len 
= 0; 
2243          * Don't test for INPCB_STATE_DEAD since this may be called 
2244          * after SOF_PCBCLEARING is set, e.g. after tcp_close(). 
2251         if (cid 
!= SAE_CONNID_ANY 
&& cid 
!= SAE_CONNID_ALL 
&& cid 
!= 1) { 
2256         ifp 
= inp
->inp_last_outifp
; 
2257         *ifindex 
= ((ifp 
!= NULL
) ? ifp
->if_index 
: 0); 
2258         *soerror 
= so
->so_error
; 
2260         if (so
->so_state 
& SS_ISCONNECTED
) 
2261                 *flags 
|= (CIF_CONNECTED 
| CIF_PREFERRED
); 
2262         if (inp
->inp_flags 
& INP_BOUND_IF
) 
2263                 *flags 
|= CIF_BOUND_IF
; 
2264         if (!(inp
->inp_flags 
& INP_INADDR_ANY
)) 
2265                 *flags 
|= CIF_BOUND_IP
; 
2266         if (!(inp
->inp_flags 
& INP_ANONPORT
)) 
2267                 *flags 
|= CIF_BOUND_PORT
; 
2269         bzero(&sin
, sizeof (sin
)); 
2270         sin
.sin_len 
= sizeof (sin
); 
2271         sin
.sin_family 
= AF_INET
; 
2273         /* source address and port */ 
2274         sin
.sin_port 
= inp
->inp_lport
; 
2275         sin
.sin_addr
.s_addr 
= inp
->inp_laddr
.s_addr
; 
2276         if (*src_len 
== 0) { 
2277                 *src_len 
= sin
.sin_len
; 
2279                 if (src 
!= USER_ADDR_NULL
) { 
2280                         copy_len 
= min(*src_len
, sizeof (sin
)); 
2281                         error 
= copyout(&sin
, src
, copy_len
); 
2284                         *src_len 
= copy_len
; 
2288         /* destination address and port */ 
2289         sin
.sin_port 
= inp
->inp_fport
; 
2290         sin
.sin_addr
.s_addr 
= inp
->inp_faddr
.s_addr
; 
2291         if (*dst_len 
== 0) { 
2292                 *dst_len 
= sin
.sin_len
; 
2294                 if (dst 
!= USER_ADDR_NULL
) { 
2295                         copy_len 
= min(*dst_len
, sizeof (sin
)); 
2296                         error 
= copyout(&sin
, dst
, copy_len
); 
2299                         *dst_len 
= copy_len
; 
2305         if (SOCK_PROTO(so
) == IPPROTO_TCP
) { 
2306                 struct conninfo_tcp tcp_ci
; 
2308                 *aux_type 
= CIAUX_TCP
; 
2309                 if (*aux_len 
== 0) { 
2310                         *aux_len 
= sizeof (tcp_ci
); 
2312                         if (aux_data 
!= USER_ADDR_NULL
) { 
2313                                 copy_len 
= min(*aux_len
, sizeof (tcp_ci
)); 
2314                                 bzero(&tcp_ci
, sizeof (tcp_ci
)); 
2315                                 tcp_getconninfo(so
, &tcp_ci
); 
2316                                 error 
= copyout(&tcp_ci
, aux_data
, copy_len
); 
2319                                 *aux_len 
= copy_len
;