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