1*43a90889SApple OSS Distributions /*
2*43a90889SApple OSS Distributions * Copyright (c) 2000-2021 Apple Inc. All rights reserved.
3*43a90889SApple OSS Distributions *
4*43a90889SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*43a90889SApple OSS Distributions *
6*43a90889SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*43a90889SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*43a90889SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*43a90889SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*43a90889SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*43a90889SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*43a90889SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*43a90889SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*43a90889SApple OSS Distributions *
15*43a90889SApple OSS Distributions * Please obtain a copy of the License at
16*43a90889SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*43a90889SApple OSS Distributions *
18*43a90889SApple OSS Distributions * The Original Code and all software distributed under the License are
19*43a90889SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*43a90889SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*43a90889SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*43a90889SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*43a90889SApple OSS Distributions * Please see the License for the specific language governing rights and
24*43a90889SApple OSS Distributions * limitations under the License.
25*43a90889SApple OSS Distributions *
26*43a90889SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*43a90889SApple OSS Distributions */
28*43a90889SApple OSS Distributions /*
29*43a90889SApple OSS Distributions * Copyright (c) 1982, 1986, 1991, 1993
30*43a90889SApple OSS Distributions * The Regents of the University of California. All rights reserved.
31*43a90889SApple OSS Distributions *
32*43a90889SApple OSS Distributions * Redistribution and use in source and binary forms, with or without
33*43a90889SApple OSS Distributions * modification, are permitted provided that the following conditions
34*43a90889SApple OSS Distributions * are met:
35*43a90889SApple OSS Distributions * 1. Redistributions of source code must retain the above copyright
36*43a90889SApple OSS Distributions * notice, this list of conditions and the following disclaimer.
37*43a90889SApple OSS Distributions * 2. Redistributions in binary form must reproduce the above copyright
38*43a90889SApple OSS Distributions * notice, this list of conditions and the following disclaimer in the
39*43a90889SApple OSS Distributions * documentation and/or other materials provided with the distribution.
40*43a90889SApple OSS Distributions * 3. All advertising materials mentioning features or use of this software
41*43a90889SApple OSS Distributions * must display the following acknowledgement:
42*43a90889SApple OSS Distributions * This product includes software developed by the University of
43*43a90889SApple OSS Distributions * California, Berkeley and its contributors.
44*43a90889SApple OSS Distributions * 4. Neither the name of the University nor the names of its contributors
45*43a90889SApple OSS Distributions * may be used to endorse or promote products derived from this software
46*43a90889SApple OSS Distributions * without specific prior written permission.
47*43a90889SApple OSS Distributions *
48*43a90889SApple OSS Distributions * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49*43a90889SApple OSS Distributions * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50*43a90889SApple OSS Distributions * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51*43a90889SApple OSS Distributions * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52*43a90889SApple OSS Distributions * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53*43a90889SApple OSS Distributions * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54*43a90889SApple OSS Distributions * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55*43a90889SApple OSS Distributions * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56*43a90889SApple OSS Distributions * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57*43a90889SApple OSS Distributions * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58*43a90889SApple OSS Distributions * SUCH DAMAGE.
59*43a90889SApple OSS Distributions *
60*43a90889SApple OSS Distributions * @(#)in.c 8.4 (Berkeley) 1/9/95
61*43a90889SApple OSS Distributions */
62*43a90889SApple OSS Distributions
63*43a90889SApple OSS Distributions #include <sys/param.h>
64*43a90889SApple OSS Distributions #include <sys/systm.h>
65*43a90889SApple OSS Distributions #include <sys/sockio.h>
66*43a90889SApple OSS Distributions #include <sys/socketvar.h>
67*43a90889SApple OSS Distributions #include <sys/malloc.h>
68*43a90889SApple OSS Distributions #include <sys/proc.h>
69*43a90889SApple OSS Distributions #include <sys/socket.h>
70*43a90889SApple OSS Distributions #include <sys/kernel.h>
71*43a90889SApple OSS Distributions #include <sys/sysctl.h>
72*43a90889SApple OSS Distributions #include <sys/kern_event.h>
73*43a90889SApple OSS Distributions #include <sys/syslog.h>
74*43a90889SApple OSS Distributions #include <sys/mcache.h>
75*43a90889SApple OSS Distributions #include <sys/protosw.h>
76*43a90889SApple OSS Distributions #include <sys/file.h>
77*43a90889SApple OSS Distributions
78*43a90889SApple OSS Distributions #include <kern/zalloc.h>
79*43a90889SApple OSS Distributions #include <pexpert/pexpert.h>
80*43a90889SApple OSS Distributions #include <os/log.h>
81*43a90889SApple OSS Distributions
82*43a90889SApple OSS Distributions #include <net/if.h>
83*43a90889SApple OSS Distributions #include <net/if_types.h>
84*43a90889SApple OSS Distributions #include <net/route.h>
85*43a90889SApple OSS Distributions #include <net/kpi_protocol.h>
86*43a90889SApple OSS Distributions #include <net/dlil.h>
87*43a90889SApple OSS Distributions #if PF
88*43a90889SApple OSS Distributions #include <net/pfvar.h>
89*43a90889SApple OSS Distributions #endif /* PF */
90*43a90889SApple OSS Distributions
91*43a90889SApple OSS Distributions #include <netinet/in.h>
92*43a90889SApple OSS Distributions #include <netinet/in_var.h>
93*43a90889SApple OSS Distributions #include <netinet/in_pcb.h>
94*43a90889SApple OSS Distributions #include <netinet/igmp_var.h>
95*43a90889SApple OSS Distributions #include <netinet/ip_var.h>
96*43a90889SApple OSS Distributions #include <netinet/tcp.h>
97*43a90889SApple OSS Distributions #include <netinet/tcp_timer.h>
98*43a90889SApple OSS Distributions #include <netinet/tcp_var.h>
99*43a90889SApple OSS Distributions
100*43a90889SApple OSS Distributions #include <net/sockaddr_utils.h>
101*43a90889SApple OSS Distributions
102*43a90889SApple OSS Distributions static int inctl_associd(struct socket *, u_long, caddr_t __indexable);
103*43a90889SApple OSS Distributions static int inctl_connid(struct socket *, u_long, caddr_t __indexable);
104*43a90889SApple OSS Distributions static int inctl_conninfo(struct socket *, u_long, caddr_t __indexable);
105*43a90889SApple OSS Distributions
106*43a90889SApple OSS Distributions static int inctl_autoaddr(struct ifnet *, struct ifreq *);
107*43a90889SApple OSS Distributions static int inctl_arpipll(struct ifnet *, struct ifreq *);
108*43a90889SApple OSS Distributions static int inctl_setrouter(struct ifnet *, struct ifreq *);
109*43a90889SApple OSS Distributions static int inctl_ifaddr(struct ifnet *, struct in_ifaddr *, u_long,
110*43a90889SApple OSS Distributions struct ifreq *);
111*43a90889SApple OSS Distributions static int inctl_ifdstaddr(struct ifnet *, struct in_ifaddr *, u_long,
112*43a90889SApple OSS Distributions struct ifreq *);
113*43a90889SApple OSS Distributions static int inctl_ifbrdaddr(struct ifnet *, struct in_ifaddr *, u_long,
114*43a90889SApple OSS Distributions struct ifreq *);
115*43a90889SApple OSS Distributions static int inctl_ifnetmask(struct ifnet *, struct in_ifaddr *, u_long,
116*43a90889SApple OSS Distributions struct ifreq *);
117*43a90889SApple OSS Distributions
118*43a90889SApple OSS Distributions static void in_socktrim(struct sockaddr_in *);
119*43a90889SApple OSS Distributions static int in_ifinit(struct ifnet *, struct in_ifaddr *,
120*43a90889SApple OSS Distributions struct sockaddr_in *, int);
121*43a90889SApple OSS Distributions
122*43a90889SApple OSS Distributions #define IA_HASH_INIT(ia) { \
123*43a90889SApple OSS Distributions (ia)->ia_hash.tqe_next = __unsafe_forge_single(void *, ~(uintptr_t)0); \
124*43a90889SApple OSS Distributions (ia)->ia_hash.tqe_prev = __unsafe_forge_single(void *, ~(uintptr_t)0); \
125*43a90889SApple OSS Distributions }
126*43a90889SApple OSS Distributions
127*43a90889SApple OSS Distributions #define IA_IS_HASHED(ia) \
128*43a90889SApple OSS Distributions (!((ia)->ia_hash.tqe_next == __unsafe_forge_single(void *, ~(uintptr_t)0) || \
129*43a90889SApple OSS Distributions (ia)->ia_hash.tqe_prev == __unsafe_forge_single(void *, ~(uintptr_t)0)))
130*43a90889SApple OSS Distributions
131*43a90889SApple OSS Distributions static void in_iahash_remove(struct in_ifaddr *);
132*43a90889SApple OSS Distributions static void in_iahash_insert(struct in_ifaddr *);
133*43a90889SApple OSS Distributions static void in_iahash_insert_ptp(struct in_ifaddr *);
134*43a90889SApple OSS Distributions static struct in_ifaddr *in_ifaddr_alloc(void);
135*43a90889SApple OSS Distributions static void in_ifaddr_free(struct ifaddr *);
136*43a90889SApple OSS Distributions
137*43a90889SApple OSS Distributions static int in_getassocids(struct socket *, uint32_t *, user_addr_t);
138*43a90889SApple OSS Distributions static int in_getconnids(struct socket *, sae_associd_t, uint32_t *, user_addr_t);
139*43a90889SApple OSS Distributions
140*43a90889SApple OSS Distributions static int subnetsarelocal = 0;
141*43a90889SApple OSS Distributions SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local,
142*43a90889SApple OSS Distributions CTLFLAG_RW | CTLFLAG_LOCKED, &subnetsarelocal, 0, "");
143*43a90889SApple OSS Distributions
144*43a90889SApple OSS Distributions /* Track whether or not the SIOCARPIPLL ioctl has been called */
145*43a90889SApple OSS Distributions u_int32_t ipv4_ll_arp_aware = 0;
146*43a90889SApple OSS Distributions
147*43a90889SApple OSS Distributions /*
148*43a90889SApple OSS Distributions * Return 1 if the address is
149*43a90889SApple OSS Distributions * - loopback
150*43a90889SApple OSS Distributions * - unicast or multicast link local
151*43a90889SApple OSS Distributions * - routed via a link level gateway
152*43a90889SApple OSS Distributions * - belongs to a directly connected (sub)net
153*43a90889SApple OSS Distributions */
154*43a90889SApple OSS Distributions int
inaddr_local(struct in_addr in)155*43a90889SApple OSS Distributions inaddr_local(struct in_addr in)
156*43a90889SApple OSS Distributions {
157*43a90889SApple OSS Distributions struct rtentry *__single rt;
158*43a90889SApple OSS Distributions struct sockaddr_in sin;
159*43a90889SApple OSS Distributions int local = 0;
160*43a90889SApple OSS Distributions
161*43a90889SApple OSS Distributions if (ntohl(in.s_addr) == INADDR_LOOPBACK ||
162*43a90889SApple OSS Distributions IN_LINKLOCAL(ntohl(in.s_addr))) {
163*43a90889SApple OSS Distributions local = 1;
164*43a90889SApple OSS Distributions } else if (ntohl(in.s_addr) >= INADDR_UNSPEC_GROUP &&
165*43a90889SApple OSS Distributions ntohl(in.s_addr) <= INADDR_MAX_LOCAL_GROUP) {
166*43a90889SApple OSS Distributions local = 1;
167*43a90889SApple OSS Distributions } else {
168*43a90889SApple OSS Distributions sin.sin_family = AF_INET;
169*43a90889SApple OSS Distributions sin.sin_len = sizeof(sin);
170*43a90889SApple OSS Distributions sin.sin_addr = in;
171*43a90889SApple OSS Distributions rt = rtalloc1(SA(&sin), 0, 0);
172*43a90889SApple OSS Distributions
173*43a90889SApple OSS Distributions if (rt != NULL) {
174*43a90889SApple OSS Distributions RT_LOCK_SPIN(rt);
175*43a90889SApple OSS Distributions if (rt->rt_gateway->sa_family == AF_LINK ||
176*43a90889SApple OSS Distributions (rt->rt_ifp->if_flags & IFF_LOOPBACK)) {
177*43a90889SApple OSS Distributions local = 1;
178*43a90889SApple OSS Distributions }
179*43a90889SApple OSS Distributions RT_UNLOCK(rt);
180*43a90889SApple OSS Distributions rtfree(rt);
181*43a90889SApple OSS Distributions } else {
182*43a90889SApple OSS Distributions local = in_localaddr(in);
183*43a90889SApple OSS Distributions }
184*43a90889SApple OSS Distributions }
185*43a90889SApple OSS Distributions return local;
186*43a90889SApple OSS Distributions }
187*43a90889SApple OSS Distributions
188*43a90889SApple OSS Distributions /*
189*43a90889SApple OSS Distributions * Return 1 if an internet address is for a ``local'' host
190*43a90889SApple OSS Distributions * (one to which we have a connection). If subnetsarelocal
191*43a90889SApple OSS Distributions * is true, this includes other subnets of the local net,
192*43a90889SApple OSS Distributions * otherwise, it includes the directly-connected (sub)nets.
193*43a90889SApple OSS Distributions * The IPv4 link local prefix 169.254/16 is also included.
194*43a90889SApple OSS Distributions */
195*43a90889SApple OSS Distributions int
in_localaddr(struct in_addr in)196*43a90889SApple OSS Distributions in_localaddr(struct in_addr in)
197*43a90889SApple OSS Distributions {
198*43a90889SApple OSS Distributions u_int32_t i = ntohl(in.s_addr);
199*43a90889SApple OSS Distributions struct in_ifaddr *__single ia;
200*43a90889SApple OSS Distributions
201*43a90889SApple OSS Distributions if (IN_LINKLOCAL(i)) {
202*43a90889SApple OSS Distributions return 1;
203*43a90889SApple OSS Distributions }
204*43a90889SApple OSS Distributions
205*43a90889SApple OSS Distributions if (subnetsarelocal) {
206*43a90889SApple OSS Distributions lck_rw_lock_shared(&in_ifaddr_rwlock);
207*43a90889SApple OSS Distributions for (ia = in_ifaddrhead.tqh_first; ia != NULL;
208*43a90889SApple OSS Distributions ia = ia->ia_link.tqe_next) {
209*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
210*43a90889SApple OSS Distributions if ((i & ia->ia_netmask) == ia->ia_net) {
211*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
212*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
213*43a90889SApple OSS Distributions return 1;
214*43a90889SApple OSS Distributions }
215*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
216*43a90889SApple OSS Distributions }
217*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
218*43a90889SApple OSS Distributions } else {
219*43a90889SApple OSS Distributions lck_rw_lock_shared(&in_ifaddr_rwlock);
220*43a90889SApple OSS Distributions for (ia = in_ifaddrhead.tqh_first; ia != NULL;
221*43a90889SApple OSS Distributions ia = ia->ia_link.tqe_next) {
222*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
223*43a90889SApple OSS Distributions if ((i & ia->ia_subnetmask) == ia->ia_subnet) {
224*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
225*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
226*43a90889SApple OSS Distributions return 1;
227*43a90889SApple OSS Distributions }
228*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
229*43a90889SApple OSS Distributions }
230*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
231*43a90889SApple OSS Distributions }
232*43a90889SApple OSS Distributions return 0;
233*43a90889SApple OSS Distributions }
234*43a90889SApple OSS Distributions
235*43a90889SApple OSS Distributions /*
236*43a90889SApple OSS Distributions * Determine whether an IP address is in a reserved set of addresses
237*43a90889SApple OSS Distributions * that may not be forwarded, or whether datagrams to that destination
238*43a90889SApple OSS Distributions * may be forwarded.
239*43a90889SApple OSS Distributions */
240*43a90889SApple OSS Distributions boolean_t
in_canforward(struct in_addr in)241*43a90889SApple OSS Distributions in_canforward(struct in_addr in)
242*43a90889SApple OSS Distributions {
243*43a90889SApple OSS Distributions u_int32_t i = ntohl(in.s_addr);
244*43a90889SApple OSS Distributions u_int32_t net;
245*43a90889SApple OSS Distributions
246*43a90889SApple OSS Distributions if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i)) {
247*43a90889SApple OSS Distributions return FALSE;
248*43a90889SApple OSS Distributions }
249*43a90889SApple OSS Distributions if (IN_CLASSA(i)) {
250*43a90889SApple OSS Distributions net = i & IN_CLASSA_NET;
251*43a90889SApple OSS Distributions if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) {
252*43a90889SApple OSS Distributions return FALSE;
253*43a90889SApple OSS Distributions }
254*43a90889SApple OSS Distributions }
255*43a90889SApple OSS Distributions return TRUE;
256*43a90889SApple OSS Distributions }
257*43a90889SApple OSS Distributions
258*43a90889SApple OSS Distributions /*
259*43a90889SApple OSS Distributions * Trim a mask in a sockaddr
260*43a90889SApple OSS Distributions */
261*43a90889SApple OSS Distributions static void
in_socktrim(struct sockaddr_in * ap)262*43a90889SApple OSS Distributions in_socktrim(struct sockaddr_in *ap)
263*43a90889SApple OSS Distributions {
264*43a90889SApple OSS Distributions char *cplim = (char *)&ap->sin_addr;
265*43a90889SApple OSS Distributions char *cp = (char *)(&ap->sin_addr + 1);
266*43a90889SApple OSS Distributions
267*43a90889SApple OSS Distributions ap->sin_len = 0;
268*43a90889SApple OSS Distributions while (--cp >= cplim) {
269*43a90889SApple OSS Distributions if (*cp) {
270*43a90889SApple OSS Distributions (ap)->sin_len = (uint8_t)(cp - (char *)(ap) + 1);
271*43a90889SApple OSS Distributions break;
272*43a90889SApple OSS Distributions }
273*43a90889SApple OSS Distributions }
274*43a90889SApple OSS Distributions }
275*43a90889SApple OSS Distributions
276*43a90889SApple OSS Distributions static int in_interfaces; /* number of external internet interfaces */
277*43a90889SApple OSS Distributions
278*43a90889SApple OSS Distributions static int
in_domifattach(struct ifnet * ifp)279*43a90889SApple OSS Distributions in_domifattach(struct ifnet *ifp)
280*43a90889SApple OSS Distributions {
281*43a90889SApple OSS Distributions int error = 0;
282*43a90889SApple OSS Distributions
283*43a90889SApple OSS Distributions VERIFY(ifp != NULL);
284*43a90889SApple OSS Distributions
285*43a90889SApple OSS Distributions if ((error = proto_plumb(PF_INET, ifp)) && error != EEXIST) {
286*43a90889SApple OSS Distributions log(LOG_ERR, "%s: proto_plumb returned %d if=%s\n",
287*43a90889SApple OSS Distributions __func__, error, if_name(ifp));
288*43a90889SApple OSS Distributions return error;
289*43a90889SApple OSS Distributions }
290*43a90889SApple OSS Distributions
291*43a90889SApple OSS Distributions if (ifp->if_inetdata == NULL) {
292*43a90889SApple OSS Distributions ifp->if_inetdata = zalloc_permanent_type(struct in_ifextra);
293*43a90889SApple OSS Distributions error = 0;
294*43a90889SApple OSS Distributions } else if (error != EEXIST) {
295*43a90889SApple OSS Distributions /*
296*43a90889SApple OSS Distributions * Since the structure is never freed, we need to
297*43a90889SApple OSS Distributions * zero out its contents to avoid reusing stale data.
298*43a90889SApple OSS Distributions * A little redundant with allocation above, but it
299*43a90889SApple OSS Distributions * keeps the code simpler for all cases.
300*43a90889SApple OSS Distributions */
301*43a90889SApple OSS Distributions IN_IFEXTRA(ifp)->netsig_len = 0;
302*43a90889SApple OSS Distributions bzero(IN_IFEXTRA(ifp)->netsig, sizeof(IN_IFEXTRA(ifp)->netsig));
303*43a90889SApple OSS Distributions }
304*43a90889SApple OSS Distributions return error;
305*43a90889SApple OSS Distributions }
306*43a90889SApple OSS Distributions
307*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_associd(struct socket * so,u_long cmd,caddr_t __indexable data)308*43a90889SApple OSS Distributions inctl_associd(struct socket *so, u_long cmd, caddr_t __indexable data)
309*43a90889SApple OSS Distributions {
310*43a90889SApple OSS Distributions int error = 0;
311*43a90889SApple OSS Distributions union {
312*43a90889SApple OSS Distributions struct so_aidreq32 a32;
313*43a90889SApple OSS Distributions struct so_aidreq64 a64;
314*43a90889SApple OSS Distributions } u;
315*43a90889SApple OSS Distributions
316*43a90889SApple OSS Distributions VERIFY(so != NULL);
317*43a90889SApple OSS Distributions
318*43a90889SApple OSS Distributions switch (cmd) {
319*43a90889SApple OSS Distributions case SIOCGASSOCIDS32: /* struct so_aidreq32 */
320*43a90889SApple OSS Distributions bcopy(data, &u.a32, sizeof(u.a32));
321*43a90889SApple OSS Distributions error = in_getassocids(so, &u.a32.sar_cnt, u.a32.sar_aidp);
322*43a90889SApple OSS Distributions if (error == 0) {
323*43a90889SApple OSS Distributions bcopy(&u.a32, data, sizeof(u.a32));
324*43a90889SApple OSS Distributions }
325*43a90889SApple OSS Distributions break;
326*43a90889SApple OSS Distributions
327*43a90889SApple OSS Distributions case SIOCGASSOCIDS64: /* struct so_aidreq64 */
328*43a90889SApple OSS Distributions bcopy(data, &u.a64, sizeof(u.a64));
329*43a90889SApple OSS Distributions error = in_getassocids(so, &u.a64.sar_cnt, (user_addr_t)u.a64.sar_aidp);
330*43a90889SApple OSS Distributions if (error == 0) {
331*43a90889SApple OSS Distributions bcopy(&u.a64, data, sizeof(u.a64));
332*43a90889SApple OSS Distributions }
333*43a90889SApple OSS Distributions break;
334*43a90889SApple OSS Distributions
335*43a90889SApple OSS Distributions default:
336*43a90889SApple OSS Distributions VERIFY(0);
337*43a90889SApple OSS Distributions /* NOTREACHED */
338*43a90889SApple OSS Distributions }
339*43a90889SApple OSS Distributions
340*43a90889SApple OSS Distributions return error;
341*43a90889SApple OSS Distributions }
342*43a90889SApple OSS Distributions
343*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_connid(struct socket * so,u_long cmd,caddr_t __indexable data)344*43a90889SApple OSS Distributions inctl_connid(struct socket *so, u_long cmd, caddr_t __indexable data)
345*43a90889SApple OSS Distributions {
346*43a90889SApple OSS Distributions int error = 0;
347*43a90889SApple OSS Distributions union {
348*43a90889SApple OSS Distributions struct so_cidreq32 c32;
349*43a90889SApple OSS Distributions struct so_cidreq64 c64;
350*43a90889SApple OSS Distributions } u;
351*43a90889SApple OSS Distributions
352*43a90889SApple OSS Distributions VERIFY(so != NULL);
353*43a90889SApple OSS Distributions
354*43a90889SApple OSS Distributions switch (cmd) {
355*43a90889SApple OSS Distributions case SIOCGCONNIDS32: /* struct so_cidreq32 */
356*43a90889SApple OSS Distributions bcopy(data, &u.c32, sizeof(u.c32));
357*43a90889SApple OSS Distributions error = in_getconnids(so, u.c32.scr_aid, &u.c32.scr_cnt,
358*43a90889SApple OSS Distributions u.c32.scr_cidp);
359*43a90889SApple OSS Distributions if (error == 0) {
360*43a90889SApple OSS Distributions bcopy(&u.c32, data, sizeof(u.c32));
361*43a90889SApple OSS Distributions }
362*43a90889SApple OSS Distributions break;
363*43a90889SApple OSS Distributions
364*43a90889SApple OSS Distributions case SIOCGCONNIDS64: /* struct so_cidreq64 */
365*43a90889SApple OSS Distributions bcopy(data, &u.c64, sizeof(u.c64));
366*43a90889SApple OSS Distributions error = in_getconnids(so, u.c64.scr_aid, &u.c64.scr_cnt,
367*43a90889SApple OSS Distributions (user_addr_t)u.c64.scr_cidp);
368*43a90889SApple OSS Distributions if (error == 0) {
369*43a90889SApple OSS Distributions bcopy(&u.c64, data, sizeof(u.c64));
370*43a90889SApple OSS Distributions }
371*43a90889SApple OSS Distributions break;
372*43a90889SApple OSS Distributions
373*43a90889SApple OSS Distributions default:
374*43a90889SApple OSS Distributions VERIFY(0);
375*43a90889SApple OSS Distributions /* NOTREACHED */
376*43a90889SApple OSS Distributions }
377*43a90889SApple OSS Distributions
378*43a90889SApple OSS Distributions return error;
379*43a90889SApple OSS Distributions }
380*43a90889SApple OSS Distributions
381*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_conninfo(struct socket * so,u_long cmd,caddr_t __indexable data)382*43a90889SApple OSS Distributions inctl_conninfo(struct socket *so, u_long cmd, caddr_t __indexable data)
383*43a90889SApple OSS Distributions {
384*43a90889SApple OSS Distributions int error = 0;
385*43a90889SApple OSS Distributions union {
386*43a90889SApple OSS Distributions struct so_cinforeq32 ci32;
387*43a90889SApple OSS Distributions struct so_cinforeq64 ci64;
388*43a90889SApple OSS Distributions } u;
389*43a90889SApple OSS Distributions
390*43a90889SApple OSS Distributions VERIFY(so != NULL);
391*43a90889SApple OSS Distributions
392*43a90889SApple OSS Distributions switch (cmd) {
393*43a90889SApple OSS Distributions case SIOCGCONNINFO32: /* struct so_cinforeq32 */
394*43a90889SApple OSS Distributions bcopy(data, &u.ci32, sizeof(u.ci32));
395*43a90889SApple OSS Distributions error = in_getconninfo(so, u.ci32.scir_cid, &u.ci32.scir_flags,
396*43a90889SApple OSS Distributions &u.ci32.scir_ifindex, &u.ci32.scir_error, u.ci32.scir_src,
397*43a90889SApple OSS Distributions &u.ci32.scir_src_len, u.ci32.scir_dst, &u.ci32.scir_dst_len,
398*43a90889SApple OSS Distributions &u.ci32.scir_aux_type, u.ci32.scir_aux_data,
399*43a90889SApple OSS Distributions &u.ci32.scir_aux_len);
400*43a90889SApple OSS Distributions if (error == 0) {
401*43a90889SApple OSS Distributions bcopy(&u.ci32, data, sizeof(u.ci32));
402*43a90889SApple OSS Distributions }
403*43a90889SApple OSS Distributions break;
404*43a90889SApple OSS Distributions
405*43a90889SApple OSS Distributions case SIOCGCONNINFO64: /* struct so_cinforeq64 */
406*43a90889SApple OSS Distributions bcopy(data, &u.ci64, sizeof(u.ci64));
407*43a90889SApple OSS Distributions error = in_getconninfo(so, u.ci64.scir_cid, &u.ci64.scir_flags,
408*43a90889SApple OSS Distributions &u.ci64.scir_ifindex, &u.ci64.scir_error, (user_addr_t)u.ci64.scir_src,
409*43a90889SApple OSS Distributions &u.ci64.scir_src_len, (user_addr_t)u.ci64.scir_dst, &u.ci64.scir_dst_len,
410*43a90889SApple OSS Distributions &u.ci64.scir_aux_type, (user_addr_t)u.ci64.scir_aux_data,
411*43a90889SApple OSS Distributions &u.ci64.scir_aux_len);
412*43a90889SApple OSS Distributions if (error == 0) {
413*43a90889SApple OSS Distributions bcopy(&u.ci64, data, sizeof(u.ci64));
414*43a90889SApple OSS Distributions }
415*43a90889SApple OSS Distributions break;
416*43a90889SApple OSS Distributions
417*43a90889SApple OSS Distributions default:
418*43a90889SApple OSS Distributions VERIFY(0);
419*43a90889SApple OSS Distributions /* NOTREACHED */
420*43a90889SApple OSS Distributions }
421*43a90889SApple OSS Distributions
422*43a90889SApple OSS Distributions return error;
423*43a90889SApple OSS Distributions }
424*43a90889SApple OSS Distributions
425*43a90889SApple OSS Distributions /*
426*43a90889SApple OSS Distributions * Caller passes in the ioctl data pointer directly via "ifr", with the
427*43a90889SApple OSS Distributions * expectation that this routine always uses bcopy() or other byte-aligned
428*43a90889SApple OSS Distributions * memory accesses.
429*43a90889SApple OSS Distributions */
430*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_autoaddr(struct ifnet * ifp,struct ifreq * ifr)431*43a90889SApple OSS Distributions inctl_autoaddr(struct ifnet *ifp, struct ifreq *ifr)
432*43a90889SApple OSS Distributions {
433*43a90889SApple OSS Distributions int error = 0, intval;
434*43a90889SApple OSS Distributions
435*43a90889SApple OSS Distributions VERIFY(ifp != NULL);
436*43a90889SApple OSS Distributions
437*43a90889SApple OSS Distributions bcopy(&ifr->ifr_intval, &intval, sizeof(intval));
438*43a90889SApple OSS Distributions
439*43a90889SApple OSS Distributions ifnet_lock_exclusive(ifp);
440*43a90889SApple OSS Distributions if (intval) {
441*43a90889SApple OSS Distributions /*
442*43a90889SApple OSS Distributions * An interface in IPv4 router mode implies that it
443*43a90889SApple OSS Distributions * is configured with a static IP address and should
444*43a90889SApple OSS Distributions * not act as a DHCP client; prevent SIOCAUTOADDR from
445*43a90889SApple OSS Distributions * being set in that mode.
446*43a90889SApple OSS Distributions */
447*43a90889SApple OSS Distributions if (ifp->if_eflags & IFEF_IPV4_ROUTER) {
448*43a90889SApple OSS Distributions intval = 0; /* be safe; clear flag if set */
449*43a90889SApple OSS Distributions error = EBUSY;
450*43a90889SApple OSS Distributions } else {
451*43a90889SApple OSS Distributions if_set_eflags(ifp, IFEF_AUTOCONFIGURING);
452*43a90889SApple OSS Distributions }
453*43a90889SApple OSS Distributions }
454*43a90889SApple OSS Distributions if (!intval) {
455*43a90889SApple OSS Distributions if_clear_eflags(ifp, IFEF_AUTOCONFIGURING);
456*43a90889SApple OSS Distributions }
457*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
458*43a90889SApple OSS Distributions
459*43a90889SApple OSS Distributions return error;
460*43a90889SApple OSS Distributions }
461*43a90889SApple OSS Distributions
462*43a90889SApple OSS Distributions /*
463*43a90889SApple OSS Distributions * Caller passes in the ioctl data pointer directly via "ifr", with the
464*43a90889SApple OSS Distributions * expectation that this routine always uses bcopy() or other byte-aligned
465*43a90889SApple OSS Distributions * memory accesses.
466*43a90889SApple OSS Distributions */
467*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_arpipll(struct ifnet * ifp,struct ifreq * ifr)468*43a90889SApple OSS Distributions inctl_arpipll(struct ifnet *ifp, struct ifreq *ifr)
469*43a90889SApple OSS Distributions {
470*43a90889SApple OSS Distributions int error = 0, intval;
471*43a90889SApple OSS Distributions
472*43a90889SApple OSS Distributions VERIFY(ifp != NULL);
473*43a90889SApple OSS Distributions
474*43a90889SApple OSS Distributions bcopy(&ifr->ifr_intval, &intval, sizeof(intval));
475*43a90889SApple OSS Distributions ipv4_ll_arp_aware = 1;
476*43a90889SApple OSS Distributions
477*43a90889SApple OSS Distributions ifnet_lock_exclusive(ifp);
478*43a90889SApple OSS Distributions if (intval) {
479*43a90889SApple OSS Distributions /*
480*43a90889SApple OSS Distributions * An interface in IPv4 router mode implies that it
481*43a90889SApple OSS Distributions * is configured with a static IP address and should
482*43a90889SApple OSS Distributions * not have to deal with IPv4 Link-Local Address;
483*43a90889SApple OSS Distributions * prevent SIOCARPIPLL from being set in that mode.
484*43a90889SApple OSS Distributions */
485*43a90889SApple OSS Distributions if (ifp->if_eflags & IFEF_IPV4_ROUTER) {
486*43a90889SApple OSS Distributions intval = 0; /* be safe; clear flag if set */
487*43a90889SApple OSS Distributions error = EBUSY;
488*43a90889SApple OSS Distributions } else {
489*43a90889SApple OSS Distributions if_set_eflags(ifp, IFEF_ARPLL);
490*43a90889SApple OSS Distributions }
491*43a90889SApple OSS Distributions }
492*43a90889SApple OSS Distributions if (!intval) {
493*43a90889SApple OSS Distributions if_clear_eflags(ifp, IFEF_ARPLL);
494*43a90889SApple OSS Distributions }
495*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
496*43a90889SApple OSS Distributions
497*43a90889SApple OSS Distributions return error;
498*43a90889SApple OSS Distributions }
499*43a90889SApple OSS Distributions
500*43a90889SApple OSS Distributions /*
501*43a90889SApple OSS Distributions * Handle SIOCSETROUTERMODE to set or clear the IPv4 router mode flag on
502*43a90889SApple OSS Distributions * the interface. When in this mode, IPv4 Link-Local Address support is
503*43a90889SApple OSS Distributions * disabled in ARP, and DHCP client support is disabled in IP input; turning
504*43a90889SApple OSS Distributions * any of them on would cause an error to be returned. Entering or exiting
505*43a90889SApple OSS Distributions * this mode will result in the removal of IPv4 addresses currently configured
506*43a90889SApple OSS Distributions * on the interface.
507*43a90889SApple OSS Distributions *
508*43a90889SApple OSS Distributions * Caller passes in the ioctl data pointer directly via "ifr", with the
509*43a90889SApple OSS Distributions * expectation that this routine always uses bcopy() or other byte-aligned
510*43a90889SApple OSS Distributions * memory accesses.
511*43a90889SApple OSS Distributions */
512*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_setrouter(struct ifnet * ifp,struct ifreq * ifr)513*43a90889SApple OSS Distributions inctl_setrouter(struct ifnet *ifp, struct ifreq *ifr)
514*43a90889SApple OSS Distributions {
515*43a90889SApple OSS Distributions int error = 0, intval;
516*43a90889SApple OSS Distributions
517*43a90889SApple OSS Distributions VERIFY(ifp != NULL);
518*43a90889SApple OSS Distributions
519*43a90889SApple OSS Distributions /* Router mode isn't valid for loopback */
520*43a90889SApple OSS Distributions if (ifp->if_flags & IFF_LOOPBACK) {
521*43a90889SApple OSS Distributions return ENODEV;
522*43a90889SApple OSS Distributions }
523*43a90889SApple OSS Distributions
524*43a90889SApple OSS Distributions bcopy(&ifr->ifr_intval, &intval, sizeof(intval));
525*43a90889SApple OSS Distributions switch (intval) {
526*43a90889SApple OSS Distributions case 0:
527*43a90889SApple OSS Distributions case 1:
528*43a90889SApple OSS Distributions break;
529*43a90889SApple OSS Distributions default:
530*43a90889SApple OSS Distributions return EINVAL;
531*43a90889SApple OSS Distributions }
532*43a90889SApple OSS Distributions ifnet_lock_exclusive(ifp);
533*43a90889SApple OSS Distributions if (intval != 0) {
534*43a90889SApple OSS Distributions if_set_eflags(ifp, IFEF_IPV4_ROUTER);
535*43a90889SApple OSS Distributions if_clear_eflags(ifp, (IFEF_ARPLL | IFEF_AUTOCONFIGURING));
536*43a90889SApple OSS Distributions } else {
537*43a90889SApple OSS Distributions if_clear_eflags(ifp, IFEF_IPV4_ROUTER);
538*43a90889SApple OSS Distributions }
539*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
540*43a90889SApple OSS Distributions
541*43a90889SApple OSS Distributions /* purge all IPv4 addresses configured on this interface */
542*43a90889SApple OSS Distributions in_purgeaddrs(ifp);
543*43a90889SApple OSS Distributions
544*43a90889SApple OSS Distributions return error;
545*43a90889SApple OSS Distributions }
546*43a90889SApple OSS Distributions
547*43a90889SApple OSS Distributions /*
548*43a90889SApple OSS Distributions * Caller passes in the ioctl data pointer directly via "ifr", with the
549*43a90889SApple OSS Distributions * expectation that this routine always uses bcopy() or other byte-aligned
550*43a90889SApple OSS Distributions * memory accesses.
551*43a90889SApple OSS Distributions */
552*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_ifaddr(struct ifnet * ifp,struct in_ifaddr * ia,u_long cmd,struct ifreq * ifr)553*43a90889SApple OSS Distributions inctl_ifaddr(struct ifnet *ifp, struct in_ifaddr *ia, u_long cmd,
554*43a90889SApple OSS Distributions struct ifreq *ifr)
555*43a90889SApple OSS Distributions {
556*43a90889SApple OSS Distributions struct kev_in_data in_event_data;
557*43a90889SApple OSS Distributions struct kev_msg ev_msg;
558*43a90889SApple OSS Distributions struct sockaddr_in addr;
559*43a90889SApple OSS Distributions struct ifaddr *__single ifa;
560*43a90889SApple OSS Distributions int error = 0;
561*43a90889SApple OSS Distributions
562*43a90889SApple OSS Distributions VERIFY(ifp != NULL);
563*43a90889SApple OSS Distributions
564*43a90889SApple OSS Distributions bzero(&in_event_data, sizeof(struct kev_in_data));
565*43a90889SApple OSS Distributions bzero(&ev_msg, sizeof(struct kev_msg));
566*43a90889SApple OSS Distributions
567*43a90889SApple OSS Distributions switch (cmd) {
568*43a90889SApple OSS Distributions case SIOCGIFADDR: /* struct ifreq */
569*43a90889SApple OSS Distributions if (ia == NULL) {
570*43a90889SApple OSS Distributions error = EADDRNOTAVAIL;
571*43a90889SApple OSS Distributions break;
572*43a90889SApple OSS Distributions }
573*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
574*43a90889SApple OSS Distributions SOCKADDR_COPY(&ia->ia_addr, &ifr->ifr_addr, sizeof(addr));
575*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
576*43a90889SApple OSS Distributions break;
577*43a90889SApple OSS Distributions
578*43a90889SApple OSS Distributions case SIOCSIFADDR: /* struct ifreq */
579*43a90889SApple OSS Distributions VERIFY(ia != NULL);
580*43a90889SApple OSS Distributions SOCKADDR_COPY(&ifr->ifr_addr, &addr, sizeof(addr));
581*43a90889SApple OSS Distributions /*
582*43a90889SApple OSS Distributions * If this is a new address, the reference count for the
583*43a90889SApple OSS Distributions * hash table has been taken at creation time above.
584*43a90889SApple OSS Distributions */
585*43a90889SApple OSS Distributions error = in_ifinit(ifp, ia, &addr, 1);
586*43a90889SApple OSS Distributions if (error == 0) {
587*43a90889SApple OSS Distributions (void) ifnet_notify_address(ifp, AF_INET);
588*43a90889SApple OSS Distributions }
589*43a90889SApple OSS Distributions break;
590*43a90889SApple OSS Distributions
591*43a90889SApple OSS Distributions case SIOCAIFADDR: { /* struct {if,in_}aliasreq */
592*43a90889SApple OSS Distributions struct in_aliasreq *__single ifra = (struct in_aliasreq *)ifr;
593*43a90889SApple OSS Distributions struct sockaddr_in broadaddr, mask;
594*43a90889SApple OSS Distributions int hostIsNew, maskIsNew;
595*43a90889SApple OSS Distributions
596*43a90889SApple OSS Distributions VERIFY(ia != NULL);
597*43a90889SApple OSS Distributions SOCKADDR_COPY(&ifra->ifra_addr, &addr, sizeof(addr));
598*43a90889SApple OSS Distributions SOCKADDR_COPY(&ifra->ifra_broadaddr, &broadaddr, sizeof(broadaddr));
599*43a90889SApple OSS Distributions SOCKADDR_COPY(&ifra->ifra_mask, &mask, sizeof(mask));
600*43a90889SApple OSS Distributions
601*43a90889SApple OSS Distributions maskIsNew = 0;
602*43a90889SApple OSS Distributions hostIsNew = 1;
603*43a90889SApple OSS Distributions error = 0;
604*43a90889SApple OSS Distributions
605*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
606*43a90889SApple OSS Distributions if (ia->ia_addr.sin_family == AF_INET) {
607*43a90889SApple OSS Distributions if (addr.sin_len == 0) {
608*43a90889SApple OSS Distributions addr = ia->ia_addr;
609*43a90889SApple OSS Distributions hostIsNew = 0;
610*43a90889SApple OSS Distributions } else if (addr.sin_addr.s_addr ==
611*43a90889SApple OSS Distributions ia->ia_addr.sin_addr.s_addr) {
612*43a90889SApple OSS Distributions hostIsNew = 0;
613*43a90889SApple OSS Distributions }
614*43a90889SApple OSS Distributions }
615*43a90889SApple OSS Distributions if (mask.sin_len != 0) {
616*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
617*43a90889SApple OSS Distributions in_ifscrub(ifp, ia, 0);
618*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
619*43a90889SApple OSS Distributions ia->ia_sockmask.sin_len = sizeof(struct sockaddr_in);
620*43a90889SApple OSS Distributions ia->ia_sockmask.sin_family = AF_INET;
621*43a90889SApple OSS Distributions ia->ia_sockmask.sin_port = 0;
622*43a90889SApple OSS Distributions ia->ia_sockmask.sin_addr = mask.sin_addr;
623*43a90889SApple OSS Distributions bzero(&ia->ia_sockmask.sin_zero, sizeof(ia->ia_dstaddr.sin_zero));
624*43a90889SApple OSS Distributions ia->ia_subnetmask =
625*43a90889SApple OSS Distributions ntohl(ia->ia_sockmask.sin_addr.s_addr);
626*43a90889SApple OSS Distributions maskIsNew = 1;
627*43a90889SApple OSS Distributions }
628*43a90889SApple OSS Distributions if ((ifp->if_flags & IFF_POINTOPOINT) &&
629*43a90889SApple OSS Distributions (broadaddr.sin_family == AF_INET)) {
630*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
631*43a90889SApple OSS Distributions in_ifscrub(ifp, ia, 0);
632*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
633*43a90889SApple OSS Distributions ia->ia_dstaddr.sin_family = AF_INET;
634*43a90889SApple OSS Distributions ia->ia_dstaddr.sin_len = sizeof(struct sockaddr_in);
635*43a90889SApple OSS Distributions ia->ia_dstaddr.sin_port = 0;
636*43a90889SApple OSS Distributions ia->ia_dstaddr.sin_addr = broadaddr.sin_addr;
637*43a90889SApple OSS Distributions bzero(&ia->ia_dstaddr.sin_zero, sizeof(ia->ia_dstaddr.sin_zero));
638*43a90889SApple OSS Distributions maskIsNew = 1; /* We lie; but the effect's the same */
639*43a90889SApple OSS Distributions }
640*43a90889SApple OSS Distributions if (addr.sin_family == AF_INET && (hostIsNew || maskIsNew)) {
641*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
642*43a90889SApple OSS Distributions error = in_ifinit(ifp, ia, &addr, 0);
643*43a90889SApple OSS Distributions } else {
644*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
645*43a90889SApple OSS Distributions }
646*43a90889SApple OSS Distributions if (error == 0) {
647*43a90889SApple OSS Distributions (void) ifnet_notify_address(ifp, AF_INET);
648*43a90889SApple OSS Distributions }
649*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
650*43a90889SApple OSS Distributions if ((ifp->if_flags & IFF_BROADCAST) &&
651*43a90889SApple OSS Distributions (broadaddr.sin_family == AF_INET)) {
652*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_family = AF_INET;
653*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_len = sizeof(struct sockaddr_in);
654*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_port = 0;
655*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_addr = broadaddr.sin_addr;
656*43a90889SApple OSS Distributions bzero(&ia->ia_broadaddr.sin_zero, sizeof(ia->ia_broadaddr.sin_zero));
657*43a90889SApple OSS Distributions }
658*43a90889SApple OSS Distributions
659*43a90889SApple OSS Distributions /*
660*43a90889SApple OSS Distributions * Report event.
661*43a90889SApple OSS Distributions */
662*43a90889SApple OSS Distributions if ((error == 0) || (error == EEXIST)) {
663*43a90889SApple OSS Distributions ev_msg.vendor_code = KEV_VENDOR_APPLE;
664*43a90889SApple OSS Distributions ev_msg.kev_class = KEV_NETWORK_CLASS;
665*43a90889SApple OSS Distributions ev_msg.kev_subclass = KEV_INET_SUBCLASS;
666*43a90889SApple OSS Distributions
667*43a90889SApple OSS Distributions if (hostIsNew) {
668*43a90889SApple OSS Distributions ev_msg.event_code = KEV_INET_NEW_ADDR;
669*43a90889SApple OSS Distributions } else {
670*43a90889SApple OSS Distributions ev_msg.event_code = KEV_INET_CHANGED_ADDR;
671*43a90889SApple OSS Distributions }
672*43a90889SApple OSS Distributions
673*43a90889SApple OSS Distributions if (ia->ia_ifa.ifa_dstaddr) {
674*43a90889SApple OSS Distributions in_event_data.ia_dstaddr = SIN(ia->ia_ifa.ifa_dstaddr)->sin_addr;
675*43a90889SApple OSS Distributions } else {
676*43a90889SApple OSS Distributions in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
677*43a90889SApple OSS Distributions }
678*43a90889SApple OSS Distributions in_event_data.ia_addr = ia->ia_addr.sin_addr;
679*43a90889SApple OSS Distributions in_event_data.ia_net = ia->ia_net;
680*43a90889SApple OSS Distributions in_event_data.ia_netmask = ia->ia_netmask;
681*43a90889SApple OSS Distributions in_event_data.ia_subnet = ia->ia_subnet;
682*43a90889SApple OSS Distributions in_event_data.ia_subnetmask = ia->ia_subnetmask;
683*43a90889SApple OSS Distributions in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
684*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
685*43a90889SApple OSS Distributions (void) strlcpy(&in_event_data.link_data.if_name[0],
686*43a90889SApple OSS Distributions ifp->if_name, IFNAMSIZ);
687*43a90889SApple OSS Distributions in_event_data.link_data.if_family = ifp->if_family;
688*43a90889SApple OSS Distributions in_event_data.link_data.if_unit = ifp->if_unit;
689*43a90889SApple OSS Distributions
690*43a90889SApple OSS Distributions ev_msg.dv[0].data_ptr = &in_event_data;
691*43a90889SApple OSS Distributions ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
692*43a90889SApple OSS Distributions ev_msg.dv[1].data_length = 0;
693*43a90889SApple OSS Distributions
694*43a90889SApple OSS Distributions dlil_post_complete_msg(ifp, &ev_msg);
695*43a90889SApple OSS Distributions } else {
696*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
697*43a90889SApple OSS Distributions }
698*43a90889SApple OSS Distributions break;
699*43a90889SApple OSS Distributions }
700*43a90889SApple OSS Distributions
701*43a90889SApple OSS Distributions case SIOCDIFADDR: /* struct ifreq */
702*43a90889SApple OSS Distributions VERIFY(ia != NULL);
703*43a90889SApple OSS Distributions error = ifnet_ioctl(ifp, PF_INET, SIOCDIFADDR, ia);
704*43a90889SApple OSS Distributions if (error == EOPNOTSUPP) {
705*43a90889SApple OSS Distributions error = 0;
706*43a90889SApple OSS Distributions }
707*43a90889SApple OSS Distributions if (error != 0) {
708*43a90889SApple OSS Distributions break;
709*43a90889SApple OSS Distributions }
710*43a90889SApple OSS Distributions
711*43a90889SApple OSS Distributions /* Fill out the kernel event information */
712*43a90889SApple OSS Distributions ev_msg.vendor_code = KEV_VENDOR_APPLE;
713*43a90889SApple OSS Distributions ev_msg.kev_class = KEV_NETWORK_CLASS;
714*43a90889SApple OSS Distributions ev_msg.kev_subclass = KEV_INET_SUBCLASS;
715*43a90889SApple OSS Distributions
716*43a90889SApple OSS Distributions ev_msg.event_code = KEV_INET_ADDR_DELETED;
717*43a90889SApple OSS Distributions
718*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
719*43a90889SApple OSS Distributions if (ia->ia_ifa.ifa_dstaddr) {
720*43a90889SApple OSS Distributions in_event_data.ia_dstaddr = SIN(ia->ia_ifa.ifa_dstaddr)->sin_addr;
721*43a90889SApple OSS Distributions } else {
722*43a90889SApple OSS Distributions in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
723*43a90889SApple OSS Distributions }
724*43a90889SApple OSS Distributions in_event_data.ia_addr = ia->ia_addr.sin_addr;
725*43a90889SApple OSS Distributions in_event_data.ia_net = ia->ia_net;
726*43a90889SApple OSS Distributions in_event_data.ia_netmask = ia->ia_netmask;
727*43a90889SApple OSS Distributions in_event_data.ia_subnet = ia->ia_subnet;
728*43a90889SApple OSS Distributions in_event_data.ia_subnetmask = ia->ia_subnetmask;
729*43a90889SApple OSS Distributions in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
730*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
731*43a90889SApple OSS Distributions (void) strlcpy(&in_event_data.link_data.if_name[0],
732*43a90889SApple OSS Distributions ifp->if_name, IFNAMSIZ);
733*43a90889SApple OSS Distributions in_event_data.link_data.if_family = ifp->if_family;
734*43a90889SApple OSS Distributions in_event_data.link_data.if_unit = (u_int32_t)ifp->if_unit;
735*43a90889SApple OSS Distributions
736*43a90889SApple OSS Distributions ev_msg.dv[0].data_ptr = &in_event_data;
737*43a90889SApple OSS Distributions ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
738*43a90889SApple OSS Distributions ev_msg.dv[1].data_length = 0;
739*43a90889SApple OSS Distributions
740*43a90889SApple OSS Distributions ifa = &ia->ia_ifa;
741*43a90889SApple OSS Distributions lck_rw_lock_exclusive(&in_ifaddr_rwlock);
742*43a90889SApple OSS Distributions /* Release ia_link reference */
743*43a90889SApple OSS Distributions ifa_remref(ifa);
744*43a90889SApple OSS Distributions TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
745*43a90889SApple OSS Distributions IFA_LOCK(ifa);
746*43a90889SApple OSS Distributions if (IA_IS_HASHED(ia)) {
747*43a90889SApple OSS Distributions in_iahash_remove(ia);
748*43a90889SApple OSS Distributions }
749*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
750*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
751*43a90889SApple OSS Distributions
752*43a90889SApple OSS Distributions /*
753*43a90889SApple OSS Distributions * in_ifscrub kills the interface route.
754*43a90889SApple OSS Distributions */
755*43a90889SApple OSS Distributions in_ifscrub(ifp, ia, 0);
756*43a90889SApple OSS Distributions ifnet_lock_exclusive(ifp);
757*43a90889SApple OSS Distributions IFA_LOCK(ifa);
758*43a90889SApple OSS Distributions /* if_detach_ifa() releases ifa_link reference */
759*43a90889SApple OSS Distributions if_detach_ifa(ifp, ifa);
760*43a90889SApple OSS Distributions /* Our reference to this address is dropped at the bottom */
761*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
762*43a90889SApple OSS Distributions
763*43a90889SApple OSS Distributions /* invalidate route caches */
764*43a90889SApple OSS Distributions routegenid_inet_update();
765*43a90889SApple OSS Distributions
766*43a90889SApple OSS Distributions /*
767*43a90889SApple OSS Distributions * If the interface supports multicast, and no address is left,
768*43a90889SApple OSS Distributions * remove the "all hosts" multicast group from that interface.
769*43a90889SApple OSS Distributions */
770*43a90889SApple OSS Distributions if ((ifp->if_flags & IFF_MULTICAST) ||
771*43a90889SApple OSS Distributions ifp->if_allhostsinm != NULL) {
772*43a90889SApple OSS Distributions TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
773*43a90889SApple OSS Distributions IFA_LOCK(ifa);
774*43a90889SApple OSS Distributions if (ifa->ifa_addr->sa_family == AF_INET) {
775*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
776*43a90889SApple OSS Distributions break;
777*43a90889SApple OSS Distributions }
778*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
779*43a90889SApple OSS Distributions }
780*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
781*43a90889SApple OSS Distributions
782*43a90889SApple OSS Distributions lck_mtx_lock(&ifp->if_addrconfig_lock);
783*43a90889SApple OSS Distributions if (ifa == NULL && ifp->if_allhostsinm != NULL) {
784*43a90889SApple OSS Distributions struct in_multi *__single inm = ifp->if_allhostsinm;
785*43a90889SApple OSS Distributions ifp->if_allhostsinm = NULL;
786*43a90889SApple OSS Distributions
787*43a90889SApple OSS Distributions in_delmulti(inm);
788*43a90889SApple OSS Distributions /* release the reference for allhostsinm */
789*43a90889SApple OSS Distributions INM_REMREF(inm);
790*43a90889SApple OSS Distributions }
791*43a90889SApple OSS Distributions lck_mtx_unlock(&ifp->if_addrconfig_lock);
792*43a90889SApple OSS Distributions } else {
793*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
794*43a90889SApple OSS Distributions }
795*43a90889SApple OSS Distributions
796*43a90889SApple OSS Distributions /* Post the kernel event */
797*43a90889SApple OSS Distributions dlil_post_complete_msg(ifp, &ev_msg);
798*43a90889SApple OSS Distributions
799*43a90889SApple OSS Distributions /*
800*43a90889SApple OSS Distributions * See if there is any IPV4 address left and if so,
801*43a90889SApple OSS Distributions * reconfigure KDP to use current primary address.
802*43a90889SApple OSS Distributions */
803*43a90889SApple OSS Distributions ifa = ifa_ifpgetprimary(ifp, AF_INET);
804*43a90889SApple OSS Distributions if (ifa != NULL) {
805*43a90889SApple OSS Distributions /*
806*43a90889SApple OSS Distributions * NOTE: SIOCSIFADDR is defined with struct ifreq
807*43a90889SApple OSS Distributions * as parameter, but here we are sending it down
808*43a90889SApple OSS Distributions * to the interface with a pointer to struct ifaddr,
809*43a90889SApple OSS Distributions * for legacy reasons.
810*43a90889SApple OSS Distributions */
811*43a90889SApple OSS Distributions error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa);
812*43a90889SApple OSS Distributions if (error == EOPNOTSUPP) {
813*43a90889SApple OSS Distributions error = 0;
814*43a90889SApple OSS Distributions }
815*43a90889SApple OSS Distributions
816*43a90889SApple OSS Distributions /* Release reference from ifa_ifpgetprimary() */
817*43a90889SApple OSS Distributions ifa_remref(ifa);
818*43a90889SApple OSS Distributions }
819*43a90889SApple OSS Distributions (void) ifnet_notify_address(ifp, AF_INET);
820*43a90889SApple OSS Distributions break;
821*43a90889SApple OSS Distributions
822*43a90889SApple OSS Distributions default:
823*43a90889SApple OSS Distributions VERIFY(0);
824*43a90889SApple OSS Distributions /* NOTREACHED */
825*43a90889SApple OSS Distributions }
826*43a90889SApple OSS Distributions
827*43a90889SApple OSS Distributions return error;
828*43a90889SApple OSS Distributions }
829*43a90889SApple OSS Distributions
830*43a90889SApple OSS Distributions /*
831*43a90889SApple OSS Distributions * Caller passes in the ioctl data pointer directly via "ifr", with the
832*43a90889SApple OSS Distributions * expectation that this routine always uses bcopy() or other byte-aligned
833*43a90889SApple OSS Distributions * memory accesses.
834*43a90889SApple OSS Distributions */
835*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_ifdstaddr(struct ifnet * ifp,struct in_ifaddr * ia,u_long cmd,struct ifreq * ifr)836*43a90889SApple OSS Distributions inctl_ifdstaddr(struct ifnet *ifp, struct in_ifaddr *ia, u_long cmd,
837*43a90889SApple OSS Distributions struct ifreq *ifr)
838*43a90889SApple OSS Distributions {
839*43a90889SApple OSS Distributions struct kev_in_data in_event_data;
840*43a90889SApple OSS Distributions struct kev_msg ev_msg;
841*43a90889SApple OSS Distributions struct sockaddr_in dstaddr;
842*43a90889SApple OSS Distributions int error = 0;
843*43a90889SApple OSS Distributions
844*43a90889SApple OSS Distributions VERIFY(ifp != NULL);
845*43a90889SApple OSS Distributions
846*43a90889SApple OSS Distributions if (!(ifp->if_flags & IFF_POINTOPOINT)) {
847*43a90889SApple OSS Distributions return EINVAL;
848*43a90889SApple OSS Distributions }
849*43a90889SApple OSS Distributions
850*43a90889SApple OSS Distributions bzero(&in_event_data, sizeof(struct kev_in_data));
851*43a90889SApple OSS Distributions bzero(&ev_msg, sizeof(struct kev_msg));
852*43a90889SApple OSS Distributions
853*43a90889SApple OSS Distributions switch (cmd) {
854*43a90889SApple OSS Distributions case SIOCGIFDSTADDR: /* struct ifreq */
855*43a90889SApple OSS Distributions if (ia == NULL) {
856*43a90889SApple OSS Distributions error = EADDRNOTAVAIL;
857*43a90889SApple OSS Distributions break;
858*43a90889SApple OSS Distributions }
859*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
860*43a90889SApple OSS Distributions SOCKADDR_COPY(&ia->ia_dstaddr, &ifr->ifr_dstaddr, sizeof(dstaddr));
861*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
862*43a90889SApple OSS Distributions break;
863*43a90889SApple OSS Distributions
864*43a90889SApple OSS Distributions case SIOCSIFDSTADDR: /* struct ifreq */
865*43a90889SApple OSS Distributions VERIFY(ia != NULL);
866*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
867*43a90889SApple OSS Distributions dstaddr = ia->ia_dstaddr;
868*43a90889SApple OSS Distributions
869*43a90889SApple OSS Distributions ia->ia_dstaddr.sin_family = AF_INET;
870*43a90889SApple OSS Distributions ia->ia_dstaddr.sin_len = sizeof(struct sockaddr_in);
871*43a90889SApple OSS Distributions ia->ia_dstaddr.sin_port = 0;
872*43a90889SApple OSS Distributions bcopy(&SIN(&ifr->ifr_dstaddr)->sin_addr,
873*43a90889SApple OSS Distributions &ia->ia_dstaddr.sin_addr, sizeof(ia->ia_dstaddr.sin_addr));
874*43a90889SApple OSS Distributions bzero(&ia->ia_dstaddr.sin_zero, sizeof(ia->ia_dstaddr.sin_zero));
875*43a90889SApple OSS Distributions
876*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
877*43a90889SApple OSS Distributions /*
878*43a90889SApple OSS Distributions * NOTE: SIOCSIFDSTADDR is defined with struct ifreq
879*43a90889SApple OSS Distributions * as parameter, but here we are sending it down
880*43a90889SApple OSS Distributions * to the interface with a pointer to struct ifaddr,
881*43a90889SApple OSS Distributions * for legacy reasons.
882*43a90889SApple OSS Distributions */
883*43a90889SApple OSS Distributions error = ifnet_ioctl(ifp, PF_INET, SIOCSIFDSTADDR, ia);
884*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
885*43a90889SApple OSS Distributions if (error == EOPNOTSUPP) {
886*43a90889SApple OSS Distributions error = 0;
887*43a90889SApple OSS Distributions }
888*43a90889SApple OSS Distributions if (error != 0) {
889*43a90889SApple OSS Distributions ia->ia_dstaddr = dstaddr;
890*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
891*43a90889SApple OSS Distributions break;
892*43a90889SApple OSS Distributions }
893*43a90889SApple OSS Distributions IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
894*43a90889SApple OSS Distributions
895*43a90889SApple OSS Distributions ev_msg.vendor_code = KEV_VENDOR_APPLE;
896*43a90889SApple OSS Distributions ev_msg.kev_class = KEV_NETWORK_CLASS;
897*43a90889SApple OSS Distributions ev_msg.kev_subclass = KEV_INET_SUBCLASS;
898*43a90889SApple OSS Distributions
899*43a90889SApple OSS Distributions ev_msg.event_code = KEV_INET_SIFDSTADDR;
900*43a90889SApple OSS Distributions
901*43a90889SApple OSS Distributions if (ia->ia_ifa.ifa_dstaddr) {
902*43a90889SApple OSS Distributions in_event_data.ia_dstaddr = SIN(ia->ia_ifa.ifa_dstaddr)->sin_addr;
903*43a90889SApple OSS Distributions } else {
904*43a90889SApple OSS Distributions in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
905*43a90889SApple OSS Distributions }
906*43a90889SApple OSS Distributions
907*43a90889SApple OSS Distributions in_event_data.ia_addr = ia->ia_addr.sin_addr;
908*43a90889SApple OSS Distributions in_event_data.ia_net = ia->ia_net;
909*43a90889SApple OSS Distributions in_event_data.ia_netmask = ia->ia_netmask;
910*43a90889SApple OSS Distributions in_event_data.ia_subnet = ia->ia_subnet;
911*43a90889SApple OSS Distributions in_event_data.ia_subnetmask = ia->ia_subnetmask;
912*43a90889SApple OSS Distributions in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
913*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
914*43a90889SApple OSS Distributions (void) strlcpy(&in_event_data.link_data.if_name[0],
915*43a90889SApple OSS Distributions ifp->if_name, IFNAMSIZ);
916*43a90889SApple OSS Distributions in_event_data.link_data.if_family = ifp->if_family;
917*43a90889SApple OSS Distributions in_event_data.link_data.if_unit = (u_int32_t)ifp->if_unit;
918*43a90889SApple OSS Distributions
919*43a90889SApple OSS Distributions ev_msg.dv[0].data_ptr = &in_event_data;
920*43a90889SApple OSS Distributions ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
921*43a90889SApple OSS Distributions ev_msg.dv[1].data_length = 0;
922*43a90889SApple OSS Distributions
923*43a90889SApple OSS Distributions dlil_post_complete_msg(ifp, &ev_msg);
924*43a90889SApple OSS Distributions
925*43a90889SApple OSS Distributions lck_mtx_lock(rnh_lock);
926*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
927*43a90889SApple OSS Distributions if (ia->ia_flags & IFA_ROUTE) {
928*43a90889SApple OSS Distributions ia->ia_ifa.ifa_dstaddr = SA(&dstaddr);
929*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
930*43a90889SApple OSS Distributions rtinit_locked(&(ia->ia_ifa), RTM_DELETE, RTF_HOST);
931*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
932*43a90889SApple OSS Distributions ia->ia_ifa.ifa_dstaddr =
933*43a90889SApple OSS Distributions SA(&ia->ia_dstaddr);
934*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
935*43a90889SApple OSS Distributions rtinit_locked(&(ia->ia_ifa), RTM_ADD,
936*43a90889SApple OSS Distributions RTF_HOST | RTF_UP);
937*43a90889SApple OSS Distributions } else {
938*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
939*43a90889SApple OSS Distributions }
940*43a90889SApple OSS Distributions lck_mtx_unlock(rnh_lock);
941*43a90889SApple OSS Distributions break;
942*43a90889SApple OSS Distributions
943*43a90889SApple OSS Distributions
944*43a90889SApple OSS Distributions
945*43a90889SApple OSS Distributions default:
946*43a90889SApple OSS Distributions VERIFY(0);
947*43a90889SApple OSS Distributions /* NOTREACHED */
948*43a90889SApple OSS Distributions }
949*43a90889SApple OSS Distributions
950*43a90889SApple OSS Distributions return error;
951*43a90889SApple OSS Distributions }
952*43a90889SApple OSS Distributions
953*43a90889SApple OSS Distributions /*
954*43a90889SApple OSS Distributions * Caller passes in the ioctl data pointer directly via "ifr", with the
955*43a90889SApple OSS Distributions * expectation that this routine always uses bcopy() or other byte-aligned
956*43a90889SApple OSS Distributions * memory accesses.
957*43a90889SApple OSS Distributions */
958*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_ifbrdaddr(struct ifnet * ifp,struct in_ifaddr * ia,u_long cmd,struct ifreq * ifr)959*43a90889SApple OSS Distributions inctl_ifbrdaddr(struct ifnet *ifp, struct in_ifaddr *ia, u_long cmd,
960*43a90889SApple OSS Distributions struct ifreq *ifr)
961*43a90889SApple OSS Distributions {
962*43a90889SApple OSS Distributions struct kev_in_data in_event_data;
963*43a90889SApple OSS Distributions struct kev_msg ev_msg;
964*43a90889SApple OSS Distributions int error = 0;
965*43a90889SApple OSS Distributions
966*43a90889SApple OSS Distributions VERIFY(ifp != NULL);
967*43a90889SApple OSS Distributions
968*43a90889SApple OSS Distributions if (ia == NULL) {
969*43a90889SApple OSS Distributions return EADDRNOTAVAIL;
970*43a90889SApple OSS Distributions }
971*43a90889SApple OSS Distributions
972*43a90889SApple OSS Distributions if (!(ifp->if_flags & IFF_BROADCAST)) {
973*43a90889SApple OSS Distributions return EINVAL;
974*43a90889SApple OSS Distributions }
975*43a90889SApple OSS Distributions
976*43a90889SApple OSS Distributions bzero(&in_event_data, sizeof(struct kev_in_data));
977*43a90889SApple OSS Distributions bzero(&ev_msg, sizeof(struct kev_msg));
978*43a90889SApple OSS Distributions
979*43a90889SApple OSS Distributions switch (cmd) {
980*43a90889SApple OSS Distributions case SIOCGIFBRDADDR: /* struct ifreq */
981*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
982*43a90889SApple OSS Distributions SOCKADDR_COPY(&ia->ia_broadaddr, &ifr->ifr_broadaddr,
983*43a90889SApple OSS Distributions sizeof(struct sockaddr_in));
984*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
985*43a90889SApple OSS Distributions break;
986*43a90889SApple OSS Distributions
987*43a90889SApple OSS Distributions case SIOCSIFBRDADDR: /* struct ifreq */
988*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
989*43a90889SApple OSS Distributions
990*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_family = AF_INET;
991*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_len = sizeof(struct sockaddr_in);
992*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_port = 0;
993*43a90889SApple OSS Distributions bcopy(&SIN(&ifr->ifr_broadaddr)->sin_addr,
994*43a90889SApple OSS Distributions &ia->ia_broadaddr.sin_addr, sizeof(ia->ia_broadaddr.sin_addr));
995*43a90889SApple OSS Distributions bzero(&ia->ia_broadaddr.sin_zero, sizeof(ia->ia_broadaddr.sin_zero));
996*43a90889SApple OSS Distributions
997*43a90889SApple OSS Distributions ev_msg.vendor_code = KEV_VENDOR_APPLE;
998*43a90889SApple OSS Distributions ev_msg.kev_class = KEV_NETWORK_CLASS;
999*43a90889SApple OSS Distributions ev_msg.kev_subclass = KEV_INET_SUBCLASS;
1000*43a90889SApple OSS Distributions
1001*43a90889SApple OSS Distributions ev_msg.event_code = KEV_INET_SIFBRDADDR;
1002*43a90889SApple OSS Distributions
1003*43a90889SApple OSS Distributions if (ia->ia_ifa.ifa_dstaddr) {
1004*43a90889SApple OSS Distributions in_event_data.ia_dstaddr = SIN(ia->ia_ifa.ifa_dstaddr)->sin_addr;
1005*43a90889SApple OSS Distributions } else {
1006*43a90889SApple OSS Distributions in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
1007*43a90889SApple OSS Distributions }
1008*43a90889SApple OSS Distributions in_event_data.ia_addr = ia->ia_addr.sin_addr;
1009*43a90889SApple OSS Distributions in_event_data.ia_net = ia->ia_net;
1010*43a90889SApple OSS Distributions in_event_data.ia_netmask = ia->ia_netmask;
1011*43a90889SApple OSS Distributions in_event_data.ia_subnet = ia->ia_subnet;
1012*43a90889SApple OSS Distributions in_event_data.ia_subnetmask = ia->ia_subnetmask;
1013*43a90889SApple OSS Distributions in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
1014*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1015*43a90889SApple OSS Distributions (void) strlcpy(&in_event_data.link_data.if_name[0],
1016*43a90889SApple OSS Distributions ifp->if_name, IFNAMSIZ);
1017*43a90889SApple OSS Distributions in_event_data.link_data.if_family = ifp->if_family;
1018*43a90889SApple OSS Distributions in_event_data.link_data.if_unit = (u_int32_t)ifp->if_unit;
1019*43a90889SApple OSS Distributions
1020*43a90889SApple OSS Distributions ev_msg.dv[0].data_ptr = &in_event_data;
1021*43a90889SApple OSS Distributions ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
1022*43a90889SApple OSS Distributions ev_msg.dv[1].data_length = 0;
1023*43a90889SApple OSS Distributions
1024*43a90889SApple OSS Distributions dlil_post_complete_msg(ifp, &ev_msg);
1025*43a90889SApple OSS Distributions break;
1026*43a90889SApple OSS Distributions
1027*43a90889SApple OSS Distributions default:
1028*43a90889SApple OSS Distributions VERIFY(0);
1029*43a90889SApple OSS Distributions /* NOTREACHED */
1030*43a90889SApple OSS Distributions }
1031*43a90889SApple OSS Distributions
1032*43a90889SApple OSS Distributions return error;
1033*43a90889SApple OSS Distributions }
1034*43a90889SApple OSS Distributions
1035*43a90889SApple OSS Distributions /*
1036*43a90889SApple OSS Distributions * Caller passes in the ioctl data pointer directly via "ifr", with the
1037*43a90889SApple OSS Distributions * expectation that this routine always uses bcopy() or other byte-aligned
1038*43a90889SApple OSS Distributions * memory accesses.
1039*43a90889SApple OSS Distributions */
1040*43a90889SApple OSS Distributions static __attribute__((noinline)) int
inctl_ifnetmask(struct ifnet * ifp,struct in_ifaddr * ia,u_long cmd,struct ifreq * ifr)1041*43a90889SApple OSS Distributions inctl_ifnetmask(struct ifnet *ifp, struct in_ifaddr *ia, u_long cmd,
1042*43a90889SApple OSS Distributions struct ifreq *ifr)
1043*43a90889SApple OSS Distributions {
1044*43a90889SApple OSS Distributions struct kev_in_data in_event_data;
1045*43a90889SApple OSS Distributions struct kev_msg ev_msg;
1046*43a90889SApple OSS Distributions struct sockaddr_in mask;
1047*43a90889SApple OSS Distributions int error = 0;
1048*43a90889SApple OSS Distributions
1049*43a90889SApple OSS Distributions VERIFY(ifp != NULL);
1050*43a90889SApple OSS Distributions
1051*43a90889SApple OSS Distributions bzero(&in_event_data, sizeof(struct kev_in_data));
1052*43a90889SApple OSS Distributions bzero(&ev_msg, sizeof(struct kev_msg));
1053*43a90889SApple OSS Distributions
1054*43a90889SApple OSS Distributions switch (cmd) {
1055*43a90889SApple OSS Distributions case SIOCGIFNETMASK: /* struct ifreq */
1056*43a90889SApple OSS Distributions if (ia == NULL) {
1057*43a90889SApple OSS Distributions error = EADDRNOTAVAIL;
1058*43a90889SApple OSS Distributions break;
1059*43a90889SApple OSS Distributions }
1060*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1061*43a90889SApple OSS Distributions SOCKADDR_COPY(&ia->ia_sockmask, &ifr->ifr_addr, sizeof(mask));
1062*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1063*43a90889SApple OSS Distributions break;
1064*43a90889SApple OSS Distributions
1065*43a90889SApple OSS Distributions case SIOCSIFNETMASK: { /* struct ifreq */
1066*43a90889SApple OSS Distributions in_addr_t i;
1067*43a90889SApple OSS Distributions
1068*43a90889SApple OSS Distributions SOCKADDR_COPY(&ifr->ifr_addr, &mask, sizeof(mask));
1069*43a90889SApple OSS Distributions i = mask.sin_addr.s_addr;
1070*43a90889SApple OSS Distributions
1071*43a90889SApple OSS Distributions VERIFY(ia != NULL);
1072*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1073*43a90889SApple OSS Distributions ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i);
1074*43a90889SApple OSS Distributions ev_msg.vendor_code = KEV_VENDOR_APPLE;
1075*43a90889SApple OSS Distributions ev_msg.kev_class = KEV_NETWORK_CLASS;
1076*43a90889SApple OSS Distributions ev_msg.kev_subclass = KEV_INET_SUBCLASS;
1077*43a90889SApple OSS Distributions
1078*43a90889SApple OSS Distributions ev_msg.event_code = KEV_INET_SIFNETMASK;
1079*43a90889SApple OSS Distributions
1080*43a90889SApple OSS Distributions if (ia->ia_ifa.ifa_dstaddr) {
1081*43a90889SApple OSS Distributions in_event_data.ia_dstaddr = SIN(ia->ia_ifa.ifa_dstaddr)->sin_addr;
1082*43a90889SApple OSS Distributions } else {
1083*43a90889SApple OSS Distributions in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
1084*43a90889SApple OSS Distributions }
1085*43a90889SApple OSS Distributions in_event_data.ia_addr = ia->ia_addr.sin_addr;
1086*43a90889SApple OSS Distributions in_event_data.ia_net = ia->ia_net;
1087*43a90889SApple OSS Distributions in_event_data.ia_netmask = ia->ia_netmask;
1088*43a90889SApple OSS Distributions in_event_data.ia_subnet = ia->ia_subnet;
1089*43a90889SApple OSS Distributions in_event_data.ia_subnetmask = ia->ia_subnetmask;
1090*43a90889SApple OSS Distributions in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
1091*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1092*43a90889SApple OSS Distributions (void) strlcpy(&in_event_data.link_data.if_name[0],
1093*43a90889SApple OSS Distributions ifp->if_name, IFNAMSIZ);
1094*43a90889SApple OSS Distributions in_event_data.link_data.if_family = ifp->if_family;
1095*43a90889SApple OSS Distributions in_event_data.link_data.if_unit = (u_int32_t)ifp->if_unit;
1096*43a90889SApple OSS Distributions
1097*43a90889SApple OSS Distributions ev_msg.dv[0].data_ptr = &in_event_data;
1098*43a90889SApple OSS Distributions ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
1099*43a90889SApple OSS Distributions ev_msg.dv[1].data_length = 0;
1100*43a90889SApple OSS Distributions
1101*43a90889SApple OSS Distributions dlil_post_complete_msg(ifp, &ev_msg);
1102*43a90889SApple OSS Distributions break;
1103*43a90889SApple OSS Distributions }
1104*43a90889SApple OSS Distributions
1105*43a90889SApple OSS Distributions default:
1106*43a90889SApple OSS Distributions VERIFY(0);
1107*43a90889SApple OSS Distributions /* NOTREACHED */
1108*43a90889SApple OSS Distributions }
1109*43a90889SApple OSS Distributions
1110*43a90889SApple OSS Distributions return error;
1111*43a90889SApple OSS Distributions }
1112*43a90889SApple OSS Distributions
1113*43a90889SApple OSS Distributions /*
1114*43a90889SApple OSS Distributions * Generic INET control operations (ioctl's).
1115*43a90889SApple OSS Distributions *
1116*43a90889SApple OSS Distributions * ifp is NULL if not an interface-specific ioctl.
1117*43a90889SApple OSS Distributions *
1118*43a90889SApple OSS Distributions * Most of the routines called to handle the ioctls would end up being
1119*43a90889SApple OSS Distributions * tail-call optimized, which unfortunately causes this routine to
1120*43a90889SApple OSS Distributions * consume too much stack space; this is the reason for the "noinline"
1121*43a90889SApple OSS Distributions * attribute used on those routines.
1122*43a90889SApple OSS Distributions *
1123*43a90889SApple OSS Distributions * If called directly from within the networking stack (as opposed to via
1124*43a90889SApple OSS Distributions * pru_control), the socket parameter may be NULL.
1125*43a90889SApple OSS Distributions */
1126*43a90889SApple OSS Distributions int
in_control(struct socket * so,u_long cmd,caddr_t __sized_by (IOCPARM_LEN (cmd))data,struct ifnet * ifp,struct proc * p)1127*43a90889SApple OSS Distributions in_control(struct socket *so, u_long cmd, caddr_t __sized_by(IOCPARM_LEN(cmd)) data,
1128*43a90889SApple OSS Distributions struct ifnet *ifp, struct proc *p)
1129*43a90889SApple OSS Distributions {
1130*43a90889SApple OSS Distributions struct ifreq *__single ifr = NULL;
1131*43a90889SApple OSS Distributions struct sockaddr_in addr, dstaddr;
1132*43a90889SApple OSS Distributions struct sockaddr_in sin;
1133*43a90889SApple OSS Distributions struct sockaddr_in *__single sa = NULL;
1134*43a90889SApple OSS Distributions boolean_t privileged = (proc_suser(p) == 0);
1135*43a90889SApple OSS Distributions boolean_t so_unlocked = FALSE;
1136*43a90889SApple OSS Distributions struct in_ifaddr *__single ia = NULL;
1137*43a90889SApple OSS Distributions struct ifaddr *__single ifa;
1138*43a90889SApple OSS Distributions int error = 0;
1139*43a90889SApple OSS Distributions int intval;
1140*43a90889SApple OSS Distributions
1141*43a90889SApple OSS Distributions /* In case it's NULL, make sure it came from the kernel */
1142*43a90889SApple OSS Distributions VERIFY(so != NULL || p == kernproc);
1143*43a90889SApple OSS Distributions
1144*43a90889SApple OSS Distributions /*
1145*43a90889SApple OSS Distributions * ioctls which don't require ifp, but require socket.
1146*43a90889SApple OSS Distributions */
1147*43a90889SApple OSS Distributions switch (cmd) {
1148*43a90889SApple OSS Distributions case SIOCGASSOCIDS32: /* struct so_aidreq32 */
1149*43a90889SApple OSS Distributions case SIOCGASSOCIDS64: /* struct so_aidreq64 */
1150*43a90889SApple OSS Distributions return inctl_associd(so, cmd, data);
1151*43a90889SApple OSS Distributions /* NOTREACHED */
1152*43a90889SApple OSS Distributions
1153*43a90889SApple OSS Distributions case SIOCGCONNIDS32: /* struct so_cidreq32 */
1154*43a90889SApple OSS Distributions case SIOCGCONNIDS64: /* struct so_cidreq64 */
1155*43a90889SApple OSS Distributions return inctl_connid(so, cmd, data);
1156*43a90889SApple OSS Distributions /* NOTREACHED */
1157*43a90889SApple OSS Distributions
1158*43a90889SApple OSS Distributions case SIOCGCONNINFO32: /* struct so_cinforeq32 */
1159*43a90889SApple OSS Distributions case SIOCGCONNINFO64: /* struct so_cinforeq64 */
1160*43a90889SApple OSS Distributions return inctl_conninfo(so, cmd, data);
1161*43a90889SApple OSS Distributions /* NOTREACHED */
1162*43a90889SApple OSS Distributions }
1163*43a90889SApple OSS Distributions
1164*43a90889SApple OSS Distributions /*
1165*43a90889SApple OSS Distributions * The rest of ioctls require ifp; reject if we don't have one;
1166*43a90889SApple OSS Distributions * return ENXIO to be consistent with ifioctl().
1167*43a90889SApple OSS Distributions */
1168*43a90889SApple OSS Distributions if (ifp == NULL) {
1169*43a90889SApple OSS Distributions return ENXIO;
1170*43a90889SApple OSS Distributions }
1171*43a90889SApple OSS Distributions
1172*43a90889SApple OSS Distributions /*
1173*43a90889SApple OSS Distributions * ioctls which require ifp but not interface address.
1174*43a90889SApple OSS Distributions */
1175*43a90889SApple OSS Distributions switch (cmd) {
1176*43a90889SApple OSS Distributions case SIOCAUTOADDR: /* struct ifreq */
1177*43a90889SApple OSS Distributions if (!privileged) {
1178*43a90889SApple OSS Distributions return EPERM;
1179*43a90889SApple OSS Distributions }
1180*43a90889SApple OSS Distributions ifr = (struct ifreq *)(void *)data;
1181*43a90889SApple OSS Distributions return inctl_autoaddr(ifp, ifr);
1182*43a90889SApple OSS Distributions /* NOTREACHED */
1183*43a90889SApple OSS Distributions
1184*43a90889SApple OSS Distributions case SIOCARPIPLL: /* struct ifreq */
1185*43a90889SApple OSS Distributions if (!privileged) {
1186*43a90889SApple OSS Distributions return EPERM;
1187*43a90889SApple OSS Distributions }
1188*43a90889SApple OSS Distributions ifr = (struct ifreq *)(void *)data;
1189*43a90889SApple OSS Distributions return inctl_arpipll(ifp, ifr);
1190*43a90889SApple OSS Distributions /* NOTREACHED */
1191*43a90889SApple OSS Distributions
1192*43a90889SApple OSS Distributions case SIOCGETROUTERMODE: /* struct ifreq */
1193*43a90889SApple OSS Distributions ifr = (struct ifreq *)(void *)data;
1194*43a90889SApple OSS Distributions intval = (ifp->if_eflags & IFEF_IPV4_ROUTER) != 0 ? 1 : 0;
1195*43a90889SApple OSS Distributions bcopy(&intval, &ifr->ifr_intval, sizeof(intval));
1196*43a90889SApple OSS Distributions return 0;
1197*43a90889SApple OSS Distributions /* NOTREACHED */
1198*43a90889SApple OSS Distributions
1199*43a90889SApple OSS Distributions case SIOCSETROUTERMODE: /* struct ifreq */
1200*43a90889SApple OSS Distributions if (!privileged) {
1201*43a90889SApple OSS Distributions return EPERM;
1202*43a90889SApple OSS Distributions }
1203*43a90889SApple OSS Distributions ifr = (struct ifreq *)(void *)data;
1204*43a90889SApple OSS Distributions return inctl_setrouter(ifp, ifr);
1205*43a90889SApple OSS Distributions /* NOTREACHED */
1206*43a90889SApple OSS Distributions
1207*43a90889SApple OSS Distributions case SIOCPROTOATTACH: /* struct ifreq */
1208*43a90889SApple OSS Distributions if (!privileged) {
1209*43a90889SApple OSS Distributions return EPERM;
1210*43a90889SApple OSS Distributions }
1211*43a90889SApple OSS Distributions return in_domifattach(ifp);
1212*43a90889SApple OSS Distributions /* NOTREACHED */
1213*43a90889SApple OSS Distributions
1214*43a90889SApple OSS Distributions case SIOCPROTODETACH: /* struct ifreq */
1215*43a90889SApple OSS Distributions if (!privileged) {
1216*43a90889SApple OSS Distributions return EPERM;
1217*43a90889SApple OSS Distributions }
1218*43a90889SApple OSS Distributions
1219*43a90889SApple OSS Distributions /*
1220*43a90889SApple OSS Distributions * If an IPv4 address is still present, refuse to detach.
1221*43a90889SApple OSS Distributions */
1222*43a90889SApple OSS Distributions ifnet_lock_shared(ifp);
1223*43a90889SApple OSS Distributions TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1224*43a90889SApple OSS Distributions IFA_LOCK(ifa);
1225*43a90889SApple OSS Distributions if (ifa->ifa_addr->sa_family == AF_INET) {
1226*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
1227*43a90889SApple OSS Distributions break;
1228*43a90889SApple OSS Distributions }
1229*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
1230*43a90889SApple OSS Distributions }
1231*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
1232*43a90889SApple OSS Distributions return (ifa == NULL) ? proto_unplumb(PF_INET, ifp) : EBUSY;
1233*43a90889SApple OSS Distributions /* NOTREACHED */
1234*43a90889SApple OSS Distributions }
1235*43a90889SApple OSS Distributions
1236*43a90889SApple OSS Distributions /*
1237*43a90889SApple OSS Distributions * ioctls which require interface address; obtain sockaddr_in.
1238*43a90889SApple OSS Distributions */
1239*43a90889SApple OSS Distributions switch (cmd) {
1240*43a90889SApple OSS Distributions case SIOCAIFADDR: /* struct {if,in_}aliasreq */
1241*43a90889SApple OSS Distributions if (!privileged) {
1242*43a90889SApple OSS Distributions return EPERM;
1243*43a90889SApple OSS Distributions }
1244*43a90889SApple OSS Distributions SOCKADDR_COPY(&((struct in_aliasreq *)(void *)data)->ifra_addr,
1245*43a90889SApple OSS Distributions &sin, sizeof(sin));
1246*43a90889SApple OSS Distributions sa = &sin;
1247*43a90889SApple OSS Distributions break;
1248*43a90889SApple OSS Distributions
1249*43a90889SApple OSS Distributions case SIOCDIFADDR: /* struct ifreq */
1250*43a90889SApple OSS Distributions case SIOCSIFADDR: /* struct ifreq */
1251*43a90889SApple OSS Distributions case SIOCSIFDSTADDR: /* struct ifreq */
1252*43a90889SApple OSS Distributions case SIOCSIFNETMASK: /* struct ifreq */
1253*43a90889SApple OSS Distributions case SIOCSIFBRDADDR: /* struct ifreq */
1254*43a90889SApple OSS Distributions if (!privileged) {
1255*43a90889SApple OSS Distributions return EPERM;
1256*43a90889SApple OSS Distributions }
1257*43a90889SApple OSS Distributions OS_FALLTHROUGH;
1258*43a90889SApple OSS Distributions case SIOCGIFADDR: /* struct ifreq */
1259*43a90889SApple OSS Distributions case SIOCGIFDSTADDR: /* struct ifreq */
1260*43a90889SApple OSS Distributions case SIOCGIFNETMASK: /* struct ifreq */
1261*43a90889SApple OSS Distributions case SIOCGIFBRDADDR: /* struct ifreq */
1262*43a90889SApple OSS Distributions ifr = (struct ifreq *)(void *)data;
1263*43a90889SApple OSS Distributions SOCKADDR_COPY(&ifr->ifr_addr, &sin, sizeof(sin));
1264*43a90889SApple OSS Distributions sa = &sin;
1265*43a90889SApple OSS Distributions break;
1266*43a90889SApple OSS Distributions }
1267*43a90889SApple OSS Distributions
1268*43a90889SApple OSS Distributions /*
1269*43a90889SApple OSS Distributions * Find address for this interface, if it exists.
1270*43a90889SApple OSS Distributions *
1271*43a90889SApple OSS Distributions * If an alias address was specified, find that one instead of
1272*43a90889SApple OSS Distributions * the first one on the interface, if possible.
1273*43a90889SApple OSS Distributions */
1274*43a90889SApple OSS Distributions VERIFY(ia == NULL);
1275*43a90889SApple OSS Distributions if (sa != NULL) {
1276*43a90889SApple OSS Distributions struct in_ifaddr *iap;
1277*43a90889SApple OSS Distributions
1278*43a90889SApple OSS Distributions /*
1279*43a90889SApple OSS Distributions * Any failures from this point on must take into account
1280*43a90889SApple OSS Distributions * a non-NULL "ia" with an outstanding reference count, and
1281*43a90889SApple OSS Distributions * therefore requires ifa_remref. Jump to "done" label
1282*43a90889SApple OSS Distributions * instead of calling return if "ia" is valid.
1283*43a90889SApple OSS Distributions */
1284*43a90889SApple OSS Distributions lck_rw_lock_shared(&in_ifaddr_rwlock);
1285*43a90889SApple OSS Distributions TAILQ_FOREACH(iap, INADDR_HASH(sa->sin_addr.s_addr), ia_hash) {
1286*43a90889SApple OSS Distributions IFA_LOCK(&iap->ia_ifa);
1287*43a90889SApple OSS Distributions if (iap->ia_ifp == ifp &&
1288*43a90889SApple OSS Distributions iap->ia_addr.sin_addr.s_addr ==
1289*43a90889SApple OSS Distributions sa->sin_addr.s_addr) {
1290*43a90889SApple OSS Distributions ia = iap;
1291*43a90889SApple OSS Distributions ifa_addref(&iap->ia_ifa);
1292*43a90889SApple OSS Distributions IFA_UNLOCK(&iap->ia_ifa);
1293*43a90889SApple OSS Distributions break;
1294*43a90889SApple OSS Distributions }
1295*43a90889SApple OSS Distributions IFA_UNLOCK(&iap->ia_ifa);
1296*43a90889SApple OSS Distributions }
1297*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
1298*43a90889SApple OSS Distributions
1299*43a90889SApple OSS Distributions if (ia == NULL) {
1300*43a90889SApple OSS Distributions ifnet_lock_shared(ifp);
1301*43a90889SApple OSS Distributions TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1302*43a90889SApple OSS Distributions iap = ifatoia(ifa);
1303*43a90889SApple OSS Distributions IFA_LOCK(&iap->ia_ifa);
1304*43a90889SApple OSS Distributions if (iap->ia_addr.sin_family == AF_INET) {
1305*43a90889SApple OSS Distributions ia = iap;
1306*43a90889SApple OSS Distributions ifa_addref(&iap->ia_ifa);
1307*43a90889SApple OSS Distributions IFA_UNLOCK(&iap->ia_ifa);
1308*43a90889SApple OSS Distributions break;
1309*43a90889SApple OSS Distributions }
1310*43a90889SApple OSS Distributions IFA_UNLOCK(&iap->ia_ifa);
1311*43a90889SApple OSS Distributions }
1312*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
1313*43a90889SApple OSS Distributions }
1314*43a90889SApple OSS Distributions }
1315*43a90889SApple OSS Distributions
1316*43a90889SApple OSS Distributions /*
1317*43a90889SApple OSS Distributions * Unlock the socket since ifnet_ioctl() may be invoked by
1318*43a90889SApple OSS Distributions * one of the ioctl handlers below. Socket will be re-locked
1319*43a90889SApple OSS Distributions * prior to returning.
1320*43a90889SApple OSS Distributions */
1321*43a90889SApple OSS Distributions if (so != NULL) {
1322*43a90889SApple OSS Distributions socket_unlock(so, 0);
1323*43a90889SApple OSS Distributions so_unlocked = TRUE;
1324*43a90889SApple OSS Distributions }
1325*43a90889SApple OSS Distributions
1326*43a90889SApple OSS Distributions switch (cmd) {
1327*43a90889SApple OSS Distributions case SIOCAIFADDR: /* struct {if,in_}aliasreq */
1328*43a90889SApple OSS Distributions case SIOCDIFADDR: /* struct ifreq */
1329*43a90889SApple OSS Distributions if (cmd == SIOCAIFADDR) {
1330*43a90889SApple OSS Distributions SOCKADDR_COPY(&((struct in_aliasreq *)(void *)data)->
1331*43a90889SApple OSS Distributions ifra_addr, &addr, sizeof(addr));
1332*43a90889SApple OSS Distributions SOCKADDR_COPY(&((struct in_aliasreq *)(void *)data)->
1333*43a90889SApple OSS Distributions ifra_dstaddr, &dstaddr, sizeof(dstaddr));
1334*43a90889SApple OSS Distributions } else {
1335*43a90889SApple OSS Distributions VERIFY(cmd == SIOCDIFADDR);
1336*43a90889SApple OSS Distributions SOCKADDR_COPY(&((struct ifreq *)(void *)data)->ifr_addr,
1337*43a90889SApple OSS Distributions &addr, sizeof(addr));
1338*43a90889SApple OSS Distributions SOCKADDR_ZERO(&dstaddr, sizeof(dstaddr));
1339*43a90889SApple OSS Distributions }
1340*43a90889SApple OSS Distributions
1341*43a90889SApple OSS Distributions if (addr.sin_family == AF_INET) {
1342*43a90889SApple OSS Distributions struct in_ifaddr *__single oia;
1343*43a90889SApple OSS Distributions
1344*43a90889SApple OSS Distributions lck_rw_lock_shared(&in_ifaddr_rwlock);
1345*43a90889SApple OSS Distributions for (oia = ia; ia; ia = ia->ia_link.tqe_next) {
1346*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1347*43a90889SApple OSS Distributions if (ia->ia_ifp == ifp &&
1348*43a90889SApple OSS Distributions ia->ia_addr.sin_addr.s_addr ==
1349*43a90889SApple OSS Distributions addr.sin_addr.s_addr) {
1350*43a90889SApple OSS Distributions ifa_addref(&ia->ia_ifa);
1351*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1352*43a90889SApple OSS Distributions break;
1353*43a90889SApple OSS Distributions }
1354*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1355*43a90889SApple OSS Distributions }
1356*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
1357*43a90889SApple OSS Distributions if (oia != NULL) {
1358*43a90889SApple OSS Distributions ifa_remref(&oia->ia_ifa);
1359*43a90889SApple OSS Distributions }
1360*43a90889SApple OSS Distributions if ((ifp->if_flags & IFF_POINTOPOINT) &&
1361*43a90889SApple OSS Distributions (cmd == SIOCAIFADDR) &&
1362*43a90889SApple OSS Distributions (dstaddr.sin_addr.s_addr == INADDR_ANY)) {
1363*43a90889SApple OSS Distributions error = EDESTADDRREQ;
1364*43a90889SApple OSS Distributions goto done;
1365*43a90889SApple OSS Distributions }
1366*43a90889SApple OSS Distributions } else if (cmd == SIOCAIFADDR) {
1367*43a90889SApple OSS Distributions error = EINVAL;
1368*43a90889SApple OSS Distributions goto done;
1369*43a90889SApple OSS Distributions }
1370*43a90889SApple OSS Distributions if (cmd == SIOCDIFADDR) {
1371*43a90889SApple OSS Distributions if (ia == NULL) {
1372*43a90889SApple OSS Distributions error = EADDRNOTAVAIL;
1373*43a90889SApple OSS Distributions goto done;
1374*43a90889SApple OSS Distributions }
1375*43a90889SApple OSS Distributions
1376*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1377*43a90889SApple OSS Distributions /*
1378*43a90889SApple OSS Distributions * Avoid the race condition seen when two
1379*43a90889SApple OSS Distributions * threads process SIOCDIFADDR command
1380*43a90889SApple OSS Distributions * at the same time.
1381*43a90889SApple OSS Distributions */
1382*43a90889SApple OSS Distributions while (ia->ia_ifa.ifa_debug & IFD_DETACHING) {
1383*43a90889SApple OSS Distributions os_log(OS_LOG_DEFAULT,
1384*43a90889SApple OSS Distributions "Another thread is already attempting to "
1385*43a90889SApple OSS Distributions "delete IPv4 address: %s on interface %s. "
1386*43a90889SApple OSS Distributions "Go to sleep and check again after the operation is done",
1387*43a90889SApple OSS Distributions inet_ntoa(sa->sin_addr), ia->ia_ifp->if_xname);
1388*43a90889SApple OSS Distributions ia->ia_ifa.ifa_del_waiters++;
1389*43a90889SApple OSS Distributions (void) msleep(ia->ia_ifa.ifa_del_wc, &ia->ia_ifa.ifa_lock, (PZERO - 1),
1390*43a90889SApple OSS Distributions __func__, NULL);
1391*43a90889SApple OSS Distributions IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
1392*43a90889SApple OSS Distributions }
1393*43a90889SApple OSS Distributions
1394*43a90889SApple OSS Distributions if ((ia->ia_ifa.ifa_debug & IFD_ATTACHED) == 0) {
1395*43a90889SApple OSS Distributions error = EADDRNOTAVAIL;
1396*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1397*43a90889SApple OSS Distributions goto done;
1398*43a90889SApple OSS Distributions }
1399*43a90889SApple OSS Distributions
1400*43a90889SApple OSS Distributions ia->ia_ifa.ifa_debug |= IFD_DETACHING;
1401*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1402*43a90889SApple OSS Distributions }
1403*43a90889SApple OSS Distributions
1404*43a90889SApple OSS Distributions OS_FALLTHROUGH;
1405*43a90889SApple OSS Distributions case SIOCSIFADDR: /* struct ifreq */
1406*43a90889SApple OSS Distributions case SIOCSIFDSTADDR: /* struct ifreq */
1407*43a90889SApple OSS Distributions case SIOCSIFNETMASK: /* struct ifreq */
1408*43a90889SApple OSS Distributions if (cmd == SIOCAIFADDR) {
1409*43a90889SApple OSS Distributions /* fell thru from above; just repeat it */
1410*43a90889SApple OSS Distributions SOCKADDR_COPY(&((struct in_aliasreq *)(void *)data)->
1411*43a90889SApple OSS Distributions ifra_addr, &addr, sizeof(addr));
1412*43a90889SApple OSS Distributions } else {
1413*43a90889SApple OSS Distributions VERIFY(cmd == SIOCDIFADDR || cmd == SIOCSIFADDR ||
1414*43a90889SApple OSS Distributions cmd == SIOCSIFNETMASK || cmd == SIOCSIFDSTADDR);
1415*43a90889SApple OSS Distributions SOCKADDR_COPY(&((struct ifreq *)(void *)data)->ifr_addr,
1416*43a90889SApple OSS Distributions &addr, sizeof(addr));
1417*43a90889SApple OSS Distributions }
1418*43a90889SApple OSS Distributions
1419*43a90889SApple OSS Distributions if (addr.sin_family != AF_INET && cmd == SIOCSIFADDR) {
1420*43a90889SApple OSS Distributions error = EINVAL;
1421*43a90889SApple OSS Distributions goto done;
1422*43a90889SApple OSS Distributions }
1423*43a90889SApple OSS Distributions
1424*43a90889SApple OSS Distributions if ((cmd == SIOCAIFADDR || cmd == SIOCSIFADDR) &&
1425*43a90889SApple OSS Distributions (IN_MULTICAST(ntohl(addr.sin_addr.s_addr)) ||
1426*43a90889SApple OSS Distributions addr.sin_addr.s_addr == INADDR_BROADCAST ||
1427*43a90889SApple OSS Distributions addr.sin_addr.s_addr == INADDR_ANY)) {
1428*43a90889SApple OSS Distributions error = EINVAL;
1429*43a90889SApple OSS Distributions goto done;
1430*43a90889SApple OSS Distributions }
1431*43a90889SApple OSS Distributions
1432*43a90889SApple OSS Distributions if (ia == NULL) {
1433*43a90889SApple OSS Distributions ia = in_ifaddr_alloc();
1434*43a90889SApple OSS Distributions if (ia == NULL) {
1435*43a90889SApple OSS Distributions error = ENOBUFS;
1436*43a90889SApple OSS Distributions goto done;
1437*43a90889SApple OSS Distributions }
1438*43a90889SApple OSS Distributions ifnet_lock_exclusive(ifp);
1439*43a90889SApple OSS Distributions ifa = &ia->ia_ifa;
1440*43a90889SApple OSS Distributions IFA_LOCK(ifa);
1441*43a90889SApple OSS Distributions IA_HASH_INIT(ia);
1442*43a90889SApple OSS Distributions ifa->ifa_addr = SA(&ia->ia_addr);
1443*43a90889SApple OSS Distributions ifa->ifa_dstaddr = SA(&ia->ia_dstaddr);
1444*43a90889SApple OSS Distributions ifa->ifa_netmask = SA(&ia->ia_sockmask);
1445*43a90889SApple OSS Distributions ia->ia_sockmask.sin_len = offsetof(struct sockaddr_in, sin_zero);
1446*43a90889SApple OSS Distributions if (ifp->if_flags & IFF_BROADCAST) {
1447*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
1448*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_family = AF_INET;
1449*43a90889SApple OSS Distributions }
1450*43a90889SApple OSS Distributions ia->ia_ifp = ifp;
1451*43a90889SApple OSS Distributions if (!(ifp->if_flags & IFF_LOOPBACK)) {
1452*43a90889SApple OSS Distributions in_interfaces++;
1453*43a90889SApple OSS Distributions }
1454*43a90889SApple OSS Distributions /* if_attach_ifa() holds a reference for ifa_link */
1455*43a90889SApple OSS Distributions if_attach_ifa(ifp, ifa);
1456*43a90889SApple OSS Distributions /*
1457*43a90889SApple OSS Distributions * If we have to go through in_ifinit(), make sure
1458*43a90889SApple OSS Distributions * to avoid installing route(s) based on this address
1459*43a90889SApple OSS Distributions * via PFC_IFUP event, before the link resolver (ARP)
1460*43a90889SApple OSS Distributions * initializes it.
1461*43a90889SApple OSS Distributions */
1462*43a90889SApple OSS Distributions if (cmd == SIOCAIFADDR || cmd == SIOCSIFADDR) {
1463*43a90889SApple OSS Distributions ifa->ifa_debug |= IFD_NOTREADY;
1464*43a90889SApple OSS Distributions }
1465*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
1466*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
1467*43a90889SApple OSS Distributions lck_rw_lock_exclusive(&in_ifaddr_rwlock);
1468*43a90889SApple OSS Distributions /* Hold a reference for ia_link */
1469*43a90889SApple OSS Distributions ifa_addref(ifa);
1470*43a90889SApple OSS Distributions TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
1471*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
1472*43a90889SApple OSS Distributions /* discard error */
1473*43a90889SApple OSS Distributions (void) in_domifattach(ifp);
1474*43a90889SApple OSS Distributions error = 0;
1475*43a90889SApple OSS Distributions }
1476*43a90889SApple OSS Distributions break;
1477*43a90889SApple OSS Distributions }
1478*43a90889SApple OSS Distributions
1479*43a90889SApple OSS Distributions switch (cmd) {
1480*43a90889SApple OSS Distributions case SIOCGIFDSTADDR: /* struct ifreq */
1481*43a90889SApple OSS Distributions case SIOCSIFDSTADDR: /* struct ifreq */
1482*43a90889SApple OSS Distributions ifr = (struct ifreq *)(void *)data;
1483*43a90889SApple OSS Distributions error = inctl_ifdstaddr(ifp, ia, cmd, ifr);
1484*43a90889SApple OSS Distributions break;
1485*43a90889SApple OSS Distributions
1486*43a90889SApple OSS Distributions case SIOCGIFBRDADDR: /* struct ifreq */
1487*43a90889SApple OSS Distributions case SIOCSIFBRDADDR: /* struct ifreq */
1488*43a90889SApple OSS Distributions ifr = (struct ifreq *)(void *)data;
1489*43a90889SApple OSS Distributions error = inctl_ifbrdaddr(ifp, ia, cmd, ifr);
1490*43a90889SApple OSS Distributions break;
1491*43a90889SApple OSS Distributions
1492*43a90889SApple OSS Distributions case SIOCGIFNETMASK: /* struct ifreq */
1493*43a90889SApple OSS Distributions case SIOCSIFNETMASK: /* struct ifreq */
1494*43a90889SApple OSS Distributions ifr = (struct ifreq *)(void *)data;
1495*43a90889SApple OSS Distributions error = inctl_ifnetmask(ifp, ia, cmd, ifr);
1496*43a90889SApple OSS Distributions break;
1497*43a90889SApple OSS Distributions
1498*43a90889SApple OSS Distributions case SIOCGIFADDR: /* struct ifreq */
1499*43a90889SApple OSS Distributions case SIOCSIFADDR: /* struct ifreq */
1500*43a90889SApple OSS Distributions case SIOCAIFADDR: /* struct {if,in_}aliasreq */
1501*43a90889SApple OSS Distributions case SIOCDIFADDR: /* struct ifreq */
1502*43a90889SApple OSS Distributions ifr = (struct ifreq *)(void *)data;
1503*43a90889SApple OSS Distributions error = inctl_ifaddr(ifp, ia, cmd, ifr);
1504*43a90889SApple OSS Distributions break;
1505*43a90889SApple OSS Distributions
1506*43a90889SApple OSS Distributions default:
1507*43a90889SApple OSS Distributions error = EOPNOTSUPP;
1508*43a90889SApple OSS Distributions break;
1509*43a90889SApple OSS Distributions }
1510*43a90889SApple OSS Distributions
1511*43a90889SApple OSS Distributions done:
1512*43a90889SApple OSS Distributions if (ia != NULL) {
1513*43a90889SApple OSS Distributions if (cmd == SIOCDIFADDR) {
1514*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1515*43a90889SApple OSS Distributions ia->ia_ifa.ifa_debug &= ~IFD_DETACHING;
1516*43a90889SApple OSS Distributions if (ia->ia_ifa.ifa_del_waiters > 0) {
1517*43a90889SApple OSS Distributions ia->ia_ifa.ifa_del_waiters = 0;
1518*43a90889SApple OSS Distributions wakeup(ia->ia_ifa.ifa_del_wc);
1519*43a90889SApple OSS Distributions }
1520*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1521*43a90889SApple OSS Distributions }
1522*43a90889SApple OSS Distributions ifa_remref(&ia->ia_ifa);
1523*43a90889SApple OSS Distributions }
1524*43a90889SApple OSS Distributions if (so_unlocked) {
1525*43a90889SApple OSS Distributions socket_lock(so, 0);
1526*43a90889SApple OSS Distributions }
1527*43a90889SApple OSS Distributions
1528*43a90889SApple OSS Distributions return error;
1529*43a90889SApple OSS Distributions }
1530*43a90889SApple OSS Distributions
1531*43a90889SApple OSS Distributions /*
1532*43a90889SApple OSS Distributions * Delete any existing route for an interface.
1533*43a90889SApple OSS Distributions */
1534*43a90889SApple OSS Distributions void
in_ifscrub(struct ifnet * ifp,struct in_ifaddr * ia,int locked)1535*43a90889SApple OSS Distributions in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia, int locked)
1536*43a90889SApple OSS Distributions {
1537*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1538*43a90889SApple OSS Distributions if ((ia->ia_flags & IFA_ROUTE) == 0) {
1539*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1540*43a90889SApple OSS Distributions return;
1541*43a90889SApple OSS Distributions }
1542*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1543*43a90889SApple OSS Distributions if (!locked) {
1544*43a90889SApple OSS Distributions lck_mtx_lock(rnh_lock);
1545*43a90889SApple OSS Distributions }
1546*43a90889SApple OSS Distributions if (ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) {
1547*43a90889SApple OSS Distributions rtinit_locked(&(ia->ia_ifa), RTM_DELETE, RTF_HOST);
1548*43a90889SApple OSS Distributions } else {
1549*43a90889SApple OSS Distributions rtinit_locked(&(ia->ia_ifa), RTM_DELETE, 0);
1550*43a90889SApple OSS Distributions }
1551*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1552*43a90889SApple OSS Distributions ia->ia_flags &= ~IFA_ROUTE;
1553*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1554*43a90889SApple OSS Distributions if (!locked) {
1555*43a90889SApple OSS Distributions lck_mtx_unlock(rnh_lock);
1556*43a90889SApple OSS Distributions }
1557*43a90889SApple OSS Distributions }
1558*43a90889SApple OSS Distributions
1559*43a90889SApple OSS Distributions /*
1560*43a90889SApple OSS Distributions * Caller must hold in_ifaddr_rwlock as writer.
1561*43a90889SApple OSS Distributions */
1562*43a90889SApple OSS Distributions static void
in_iahash_remove(struct in_ifaddr * ia)1563*43a90889SApple OSS Distributions in_iahash_remove(struct in_ifaddr *ia)
1564*43a90889SApple OSS Distributions {
1565*43a90889SApple OSS Distributions LCK_RW_ASSERT(&in_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
1566*43a90889SApple OSS Distributions IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
1567*43a90889SApple OSS Distributions
1568*43a90889SApple OSS Distributions if (!IA_IS_HASHED(ia)) {
1569*43a90889SApple OSS Distributions panic("attempt to remove wrong ia %p from hash table", ia);
1570*43a90889SApple OSS Distributions /* NOTREACHED */
1571*43a90889SApple OSS Distributions }
1572*43a90889SApple OSS Distributions TAILQ_REMOVE(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
1573*43a90889SApple OSS Distributions IA_HASH_INIT(ia);
1574*43a90889SApple OSS Distributions ifa_remref(&ia->ia_ifa);
1575*43a90889SApple OSS Distributions }
1576*43a90889SApple OSS Distributions
1577*43a90889SApple OSS Distributions /*
1578*43a90889SApple OSS Distributions * Caller must hold in_ifaddr_rwlock as writer.
1579*43a90889SApple OSS Distributions */
1580*43a90889SApple OSS Distributions static void
in_iahash_insert(struct in_ifaddr * ia)1581*43a90889SApple OSS Distributions in_iahash_insert(struct in_ifaddr *ia)
1582*43a90889SApple OSS Distributions {
1583*43a90889SApple OSS Distributions LCK_RW_ASSERT(&in_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
1584*43a90889SApple OSS Distributions IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
1585*43a90889SApple OSS Distributions
1586*43a90889SApple OSS Distributions if (ia->ia_addr.sin_family != AF_INET) {
1587*43a90889SApple OSS Distributions panic("attempt to insert wrong ia %p into hash table", ia);
1588*43a90889SApple OSS Distributions /* NOTREACHED */
1589*43a90889SApple OSS Distributions } else if (IA_IS_HASHED(ia)) {
1590*43a90889SApple OSS Distributions panic("attempt to double-insert ia %p into hash table", ia);
1591*43a90889SApple OSS Distributions /* NOTREACHED */
1592*43a90889SApple OSS Distributions }
1593*43a90889SApple OSS Distributions TAILQ_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
1594*43a90889SApple OSS Distributions ia, ia_hash);
1595*43a90889SApple OSS Distributions ifa_addref(&ia->ia_ifa);
1596*43a90889SApple OSS Distributions }
1597*43a90889SApple OSS Distributions
1598*43a90889SApple OSS Distributions /*
1599*43a90889SApple OSS Distributions * Some point to point interfaces that are tunnels borrow the address from
1600*43a90889SApple OSS Distributions * an underlying interface (e.g. VPN server). In order for source address
1601*43a90889SApple OSS Distributions * selection logic to find the underlying interface first, we add the address
1602*43a90889SApple OSS Distributions * of borrowing point to point interfaces at the end of the list.
1603*43a90889SApple OSS Distributions * (see rdar://6733789)
1604*43a90889SApple OSS Distributions *
1605*43a90889SApple OSS Distributions * Caller must hold in_ifaddr_rwlock as writer.
1606*43a90889SApple OSS Distributions */
1607*43a90889SApple OSS Distributions static void
in_iahash_insert_ptp(struct in_ifaddr * ia)1608*43a90889SApple OSS Distributions in_iahash_insert_ptp(struct in_ifaddr *ia)
1609*43a90889SApple OSS Distributions {
1610*43a90889SApple OSS Distributions struct in_ifaddr *__single tmp_ifa;
1611*43a90889SApple OSS Distributions struct ifnet *__single tmp_ifp;
1612*43a90889SApple OSS Distributions
1613*43a90889SApple OSS Distributions LCK_RW_ASSERT(&in_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
1614*43a90889SApple OSS Distributions IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
1615*43a90889SApple OSS Distributions
1616*43a90889SApple OSS Distributions if (ia->ia_addr.sin_family != AF_INET) {
1617*43a90889SApple OSS Distributions panic("attempt to insert wrong ia %p into hash table", ia);
1618*43a90889SApple OSS Distributions /* NOTREACHED */
1619*43a90889SApple OSS Distributions } else if (IA_IS_HASHED(ia)) {
1620*43a90889SApple OSS Distributions panic("attempt to double-insert ia %p into hash table", ia);
1621*43a90889SApple OSS Distributions /* NOTREACHED */
1622*43a90889SApple OSS Distributions }
1623*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1624*43a90889SApple OSS Distributions TAILQ_FOREACH(tmp_ifa, INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
1625*43a90889SApple OSS Distributions ia_hash) {
1626*43a90889SApple OSS Distributions IFA_LOCK(&tmp_ifa->ia_ifa);
1627*43a90889SApple OSS Distributions /* ia->ia_addr won't change, so check without lock */
1628*43a90889SApple OSS Distributions if (IA_SIN(tmp_ifa)->sin_addr.s_addr ==
1629*43a90889SApple OSS Distributions ia->ia_addr.sin_addr.s_addr) {
1630*43a90889SApple OSS Distributions IFA_UNLOCK(&tmp_ifa->ia_ifa);
1631*43a90889SApple OSS Distributions break;
1632*43a90889SApple OSS Distributions }
1633*43a90889SApple OSS Distributions IFA_UNLOCK(&tmp_ifa->ia_ifa);
1634*43a90889SApple OSS Distributions }
1635*43a90889SApple OSS Distributions tmp_ifp = (tmp_ifa == NULL) ? NULL : tmp_ifa->ia_ifp;
1636*43a90889SApple OSS Distributions
1637*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1638*43a90889SApple OSS Distributions if (tmp_ifp == NULL) {
1639*43a90889SApple OSS Distributions TAILQ_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
1640*43a90889SApple OSS Distributions ia, ia_hash);
1641*43a90889SApple OSS Distributions } else {
1642*43a90889SApple OSS Distributions TAILQ_INSERT_TAIL(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
1643*43a90889SApple OSS Distributions ia, ia_hash);
1644*43a90889SApple OSS Distributions }
1645*43a90889SApple OSS Distributions ifa_addref(&ia->ia_ifa);
1646*43a90889SApple OSS Distributions }
1647*43a90889SApple OSS Distributions
1648*43a90889SApple OSS Distributions /*
1649*43a90889SApple OSS Distributions * Initialize an interface's internet address
1650*43a90889SApple OSS Distributions * and routing table entry.
1651*43a90889SApple OSS Distributions */
1652*43a90889SApple OSS Distributions static int
in_ifinit(struct ifnet * ifp,struct in_ifaddr * ia,struct sockaddr_in * sin,int scrub)1653*43a90889SApple OSS Distributions in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
1654*43a90889SApple OSS Distributions int scrub)
1655*43a90889SApple OSS Distributions {
1656*43a90889SApple OSS Distributions u_int32_t i = ntohl(sin->sin_addr.s_addr);
1657*43a90889SApple OSS Distributions struct sockaddr_in oldaddr;
1658*43a90889SApple OSS Distributions int flags = RTF_UP, error;
1659*43a90889SApple OSS Distributions struct ifaddr *__single ifa0;
1660*43a90889SApple OSS Distributions unsigned int cmd;
1661*43a90889SApple OSS Distributions int oldremoved = 0;
1662*43a90889SApple OSS Distributions
1663*43a90889SApple OSS Distributions /* Take an extra reference for this routine */
1664*43a90889SApple OSS Distributions ifa_addref(&ia->ia_ifa);
1665*43a90889SApple OSS Distributions
1666*43a90889SApple OSS Distributions lck_rw_lock_exclusive(&in_ifaddr_rwlock);
1667*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1668*43a90889SApple OSS Distributions oldaddr = ia->ia_addr;
1669*43a90889SApple OSS Distributions if (IA_IS_HASHED(ia)) {
1670*43a90889SApple OSS Distributions oldremoved = 1;
1671*43a90889SApple OSS Distributions in_iahash_remove(ia);
1672*43a90889SApple OSS Distributions }
1673*43a90889SApple OSS Distributions ia->ia_addr = *sin;
1674*43a90889SApple OSS Distributions /*
1675*43a90889SApple OSS Distributions * Interface addresses should not contain port or sin_zero information.
1676*43a90889SApple OSS Distributions */
1677*43a90889SApple OSS Distributions SIN(&ia->ia_addr)->sin_family = AF_INET;
1678*43a90889SApple OSS Distributions SIN(&ia->ia_addr)->sin_len = sizeof(struct sockaddr_in);
1679*43a90889SApple OSS Distributions SIN(&ia->ia_addr)->sin_port = 0;
1680*43a90889SApple OSS Distributions bzero(&SIN(&ia->ia_addr)->sin_zero, sizeof(sin->sin_zero));
1681*43a90889SApple OSS Distributions if ((ifp->if_flags & IFF_POINTOPOINT)) {
1682*43a90889SApple OSS Distributions in_iahash_insert_ptp(ia);
1683*43a90889SApple OSS Distributions } else {
1684*43a90889SApple OSS Distributions in_iahash_insert(ia);
1685*43a90889SApple OSS Distributions }
1686*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1687*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
1688*43a90889SApple OSS Distributions
1689*43a90889SApple OSS Distributions /*
1690*43a90889SApple OSS Distributions * Give the interface a chance to initialize if this is its first
1691*43a90889SApple OSS Distributions * address, and to validate the address if necessary. Send down
1692*43a90889SApple OSS Distributions * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es).
1693*43a90889SApple OSS Distributions * We find the first IPV4 address assigned to it and check if this
1694*43a90889SApple OSS Distributions * is the same as the one passed into this routine.
1695*43a90889SApple OSS Distributions */
1696*43a90889SApple OSS Distributions ifa0 = ifa_ifpgetprimary(ifp, AF_INET);
1697*43a90889SApple OSS Distributions cmd = (&ia->ia_ifa == ifa0) ? SIOCSIFADDR : SIOCAIFADDR;
1698*43a90889SApple OSS Distributions error = ifnet_ioctl(ifp, PF_INET, cmd, ia);
1699*43a90889SApple OSS Distributions if (error == EOPNOTSUPP) {
1700*43a90889SApple OSS Distributions error = 0;
1701*43a90889SApple OSS Distributions }
1702*43a90889SApple OSS Distributions /*
1703*43a90889SApple OSS Distributions * If we've just sent down SIOCAIFADDR, send another ioctl down
1704*43a90889SApple OSS Distributions * for SIOCSIFADDR for the first IPV4 address of the interface,
1705*43a90889SApple OSS Distributions * because an address change on one of the addresses will result
1706*43a90889SApple OSS Distributions * in the removal of the previous first IPV4 address. KDP needs
1707*43a90889SApple OSS Distributions * be reconfigured with the current primary IPV4 address.
1708*43a90889SApple OSS Distributions */
1709*43a90889SApple OSS Distributions if (error == 0 && cmd == SIOCAIFADDR) {
1710*43a90889SApple OSS Distributions /*
1711*43a90889SApple OSS Distributions * NOTE: SIOCSIFADDR is defined with struct ifreq
1712*43a90889SApple OSS Distributions * as parameter, but here we are sending it down
1713*43a90889SApple OSS Distributions * to the interface with a pointer to struct ifaddr,
1714*43a90889SApple OSS Distributions * for legacy reasons.
1715*43a90889SApple OSS Distributions */
1716*43a90889SApple OSS Distributions error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa0);
1717*43a90889SApple OSS Distributions if (error == EOPNOTSUPP) {
1718*43a90889SApple OSS Distributions error = 0;
1719*43a90889SApple OSS Distributions }
1720*43a90889SApple OSS Distributions }
1721*43a90889SApple OSS Distributions
1722*43a90889SApple OSS Distributions /* Release reference from ifa_ifpgetprimary() */
1723*43a90889SApple OSS Distributions ifa_remref(ifa0);
1724*43a90889SApple OSS Distributions
1725*43a90889SApple OSS Distributions if (error) {
1726*43a90889SApple OSS Distributions lck_rw_lock_exclusive(&in_ifaddr_rwlock);
1727*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1728*43a90889SApple OSS Distributions if (IA_IS_HASHED(ia)) {
1729*43a90889SApple OSS Distributions in_iahash_remove(ia);
1730*43a90889SApple OSS Distributions }
1731*43a90889SApple OSS Distributions ia->ia_addr = oldaddr;
1732*43a90889SApple OSS Distributions if (oldremoved) {
1733*43a90889SApple OSS Distributions if ((ifp->if_flags & IFF_POINTOPOINT)) {
1734*43a90889SApple OSS Distributions in_iahash_insert_ptp(ia);
1735*43a90889SApple OSS Distributions } else {
1736*43a90889SApple OSS Distributions in_iahash_insert(ia);
1737*43a90889SApple OSS Distributions }
1738*43a90889SApple OSS Distributions }
1739*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1740*43a90889SApple OSS Distributions lck_rw_done(&in_ifaddr_rwlock);
1741*43a90889SApple OSS Distributions /* Release extra reference taken above */
1742*43a90889SApple OSS Distributions ifa_remref(&ia->ia_ifa);
1743*43a90889SApple OSS Distributions return error;
1744*43a90889SApple OSS Distributions }
1745*43a90889SApple OSS Distributions lck_mtx_lock(rnh_lock);
1746*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1747*43a90889SApple OSS Distributions /*
1748*43a90889SApple OSS Distributions * Address has been initialized by the link resolver (ARP)
1749*43a90889SApple OSS Distributions * via ifnet_ioctl() above; it may now generate route(s).
1750*43a90889SApple OSS Distributions */
1751*43a90889SApple OSS Distributions ia->ia_ifa.ifa_debug &= ~IFD_NOTREADY;
1752*43a90889SApple OSS Distributions if (scrub) {
1753*43a90889SApple OSS Distributions ia->ia_ifa.ifa_addr = SA(&oldaddr);
1754*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1755*43a90889SApple OSS Distributions in_ifscrub(ifp, ia, 1);
1756*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1757*43a90889SApple OSS Distributions ia->ia_ifa.ifa_addr = SA(&ia->ia_addr);
1758*43a90889SApple OSS Distributions }
1759*43a90889SApple OSS Distributions IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
1760*43a90889SApple OSS Distributions if (IN_CLASSA(i)) {
1761*43a90889SApple OSS Distributions ia->ia_netmask = IN_CLASSA_NET;
1762*43a90889SApple OSS Distributions } else if (IN_CLASSB(i)) {
1763*43a90889SApple OSS Distributions ia->ia_netmask = IN_CLASSB_NET;
1764*43a90889SApple OSS Distributions } else {
1765*43a90889SApple OSS Distributions ia->ia_netmask = IN_CLASSC_NET;
1766*43a90889SApple OSS Distributions }
1767*43a90889SApple OSS Distributions /*
1768*43a90889SApple OSS Distributions * The subnet mask usually includes at least the standard network part,
1769*43a90889SApple OSS Distributions * but may may be smaller in the case of supernetting.
1770*43a90889SApple OSS Distributions * If it is set, we believe it.
1771*43a90889SApple OSS Distributions */
1772*43a90889SApple OSS Distributions if (ia->ia_subnetmask == 0) {
1773*43a90889SApple OSS Distributions ia->ia_subnetmask = ia->ia_netmask;
1774*43a90889SApple OSS Distributions ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
1775*43a90889SApple OSS Distributions } else {
1776*43a90889SApple OSS Distributions ia->ia_netmask &= ia->ia_subnetmask;
1777*43a90889SApple OSS Distributions }
1778*43a90889SApple OSS Distributions ia->ia_net = i & ia->ia_netmask;
1779*43a90889SApple OSS Distributions ia->ia_subnet = i & ia->ia_subnetmask;
1780*43a90889SApple OSS Distributions in_socktrim(&ia->ia_sockmask);
1781*43a90889SApple OSS Distributions /*
1782*43a90889SApple OSS Distributions * Add route for the network.
1783*43a90889SApple OSS Distributions */
1784*43a90889SApple OSS Distributions ia->ia_ifa.ifa_metric = ifp->if_metric;
1785*43a90889SApple OSS Distributions if (ifp->if_flags & IFF_BROADCAST) {
1786*43a90889SApple OSS Distributions ia->ia_broadaddr.sin_addr.s_addr =
1787*43a90889SApple OSS Distributions htonl(ia->ia_subnet | ~ia->ia_subnetmask);
1788*43a90889SApple OSS Distributions ia->ia_netbroadcast.s_addr =
1789*43a90889SApple OSS Distributions htonl(ia->ia_net | ~ia->ia_netmask);
1790*43a90889SApple OSS Distributions } else if (ifp->if_flags & IFF_LOOPBACK) {
1791*43a90889SApple OSS Distributions ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
1792*43a90889SApple OSS Distributions flags |= RTF_HOST;
1793*43a90889SApple OSS Distributions } else if (ifp->if_flags & IFF_POINTOPOINT) {
1794*43a90889SApple OSS Distributions if (ia->ia_dstaddr.sin_family != AF_INET) {
1795*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1796*43a90889SApple OSS Distributions lck_mtx_unlock(rnh_lock);
1797*43a90889SApple OSS Distributions /* Release extra reference taken above */
1798*43a90889SApple OSS Distributions ifa_remref(&ia->ia_ifa);
1799*43a90889SApple OSS Distributions return 0;
1800*43a90889SApple OSS Distributions }
1801*43a90889SApple OSS Distributions ia->ia_dstaddr.sin_len = sizeof(struct sockaddr_in);
1802*43a90889SApple OSS Distributions flags |= RTF_HOST;
1803*43a90889SApple OSS Distributions }
1804*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1805*43a90889SApple OSS Distributions
1806*43a90889SApple OSS Distributions if ((error = rtinit_locked(&(ia->ia_ifa), RTM_ADD, flags)) == 0) {
1807*43a90889SApple OSS Distributions IFA_LOCK(&ia->ia_ifa);
1808*43a90889SApple OSS Distributions ia->ia_flags |= IFA_ROUTE;
1809*43a90889SApple OSS Distributions IFA_UNLOCK(&ia->ia_ifa);
1810*43a90889SApple OSS Distributions }
1811*43a90889SApple OSS Distributions lck_mtx_unlock(rnh_lock);
1812*43a90889SApple OSS Distributions
1813*43a90889SApple OSS Distributions /* XXX check if the subnet route points to the same interface */
1814*43a90889SApple OSS Distributions if (error == EEXIST) {
1815*43a90889SApple OSS Distributions error = 0;
1816*43a90889SApple OSS Distributions }
1817*43a90889SApple OSS Distributions
1818*43a90889SApple OSS Distributions /*
1819*43a90889SApple OSS Distributions * If the interface supports multicast, join the "all hosts"
1820*43a90889SApple OSS Distributions * multicast group on that interface.
1821*43a90889SApple OSS Distributions */
1822*43a90889SApple OSS Distributions if (ifp->if_flags & IFF_MULTICAST) {
1823*43a90889SApple OSS Distributions struct in_addr addr;
1824*43a90889SApple OSS Distributions
1825*43a90889SApple OSS Distributions lck_mtx_lock(&ifp->if_addrconfig_lock);
1826*43a90889SApple OSS Distributions addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
1827*43a90889SApple OSS Distributions if (ifp->if_allhostsinm == NULL) {
1828*43a90889SApple OSS Distributions struct in_multi *__single inm;
1829*43a90889SApple OSS Distributions inm = in_addmulti(&addr, ifp);
1830*43a90889SApple OSS Distributions
1831*43a90889SApple OSS Distributions if (inm != NULL) {
1832*43a90889SApple OSS Distributions /*
1833*43a90889SApple OSS Distributions * Keep the reference on inm added by
1834*43a90889SApple OSS Distributions * in_addmulti above for storing the
1835*43a90889SApple OSS Distributions * pointer in allhostsinm.
1836*43a90889SApple OSS Distributions */
1837*43a90889SApple OSS Distributions ifp->if_allhostsinm = inm;
1838*43a90889SApple OSS Distributions } else {
1839*43a90889SApple OSS Distributions printf("%s: failed to add membership to "
1840*43a90889SApple OSS Distributions "all-hosts multicast address on %s\n",
1841*43a90889SApple OSS Distributions __func__, if_name(ifp));
1842*43a90889SApple OSS Distributions }
1843*43a90889SApple OSS Distributions }
1844*43a90889SApple OSS Distributions lck_mtx_unlock(&ifp->if_addrconfig_lock);
1845*43a90889SApple OSS Distributions }
1846*43a90889SApple OSS Distributions
1847*43a90889SApple OSS Distributions /* Release extra reference taken above */
1848*43a90889SApple OSS Distributions ifa_remref(&ia->ia_ifa);
1849*43a90889SApple OSS Distributions
1850*43a90889SApple OSS Distributions if (error == 0) {
1851*43a90889SApple OSS Distributions /* invalidate route caches */
1852*43a90889SApple OSS Distributions routegenid_inet_update();
1853*43a90889SApple OSS Distributions }
1854*43a90889SApple OSS Distributions
1855*43a90889SApple OSS Distributions return error;
1856*43a90889SApple OSS Distributions }
1857*43a90889SApple OSS Distributions
1858*43a90889SApple OSS Distributions /*
1859*43a90889SApple OSS Distributions * Return TRUE if the address might be a local broadcast address.
1860*43a90889SApple OSS Distributions */
1861*43a90889SApple OSS Distributions boolean_t
in_broadcast(struct in_addr in,struct ifnet * ifp)1862*43a90889SApple OSS Distributions in_broadcast(struct in_addr in, struct ifnet *ifp)
1863*43a90889SApple OSS Distributions {
1864*43a90889SApple OSS Distributions struct ifaddr *__single ifa;
1865*43a90889SApple OSS Distributions u_int32_t t;
1866*43a90889SApple OSS Distributions
1867*43a90889SApple OSS Distributions if (in.s_addr == INADDR_BROADCAST || in.s_addr == INADDR_ANY) {
1868*43a90889SApple OSS Distributions return TRUE;
1869*43a90889SApple OSS Distributions }
1870*43a90889SApple OSS Distributions if (!(ifp->if_flags & IFF_BROADCAST)) {
1871*43a90889SApple OSS Distributions return FALSE;
1872*43a90889SApple OSS Distributions }
1873*43a90889SApple OSS Distributions t = ntohl(in.s_addr);
1874*43a90889SApple OSS Distributions
1875*43a90889SApple OSS Distributions /*
1876*43a90889SApple OSS Distributions * Look through the list of addresses for a match
1877*43a90889SApple OSS Distributions * with a broadcast address.
1878*43a90889SApple OSS Distributions */
1879*43a90889SApple OSS Distributions ifnet_lock_shared(ifp);
1880*43a90889SApple OSS Distributions TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1881*43a90889SApple OSS Distributions struct in_ifaddr *ia = ifatoia(ifa);
1882*43a90889SApple OSS Distributions IFA_LOCK(ifa);
1883*43a90889SApple OSS Distributions if (ifa->ifa_addr->sa_family == AF_INET &&
1884*43a90889SApple OSS Distributions (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
1885*43a90889SApple OSS Distributions in.s_addr == ia->ia_netbroadcast.s_addr ||
1886*43a90889SApple OSS Distributions /*
1887*43a90889SApple OSS Distributions * Check for old-style (host 0) broadcast.
1888*43a90889SApple OSS Distributions */
1889*43a90889SApple OSS Distributions t == ia->ia_subnet || t == ia->ia_net) &&
1890*43a90889SApple OSS Distributions /*
1891*43a90889SApple OSS Distributions * Check for an all one subnetmask. These
1892*43a90889SApple OSS Distributions * only exist when an interface gets a secondary
1893*43a90889SApple OSS Distributions * address.
1894*43a90889SApple OSS Distributions */
1895*43a90889SApple OSS Distributions ia->ia_subnetmask != (u_int32_t)0xffffffff) {
1896*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
1897*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
1898*43a90889SApple OSS Distributions return TRUE;
1899*43a90889SApple OSS Distributions }
1900*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
1901*43a90889SApple OSS Distributions }
1902*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
1903*43a90889SApple OSS Distributions return FALSE;
1904*43a90889SApple OSS Distributions #undef ia
1905*43a90889SApple OSS Distributions }
1906*43a90889SApple OSS Distributions
1907*43a90889SApple OSS Distributions void
in_purgeaddrs(struct ifnet * ifp)1908*43a90889SApple OSS Distributions in_purgeaddrs(struct ifnet *ifp)
1909*43a90889SApple OSS Distributions {
1910*43a90889SApple OSS Distributions uint16_t addresses_count = 0;
1911*43a90889SApple OSS Distributions struct ifaddr **__counted_by(addresses_count) ifap = NULL;
1912*43a90889SApple OSS Distributions int err, i;
1913*43a90889SApple OSS Distributions
1914*43a90889SApple OSS Distributions VERIFY(ifp != NULL);
1915*43a90889SApple OSS Distributions
1916*43a90889SApple OSS Distributions /*
1917*43a90889SApple OSS Distributions * Be nice, and try the civilized way first. If we can't get
1918*43a90889SApple OSS Distributions * rid of them this way, then do it the rough way. We must
1919*43a90889SApple OSS Distributions * only get here during detach time, after the ifnet has been
1920*43a90889SApple OSS Distributions * removed from the global list and arrays.
1921*43a90889SApple OSS Distributions */
1922*43a90889SApple OSS Distributions err = ifnet_get_address_list_family_internal(ifp, &ifap, &addresses_count,
1923*43a90889SApple OSS Distributions AF_INET, 1, M_WAITOK, 0);
1924*43a90889SApple OSS Distributions if (err == 0 && ifap != NULL) {
1925*43a90889SApple OSS Distributions struct ifreq ifr;
1926*43a90889SApple OSS Distributions
1927*43a90889SApple OSS Distributions bzero(&ifr, sizeof(ifr));
1928*43a90889SApple OSS Distributions (void) snprintf(ifr.ifr_name, sizeof(ifr.ifr_name),
1929*43a90889SApple OSS Distributions "%s", if_name(ifp));
1930*43a90889SApple OSS Distributions
1931*43a90889SApple OSS Distributions for (i = 0; ifap[i] != NULL; i++) {
1932*43a90889SApple OSS Distributions struct ifaddr *__single ifa;
1933*43a90889SApple OSS Distributions
1934*43a90889SApple OSS Distributions ifa = ifap[i];
1935*43a90889SApple OSS Distributions IFA_LOCK(ifa);
1936*43a90889SApple OSS Distributions SOCKADDR_COPY(ifa->ifa_addr, &ifr.ifr_addr,
1937*43a90889SApple OSS Distributions sizeof(struct sockaddr_in));
1938*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
1939*43a90889SApple OSS Distributions err = in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr, ifp,
1940*43a90889SApple OSS Distributions kernproc);
1941*43a90889SApple OSS Distributions /* if we lost the race, ignore it */
1942*43a90889SApple OSS Distributions if (err == EADDRNOTAVAIL) {
1943*43a90889SApple OSS Distributions err = 0;
1944*43a90889SApple OSS Distributions }
1945*43a90889SApple OSS Distributions if (err != 0) {
1946*43a90889SApple OSS Distributions char s_addr[MAX_IPv4_STR_LEN];
1947*43a90889SApple OSS Distributions char s_dstaddr[MAX_IPv4_STR_LEN];
1948*43a90889SApple OSS Distributions struct in_addr *__single s, *d;
1949*43a90889SApple OSS Distributions
1950*43a90889SApple OSS Distributions IFA_LOCK(ifa);
1951*43a90889SApple OSS Distributions s = &SIN(ifa->ifa_addr)->sin_addr;
1952*43a90889SApple OSS Distributions d = &SIN(ifa->ifa_dstaddr)->sin_addr;
1953*43a90889SApple OSS Distributions (void) inet_ntop(AF_INET, &s->s_addr, s_addr,
1954*43a90889SApple OSS Distributions sizeof(s_addr));
1955*43a90889SApple OSS Distributions (void) inet_ntop(AF_INET, &d->s_addr, s_dstaddr,
1956*43a90889SApple OSS Distributions sizeof(s_dstaddr));
1957*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
1958*43a90889SApple OSS Distributions
1959*43a90889SApple OSS Distributions printf("%s: SIOCDIFADDR ifp=%s ifa_addr=%s "
1960*43a90889SApple OSS Distributions "ifa_dstaddr=%s (err=%d)\n", __func__,
1961*43a90889SApple OSS Distributions ifp->if_xname, s_addr, s_dstaddr, err);
1962*43a90889SApple OSS Distributions }
1963*43a90889SApple OSS Distributions }
1964*43a90889SApple OSS Distributions ifnet_address_list_free_counted_by(ifap, addresses_count);
1965*43a90889SApple OSS Distributions } else if (err != 0 && err != ENXIO) {
1966*43a90889SApple OSS Distributions printf("%s: error retrieving list of AF_INET addresses for "
1967*43a90889SApple OSS Distributions "ifp=%s (err=%d)\n", __func__, ifp->if_xname, err);
1968*43a90889SApple OSS Distributions }
1969*43a90889SApple OSS Distributions }
1970*43a90889SApple OSS Distributions
1971*43a90889SApple OSS Distributions static struct in_ifaddr *
in_ifaddr_alloc(void)1972*43a90889SApple OSS Distributions in_ifaddr_alloc(void)
1973*43a90889SApple OSS Distributions {
1974*43a90889SApple OSS Distributions struct in_ifaddr *__single inifa;
1975*43a90889SApple OSS Distributions
1976*43a90889SApple OSS Distributions inifa = kalloc_type(struct in_ifaddr, Z_ZERO | Z_WAITOK);
1977*43a90889SApple OSS Distributions if (inifa == NULL) {
1978*43a90889SApple OSS Distributions return NULL;
1979*43a90889SApple OSS Distributions }
1980*43a90889SApple OSS Distributions
1981*43a90889SApple OSS Distributions inifa->ia_ifa.ifa_free = in_ifaddr_free;
1982*43a90889SApple OSS Distributions inifa->ia_ifa.ifa_debug |= IFD_ALLOC;
1983*43a90889SApple OSS Distributions inifa->ia_ifa.ifa_del_wc = &inifa->ia_ifa.ifa_debug;
1984*43a90889SApple OSS Distributions inifa->ia_ifa.ifa_del_waiters = 0;
1985*43a90889SApple OSS Distributions ifa_lock_init(&inifa->ia_ifa);
1986*43a90889SApple OSS Distributions ifa_initref(&inifa->ia_ifa);
1987*43a90889SApple OSS Distributions
1988*43a90889SApple OSS Distributions return inifa;
1989*43a90889SApple OSS Distributions }
1990*43a90889SApple OSS Distributions
1991*43a90889SApple OSS Distributions static void
in_ifaddr_free(struct ifaddr * ifa)1992*43a90889SApple OSS Distributions in_ifaddr_free(struct ifaddr *ifa)
1993*43a90889SApple OSS Distributions {
1994*43a90889SApple OSS Distributions struct in_ifaddr *__single inifa = ifatoia(ifa);
1995*43a90889SApple OSS Distributions
1996*43a90889SApple OSS Distributions IFA_LOCK_ASSERT_HELD(ifa);
1997*43a90889SApple OSS Distributions
1998*43a90889SApple OSS Distributions if (__improbable(!(ifa->ifa_debug & IFD_ALLOC))) {
1999*43a90889SApple OSS Distributions panic("%s: ifa %p cannot be freed", __func__, ifa);
2000*43a90889SApple OSS Distributions /* NOTREACHED */
2001*43a90889SApple OSS Distributions }
2002*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
2003*43a90889SApple OSS Distributions ifa_lock_destroy(ifa);
2004*43a90889SApple OSS Distributions
2005*43a90889SApple OSS Distributions kfree_type(struct in_ifaddr, inifa);
2006*43a90889SApple OSS Distributions }
2007*43a90889SApple OSS Distributions
2008*43a90889SApple OSS Distributions /*
2009*43a90889SApple OSS Distributions * Handle SIOCGASSOCIDS ioctl for PF_INET domain.
2010*43a90889SApple OSS Distributions */
2011*43a90889SApple OSS Distributions static int
in_getassocids(struct socket * so,uint32_t * cnt,user_addr_t aidp)2012*43a90889SApple OSS Distributions in_getassocids(struct socket *so, uint32_t *cnt, user_addr_t aidp)
2013*43a90889SApple OSS Distributions {
2014*43a90889SApple OSS Distributions struct inpcb *__single inp = sotoinpcb(so);
2015*43a90889SApple OSS Distributions sae_associd_t aid;
2016*43a90889SApple OSS Distributions
2017*43a90889SApple OSS Distributions if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD) {
2018*43a90889SApple OSS Distributions return EINVAL;
2019*43a90889SApple OSS Distributions }
2020*43a90889SApple OSS Distributions
2021*43a90889SApple OSS Distributions /* INPCB has no concept of association */
2022*43a90889SApple OSS Distributions aid = SAE_ASSOCID_ANY;
2023*43a90889SApple OSS Distributions *cnt = 0;
2024*43a90889SApple OSS Distributions
2025*43a90889SApple OSS Distributions /* just asking how many there are? */
2026*43a90889SApple OSS Distributions if (aidp == USER_ADDR_NULL) {
2027*43a90889SApple OSS Distributions return 0;
2028*43a90889SApple OSS Distributions }
2029*43a90889SApple OSS Distributions
2030*43a90889SApple OSS Distributions return copyout(&aid, aidp, sizeof(aid));
2031*43a90889SApple OSS Distributions }
2032*43a90889SApple OSS Distributions
2033*43a90889SApple OSS Distributions /*
2034*43a90889SApple OSS Distributions * Handle SIOCGCONNIDS ioctl for PF_INET domain.
2035*43a90889SApple OSS Distributions */
2036*43a90889SApple OSS Distributions static int
in_getconnids(struct socket * so,sae_associd_t aid,uint32_t * cnt,user_addr_t cidp)2037*43a90889SApple OSS Distributions in_getconnids(struct socket *so, sae_associd_t aid, uint32_t *cnt,
2038*43a90889SApple OSS Distributions user_addr_t cidp)
2039*43a90889SApple OSS Distributions {
2040*43a90889SApple OSS Distributions struct inpcb *__single inp = sotoinpcb(so);
2041*43a90889SApple OSS Distributions sae_connid_t cid;
2042*43a90889SApple OSS Distributions
2043*43a90889SApple OSS Distributions if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD) {
2044*43a90889SApple OSS Distributions return EINVAL;
2045*43a90889SApple OSS Distributions }
2046*43a90889SApple OSS Distributions
2047*43a90889SApple OSS Distributions if (aid != SAE_ASSOCID_ANY && aid != SAE_ASSOCID_ALL) {
2048*43a90889SApple OSS Distributions return EINVAL;
2049*43a90889SApple OSS Distributions }
2050*43a90889SApple OSS Distributions
2051*43a90889SApple OSS Distributions /* if connected, return 1 connection count */
2052*43a90889SApple OSS Distributions *cnt = ((so->so_state & SS_ISCONNECTED) ? 1 : 0);
2053*43a90889SApple OSS Distributions
2054*43a90889SApple OSS Distributions /* just asking how many there are? */
2055*43a90889SApple OSS Distributions if (cidp == USER_ADDR_NULL) {
2056*43a90889SApple OSS Distributions return 0;
2057*43a90889SApple OSS Distributions }
2058*43a90889SApple OSS Distributions
2059*43a90889SApple OSS Distributions /* if INPCB is connected, assign it connid 1 */
2060*43a90889SApple OSS Distributions cid = ((*cnt != 0) ? 1 : SAE_CONNID_ANY);
2061*43a90889SApple OSS Distributions
2062*43a90889SApple OSS Distributions return copyout(&cid, cidp, sizeof(cid));
2063*43a90889SApple OSS Distributions }
2064*43a90889SApple OSS Distributions
2065*43a90889SApple OSS Distributions /*
2066*43a90889SApple OSS Distributions * Handle SIOCGCONNINFO ioctl for PF_INET domain.
2067*43a90889SApple OSS Distributions */
2068*43a90889SApple OSS Distributions int
in_getconninfo(struct socket * so,sae_connid_t cid,uint32_t * flags,uint32_t * ifindex,int32_t * soerror,user_addr_t src,socklen_t * src_len,user_addr_t dst,socklen_t * dst_len,uint32_t * aux_type,user_addr_t aux_data,uint32_t * aux_len)2069*43a90889SApple OSS Distributions in_getconninfo(struct socket *so, sae_connid_t cid, uint32_t *flags,
2070*43a90889SApple OSS Distributions uint32_t *ifindex, int32_t *soerror, user_addr_t src, socklen_t *src_len,
2071*43a90889SApple OSS Distributions user_addr_t dst, socklen_t *dst_len, uint32_t *aux_type,
2072*43a90889SApple OSS Distributions user_addr_t aux_data, uint32_t *aux_len)
2073*43a90889SApple OSS Distributions {
2074*43a90889SApple OSS Distributions struct inpcb *__single inp = sotoinpcb(so);
2075*43a90889SApple OSS Distributions struct sockaddr_in sin;
2076*43a90889SApple OSS Distributions struct ifnet *__single ifp = NULL;
2077*43a90889SApple OSS Distributions int error = 0;
2078*43a90889SApple OSS Distributions u_int32_t copy_len = 0;
2079*43a90889SApple OSS Distributions
2080*43a90889SApple OSS Distributions /*
2081*43a90889SApple OSS Distributions * Don't test for INPCB_STATE_DEAD since this may be called
2082*43a90889SApple OSS Distributions * after SOF_PCBCLEARING is set, e.g. after tcp_close().
2083*43a90889SApple OSS Distributions */
2084*43a90889SApple OSS Distributions if (inp == NULL) {
2085*43a90889SApple OSS Distributions error = EINVAL;
2086*43a90889SApple OSS Distributions goto out;
2087*43a90889SApple OSS Distributions }
2088*43a90889SApple OSS Distributions
2089*43a90889SApple OSS Distributions if (cid != SAE_CONNID_ANY && cid != SAE_CONNID_ALL && cid != 1) {
2090*43a90889SApple OSS Distributions error = EINVAL;
2091*43a90889SApple OSS Distributions goto out;
2092*43a90889SApple OSS Distributions }
2093*43a90889SApple OSS Distributions
2094*43a90889SApple OSS Distributions ifp = inp->inp_last_outifp;
2095*43a90889SApple OSS Distributions *ifindex = ((ifp != NULL) ? ifp->if_index : 0);
2096*43a90889SApple OSS Distributions *soerror = so->so_error;
2097*43a90889SApple OSS Distributions *flags = 0;
2098*43a90889SApple OSS Distributions if (so->so_state & SS_ISCONNECTED) {
2099*43a90889SApple OSS Distributions *flags |= (CIF_CONNECTED | CIF_PREFERRED);
2100*43a90889SApple OSS Distributions }
2101*43a90889SApple OSS Distributions if (inp->inp_flags & INP_BOUND_IF) {
2102*43a90889SApple OSS Distributions *flags |= CIF_BOUND_IF;
2103*43a90889SApple OSS Distributions }
2104*43a90889SApple OSS Distributions if (!(inp->inp_flags & INP_INADDR_ANY)) {
2105*43a90889SApple OSS Distributions *flags |= CIF_BOUND_IP;
2106*43a90889SApple OSS Distributions }
2107*43a90889SApple OSS Distributions if (!(inp->inp_flags & INP_ANONPORT)) {
2108*43a90889SApple OSS Distributions *flags |= CIF_BOUND_PORT;
2109*43a90889SApple OSS Distributions }
2110*43a90889SApple OSS Distributions
2111*43a90889SApple OSS Distributions SOCKADDR_ZERO(&sin, sizeof(sin));
2112*43a90889SApple OSS Distributions sin.sin_len = sizeof(sin);
2113*43a90889SApple OSS Distributions sin.sin_family = AF_INET;
2114*43a90889SApple OSS Distributions
2115*43a90889SApple OSS Distributions /* source address and port */
2116*43a90889SApple OSS Distributions sin.sin_port = inp->inp_lport;
2117*43a90889SApple OSS Distributions sin.sin_addr.s_addr = inp->inp_laddr.s_addr;
2118*43a90889SApple OSS Distributions if (*src_len == 0) {
2119*43a90889SApple OSS Distributions *src_len = sin.sin_len;
2120*43a90889SApple OSS Distributions } else {
2121*43a90889SApple OSS Distributions if (src != USER_ADDR_NULL) {
2122*43a90889SApple OSS Distributions copy_len = min(*src_len, sizeof(sin));
2123*43a90889SApple OSS Distributions error = copyout(&sin, src, copy_len);
2124*43a90889SApple OSS Distributions if (error != 0) {
2125*43a90889SApple OSS Distributions goto out;
2126*43a90889SApple OSS Distributions }
2127*43a90889SApple OSS Distributions *src_len = copy_len;
2128*43a90889SApple OSS Distributions }
2129*43a90889SApple OSS Distributions }
2130*43a90889SApple OSS Distributions
2131*43a90889SApple OSS Distributions /* destination address and port */
2132*43a90889SApple OSS Distributions sin.sin_port = inp->inp_fport;
2133*43a90889SApple OSS Distributions sin.sin_addr.s_addr = inp->inp_faddr.s_addr;
2134*43a90889SApple OSS Distributions if (*dst_len == 0) {
2135*43a90889SApple OSS Distributions *dst_len = sin.sin_len;
2136*43a90889SApple OSS Distributions } else {
2137*43a90889SApple OSS Distributions if (dst != USER_ADDR_NULL) {
2138*43a90889SApple OSS Distributions copy_len = min(*dst_len, sizeof(sin));
2139*43a90889SApple OSS Distributions error = copyout(&sin, dst, copy_len);
2140*43a90889SApple OSS Distributions if (error != 0) {
2141*43a90889SApple OSS Distributions goto out;
2142*43a90889SApple OSS Distributions }
2143*43a90889SApple OSS Distributions *dst_len = copy_len;
2144*43a90889SApple OSS Distributions }
2145*43a90889SApple OSS Distributions }
2146*43a90889SApple OSS Distributions
2147*43a90889SApple OSS Distributions if (SOCK_PROTO(so) == IPPROTO_TCP) {
2148*43a90889SApple OSS Distributions struct conninfo_tcp tcp_ci;
2149*43a90889SApple OSS Distributions
2150*43a90889SApple OSS Distributions *aux_type = CIAUX_TCP;
2151*43a90889SApple OSS Distributions if (*aux_len == 0) {
2152*43a90889SApple OSS Distributions *aux_len = sizeof(tcp_ci);
2153*43a90889SApple OSS Distributions } else {
2154*43a90889SApple OSS Distributions if (aux_data != USER_ADDR_NULL) {
2155*43a90889SApple OSS Distributions copy_len = min(*aux_len, sizeof(tcp_ci));
2156*43a90889SApple OSS Distributions bzero(&tcp_ci, sizeof(tcp_ci));
2157*43a90889SApple OSS Distributions tcp_getconninfo(so, &tcp_ci);
2158*43a90889SApple OSS Distributions error = copyout(&tcp_ci, aux_data, copy_len);
2159*43a90889SApple OSS Distributions if (error != 0) {
2160*43a90889SApple OSS Distributions goto out;
2161*43a90889SApple OSS Distributions }
2162*43a90889SApple OSS Distributions *aux_len = copy_len;
2163*43a90889SApple OSS Distributions }
2164*43a90889SApple OSS Distributions }
2165*43a90889SApple OSS Distributions } else {
2166*43a90889SApple OSS Distributions *aux_type = 0;
2167*43a90889SApple OSS Distributions *aux_len = 0;
2168*43a90889SApple OSS Distributions }
2169*43a90889SApple OSS Distributions
2170*43a90889SApple OSS Distributions out:
2171*43a90889SApple OSS Distributions return error;
2172*43a90889SApple OSS Distributions }
2173*43a90889SApple OSS Distributions
2174*43a90889SApple OSS Distributions struct in_ifaddr*
inifa_ifpwithflag(struct ifnet * ifp,uint32_t flag)2175*43a90889SApple OSS Distributions inifa_ifpwithflag(struct ifnet * ifp, uint32_t flag)
2176*43a90889SApple OSS Distributions {
2177*43a90889SApple OSS Distributions struct ifaddr *__single ifa;
2178*43a90889SApple OSS Distributions
2179*43a90889SApple OSS Distributions ifnet_lock_shared(ifp);
2180*43a90889SApple OSS Distributions TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_link)
2181*43a90889SApple OSS Distributions {
2182*43a90889SApple OSS Distributions IFA_LOCK_SPIN(ifa);
2183*43a90889SApple OSS Distributions if (ifa->ifa_addr->sa_family != AF_INET) {
2184*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
2185*43a90889SApple OSS Distributions continue;
2186*43a90889SApple OSS Distributions }
2187*43a90889SApple OSS Distributions if (((ifatoia(ifa))->ia_flags & flag) == flag) {
2188*43a90889SApple OSS Distributions ifa_addref(ifa);
2189*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
2190*43a90889SApple OSS Distributions break;
2191*43a90889SApple OSS Distributions }
2192*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
2193*43a90889SApple OSS Distributions }
2194*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
2195*43a90889SApple OSS Distributions
2196*43a90889SApple OSS Distributions return ifatoia(ifa);
2197*43a90889SApple OSS Distributions }
2198*43a90889SApple OSS Distributions
2199*43a90889SApple OSS Distributions struct in_ifaddr *
inifa_ifpclatv4(struct ifnet * ifp)2200*43a90889SApple OSS Distributions inifa_ifpclatv4(struct ifnet * ifp)
2201*43a90889SApple OSS Distributions {
2202*43a90889SApple OSS Distributions struct ifaddr *__single ifa;
2203*43a90889SApple OSS Distributions
2204*43a90889SApple OSS Distributions ifnet_lock_shared(ifp);
2205*43a90889SApple OSS Distributions TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_link)
2206*43a90889SApple OSS Distributions {
2207*43a90889SApple OSS Distributions uint32_t addr = 0;
2208*43a90889SApple OSS Distributions IFA_LOCK_SPIN(ifa);
2209*43a90889SApple OSS Distributions if (ifa->ifa_addr->sa_family != AF_INET) {
2210*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
2211*43a90889SApple OSS Distributions continue;
2212*43a90889SApple OSS Distributions }
2213*43a90889SApple OSS Distributions
2214*43a90889SApple OSS Distributions addr = ntohl(SIN(ifa->ifa_addr)->sin_addr.s_addr);
2215*43a90889SApple OSS Distributions if (!IN_LINKLOCAL(addr) &&
2216*43a90889SApple OSS Distributions !IN_LOOPBACK(addr)) {
2217*43a90889SApple OSS Distributions ifa_addref(ifa);
2218*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
2219*43a90889SApple OSS Distributions break;
2220*43a90889SApple OSS Distributions }
2221*43a90889SApple OSS Distributions IFA_UNLOCK(ifa);
2222*43a90889SApple OSS Distributions }
2223*43a90889SApple OSS Distributions ifnet_lock_done(ifp);
2224*43a90889SApple OSS Distributions
2225*43a90889SApple OSS Distributions return ifatoia(ifa);
2226*43a90889SApple OSS Distributions }
2227*43a90889SApple OSS Distributions
2228*43a90889SApple OSS Distributions /*
2229*43a90889SApple OSS Distributions * IPPROTO_xxx.
2230*43a90889SApple OSS Distributions *
2231*43a90889SApple OSS Distributions * The switch statement below does nothing at runtime, as it serves as a
2232*43a90889SApple OSS Distributions * compile time check to ensure that all of the IPPROTO_xxx constants are
2233*43a90889SApple OSS Distributions * unique. This works as long as this routine gets updated each time a
2234*43a90889SApple OSS Distributions * new IPPROTO_xxx constant gets added.
2235*43a90889SApple OSS Distributions *
2236*43a90889SApple OSS Distributions * Any failures at compile time indicates duplicated IPPROTO_xxx values.
2237*43a90889SApple OSS Distributions */
2238*43a90889SApple OSS Distributions static __attribute__((unused)) void
ipproto_cassert(void)2239*43a90889SApple OSS Distributions ipproto_cassert(void)
2240*43a90889SApple OSS Distributions {
2241*43a90889SApple OSS Distributions /*
2242*43a90889SApple OSS Distributions * This is equivalent to _CASSERT() and the compiler wouldn't
2243*43a90889SApple OSS Distributions * generate any instructions, thus for compile time only.
2244*43a90889SApple OSS Distributions */
2245*43a90889SApple OSS Distributions switch ((u_int16_t)0) {
2246*43a90889SApple OSS Distributions /* bsd/netinet/in.h */
2247*43a90889SApple OSS Distributions case IPPROTO_IP:
2248*43a90889SApple OSS Distributions // case IPPROTO_HOPOPTS: // same value as IPPROTO_IP
2249*43a90889SApple OSS Distributions case IPPROTO_ICMP:
2250*43a90889SApple OSS Distributions case IPPROTO_IGMP:
2251*43a90889SApple OSS Distributions case IPPROTO_GGP:
2252*43a90889SApple OSS Distributions case IPPROTO_IPV4:
2253*43a90889SApple OSS Distributions // #define IPPROTO_IPIP IPPROTO_IPV4
2254*43a90889SApple OSS Distributions case IPPROTO_TCP:
2255*43a90889SApple OSS Distributions case IPPROTO_ST:
2256*43a90889SApple OSS Distributions case IPPROTO_EGP:
2257*43a90889SApple OSS Distributions case IPPROTO_PIGP:
2258*43a90889SApple OSS Distributions case IPPROTO_RCCMON:
2259*43a90889SApple OSS Distributions case IPPROTO_NVPII:
2260*43a90889SApple OSS Distributions case IPPROTO_PUP:
2261*43a90889SApple OSS Distributions case IPPROTO_ARGUS:
2262*43a90889SApple OSS Distributions case IPPROTO_EMCON:
2263*43a90889SApple OSS Distributions case IPPROTO_XNET:
2264*43a90889SApple OSS Distributions case IPPROTO_CHAOS:
2265*43a90889SApple OSS Distributions case IPPROTO_UDP:
2266*43a90889SApple OSS Distributions case IPPROTO_MUX:
2267*43a90889SApple OSS Distributions case IPPROTO_MEAS:
2268*43a90889SApple OSS Distributions case IPPROTO_HMP:
2269*43a90889SApple OSS Distributions case IPPROTO_PRM:
2270*43a90889SApple OSS Distributions case IPPROTO_IDP:
2271*43a90889SApple OSS Distributions case IPPROTO_TRUNK1:
2272*43a90889SApple OSS Distributions case IPPROTO_TRUNK2:
2273*43a90889SApple OSS Distributions case IPPROTO_LEAF1:
2274*43a90889SApple OSS Distributions case IPPROTO_LEAF2:
2275*43a90889SApple OSS Distributions case IPPROTO_RDP:
2276*43a90889SApple OSS Distributions case IPPROTO_IRTP:
2277*43a90889SApple OSS Distributions case IPPROTO_TP:
2278*43a90889SApple OSS Distributions case IPPROTO_BLT:
2279*43a90889SApple OSS Distributions case IPPROTO_NSP:
2280*43a90889SApple OSS Distributions case IPPROTO_INP:
2281*43a90889SApple OSS Distributions case IPPROTO_SEP:
2282*43a90889SApple OSS Distributions case IPPROTO_3PC:
2283*43a90889SApple OSS Distributions case IPPROTO_IDPR:
2284*43a90889SApple OSS Distributions case IPPROTO_XTP:
2285*43a90889SApple OSS Distributions case IPPROTO_DDP:
2286*43a90889SApple OSS Distributions case IPPROTO_CMTP:
2287*43a90889SApple OSS Distributions case IPPROTO_TPXX:
2288*43a90889SApple OSS Distributions case IPPROTO_IL:
2289*43a90889SApple OSS Distributions case IPPROTO_IPV6:
2290*43a90889SApple OSS Distributions case IPPROTO_SDRP:
2291*43a90889SApple OSS Distributions case IPPROTO_ROUTING:
2292*43a90889SApple OSS Distributions case IPPROTO_FRAGMENT:
2293*43a90889SApple OSS Distributions case IPPROTO_IDRP:
2294*43a90889SApple OSS Distributions case IPPROTO_RSVP:
2295*43a90889SApple OSS Distributions case IPPROTO_GRE:
2296*43a90889SApple OSS Distributions case IPPROTO_MHRP:
2297*43a90889SApple OSS Distributions case IPPROTO_BHA:
2298*43a90889SApple OSS Distributions case IPPROTO_ESP:
2299*43a90889SApple OSS Distributions case IPPROTO_AH:
2300*43a90889SApple OSS Distributions case IPPROTO_INLSP:
2301*43a90889SApple OSS Distributions case IPPROTO_SWIPE:
2302*43a90889SApple OSS Distributions case IPPROTO_NHRP:
2303*43a90889SApple OSS Distributions case IPPROTO_ICMPV6:
2304*43a90889SApple OSS Distributions case IPPROTO_NONE:
2305*43a90889SApple OSS Distributions case IPPROTO_DSTOPTS:
2306*43a90889SApple OSS Distributions case IPPROTO_AHIP:
2307*43a90889SApple OSS Distributions case IPPROTO_CFTP:
2308*43a90889SApple OSS Distributions case IPPROTO_HELLO:
2309*43a90889SApple OSS Distributions case IPPROTO_SATEXPAK:
2310*43a90889SApple OSS Distributions case IPPROTO_KRYPTOLAN:
2311*43a90889SApple OSS Distributions case IPPROTO_RVD:
2312*43a90889SApple OSS Distributions case IPPROTO_IPPC:
2313*43a90889SApple OSS Distributions case IPPROTO_ADFS:
2314*43a90889SApple OSS Distributions case IPPROTO_SATMON:
2315*43a90889SApple OSS Distributions case IPPROTO_VISA:
2316*43a90889SApple OSS Distributions case IPPROTO_IPCV:
2317*43a90889SApple OSS Distributions case IPPROTO_CPNX:
2318*43a90889SApple OSS Distributions case IPPROTO_CPHB:
2319*43a90889SApple OSS Distributions case IPPROTO_WSN:
2320*43a90889SApple OSS Distributions case IPPROTO_PVP:
2321*43a90889SApple OSS Distributions case IPPROTO_BRSATMON:
2322*43a90889SApple OSS Distributions case IPPROTO_ND:
2323*43a90889SApple OSS Distributions case IPPROTO_WBMON:
2324*43a90889SApple OSS Distributions case IPPROTO_WBEXPAK:
2325*43a90889SApple OSS Distributions case IPPROTO_EON:
2326*43a90889SApple OSS Distributions case IPPROTO_VMTP:
2327*43a90889SApple OSS Distributions case IPPROTO_SVMTP:
2328*43a90889SApple OSS Distributions case IPPROTO_VINES:
2329*43a90889SApple OSS Distributions case IPPROTO_TTP:
2330*43a90889SApple OSS Distributions case IPPROTO_IGP:
2331*43a90889SApple OSS Distributions case IPPROTO_DGP:
2332*43a90889SApple OSS Distributions case IPPROTO_TCF:
2333*43a90889SApple OSS Distributions case IPPROTO_IGRP:
2334*43a90889SApple OSS Distributions case IPPROTO_OSPFIGP:
2335*43a90889SApple OSS Distributions case IPPROTO_SRPC:
2336*43a90889SApple OSS Distributions case IPPROTO_LARP:
2337*43a90889SApple OSS Distributions case IPPROTO_MTP:
2338*43a90889SApple OSS Distributions case IPPROTO_AX25:
2339*43a90889SApple OSS Distributions case IPPROTO_IPEIP:
2340*43a90889SApple OSS Distributions case IPPROTO_MICP:
2341*43a90889SApple OSS Distributions case IPPROTO_SCCSP:
2342*43a90889SApple OSS Distributions case IPPROTO_ETHERIP:
2343*43a90889SApple OSS Distributions case IPPROTO_ENCAP:
2344*43a90889SApple OSS Distributions case IPPROTO_APES:
2345*43a90889SApple OSS Distributions case IPPROTO_GMTP:
2346*43a90889SApple OSS Distributions case IPPROTO_PIM:
2347*43a90889SApple OSS Distributions case IPPROTO_IPCOMP:
2348*43a90889SApple OSS Distributions case IPPROTO_PGM:
2349*43a90889SApple OSS Distributions case IPPROTO_SCTP:
2350*43a90889SApple OSS Distributions case IPPROTO_DIVERT:
2351*43a90889SApple OSS Distributions case IPPROTO_RAW:
2352*43a90889SApple OSS Distributions case IPPROTO_MAX:
2353*43a90889SApple OSS Distributions case IPPROTO_DONE:
2354*43a90889SApple OSS Distributions
2355*43a90889SApple OSS Distributions /* bsd/netinet/in_private.h */
2356*43a90889SApple OSS Distributions case IPPROTO_QUIC:
2357*43a90889SApple OSS Distributions ;
2358*43a90889SApple OSS Distributions }
2359*43a90889SApple OSS Distributions }
2360*43a90889SApple OSS Distributions
2361*43a90889SApple OSS Distributions static __attribute__((unused)) void
ipsockopt_cassert(void)2362*43a90889SApple OSS Distributions ipsockopt_cassert(void)
2363*43a90889SApple OSS Distributions {
2364*43a90889SApple OSS Distributions switch ((int)0) {
2365*43a90889SApple OSS Distributions case 0:
2366*43a90889SApple OSS Distributions
2367*43a90889SApple OSS Distributions /* bsd/netinet/in.h */
2368*43a90889SApple OSS Distributions case IP_OPTIONS:
2369*43a90889SApple OSS Distributions case IP_HDRINCL:
2370*43a90889SApple OSS Distributions case IP_TOS:
2371*43a90889SApple OSS Distributions case IP_TTL:
2372*43a90889SApple OSS Distributions case IP_RECVOPTS:
2373*43a90889SApple OSS Distributions case IP_RECVRETOPTS:
2374*43a90889SApple OSS Distributions case IP_RECVDSTADDR:
2375*43a90889SApple OSS Distributions case IP_RETOPTS:
2376*43a90889SApple OSS Distributions case IP_MULTICAST_IF:
2377*43a90889SApple OSS Distributions case IP_MULTICAST_TTL:
2378*43a90889SApple OSS Distributions case IP_MULTICAST_LOOP:
2379*43a90889SApple OSS Distributions case IP_ADD_MEMBERSHIP:
2380*43a90889SApple OSS Distributions case IP_DROP_MEMBERSHIP:
2381*43a90889SApple OSS Distributions case IP_MULTICAST_VIF:
2382*43a90889SApple OSS Distributions case IP_RSVP_ON:
2383*43a90889SApple OSS Distributions case IP_RSVP_OFF:
2384*43a90889SApple OSS Distributions case IP_RSVP_VIF_ON:
2385*43a90889SApple OSS Distributions case IP_RSVP_VIF_OFF:
2386*43a90889SApple OSS Distributions case IP_PORTRANGE:
2387*43a90889SApple OSS Distributions case IP_RECVIF:
2388*43a90889SApple OSS Distributions case IP_IPSEC_POLICY:
2389*43a90889SApple OSS Distributions case IP_FAITH:
2390*43a90889SApple OSS Distributions #ifdef __APPLE__
2391*43a90889SApple OSS Distributions case IP_STRIPHDR:
2392*43a90889SApple OSS Distributions #endif
2393*43a90889SApple OSS Distributions case IP_RECVTTL:
2394*43a90889SApple OSS Distributions case IP_BOUND_IF:
2395*43a90889SApple OSS Distributions case IP_PKTINFO:
2396*43a90889SApple OSS Distributions // #define IP_RECVPKTINFO IP_PKTINFO
2397*43a90889SApple OSS Distributions case IP_RECVTOS:
2398*43a90889SApple OSS Distributions case IP_DONTFRAG:
2399*43a90889SApple OSS Distributions case IP_FW_ADD:
2400*43a90889SApple OSS Distributions case IP_FW_DEL:
2401*43a90889SApple OSS Distributions case IP_FW_FLUSH:
2402*43a90889SApple OSS Distributions case IP_FW_ZERO:
2403*43a90889SApple OSS Distributions case IP_FW_GET:
2404*43a90889SApple OSS Distributions case IP_FW_RESETLOG:
2405*43a90889SApple OSS Distributions case IP_OLD_FW_ADD:
2406*43a90889SApple OSS Distributions case IP_OLD_FW_DEL:
2407*43a90889SApple OSS Distributions case IP_OLD_FW_FLUSH:
2408*43a90889SApple OSS Distributions case IP_OLD_FW_ZERO:
2409*43a90889SApple OSS Distributions case IP_OLD_FW_GET:
2410*43a90889SApple OSS Distributions case IP_NAT__XXX:
2411*43a90889SApple OSS Distributions case IP_OLD_FW_RESETLOG:
2412*43a90889SApple OSS Distributions case IP_DUMMYNET_CONFIGURE:
2413*43a90889SApple OSS Distributions case IP_DUMMYNET_DEL:
2414*43a90889SApple OSS Distributions case IP_DUMMYNET_FLUSH:
2415*43a90889SApple OSS Distributions case IP_DUMMYNET_GET:
2416*43a90889SApple OSS Distributions case IP_TRAFFIC_MGT_BACKGROUND:
2417*43a90889SApple OSS Distributions case IP_MULTICAST_IFINDEX:
2418*43a90889SApple OSS Distributions case IP_ADD_SOURCE_MEMBERSHIP:
2419*43a90889SApple OSS Distributions case IP_DROP_SOURCE_MEMBERSHIP:
2420*43a90889SApple OSS Distributions case IP_BLOCK_SOURCE:
2421*43a90889SApple OSS Distributions case IP_UNBLOCK_SOURCE:
2422*43a90889SApple OSS Distributions case IP_MSFILTER:
2423*43a90889SApple OSS Distributions case MCAST_JOIN_GROUP:
2424*43a90889SApple OSS Distributions case MCAST_LEAVE_GROUP:
2425*43a90889SApple OSS Distributions case MCAST_JOIN_SOURCE_GROUP:
2426*43a90889SApple OSS Distributions case MCAST_LEAVE_SOURCE_GROUP:
2427*43a90889SApple OSS Distributions case MCAST_BLOCK_SOURCE:
2428*43a90889SApple OSS Distributions case MCAST_UNBLOCK_SOURCE:
2429*43a90889SApple OSS Distributions
2430*43a90889SApple OSS Distributions /* bsd/netinet/in_private.h */
2431*43a90889SApple OSS Distributions case IP_NO_IFT_CELLULAR:
2432*43a90889SApple OSS Distributions // #define IP_NO_IFT_PDP IP_NO_IFT_CELLULAR /* deprecated */
2433*43a90889SApple OSS Distributions case IP_OUT_IF:
2434*43a90889SApple OSS Distributions ;
2435*43a90889SApple OSS Distributions }
2436*43a90889SApple OSS Distributions }
2437