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