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