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