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