]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/if.c
xnu-1456.1.26.tar.gz
[apple/xnu.git] / bsd / net / if.c
1 /*
2 * Copyright (c) 2000-2008 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) 1980, 1986, 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 * @(#)if.c 8.3 (Berkeley) 1/4/94
61 * $FreeBSD: src/sys/net/if.c,v 1.85.2.9 2001/07/24 19:10:17 brooks Exp $
62 */
63 /*
64 * NOTICE: This file was modified by SPARTA, Inc. in 2006 to introduce
65 * support for mandatory and extensible security protections. This notice
66 * is included in support of clause 2.2 (b) of the Apple Public License,
67 * Version 2.0.
68 */
69
70 #include <kern/locks.h>
71
72 #include <sys/param.h>
73 #include <sys/malloc.h>
74 #include <sys/mbuf.h>
75 #include <sys/systm.h>
76 #include <sys/proc.h>
77 #include <sys/socket.h>
78 #include <sys/socketvar.h>
79 #include <sys/protosw.h>
80 #include <sys/kernel.h>
81 #include <sys/sockio.h>
82 #include <sys/syslog.h>
83 #include <sys/sysctl.h>
84
85 #include <machine/endian.h>
86
87 #include <net/if.h>
88 #include <net/if_arp.h>
89 #include <net/if_dl.h>
90 #include <net/if_types.h>
91 #include <net/if_var.h>
92 #include <net/net_osdep.h>
93 #include <net/ethernet.h>
94
95 #include <net/radix.h>
96 #include <net/route.h>
97 #ifdef __APPLE__
98 #include <net/dlil.h>
99 //#include <string.h>
100 #include <sys/domain.h>
101 #include <libkern/OSAtomic.h>
102 #endif
103
104 #if INET || INET6
105 /*XXX*/
106 #include <netinet/in.h>
107 #include <netinet/in_var.h>
108 #include <netinet/ip_var.h>
109 #if INET6
110 #include <netinet6/in6_var.h>
111 #include <netinet6/in6_ifattach.h>
112 #endif
113 #endif
114
115 extern int dlil_multithreaded_input;
116 extern struct dlil_threading_info *dlil_lo_thread_ptr;
117
118 #if CONFIG_MACF_NET
119 #include <security/mac_framework.h>
120 #endif
121
122
123 /*
124 * System initialization
125 */
126
127 static int ifconf(u_long cmd, user_addr_t ifrp, int * ret_space);
128 static void if_qflush(struct ifqueue *);
129 __private_extern__ void link_rtrequest(int, struct rtentry *, struct sockaddr *);
130 void if_rtproto_del(struct ifnet *ifp, int protocol);
131
132 static int if_rtmtu(struct radix_node *, void *);
133 static void if_rtmtu_update(struct ifnet *);
134
135 static struct if_clone *if_clone_lookup(const char *, int *);
136 #if IF_CLONE_LIST
137 static int if_clone_list(int count, int * total, user_addr_t dst);
138 #endif /* IF_CLONE_LIST */
139
140 MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
141 MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
142
143 int ifqmaxlen = IFQ_MAXLEN;
144 struct ifnethead ifnet_head = TAILQ_HEAD_INITIALIZER(ifnet_head);
145
146 static int if_cloners_count;
147 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
148
149 static struct ifaddr *ifa_ifwithnet_common(const struct sockaddr *,
150 unsigned int);
151
152 #if INET6
153 /*
154 * XXX: declare here to avoid to include many inet6 related files..
155 * should be more generalized?
156 */
157 extern void nd6_setmtu(struct ifnet *);
158 #endif
159
160 #define M_CLONE M_IFADDR
161
162 /*
163 * Network interface utility routines.
164 *
165 * Routines with ifa_ifwith* names take sockaddr *'s as
166 * parameters.
167 */
168
169 int if_index;
170 struct ifaddr **ifnet_addrs;
171 struct ifnet **ifindex2ifnet;
172
173 __private_extern__ void
174 if_attach_ifa(
175 struct ifnet *ifp,
176 struct ifaddr *ifa)
177 {
178 ifnet_lock_assert(ifp, LCK_MTX_ASSERT_OWNED);
179 if (ifa->ifa_debug & IFD_ATTACHED) {
180 panic("if_attach_ifa: Attempted to attach address that's already attached!\n");
181 }
182 ifaref(ifa);
183 ifa->ifa_debug |= IFD_ATTACHED;
184 TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
185 }
186
187 __private_extern__ void
188 if_detach_ifa(
189 struct ifnet *ifp,
190 struct ifaddr *ifa)
191 {
192 ifnet_lock_assert(ifp, LCK_MTX_ASSERT_OWNED);
193 #if 1
194 /* Debugging code */
195 if ((ifa->ifa_debug & IFD_ATTACHED) == 0) {
196 printf("if_detach_ifa: ifa is not attached to any interface! flags=%u\n", ifa->ifa_debug);
197 return;
198 }
199 else {
200 struct ifaddr *ifa2;
201 TAILQ_FOREACH(ifa2, &ifp->if_addrhead, ifa_link) {
202 if (ifa2 == ifa)
203 break;
204 }
205 if (ifa2 != ifa) {
206 printf("if_detach_ifa: Attempted to detach IFA that was not attached!\n");
207 }
208 }
209 #endif
210 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
211 ifa->ifa_debug &= ~IFD_ATTACHED;
212 ifafree(ifa);
213 }
214
215 #define INITIAL_IF_INDEXLIM 8
216
217 /*
218 * Function: if_next_index
219 * Purpose:
220 * Return the next available interface index.
221 * Grow the ifnet_addrs[] and ifindex2ifnet[] arrays to accomodate the
222 * added entry when necessary.
223 *
224 * Note:
225 * ifnet_addrs[] is indexed by (if_index - 1), whereas
226 * ifindex2ifnet[] is indexed by ifp->if_index. That requires us to
227 * always allocate one extra element to hold ifindex2ifnet[0], which
228 * is unused.
229 */
230 int if_next_index(void);
231
232 __private_extern__ int
233 if_next_index(void)
234 {
235 static int if_indexlim = 0;
236 int new_index;
237
238 new_index = ++if_index;
239 if (if_index > if_indexlim) {
240 unsigned n;
241 int new_if_indexlim;
242 caddr_t new_ifnet_addrs;
243 caddr_t new_ifindex2ifnet;
244 caddr_t old_ifnet_addrs;
245
246 old_ifnet_addrs = (caddr_t)ifnet_addrs;
247 if (ifnet_addrs == NULL) {
248 new_if_indexlim = INITIAL_IF_INDEXLIM;
249 } else {
250 new_if_indexlim = if_indexlim << 1;
251 }
252
253 /* allocate space for the larger arrays */
254 n = (2 * new_if_indexlim + 1) * sizeof(caddr_t);
255 new_ifnet_addrs = _MALLOC(n, M_IFADDR, M_WAITOK);
256 if (new_ifnet_addrs == NULL) {
257 --if_index;
258 return -1;
259 }
260
261 new_ifindex2ifnet = new_ifnet_addrs
262 + new_if_indexlim * sizeof(caddr_t);
263 bzero(new_ifnet_addrs, n);
264 if (ifnet_addrs != NULL) {
265 /* copy the existing data */
266 bcopy((caddr_t)ifnet_addrs, new_ifnet_addrs,
267 if_indexlim * sizeof(caddr_t));
268 bcopy((caddr_t)ifindex2ifnet,
269 new_ifindex2ifnet,
270 (if_indexlim + 1) * sizeof(caddr_t));
271 }
272
273 /* switch to the new tables and size */
274 ifnet_addrs = (struct ifaddr **)new_ifnet_addrs;
275 ifindex2ifnet = (struct ifnet **)new_ifindex2ifnet;
276 if_indexlim = new_if_indexlim;
277
278 /* release the old data */
279 if (old_ifnet_addrs != NULL) {
280 _FREE((caddr_t)old_ifnet_addrs, M_IFADDR);
281 }
282 }
283 return (new_index);
284 }
285
286 /*
287 * Create a clone network interface.
288 */
289 static int
290 if_clone_create(char *name, int len)
291 {
292 struct if_clone *ifc;
293 char *dp;
294 int wildcard, bytoff, bitoff;
295 int unit;
296 int err;
297
298 ifc = if_clone_lookup(name, &unit);
299 if (ifc == NULL)
300 return (EINVAL);
301
302 if (ifunit(name) != NULL)
303 return (EEXIST);
304
305 bytoff = bitoff = 0;
306 wildcard = (unit < 0);
307 /*
308 * Find a free unit if none was given.
309 */
310 if (wildcard) {
311 while ((bytoff < ifc->ifc_bmlen)
312 && (ifc->ifc_units[bytoff] == 0xff))
313 bytoff++;
314 if (bytoff >= ifc->ifc_bmlen)
315 return (ENOSPC);
316 while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0)
317 bitoff++;
318 unit = (bytoff << 3) + bitoff;
319 }
320
321 if (unit > ifc->ifc_maxunit)
322 return (ENXIO);
323
324 err = (*ifc->ifc_create)(ifc, unit);
325 if (err != 0)
326 return (err);
327
328 if (!wildcard) {
329 bytoff = unit >> 3;
330 bitoff = unit - (bytoff << 3);
331 }
332
333 /*
334 * Allocate the unit in the bitmap.
335 */
336 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) == 0,
337 ("%s: bit is already set", __func__));
338 ifc->ifc_units[bytoff] |= (1 << bitoff);
339
340 /* In the wildcard case, we need to update the name. */
341 if (wildcard) {
342 for (dp = name; *dp != '\0'; dp++);
343 if (snprintf(dp, len - (dp-name), "%d", unit) >
344 len - (dp-name) - 1) {
345 /*
346 * This can only be a programmer error and
347 * there's no straightforward way to recover if
348 * it happens.
349 */
350 panic("if_clone_create(): interface name too long");
351 }
352
353 }
354
355 return (0);
356 }
357
358 /*
359 * Destroy a clone network interface.
360 */
361 static int
362 if_clone_destroy(const char *name)
363 {
364 struct if_clone *ifc;
365 struct ifnet *ifp;
366 int bytoff, bitoff;
367 int unit;
368
369 ifc = if_clone_lookup(name, &unit);
370 if (ifc == NULL)
371 return (EINVAL);
372
373 if (unit < ifc->ifc_minifs)
374 return (EINVAL);
375
376 ifp = ifunit(name);
377 if (ifp == NULL)
378 return (ENXIO);
379
380 if (ifc->ifc_destroy == NULL)
381 return (EOPNOTSUPP);
382
383 (*ifc->ifc_destroy)(ifp);
384
385 /*
386 * Compute offset in the bitmap and deallocate the unit.
387 */
388 bytoff = unit >> 3;
389 bitoff = unit - (bytoff << 3);
390 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0,
391 ("%s: bit is already cleared", __func__));
392 ifc->ifc_units[bytoff] &= ~(1 << bitoff);
393 return (0);
394 }
395
396 /*
397 * Look up a network interface cloner.
398 */
399
400 static struct if_clone *
401 if_clone_lookup(const char *name, int *unitp)
402 {
403 struct if_clone *ifc;
404 const char *cp;
405 size_t i;
406
407 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) {
408 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) {
409 if (ifc->ifc_name[i] != *cp)
410 goto next_ifc;
411 }
412 goto found_name;
413 next_ifc:
414 ifc = LIST_NEXT(ifc, ifc_list);
415 }
416
417 /* No match. */
418 return ((struct if_clone *)NULL);
419
420 found_name:
421 if (*cp == '\0') {
422 i = -1;
423 } else {
424 for (i = 0; *cp != '\0'; cp++) {
425 if (*cp < '0' || *cp > '9') {
426 /* Bogus unit number. */
427 return (NULL);
428 }
429 i = (i * 10) + (*cp - '0');
430 }
431 }
432
433 if (unitp != NULL)
434 *unitp = i;
435 return (ifc);
436 }
437
438 /*
439 * Register a network interface cloner.
440 */
441 int
442 if_clone_attach(struct if_clone *ifc)
443 {
444 int bytoff, bitoff;
445 int err;
446 int len, maxclone;
447 int unit;
448
449 KASSERT(ifc->ifc_minifs - 1 <= ifc->ifc_maxunit,
450 ("%s: %s requested more units then allowed (%d > %d)",
451 __func__, ifc->ifc_name, ifc->ifc_minifs,
452 ifc->ifc_maxunit + 1));
453 /*
454 * Compute bitmap size and allocate it.
455 */
456 maxclone = ifc->ifc_maxunit + 1;
457 len = maxclone >> 3;
458 if ((len << 3) < maxclone)
459 len++;
460 ifc->ifc_units = _MALLOC(len, M_CLONE, M_WAITOK | M_ZERO);
461 if (ifc->ifc_units == NULL)
462 return ENOBUFS;
463 bzero(ifc->ifc_units, len);
464 ifc->ifc_bmlen = len;
465
466 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
467 if_cloners_count++;
468
469 for (unit = 0; unit < ifc->ifc_minifs; unit++) {
470 err = (*ifc->ifc_create)(ifc, unit);
471 KASSERT(err == 0,
472 ("%s: failed to create required interface %s%d",
473 __func__, ifc->ifc_name, unit));
474
475 /* Allocate the unit in the bitmap. */
476 bytoff = unit >> 3;
477 bitoff = unit - (bytoff << 3);
478 ifc->ifc_units[bytoff] |= (1 << bitoff);
479 }
480
481 return 0;
482 }
483
484 /*
485 * Unregister a network interface cloner.
486 */
487 void
488 if_clone_detach(struct if_clone *ifc)
489 {
490
491 LIST_REMOVE(ifc, ifc_list);
492 FREE(ifc->ifc_units, M_CLONE);
493 if_cloners_count--;
494 }
495
496 #if IF_CLONE_LIST
497 /*
498 * Provide list of interface cloners to userspace.
499 */
500 static int
501 if_clone_list(int count, int * total, user_addr_t dst)
502 {
503 char outbuf[IFNAMSIZ];
504 struct if_clone *ifc;
505 int error = 0;
506
507 *total = if_cloners_count;
508 if (dst == USER_ADDR_NULL) {
509 /* Just asking how many there are. */
510 return (0);
511 }
512
513 if (count < 0)
514 return (EINVAL);
515
516 count = (if_cloners_count < count) ? if_cloners_count : count;
517
518 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
519 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
520 strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
521 error = copyout(outbuf, dst, IFNAMSIZ);
522 if (error)
523 break;
524 }
525
526 return (error);
527 }
528 #endif /* IF_CLONE_LIST */
529
530 /*
531 * Similar to ifa_ifwithaddr, except that this is IPv4 specific
532 * and that it matches only the local (not broadcast) address.
533 */
534 __private_extern__ struct in_ifaddr *
535 ifa_foraddr(unsigned int addr)
536 {
537 return (ifa_foraddr_scoped(addr, IFSCOPE_NONE));
538 }
539
540 /*
541 * Similar to ifa_foraddr, except with the added interface scope
542 * constraint (unless the caller passes in IFSCOPE_NONE in which
543 * case there is no scope restriction).
544 */
545 __private_extern__ struct in_ifaddr *
546 ifa_foraddr_scoped(unsigned int addr, unsigned int scope)
547 {
548 struct in_ifaddr *ia = NULL;
549
550 lck_rw_lock_shared(in_ifaddr_rwlock);
551 TAILQ_FOREACH(ia, INADDR_HASH(addr), ia_hash) {
552 if (ia->ia_addr.sin_addr.s_addr == addr &&
553 (scope == IFSCOPE_NONE || ia->ia_ifp->if_index == scope))
554 break;
555 }
556 if (ia != NULL)
557 ifaref(&ia->ia_ifa);
558 lck_rw_done(in_ifaddr_rwlock);
559 return (ia);
560 }
561
562 /*
563 * Return the first (primary) address of a given family on an interface.
564 */
565 __private_extern__ struct ifaddr *
566 ifa_ifpgetprimary(struct ifnet *ifp, int family)
567 {
568 struct ifaddr *ifa0 = NULL, *ifa;
569
570 ifnet_lock_shared(ifp);
571 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
572 if (ifa->ifa_addr->sa_family == family && ifa0 == NULL) {
573 ifa0 = ifa;
574 break;
575 }
576 }
577 if (ifa0 != NULL)
578 ifaref(ifa0);
579 ifnet_lock_done(ifp);
580
581 return (ifa0);
582 }
583
584 /*
585 * Locate an interface based on a complete address.
586 */
587 /*ARGSUSED*/
588 struct ifaddr *
589 ifa_ifwithaddr(
590 const struct sockaddr *addr)
591 {
592 struct ifnet *ifp;
593 struct ifaddr *ifa;
594 struct ifaddr *result = NULL;
595
596 #define equal(a1, a2) \
597 (bcmp((const void*)(a1), (const void*)(a2), ((const struct sockaddr *)(a1))->sa_len) == 0)
598
599 ifnet_head_lock_shared();
600 for (ifp = ifnet_head.tqh_first; ifp && !result; ifp = ifp->if_link.tqe_next) {
601 ifnet_lock_shared(ifp);
602 for (ifa = ifp->if_addrhead.tqh_first; ifa;
603 ifa = ifa->ifa_link.tqe_next) {
604 if (ifa->ifa_addr->sa_family != addr->sa_family)
605 continue;
606 if (equal(addr, ifa->ifa_addr)) {
607 result = ifa;
608 break;
609 }
610 if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
611 /* IP6 doesn't have broadcast */
612 ifa->ifa_broadaddr->sa_len != 0 &&
613 equal(ifa->ifa_broadaddr, addr)) {
614 result = ifa;
615 break;
616 }
617 }
618 if (result)
619 ifaref(result);
620 ifnet_lock_done(ifp);
621 }
622 ifnet_head_done();
623
624 return result;
625 }
626 /*
627 * Locate the point to point interface with a given destination address.
628 */
629 /*ARGSUSED*/
630 struct ifaddr *
631 ifa_ifwithdstaddr(
632 const struct sockaddr *addr)
633 {
634 struct ifnet *ifp;
635 struct ifaddr *ifa;
636 struct ifaddr *result = NULL;
637
638 ifnet_head_lock_shared();
639 for (ifp = ifnet_head.tqh_first; ifp && !result; ifp = ifp->if_link.tqe_next) {
640 if (ifp->if_flags & IFF_POINTOPOINT) {
641 ifnet_lock_shared(ifp);
642 for (ifa = ifp->if_addrhead.tqh_first; ifa;
643 ifa = ifa->ifa_link.tqe_next) {
644 if (ifa->ifa_addr->sa_family != addr->sa_family)
645 continue;
646 if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)) {
647 result = ifa;
648 break;
649 }
650 }
651 if (result)
652 ifaref(result);
653 ifnet_lock_done(ifp);
654 }
655 }
656 ifnet_head_done();
657 return result;
658 }
659
660 /*
661 * Locate the source address of an interface based on a complete address.
662 */
663 struct ifaddr *
664 ifa_ifwithaddr_scoped(const struct sockaddr *addr, unsigned int ifscope)
665 {
666 struct ifaddr *result = NULL;
667 struct ifnet *ifp;
668
669 if (ifscope == IFSCOPE_NONE)
670 return (ifa_ifwithaddr(addr));
671
672 ifnet_head_lock_shared();
673 if (ifscope > (unsigned int)if_index) {
674 ifnet_head_done();
675 return (NULL);
676 }
677
678 ifp = ifindex2ifnet[ifscope];
679 if (ifp != NULL) {
680 struct ifaddr *ifa = NULL;
681
682 /*
683 * This is suboptimal; there should be a better way
684 * to search for a given address of an interface
685 * for any given address family.
686 */
687 ifnet_lock_shared(ifp);
688 for (ifa = ifp->if_addrhead.tqh_first; ifa != NULL;
689 ifa = ifa->ifa_link.tqe_next) {
690 if (ifa->ifa_addr->sa_family != addr->sa_family)
691 continue;
692 if (equal(addr, ifa->ifa_addr)) {
693 result = ifa;
694 break;
695 }
696 if ((ifp->if_flags & IFF_BROADCAST) &&
697 ifa->ifa_broadaddr != NULL &&
698 /* IP6 doesn't have broadcast */
699 ifa->ifa_broadaddr->sa_len != 0 &&
700 equal(ifa->ifa_broadaddr, addr)) {
701 result = ifa;
702 break;
703 }
704 }
705 if (result != NULL)
706 ifaref(result);
707 ifnet_lock_done(ifp);
708 }
709 ifnet_head_done();
710
711 return (result);
712 }
713
714 struct ifaddr *
715 ifa_ifwithnet(const struct sockaddr *addr)
716 {
717 return (ifa_ifwithnet_common(addr, IFSCOPE_NONE));
718 }
719
720 struct ifaddr *
721 ifa_ifwithnet_scoped(const struct sockaddr *addr, unsigned int ifscope)
722 {
723 return (ifa_ifwithnet_common(addr, ifscope));
724 }
725
726 /*
727 * Find an interface on a specific network. If many, choice
728 * is most specific found.
729 */
730 static struct ifaddr *
731 ifa_ifwithnet_common(const struct sockaddr *addr, unsigned int ifscope)
732 {
733 struct ifnet *ifp;
734 struct ifaddr *ifa = NULL;
735 struct ifaddr *ifa_maybe = (struct ifaddr *) 0;
736 u_int af = addr->sa_family;
737 const char *addr_data = addr->sa_data, *cplim;
738
739 if (!ip_doscopedroute || addr->sa_family != AF_INET)
740 ifscope = IFSCOPE_NONE;
741
742 ifnet_head_lock_shared();
743 /*
744 * AF_LINK addresses can be looked up directly by their index number,
745 * so do that if we can.
746 */
747 if (af == AF_LINK) {
748 const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)addr;
749 if (sdl->sdl_index && sdl->sdl_index <= if_index) {
750 ifa = ifnet_addrs[sdl->sdl_index - 1];
751
752 if (ifa)
753 ifaref(ifa);
754
755 ifnet_head_done();
756 return ifa;
757 }
758 }
759
760 /*
761 * Scan though each interface, looking for ones that have
762 * addresses in this address family.
763 */
764 for (ifp = ifnet_head.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
765 ifnet_lock_shared(ifp);
766 for (ifa = ifp->if_addrhead.tqh_first; ifa;
767 ifa = ifa->ifa_link.tqe_next) {
768 const char *cp, *cp2, *cp3;
769
770 if (ifa->ifa_addr->sa_family != af)
771 next: continue;
772 #ifndef __APPLE__
773 /* This breaks tunneling application trying to install a route with
774 * a specific subnet and the local address as the destination
775 * It's breaks binary compatibility with previous version of MacOS X
776 */
777 if (
778
779 #if INET6 /* XXX: for maching gif tunnel dst as routing entry gateway */
780 addr->sa_family != AF_INET6 &&
781 #endif
782 ifp->if_flags & IFF_POINTOPOINT) {
783 /*
784 * This is a bit broken as it doesn't
785 * take into account that the remote end may
786 * be a single node in the network we are
787 * looking for.
788 * The trouble is that we don't know the
789 * netmask for the remote end.
790 */
791 if (ifa->ifa_dstaddr != 0
792 && equal(addr, ifa->ifa_dstaddr)) {
793 break;
794 }
795 } else
796 #endif /* __APPLE__*/
797 {
798 /*
799 * If we're looking up with a scope,
800 * find using a matching interface.
801 */
802 if (ifscope != IFSCOPE_NONE &&
803 ifp->if_index != ifscope)
804 continue;
805
806 /*
807 * Scan all the bits in the ifa's address.
808 * If a bit dissagrees with what we are
809 * looking for, mask it with the netmask
810 * to see if it really matters.
811 * (A byte at a time)
812 */
813 if (ifa->ifa_netmask == 0)
814 continue;
815 cp = addr_data;
816 cp2 = ifa->ifa_addr->sa_data;
817 cp3 = ifa->ifa_netmask->sa_data;
818 cplim = ifa->ifa_netmask->sa_len
819 + (char *)ifa->ifa_netmask;
820 while (cp3 < cplim)
821 if ((*cp++ ^ *cp2++) & *cp3++)
822 goto next; /* next address! */
823 /*
824 * If the netmask of what we just found
825 * is more specific than what we had before
826 * (if we had one) then remember the new one
827 * before continuing to search
828 * for an even better one.
829 */
830 if (ifa_maybe == 0 ||
831 rn_refines((caddr_t)ifa->ifa_netmask,
832 (caddr_t)ifa_maybe->ifa_netmask)) {
833 ifaref(ifa);
834 if (ifa_maybe)
835 ifafree(ifa_maybe);
836 ifa_maybe = ifa;
837 }
838 }
839 }
840
841 if (ifa) {
842 ifaref(ifa);
843 }
844
845 /*
846 * ifa is set if we found an exact match.
847 * take a reference to the ifa before
848 * releasing the ifp lock
849 */
850 ifnet_lock_done(ifp);
851
852 if (ifa) {
853 break;
854 }
855 }
856 ifnet_head_done();
857 if (!ifa)
858 ifa = ifa_maybe;
859 else if (ifa_maybe) {
860 ifafree(ifa_maybe);
861 ifa_maybe = NULL;
862 }
863 return ifa;
864 }
865
866 /*
867 * Find an interface address specific to an interface best matching
868 * a given address.
869 */
870 struct ifaddr *
871 ifaof_ifpforaddr(
872 const struct sockaddr *addr,
873 struct ifnet *ifp)
874 {
875 struct ifaddr *ifa = NULL;
876 const char *cp, *cp2, *cp3;
877 char *cplim;
878 struct ifaddr *ifa_maybe = NULL;
879 struct ifaddr *better_ifa_maybe = NULL;
880 u_int af = addr->sa_family;
881
882 if (af >= AF_MAX)
883 return (NULL);
884
885 ifnet_lock_shared(ifp);
886 for (ifa = ifp->if_addrhead.tqh_first; ifa;
887 ifa = ifa->ifa_link.tqe_next) {
888 if (ifa->ifa_addr->sa_family != af)
889 continue;
890 if (ifa_maybe == 0)
891 ifa_maybe = ifa;
892 if (ifa->ifa_netmask == 0) {
893 if (equal(addr, ifa->ifa_addr) ||
894 (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
895 break;
896 continue;
897 }
898 if (ifp->if_flags & IFF_POINTOPOINT) {
899 if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))
900 break;
901 } else {
902 if (equal(addr, ifa->ifa_addr)) {
903 /* exact match */
904 break;
905 }
906 cp = addr->sa_data;
907 cp2 = ifa->ifa_addr->sa_data;
908 cp3 = ifa->ifa_netmask->sa_data;
909 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
910 for (; cp3 < cplim; cp3++)
911 if ((*cp++ ^ *cp2++) & *cp3)
912 break;
913 if (cp3 == cplim) {
914 /* subnet match */
915 if (better_ifa_maybe == NULL) {
916 better_ifa_maybe = ifa;
917 }
918 }
919 }
920 }
921
922 if (ifa == NULL) {
923 if (better_ifa_maybe != NULL) {
924 ifa = better_ifa_maybe;
925 } else {
926 ifa = ifa_maybe;
927 }
928 }
929 if (ifa) ifaref(ifa);
930
931 ifnet_lock_done(ifp);
932 return ifa;
933 }
934
935 #include <net/route.h>
936
937 /*
938 * Default action when installing a route with a Link Level gateway.
939 * Lookup an appropriate real ifa to point to.
940 * This should be moved to /sys/net/link.c eventually.
941 */
942 void
943 link_rtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa)
944 {
945 struct ifaddr *ifa;
946 struct sockaddr *dst;
947 struct ifnet *ifp;
948
949 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
950 RT_LOCK_ASSERT_HELD(rt);
951
952 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
953 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
954 return;
955 ifa = ifaof_ifpforaddr(dst, ifp);
956 if (ifa) {
957 rtsetifa(rt, ifa);
958 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
959 ifa->ifa_rtrequest(cmd, rt, sa);
960 ifafree(ifa);
961 }
962 }
963
964 /*
965 * if_updown will set the interface up or down. It will
966 * prevent other up/down events from occurring until this
967 * up/down event has completed.
968 *
969 * Caller must lock ifnet. This function will drop the
970 * lock. This allows ifnet_set_flags to set the rest of
971 * the flags after we change the up/down state without
972 * dropping the interface lock between setting the
973 * up/down state and updating the rest of the flags.
974 */
975 __private_extern__ void
976 if_updown(
977 struct ifnet *ifp,
978 int up)
979 {
980 int i;
981 struct ifaddr **ifa;
982 struct timespec tv;
983
984 /* Wait until no one else is changing the up/down state */
985 while ((ifp->if_eflags & IFEF_UPDOWNCHANGE) != 0) {
986 tv.tv_sec = 0;
987 tv.tv_nsec = NSEC_PER_SEC / 10;
988 ifnet_lock_done(ifp);
989 msleep(&ifp->if_eflags, NULL, 0, "if_updown", &tv);
990 ifnet_lock_exclusive(ifp);
991 }
992
993 /* Verify that the interface isn't already in the right state */
994 if ((!up && (ifp->if_flags & IFF_UP) == 0) ||
995 (up && (ifp->if_flags & IFF_UP) == IFF_UP)) {
996 return;
997 }
998
999 /* Indicate that the up/down state is changing */
1000 ifp->if_eflags |= IFEF_UPDOWNCHANGE;
1001
1002 /* Mark interface up or down */
1003 if (up) {
1004 ifp->if_flags |= IFF_UP;
1005 }
1006 else {
1007 ifp->if_flags &= ~IFF_UP;
1008 }
1009
1010 ifnet_touch_lastchange(ifp);
1011
1012 /* Drop the lock to notify addresses and route */
1013 ifnet_lock_done(ifp);
1014 if (ifnet_get_address_list(ifp, &ifa) == 0) {
1015 for (i = 0; ifa[i] != 0; i++) {
1016 pfctlinput(up ? PRC_IFUP : PRC_IFDOWN, ifa[i]->ifa_addr);
1017 }
1018 ifnet_free_address_list(ifa);
1019 }
1020 rt_ifmsg(ifp);
1021
1022 /* Aquire the lock to clear the changing flag and flush the send queue */
1023 ifnet_lock_exclusive(ifp);
1024 if (!up)
1025 if_qflush(&ifp->if_snd);
1026 ifp->if_eflags &= ~IFEF_UPDOWNCHANGE;
1027 wakeup(&ifp->if_eflags);
1028
1029 return;
1030 }
1031
1032 /*
1033 * Mark an interface down and notify protocols of
1034 * the transition.
1035 */
1036 void
1037 if_down(
1038 struct ifnet *ifp)
1039 {
1040 ifnet_lock_exclusive(ifp);
1041 if_updown(ifp, 0);
1042 ifnet_lock_done(ifp);
1043 }
1044
1045 /*
1046 * Mark an interface up and notify protocols of
1047 * the transition.
1048 */
1049 void
1050 if_up(
1051 struct ifnet *ifp)
1052 {
1053 ifnet_lock_exclusive(ifp);
1054 if_updown(ifp, 1);
1055 ifnet_lock_done(ifp);
1056 }
1057
1058 /*
1059 * Flush an interface queue.
1060 */
1061 static void
1062 if_qflush(struct ifqueue *ifq)
1063 {
1064 struct mbuf *m, *n;
1065
1066 n = ifq->ifq_head;
1067 while ((m = n) != 0) {
1068 n = m->m_act;
1069 m_freem(m);
1070 }
1071 ifq->ifq_head = NULL;
1072 ifq->ifq_tail = NULL;
1073 ifq->ifq_len = 0;
1074 }
1075
1076 /*
1077 * Map interface name to
1078 * interface structure pointer.
1079 */
1080 struct ifnet *
1081 ifunit(const char *name)
1082 {
1083 char namebuf[IFNAMSIZ + 1];
1084 const char *cp;
1085 struct ifnet *ifp;
1086 int unit;
1087 unsigned len, m;
1088 char c;
1089
1090 len = strlen(name);
1091 if (len < 2 || len > IFNAMSIZ)
1092 return NULL;
1093 cp = name + len - 1;
1094 c = *cp;
1095 if (c < '0' || c > '9')
1096 return NULL; /* trailing garbage */
1097 unit = 0;
1098 m = 1;
1099 do {
1100 if (cp == name)
1101 return NULL; /* no interface name */
1102 unit += (c - '0') * m;
1103 if (unit > 1000000)
1104 return NULL; /* number is unreasonable */
1105 m *= 10;
1106 c = *--cp;
1107 } while (c >= '0' && c <= '9');
1108 len = cp - name + 1;
1109 bcopy(name, namebuf, len);
1110 namebuf[len] = '\0';
1111 /*
1112 * Now search all the interfaces for this name/number
1113 */
1114 ifnet_head_lock_shared();
1115 TAILQ_FOREACH(ifp, &ifnet_head, if_link) {
1116 if (strncmp(ifp->if_name, namebuf, len))
1117 continue;
1118 if (unit == ifp->if_unit)
1119 break;
1120 }
1121 ifnet_head_done();
1122 return (ifp);
1123 }
1124
1125
1126 /*
1127 * Map interface name in a sockaddr_dl to
1128 * interface structure pointer.
1129 */
1130 struct ifnet *
1131 if_withname(struct sockaddr *sa)
1132 {
1133 char ifname[IFNAMSIZ+1];
1134 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
1135
1136 if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) ||
1137 (sdl->sdl_nlen > IFNAMSIZ) )
1138 return NULL;
1139
1140 /*
1141 * ifunit wants a null-terminated name. It may not be null-terminated
1142 * in the sockaddr. We don't want to change the caller's sockaddr,
1143 * and there might not be room to put the trailing null anyway, so we
1144 * make a local copy that we know we can null terminate safely.
1145 */
1146
1147 bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen);
1148 ifname[sdl->sdl_nlen] = '\0';
1149 return ifunit(ifname);
1150 }
1151
1152
1153 /*
1154 * Interface ioctls.
1155 */
1156 int
1157 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
1158 {
1159 struct ifnet *ifp;
1160 struct ifreq *ifr;
1161 struct ifstat *ifs;
1162 int error = 0;
1163 short oif_flags;
1164 struct kev_msg ev_msg;
1165 struct net_event_data ev_data;
1166
1167 switch (cmd) {
1168 case OSIOCGIFCONF32:
1169 case SIOCGIFCONF32: {
1170 struct ifconf32 *ifc = (struct ifconf32 *)data;
1171 return (ifconf(cmd, CAST_USER_ADDR_T(ifc->ifc_req),
1172 &ifc->ifc_len));
1173 /* NOTREACHED */
1174 }
1175 case SIOCGIFCONF64:
1176 case OSIOCGIFCONF64: {
1177 struct ifconf64 *ifc = (struct ifconf64 *)data;
1178 return (ifconf(cmd, ifc->ifc_req, &ifc->ifc_len));
1179 /* NOTREACHED */
1180 }
1181 }
1182 ifr = (struct ifreq *)data;
1183 switch (cmd) {
1184 case SIOCIFCREATE:
1185 case SIOCIFDESTROY:
1186 error = proc_suser(p);
1187 if (error)
1188 return (error);
1189 return ((cmd == SIOCIFCREATE) ?
1190 if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) :
1191 if_clone_destroy(ifr->ifr_name));
1192 #if IF_CLONE_LIST
1193 case SIOCIFGCLONERS32: {
1194 struct if_clonereq32 *ifcr = (struct if_clonereq32 *)data;
1195 return (if_clone_list(ifcr->ifcr_count, &ifcr->ifcr_total,
1196 CAST_USER_ADDR_T(ifcr->ifcru_buffer)));
1197 /* NOTREACHED */
1198
1199 }
1200 case SIOCIFGCLONERS64: {
1201 struct if_clonereq64 *ifcr = (struct if_clonereq64 *)data;
1202 return (if_clone_list(ifcr->ifcr_count, &ifcr->ifcr_total,
1203 ifcr->ifcru_buffer));
1204 /* NOTREACHED */
1205 }
1206 #endif /* IF_CLONE_LIST */
1207 }
1208
1209 ifp = ifunit(ifr->ifr_name);
1210 if (ifp == 0)
1211 return (ENXIO);
1212 switch (cmd) {
1213
1214 case SIOCGIFFLAGS:
1215 ifnet_lock_shared(ifp);
1216 ifr->ifr_flags = ifp->if_flags;
1217 ifnet_lock_done(ifp);
1218 break;
1219
1220 #if CONFIG_MACF_NET
1221 case SIOCGIFMAC:
1222 error = mac_ifnet_label_get(kauth_cred_get(), ifr, ifp);
1223 if (error)
1224 return (error);
1225 break;
1226 #endif
1227 case SIOCGIFMETRIC:
1228 ifnet_lock_shared(ifp);
1229 ifr->ifr_metric = ifp->if_metric;
1230 ifnet_lock_done(ifp);
1231 break;
1232
1233 case SIOCGIFMTU:
1234 ifnet_lock_shared(ifp);
1235 ifr->ifr_mtu = ifp->if_mtu;
1236 ifnet_lock_done(ifp);
1237 break;
1238
1239 case SIOCGIFPHYS:
1240 ifnet_lock_shared(ifp);
1241 ifr->ifr_phys = ifp->if_physical;
1242 ifnet_lock_done(ifp);
1243 break;
1244
1245 case SIOCSIFFLAGS:
1246 error = proc_suser(p);
1247 if (error)
1248 return (error);
1249
1250 ifnet_set_flags(ifp, ifr->ifr_flags, (u_int16_t)~IFF_CANTCHANGE);
1251
1252 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1253 cmd, data);
1254
1255 /* Send the event even upon error from the driver because we changed the flags */
1256 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1257 ev_msg.kev_class = KEV_NETWORK_CLASS;
1258 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1259
1260 ev_msg.event_code = KEV_DL_SIFFLAGS;
1261 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1262 ev_data.if_family = ifp->if_family;
1263 ev_data.if_unit = (u_int32_t) ifp->if_unit;
1264 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1265 ev_msg.dv[0].data_ptr = &ev_data;
1266 ev_msg.dv[1].data_length = 0;
1267 kev_post_msg(&ev_msg);
1268
1269 ifnet_touch_lastchange(ifp);
1270 break;
1271
1272 #if CONFIG_MACF_NET
1273 case SIOCSIFMAC:
1274 error = mac_ifnet_label_set(kauth_cred_get(), ifr, ifp);
1275 if (error)
1276 return (error);
1277 break;
1278 #endif
1279 case SIOCSIFMETRIC:
1280 error = proc_suser(p);
1281 if (error)
1282 return (error);
1283 ifp->if_metric = ifr->ifr_metric;
1284
1285
1286 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1287 ev_msg.kev_class = KEV_NETWORK_CLASS;
1288 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1289
1290 ev_msg.event_code = KEV_DL_SIFMETRICS;
1291 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1292 ev_data.if_family = ifp->if_family;
1293 ev_data.if_unit = (u_int32_t) ifp->if_unit;
1294 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1295 ev_msg.dv[0].data_ptr = &ev_data;
1296
1297 ev_msg.dv[1].data_length = 0;
1298 kev_post_msg(&ev_msg);
1299
1300 ifnet_touch_lastchange(ifp);
1301 break;
1302
1303 case SIOCSIFPHYS:
1304 error = proc_suser(p);
1305 if (error)
1306 return error;
1307
1308 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1309 cmd, data);
1310
1311 if (error == 0) {
1312 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1313 ev_msg.kev_class = KEV_NETWORK_CLASS;
1314 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1315
1316 ev_msg.event_code = KEV_DL_SIFPHYS;
1317 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1318 ev_data.if_family = ifp->if_family;
1319 ev_data.if_unit = (u_int32_t) ifp->if_unit;
1320 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1321 ev_msg.dv[0].data_ptr = &ev_data;
1322 ev_msg.dv[1].data_length = 0;
1323 kev_post_msg(&ev_msg);
1324
1325 ifnet_touch_lastchange(ifp);
1326 }
1327 return(error);
1328
1329 case SIOCSIFMTU:
1330 {
1331 u_int32_t oldmtu = ifp->if_mtu;
1332
1333 error = proc_suser(p);
1334 if (error)
1335 return (error);
1336 if (ifp->if_ioctl == NULL)
1337 return (EOPNOTSUPP);
1338 if (ifr->ifr_mtu < IF_MINMTU || ifr->ifr_mtu > IF_MAXMTU)
1339 return (EINVAL);
1340
1341 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1342 cmd, data);
1343
1344 if (error == 0) {
1345 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1346 ev_msg.kev_class = KEV_NETWORK_CLASS;
1347 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1348
1349 ev_msg.event_code = KEV_DL_SIFMTU;
1350 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1351 ev_data.if_family = ifp->if_family;
1352 ev_data.if_unit = (u_int32_t) ifp->if_unit;
1353 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1354 ev_msg.dv[0].data_ptr = &ev_data;
1355 ev_msg.dv[1].data_length = 0;
1356 kev_post_msg(&ev_msg);
1357
1358 ifnet_touch_lastchange(ifp);
1359 rt_ifmsg(ifp);
1360 }
1361 /*
1362 * If the link MTU changed, do network layer specific procedure
1363 * and update all route entries associated with the interface,
1364 * so that their MTU metric gets updated.
1365 */
1366 if (error == 0 && ifp->if_mtu != oldmtu) {
1367 if_rtmtu_update(ifp);
1368 #if INET6
1369 nd6_setmtu(ifp);
1370 #endif
1371 }
1372 return (error);
1373 }
1374
1375 case SIOCADDMULTI:
1376 case SIOCDELMULTI:
1377 error = proc_suser(p);
1378 if (error)
1379 return (error);
1380
1381 /* Don't allow group membership on non-multicast interfaces. */
1382 if ((ifp->if_flags & IFF_MULTICAST) == 0)
1383 return EOPNOTSUPP;
1384
1385 #ifndef __APPLE__
1386 /* Don't let users screw up protocols' entries. */
1387 if (ifr->ifr_addr.sa_family != AF_LINK)
1388 return EINVAL;
1389 #endif
1390
1391 if (cmd == SIOCADDMULTI) {
1392 error = if_addmulti(ifp, &ifr->ifr_addr, NULL);
1393 ev_msg.event_code = KEV_DL_ADDMULTI;
1394 } else {
1395 error = if_delmulti(ifp, &ifr->ifr_addr);
1396 ev_msg.event_code = KEV_DL_DELMULTI;
1397 }
1398 if (error == 0) {
1399 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1400 ev_msg.kev_class = KEV_NETWORK_CLASS;
1401 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1402 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1403
1404 ev_data.if_family = ifp->if_family;
1405 ev_data.if_unit = (u_int32_t) ifp->if_unit;
1406 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1407 ev_msg.dv[0].data_ptr = &ev_data;
1408 ev_msg.dv[1].data_length = 0;
1409 kev_post_msg(&ev_msg);
1410
1411 ifnet_touch_lastchange(ifp);
1412 }
1413 return error;
1414
1415 case SIOCSIFPHYADDR:
1416 case SIOCDIFPHYADDR:
1417 #if INET6
1418 case SIOCSIFPHYADDR_IN6_32:
1419 case SIOCSIFPHYADDR_IN6_64:
1420 #endif
1421 case SIOCSLIFPHYADDR:
1422 case SIOCSIFMEDIA:
1423 case SIOCSIFGENERIC:
1424 case SIOCSIFLLADDR:
1425 case SIOCSIFALTMTU:
1426 case SIOCSIFVLAN:
1427 case SIOCSIFBOND:
1428 error = proc_suser(p);
1429 if (error)
1430 return (error);
1431
1432 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1433 cmd, data);
1434
1435 if (error == 0)
1436 ifnet_touch_lastchange(ifp);
1437 return error;
1438
1439 case SIOCGIFSTATUS:
1440 ifs = (struct ifstat *)data;
1441 ifs->ascii[0] = '\0';
1442
1443 case SIOCGIFPSRCADDR:
1444 case SIOCGIFPDSTADDR:
1445 case SIOCGLIFPHYADDR:
1446 case SIOCGIFMEDIA32:
1447 case SIOCGIFMEDIA64:
1448 case SIOCGIFGENERIC:
1449 case SIOCGIFDEVMTU:
1450 return ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1451 cmd, data);
1452 case SIOCGIFVLAN:
1453 case SIOCGIFBOND:
1454 return ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1455 cmd, data);
1456
1457 case SIOCGIFWAKEFLAGS:
1458 ifnet_lock_shared(ifp);
1459 ifr->ifr_wake_flags = ifnet_get_wake_flags(ifp);
1460 ifnet_lock_done(ifp);
1461 break;
1462
1463 default:
1464 oif_flags = ifp->if_flags;
1465 if (so->so_proto == 0)
1466 return (EOPNOTSUPP);
1467 {
1468 int ocmd = cmd;
1469
1470 switch (cmd) {
1471
1472 case SIOCSIFDSTADDR:
1473 case SIOCSIFADDR:
1474 case SIOCSIFBRDADDR:
1475 case SIOCSIFNETMASK:
1476 #if BYTE_ORDER != BIG_ENDIAN
1477 if (ifr->ifr_addr.sa_family == 0 &&
1478 ifr->ifr_addr.sa_len < 16) {
1479 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
1480 ifr->ifr_addr.sa_len = 16;
1481 }
1482 #else
1483 if (ifr->ifr_addr.sa_len == 0)
1484 ifr->ifr_addr.sa_len = 16;
1485 #endif
1486 break;
1487
1488 case OSIOCGIFADDR:
1489 cmd = SIOCGIFADDR;
1490 break;
1491
1492 case OSIOCGIFDSTADDR:
1493 cmd = SIOCGIFDSTADDR;
1494 break;
1495
1496 case OSIOCGIFBRDADDR:
1497 cmd = SIOCGIFBRDADDR;
1498 break;
1499
1500 case OSIOCGIFNETMASK:
1501 cmd = SIOCGIFNETMASK;
1502 }
1503 socket_lock(so, 1);
1504 error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
1505 data, ifp, p));
1506 socket_unlock(so, 1);
1507 switch (ocmd) {
1508
1509 case OSIOCGIFADDR:
1510 case OSIOCGIFDSTADDR:
1511 case OSIOCGIFBRDADDR:
1512 case OSIOCGIFNETMASK:
1513 *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
1514
1515 }
1516 }
1517 if (cmd == SIOCSIFKPI) {
1518 int temperr = proc_suser(p);
1519 if (temperr != 0)
1520 error = temperr;
1521 }
1522
1523 if (error == EOPNOTSUPP || error == ENOTSUP)
1524 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1525 cmd, data);
1526
1527 return (error);
1528 }
1529 return (0);
1530 }
1531
1532 int
1533 ifioctllocked(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
1534 {
1535 int error;
1536
1537 socket_unlock(so, 0);
1538 error = ifioctl(so, cmd, data, p);
1539 socket_lock(so, 0);
1540 return(error);
1541 }
1542
1543 /*
1544 * Set/clear promiscuous mode on interface ifp based on the truth value
1545 * of pswitch. The calls are reference counted so that only the first
1546 * "on" request actually has an effect, as does the final "off" request.
1547 * Results are undefined if the "off" and "on" requests are not matched.
1548 */
1549 errno_t
1550 ifnet_set_promiscuous(
1551 ifnet_t ifp,
1552 int pswitch)
1553 {
1554 struct ifreq ifr;
1555 int error = 0;
1556 int oldflags;
1557 int locked = 0;
1558 int changed = 0;
1559
1560 ifnet_lock_exclusive(ifp);
1561 locked = 1;
1562 oldflags = ifp->if_flags;
1563 if (pswitch) {
1564 /*
1565 * If the device is not configured up, we cannot put it in
1566 * promiscuous mode.
1567 */
1568 if ((ifp->if_flags & IFF_UP) == 0) {
1569 error = ENETDOWN;
1570 goto done;
1571 }
1572 if (ifp->if_pcount++ != 0) {
1573 goto done;
1574 }
1575 ifp->if_flags |= IFF_PROMISC;
1576 } else {
1577 if (--ifp->if_pcount > 0)
1578 goto done;
1579 ifp->if_flags &= ~IFF_PROMISC;
1580 }
1581 ifr.ifr_flags = ifp->if_flags;
1582 locked = 0;
1583 ifnet_lock_done(ifp);
1584 error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, &ifr);
1585 if (error == 0)
1586 rt_ifmsg(ifp);
1587 else
1588 ifp->if_flags = oldflags;
1589 done:
1590 if (locked) ifnet_lock_done(ifp);
1591 if (changed) {
1592 log(LOG_INFO, "%s%d: promiscuous mode %s\n",
1593 ifp->if_name, ifp->if_unit,
1594 pswitch != 0 ? "enabled" : "disabled");
1595 }
1596 return error;
1597 }
1598
1599 /*
1600 * Return interface configuration
1601 * of system. List may be used
1602 * in later ioctl's (above) to get
1603 * other information.
1604 */
1605 /*ARGSUSED*/
1606 static int
1607 ifconf(u_long cmd, user_addr_t ifrp, int * ret_space)
1608 {
1609 struct ifnet *ifp = NULL;
1610 struct ifaddr *ifa;
1611 struct ifreq ifr;
1612 int error = 0;
1613 size_t space;
1614
1615 /*
1616 * Zero the ifr buffer to make sure we don't
1617 * disclose the contents of the stack.
1618 */
1619 bzero(&ifr, sizeof(struct ifreq));
1620
1621 space = *ret_space;
1622 ifnet_head_lock_shared();
1623 for (ifp = ifnet_head.tqh_first; space > sizeof(ifr) && ifp; ifp = ifp->if_link.tqe_next) {
1624 char workbuf[64];
1625 size_t ifnlen, addrs;
1626
1627 ifnlen = snprintf(workbuf, sizeof(workbuf),
1628 "%s%d", ifp->if_name, ifp->if_unit);
1629 if(ifnlen + 1 > sizeof ifr.ifr_name) {
1630 error = ENAMETOOLONG;
1631 break;
1632 } else {
1633 strlcpy(ifr.ifr_name, workbuf, IFNAMSIZ);
1634 }
1635
1636 ifnet_lock_shared(ifp);
1637
1638 addrs = 0;
1639 ifa = ifp->if_addrhead.tqh_first;
1640 for ( ; space > sizeof (ifr) && ifa;
1641 ifa = ifa->ifa_link.tqe_next) {
1642 struct sockaddr *sa = ifa->ifa_addr;
1643 #ifndef __APPLE__
1644 if (curproc->p_prison && prison_if(curproc, sa))
1645 continue;
1646 #endif
1647 addrs++;
1648 if (cmd == OSIOCGIFCONF32 || cmd == OSIOCGIFCONF64) {
1649 struct osockaddr *osa =
1650 (struct osockaddr *)&ifr.ifr_addr;
1651 ifr.ifr_addr = *sa;
1652 osa->sa_family = sa->sa_family;
1653 error = copyout((caddr_t)&ifr, ifrp, sizeof(ifr));
1654 ifrp += sizeof(struct ifreq);
1655 } else if (sa->sa_len <= sizeof(*sa)) {
1656 ifr.ifr_addr = *sa;
1657 error = copyout((caddr_t)&ifr, ifrp, sizeof(ifr));
1658 ifrp += sizeof(struct ifreq);
1659 } else {
1660 if (space < sizeof (ifr) + sa->sa_len - sizeof(*sa))
1661 break;
1662 space -= sa->sa_len - sizeof(*sa);
1663 error = copyout((caddr_t)&ifr, ifrp, sizeof (ifr.ifr_name));
1664 if (error == 0) {
1665 error = copyout((caddr_t)sa,
1666 (ifrp + offsetof(struct ifreq, ifr_addr)),
1667 sa->sa_len);
1668 }
1669 ifrp += (sa->sa_len + offsetof(struct ifreq, ifr_addr));
1670 }
1671 if (error)
1672 break;
1673 space -= sizeof (ifr);
1674 }
1675 ifnet_lock_done(ifp);
1676
1677 if (error)
1678 break;
1679 if (!addrs) {
1680 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
1681 error = copyout((caddr_t)&ifr, ifrp, sizeof (ifr));
1682 if (error)
1683 break;
1684 space -= sizeof (ifr);
1685 ifrp += sizeof(struct ifreq);
1686 }
1687 }
1688 ifnet_head_done();
1689 *ret_space -= space;
1690 return (error);
1691 }
1692
1693 /*
1694 * Just like if_promisc(), but for all-multicast-reception mode.
1695 */
1696 int
1697 if_allmulti(struct ifnet *ifp, int onswitch)
1698 {
1699 int error = 0;
1700 int modified = 0;
1701
1702 ifnet_lock_exclusive(ifp);
1703
1704 if (onswitch) {
1705 if (ifp->if_amcount++ == 0) {
1706 ifp->if_flags |= IFF_ALLMULTI;
1707 modified = 1;
1708 }
1709 } else {
1710 if (ifp->if_amcount > 1) {
1711 ifp->if_amcount--;
1712 } else {
1713 ifp->if_amcount = 0;
1714 ifp->if_flags &= ~IFF_ALLMULTI;
1715 modified = 1;
1716 }
1717 }
1718 ifnet_lock_done(ifp);
1719
1720 if (modified)
1721 error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL);
1722
1723 if (error == 0)
1724 rt_ifmsg(ifp);
1725 return error;
1726 }
1727
1728 void
1729 ifma_reference(
1730 struct ifmultiaddr *ifma)
1731 {
1732 if (OSIncrementAtomic(&ifma->ifma_refcount) <= 0)
1733 panic("ifma_reference: ifma already released or invalid\n");
1734 }
1735
1736 void
1737 ifma_release(
1738 struct ifmultiaddr *ifma)
1739 {
1740 while (ifma) {
1741 struct ifmultiaddr *next;
1742 int32_t prevValue = OSDecrementAtomic(&ifma->ifma_refcount);
1743 if (prevValue < 1)
1744 panic("ifma_release: ifma already released or invalid\n");
1745 if (prevValue != 1)
1746 break;
1747
1748 /* Allow the allocator of the protospec to free it */
1749 if (ifma->ifma_protospec && ifma->ifma_free) {
1750 ifma->ifma_free(ifma->ifma_protospec);
1751 }
1752
1753 next = ifma->ifma_ll;
1754 FREE(ifma->ifma_addr, M_IFMADDR);
1755 FREE(ifma, M_IFMADDR);
1756 ifma = next;
1757 }
1758 }
1759
1760 /*
1761 * Find an ifmultiaddr that matches a socket address on an interface.
1762 *
1763 * Caller is responsible for holding the ifnet_lock while calling
1764 * this function.
1765 */
1766 static int
1767 if_addmulti_doesexist(
1768 struct ifnet *ifp,
1769 const struct sockaddr *sa,
1770 struct ifmultiaddr **retifma)
1771 {
1772 struct ifmultiaddr *ifma;
1773 for (ifma = ifp->if_multiaddrs.lh_first; ifma;
1774 ifma = ifma->ifma_link.le_next) {
1775 if (equal(sa, ifma->ifma_addr)) {
1776 ifma->ifma_usecount++;
1777 if (retifma) {
1778 *retifma = ifma;
1779 ifma_reference(*retifma);
1780 }
1781 return 0;
1782 }
1783 }
1784
1785 return ENOENT;
1786 }
1787
1788 /*
1789 * Radar 3642395, make sure all multicasts are in a standard format.
1790 */
1791 static struct sockaddr*
1792 copy_and_normalize(
1793 const struct sockaddr *original)
1794 {
1795 int alen = 0;
1796 const u_char *aptr = NULL;
1797 struct sockaddr *copy = NULL;
1798 struct sockaddr_dl *sdl_new = NULL;
1799 int len = 0;
1800
1801 if (original->sa_family != AF_LINK &&
1802 original->sa_family != AF_UNSPEC) {
1803 /* Just make a copy */
1804 MALLOC(copy, struct sockaddr*, original->sa_len, M_IFADDR, M_WAITOK);
1805 if (copy != NULL)
1806 bcopy(original, copy, original->sa_len);
1807 return copy;
1808 }
1809
1810 switch (original->sa_family) {
1811 case AF_LINK: {
1812 const struct sockaddr_dl *sdl_original =
1813 (const struct sockaddr_dl*)original;
1814
1815 if (sdl_original->sdl_nlen + sdl_original->sdl_alen + sdl_original->sdl_slen +
1816 offsetof(struct sockaddr_dl, sdl_data) > sdl_original->sdl_len)
1817 return NULL;
1818
1819 alen = sdl_original->sdl_alen;
1820 aptr = CONST_LLADDR(sdl_original);
1821 }
1822 break;
1823
1824 case AF_UNSPEC: {
1825 if (original->sa_len < ETHER_ADDR_LEN +
1826 offsetof(struct sockaddr, sa_data)) {
1827 return NULL;
1828 }
1829
1830 alen = ETHER_ADDR_LEN;
1831 aptr = (const u_char*)original->sa_data;
1832 }
1833 break;
1834 }
1835
1836 if (alen == 0 || aptr == NULL)
1837 return NULL;
1838
1839 len = alen + offsetof(struct sockaddr_dl, sdl_data);
1840 MALLOC(sdl_new, struct sockaddr_dl*, len, M_IFADDR, M_WAITOK);
1841
1842 if (sdl_new != NULL) {
1843 bzero(sdl_new, len);
1844 sdl_new->sdl_len = len;
1845 sdl_new->sdl_family = AF_LINK;
1846 sdl_new->sdl_alen = alen;
1847 bcopy(aptr, LLADDR(sdl_new), alen);
1848 }
1849
1850 return (struct sockaddr*)sdl_new;
1851 }
1852
1853 /*
1854 * Add a multicast listenership to the interface in question.
1855 * The link layer provides a routine which converts
1856 */
1857 int
1858 if_addmulti(
1859 struct ifnet *ifp, /* interface to manipulate */
1860 const struct sockaddr *sa, /* address to add */
1861 struct ifmultiaddr **retifma)
1862 {
1863 struct sockaddr_storage storage;
1864 struct sockaddr *llsa = NULL;
1865 struct sockaddr *dupsa = NULL;
1866 int error = 0;
1867 struct ifmultiaddr *ifma = NULL;
1868 struct ifmultiaddr *llifma = NULL;
1869
1870 /* If sa is a AF_LINK or AF_UNSPEC, duplicate and normalize it */
1871 if (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC) {
1872 dupsa = copy_and_normalize(sa);
1873 if (dupsa == NULL) {
1874 return ENOMEM;
1875 }
1876 sa = dupsa;
1877 }
1878
1879 ifnet_lock_exclusive(ifp);
1880 error = if_addmulti_doesexist(ifp, sa, retifma);
1881 ifnet_lock_done(ifp);
1882
1883 if (error == 0) {
1884 goto cleanup;
1885 }
1886
1887 /*
1888 * Give the link layer a chance to accept/reject it, and also
1889 * find out which AF_LINK address this maps to, if it isn't one
1890 * already.
1891 */
1892 error = dlil_resolve_multi(ifp, sa, (struct sockaddr*)&storage,
1893 sizeof(storage));
1894 if (error == 0 && storage.ss_len != 0) {
1895 llsa = copy_and_normalize((struct sockaddr*)&storage);
1896 if (llsa == NULL) {
1897 error = ENOMEM;
1898 goto cleanup;
1899 }
1900
1901 MALLOC(llifma, struct ifmultiaddr *, sizeof *llifma, M_IFMADDR, M_WAITOK);
1902 if (llifma == NULL) {
1903 error = ENOMEM;
1904 goto cleanup;
1905 }
1906 }
1907
1908 /* to be similar to FreeBSD */
1909 if (error == EOPNOTSUPP) {
1910 error = 0;
1911 }
1912 else if (error) {
1913 goto cleanup;
1914 }
1915
1916 /* Allocate while we aren't holding any locks */
1917 if (dupsa == NULL) {
1918 dupsa = copy_and_normalize(sa);
1919 if (dupsa == NULL) {
1920 error = ENOMEM;
1921 goto cleanup;
1922 }
1923 }
1924 MALLOC(ifma, struct ifmultiaddr *, sizeof *ifma, M_IFMADDR, M_WAITOK);
1925 if (ifma == NULL) {
1926 error = ENOMEM;
1927 goto cleanup;
1928 }
1929
1930 ifnet_lock_exclusive(ifp);
1931 /*
1932 * Check again for the matching multicast.
1933 */
1934 if ((error = if_addmulti_doesexist(ifp, sa, retifma)) == 0) {
1935 ifnet_lock_done(ifp);
1936 goto cleanup;
1937 }
1938
1939 bzero(ifma, sizeof(*ifma));
1940 ifma->ifma_addr = dupsa;
1941 ifma->ifma_ifp = ifp;
1942 ifma->ifma_usecount = 1;
1943 ifma->ifma_refcount = 1;
1944
1945 if (llifma != 0) {
1946 if (if_addmulti_doesexist(ifp, llsa, &ifma->ifma_ll) == 0) {
1947 FREE(llsa, M_IFMADDR);
1948 FREE(llifma, M_IFMADDR);
1949 } else {
1950 bzero(llifma, sizeof(*llifma));
1951 llifma->ifma_addr = llsa;
1952 llifma->ifma_ifp = ifp;
1953 llifma->ifma_usecount = 1;
1954 llifma->ifma_refcount = 1;
1955 LIST_INSERT_HEAD(&ifp->if_multiaddrs, llifma, ifma_link);
1956
1957 ifma->ifma_ll = llifma;
1958 ifma_reference(ifma->ifma_ll);
1959 }
1960 }
1961
1962 LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link);
1963
1964 if (retifma) {
1965 *retifma = ifma;
1966 ifma_reference(*retifma);
1967 }
1968
1969 ifnet_lock_done(ifp);
1970
1971 if (llsa != 0)
1972 rt_newmaddrmsg(RTM_NEWMADDR, ifma);
1973
1974 /*
1975 * We are certain we have added something, so call down to the
1976 * interface to let them know about it.
1977 */
1978 ifnet_ioctl(ifp, 0, SIOCADDMULTI, NULL);
1979
1980 return 0;
1981
1982 cleanup:
1983 if (ifma)
1984 FREE(ifma, M_IFADDR);
1985 if (dupsa)
1986 FREE(dupsa, M_IFADDR);
1987 if (llifma)
1988 FREE(llifma, M_IFADDR);
1989 if (llsa)
1990 FREE(llsa, M_IFADDR);
1991
1992 return error;
1993 }
1994
1995 int
1996 if_delmultiaddr(
1997 struct ifmultiaddr *ifma,
1998 int locked)
1999 {
2000 struct ifnet *ifp;
2001 int do_del_multi = 0;
2002
2003 ifp = ifma->ifma_ifp;
2004
2005 if (!locked && ifp) {
2006 ifnet_lock_exclusive(ifp);
2007 }
2008
2009 while (ifma != NULL) {
2010 struct ifmultiaddr *ll_ifma;
2011
2012 if (ifma->ifma_usecount > 1) {
2013 ifma->ifma_usecount--;
2014 break;
2015 }
2016
2017 if (ifp)
2018 LIST_REMOVE(ifma, ifma_link);
2019
2020 ll_ifma = ifma->ifma_ll;
2021
2022 if (ll_ifma) { /* send a routing msg for network addresses only */
2023 if (ifp)
2024 ifnet_lock_done(ifp);
2025 rt_newmaddrmsg(RTM_DELMADDR, ifma);
2026 if (ifp)
2027 ifnet_lock_exclusive(ifp);
2028 }
2029
2030 /*
2031 * Make sure the interface driver is notified
2032 * in the case of a link layer mcast group being left.
2033 */
2034 if (ll_ifma == 0) {
2035 if (ifp && ifma->ifma_addr->sa_family == AF_LINK)
2036 do_del_multi = 1;
2037 break;
2038 }
2039
2040 if (ifp)
2041 ifma_release(ifma);
2042
2043 ifma = ll_ifma;
2044 }
2045
2046 if (!locked && ifp) {
2047 /* This wasn't initially locked, we should unlock it */
2048 ifnet_lock_done(ifp);
2049 }
2050
2051 if (do_del_multi) {
2052 if (locked)
2053 ifnet_lock_done(ifp);
2054 ifnet_ioctl(ifp, 0, SIOCDELMULTI, NULL);
2055 if (locked)
2056 ifnet_lock_exclusive(ifp);
2057 }
2058
2059 return 0;
2060 }
2061
2062 /*
2063 * Remove a reference to a multicast address on this interface. Yell
2064 * if the request does not match an existing membership.
2065 */
2066 int
2067 if_delmulti(
2068 struct ifnet *ifp,
2069 const struct sockaddr *sa)
2070 {
2071 struct ifmultiaddr *ifma;
2072 struct sockaddr *dupsa = NULL;
2073 int retval = 0;
2074
2075 if (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC) {
2076 dupsa = copy_and_normalize(sa);
2077 if (dupsa == NULL) {
2078 return ENOMEM;
2079 }
2080 sa = dupsa;
2081 }
2082
2083 ifnet_lock_exclusive(ifp);
2084 for (ifma = ifp->if_multiaddrs.lh_first; ifma;
2085 ifma = ifma->ifma_link.le_next)
2086 if (equal(sa, ifma->ifma_addr))
2087 break;
2088 if (ifma == 0) {
2089 ifnet_lock_done(ifp);
2090 if (dupsa)
2091 FREE(dupsa, M_IFADDR);
2092 return ENOENT;
2093 }
2094
2095 retval = if_delmultiaddr(ifma, 1);
2096 ifnet_lock_done(ifp);
2097 if (dupsa)
2098 FREE(dupsa, M_IFADDR);
2099
2100 return retval;
2101 }
2102
2103
2104 /*
2105 * We don't use if_setlladdr, our interfaces are responsible for
2106 * handling the SIOCSIFLLADDR ioctl.
2107 */
2108 #ifndef __APPLE__
2109 int
2110 if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
2111 {
2112 ...
2113 }
2114 #endif
2115
2116 struct ifmultiaddr *
2117 ifmaof_ifpforaddr(const struct sockaddr *sa, struct ifnet *ifp)
2118 {
2119 struct ifmultiaddr *ifma;
2120
2121 ifnet_lock_shared(ifp);
2122 for (ifma = ifp->if_multiaddrs.lh_first; ifma;
2123 ifma = ifma->ifma_link.le_next)
2124 if (equal(ifma->ifma_addr, sa))
2125 break;
2126 ifnet_lock_done(ifp);
2127
2128 return ifma;
2129 }
2130
2131 SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Link layers");
2132 SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Generic link-management");
2133
2134
2135 /*
2136 * Shutdown all network activity. Used boot() when halting
2137 * system.
2138 */
2139 int
2140 if_down_all(void)
2141 {
2142 struct ifnet **ifp;
2143 u_int32_t count;
2144 u_int32_t i;
2145
2146 if (ifnet_list_get_all(IFNET_FAMILY_ANY, &ifp, &count) == 0) {
2147 for (i = 0; i < count; i++) {
2148 if_down(ifp[i]);
2149 dlil_proto_unplumb_all(ifp[i]);
2150 }
2151 ifnet_list_free(ifp);
2152 }
2153
2154 return 0;
2155 }
2156
2157 /*
2158 * Delete Routes for a Network Interface
2159 *
2160 * Called for each routing entry via the rnh->rnh_walktree() call above
2161 * to delete all route entries referencing a detaching network interface.
2162 *
2163 * Arguments:
2164 * rn pointer to node in the routing table
2165 * arg argument passed to rnh->rnh_walktree() - detaching interface
2166 *
2167 * Returns:
2168 * 0 successful
2169 * errno failed - reason indicated
2170 *
2171 */
2172 static int
2173 if_rtdel(struct radix_node *rn, void *arg)
2174 {
2175 struct rtentry *rt = (struct rtentry *)rn;
2176 struct ifnet *ifp = arg;
2177 int err;
2178
2179 if (rt == NULL)
2180 return (0);
2181 /*
2182 * Checking against RTF_UP protects against walktree
2183 * recursion problems with cloned routes.
2184 */
2185 RT_LOCK(rt);
2186 if (rt->rt_ifp == ifp && (rt->rt_flags & RTF_UP)) {
2187 /*
2188 * Safe to drop rt_lock and use rt_key, rt_gateway,
2189 * since holding rnh_lock here prevents another thread
2190 * from calling rt_setgate() on this route.
2191 */
2192 RT_UNLOCK(rt);
2193 err = rtrequest_locked(RTM_DELETE, rt_key(rt), rt->rt_gateway,
2194 rt_mask(rt), rt->rt_flags, NULL);
2195 if (err) {
2196 log(LOG_WARNING, "if_rtdel: error %d\n", err);
2197 }
2198 } else {
2199 RT_UNLOCK(rt);
2200 }
2201 return (0);
2202 }
2203
2204 /*
2205 * Removes routing table reference to a given interface
2206 * for a given protocol family
2207 */
2208 void
2209 if_rtproto_del(struct ifnet *ifp, int protocol)
2210 {
2211 struct radix_node_head *rnh;
2212
2213 if (use_routegenid)
2214 routegenid_update();
2215 if ((protocol <= AF_MAX) && (protocol >= 0) &&
2216 ((rnh = rt_tables[protocol]) != NULL) && (ifp != NULL)) {
2217 lck_mtx_lock(rnh_lock);
2218 (void) rnh->rnh_walktree(rnh, if_rtdel, ifp);
2219 lck_mtx_unlock(rnh_lock);
2220 }
2221 }
2222
2223 static int
2224 if_rtmtu(struct radix_node *rn, void *arg)
2225 {
2226 struct rtentry *rt = (struct rtentry *)rn;
2227 struct ifnet *ifp = arg;
2228
2229 RT_LOCK(rt);
2230 if (rt->rt_ifp == ifp) {
2231 /*
2232 * Update the MTU of this entry only if the MTU
2233 * has not been locked (RTV_MTU is not set) and
2234 * if it was non-zero to begin with.
2235 */
2236 if (!(rt->rt_rmx.rmx_locks & RTV_MTU) && rt->rt_rmx.rmx_mtu)
2237 rt->rt_rmx.rmx_mtu = ifp->if_mtu;
2238 }
2239 RT_UNLOCK(rt);
2240
2241 return (0);
2242 }
2243
2244 /*
2245 * Update the MTU metric of all route entries in all protocol tables
2246 * associated with a particular interface; this is called when the
2247 * MTU of that interface has changed.
2248 */
2249 static
2250 void if_rtmtu_update(struct ifnet *ifp)
2251 {
2252 struct radix_node_head *rnh;
2253 int p;
2254
2255 for (p = 0; p < AF_MAX + 1; p++) {
2256 if ((rnh = rt_tables[p]) == NULL)
2257 continue;
2258
2259 lck_mtx_lock(rnh_lock);
2260 (void) rnh->rnh_walktree(rnh, if_rtmtu, ifp);
2261 lck_mtx_unlock(rnh_lock);
2262 }
2263
2264 if (use_routegenid)
2265 routegenid_update();
2266 }
2267
2268 __private_extern__ void
2269 if_data_internal_to_if_data(
2270 struct ifnet *ifp,
2271 const struct if_data_internal *if_data_int,
2272 struct if_data *if_data)
2273 {
2274 struct dlil_threading_info *thread;
2275 if ((thread = ifp->if_input_thread) == NULL || (dlil_multithreaded_input == 0))
2276 thread = dlil_lo_thread_ptr;
2277
2278 #define COPYFIELD(fld) if_data->fld = if_data_int->fld
2279 #define COPYFIELD32(fld) if_data->fld = (u_int32_t)(if_data_int->fld)
2280 COPYFIELD(ifi_type);
2281 COPYFIELD(ifi_typelen);
2282 COPYFIELD(ifi_physical);
2283 COPYFIELD(ifi_addrlen);
2284 COPYFIELD(ifi_hdrlen);
2285 COPYFIELD(ifi_recvquota);
2286 COPYFIELD(ifi_xmitquota);
2287 if_data->ifi_unused1 = 0;
2288 COPYFIELD(ifi_mtu);
2289 COPYFIELD(ifi_metric);
2290 if (if_data_int->ifi_baudrate & 0xFFFFFFFF00000000LL) {
2291 if_data->ifi_baudrate = 0xFFFFFFFF;
2292 }
2293 else {
2294 COPYFIELD32(ifi_baudrate);
2295 }
2296
2297 lck_mtx_lock(thread->input_lck);
2298 COPYFIELD32(ifi_ipackets);
2299 COPYFIELD32(ifi_ierrors);
2300 COPYFIELD32(ifi_opackets);
2301 COPYFIELD32(ifi_oerrors);
2302 COPYFIELD32(ifi_collisions);
2303 COPYFIELD32(ifi_ibytes);
2304 COPYFIELD32(ifi_obytes);
2305 COPYFIELD32(ifi_imcasts);
2306 COPYFIELD32(ifi_omcasts);
2307 COPYFIELD32(ifi_iqdrops);
2308 COPYFIELD32(ifi_noproto);
2309 COPYFIELD32(ifi_recvtiming);
2310 COPYFIELD32(ifi_xmittiming);
2311 if_data->ifi_lastchange.tv_sec = if_data_int->ifi_lastchange.tv_sec;
2312 if_data->ifi_lastchange.tv_usec = if_data_int->ifi_lastchange.tv_usec;
2313 lck_mtx_unlock(thread->input_lck);
2314
2315 #if IF_LASTCHANGEUPTIME
2316 if_data->ifi_lastchange.tv_sec += boottime_sec();
2317 #endif
2318
2319 if_data->ifi_unused2 = 0;
2320 COPYFIELD(ifi_hwassist);
2321 if_data->ifi_reserved1 = 0;
2322 if_data->ifi_reserved2 = 0;
2323 #undef COPYFIELD32
2324 #undef COPYFIELD
2325 }
2326
2327 __private_extern__ void
2328 if_data_internal_to_if_data64(
2329 struct ifnet *ifp,
2330 const struct if_data_internal *if_data_int,
2331 struct if_data64 *if_data64)
2332 {
2333 struct dlil_threading_info *thread;
2334 if ((thread = ifp->if_input_thread) == NULL || (dlil_multithreaded_input == 0))
2335 thread = dlil_lo_thread_ptr;
2336
2337 #define COPYFIELD(fld) if_data64->fld = if_data_int->fld
2338 COPYFIELD(ifi_type);
2339 COPYFIELD(ifi_typelen);
2340 COPYFIELD(ifi_physical);
2341 COPYFIELD(ifi_addrlen);
2342 COPYFIELD(ifi_hdrlen);
2343 COPYFIELD(ifi_recvquota);
2344 COPYFIELD(ifi_xmitquota);
2345 if_data64->ifi_unused1 = 0;
2346 COPYFIELD(ifi_mtu);
2347 COPYFIELD(ifi_metric);
2348 COPYFIELD(ifi_baudrate);
2349
2350 lck_mtx_lock(thread->input_lck);
2351 COPYFIELD(ifi_ipackets);
2352 COPYFIELD(ifi_ierrors);
2353 COPYFIELD(ifi_opackets);
2354 COPYFIELD(ifi_oerrors);
2355 COPYFIELD(ifi_collisions);
2356 COPYFIELD(ifi_ibytes);
2357 COPYFIELD(ifi_obytes);
2358 COPYFIELD(ifi_imcasts);
2359 COPYFIELD(ifi_omcasts);
2360 COPYFIELD(ifi_iqdrops);
2361 COPYFIELD(ifi_noproto);
2362 COPYFIELD(ifi_recvtiming);
2363 COPYFIELD(ifi_xmittiming);
2364 if_data64->ifi_lastchange.tv_sec = if_data_int->ifi_lastchange.tv_sec;
2365 if_data64->ifi_lastchange.tv_usec = if_data_int->ifi_lastchange.tv_usec;
2366 lck_mtx_unlock(thread->input_lck);
2367
2368 #if IF_LASTCHANGEUPTIME
2369 if_data64->ifi_lastchange.tv_sec += boottime_sec();
2370 #endif
2371
2372 #undef COPYFIELD
2373 }
2374
2375 void
2376 ifafree(struct ifaddr *ifa)
2377 {
2378 int oldval;
2379
2380 oldval = OSAddAtomic(-1, &ifa->ifa_refcnt);
2381 if (oldval >= 1 && ifa->ifa_trace != NULL)
2382 (*ifa->ifa_trace)(ifa, FALSE);
2383 if (oldval == 0) {
2384 panic("%s: ifa %p negative refcnt\n", __func__, ifa);
2385 } else if (oldval == 1) {
2386 if (ifa->ifa_debug & IFD_ATTACHED)
2387 panic("ifa %p attached to ifp is being freed\n", ifa);
2388 /*
2389 * Some interface addresses are allocated either statically
2390 * or carved out of a larger block; e.g. AppleTalk addresses.
2391 * Only free it if it was allocated via MALLOC or via the
2392 * corresponding per-address family allocator. Otherwise,
2393 * leave it alone.
2394 */
2395 if (ifa->ifa_debug & IFD_ALLOC) {
2396 if (ifa->ifa_free == NULL)
2397 FREE(ifa, M_IFADDR);
2398 else
2399 (*ifa->ifa_free)(ifa);
2400 }
2401 }
2402 }
2403
2404 void
2405 ifaref(struct ifaddr *ifa)
2406 {
2407 int oldval;
2408
2409 oldval = OSAddAtomic(1, &ifa->ifa_refcnt);
2410 if (oldval < 0)
2411 panic("%s: ifa %p negative refcnt\n", __func__, ifa);
2412 else if (ifa->ifa_trace != NULL)
2413 (*ifa->ifa_trace)(ifa, TRUE);
2414 }