if.c revision 1.71 1 /* $NetBSD: if.c,v 1.71 2000/10/01 23:16:07 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by William Studnemund and Jason R. Thorpe.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
41 * All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. Neither the name of the project nor the names of its contributors
52 * may be used to endorse or promote products derived from this software
53 * without specific prior written permission.
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * SUCH DAMAGE.
66 */
67
68 /*
69 * Copyright (c) 1980, 1986, 1993
70 * The Regents of the University of California. All rights reserved.
71 *
72 * Redistribution and use in source and binary forms, with or without
73 * modification, are permitted provided that the following conditions
74 * are met:
75 * 1. Redistributions of source code must retain the above copyright
76 * notice, this list of conditions and the following disclaimer.
77 * 2. Redistributions in binary form must reproduce the above copyright
78 * notice, this list of conditions and the following disclaimer in the
79 * documentation and/or other materials provided with the distribution.
80 * 3. All advertising materials mentioning features or use of this software
81 * must display the following acknowledgement:
82 * This product includes software developed by the University of
83 * California, Berkeley and its contributors.
84 * 4. Neither the name of the University nor the names of its contributors
85 * may be used to endorse or promote products derived from this software
86 * without specific prior written permission.
87 *
88 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
89 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
91 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
92 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
93 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
94 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
98 * SUCH DAMAGE.
99 *
100 * @(#)if.c 8.5 (Berkeley) 1/9/95
101 */
102
103 #include "opt_inet.h"
104
105 #include "opt_compat_linux.h"
106 #include "opt_compat_svr4.h"
107 #include "opt_compat_43.h"
108 #include "opt_atalk.h"
109
110 #include <sys/param.h>
111 #include <sys/mbuf.h>
112 #include <sys/systm.h>
113 #include <sys/callout.h>
114 #include <sys/proc.h>
115 #include <sys/socket.h>
116 #include <sys/socketvar.h>
117 #include <sys/domain.h>
118 #include <sys/protosw.h>
119 #include <sys/kernel.h>
120 #include <sys/ioctl.h>
121
122 #include <net/if.h>
123 #include <net/if_dl.h>
124 #include <net/if_ether.h>
125 #include <net/if_ieee80211.h>
126 #include <net/if_types.h>
127 #include <net/radix.h>
128 #include <net/route.h>
129 #ifdef NETATALK
130 #include <netatalk/at_extern.h>
131 #include <netatalk/at.h>
132 #endif
133
134 #ifdef INET6
135 /*XXX*/
136 #include <netinet/in.h>
137 #endif
138
139 int ifqmaxlen = IFQ_MAXLEN;
140 struct callout if_slowtimo_ch;
141
142 #ifdef INET6
143 /*
144 * XXX: declare here to avoid to include many inet6 related files..
145 * should be more generalized?
146 */
147 extern void nd6_setmtu __P((struct ifnet *));
148 #endif
149
150 int if_rt_walktree __P((struct radix_node *, void *));
151
152 struct if_clone *if_clone_lookup __P((const char *, int *));
153 int if_clone_list __P((struct if_clonereq *));
154
155 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
156 int if_cloners_count;
157
158 /*
159 * Network interface utility routines.
160 *
161 * Routines with ifa_ifwith* names take sockaddr *'s as
162 * parameters.
163 */
164 void
165 ifinit()
166 {
167
168 callout_init(&if_slowtimo_ch);
169 if_slowtimo(NULL);
170 }
171
172 /*
173 * Null routines used while an interface is going away. These routines
174 * just return an error.
175 */
176
177 int
178 if_nulloutput(ifp, m, so, rt)
179 struct ifnet *ifp;
180 struct mbuf *m;
181 struct sockaddr *so;
182 struct rtentry *rt;
183 {
184
185 return (ENXIO);
186 }
187
188 void
189 if_nullinput(ifp, m)
190 struct ifnet *ifp;
191 struct mbuf *m;
192 {
193
194 /* Nothing. */
195 }
196
197 void
198 if_nullstart(ifp)
199 struct ifnet *ifp;
200 {
201
202 /* Nothing. */
203 }
204
205 int
206 if_nullioctl(ifp, cmd, data)
207 struct ifnet *ifp;
208 u_long cmd;
209 caddr_t data;
210 {
211
212 return (ENXIO);
213 }
214
215 int
216 if_nullreset(ifp)
217 struct ifnet *ifp;
218 {
219
220 return (ENXIO);
221 }
222
223 void
224 if_nullwatchdog(ifp)
225 struct ifnet *ifp;
226 {
227
228 /* Nothing. */
229 }
230
231 void
232 if_nulldrain(ifp)
233 struct ifnet *ifp;
234 {
235
236 /* Nothing. */
237 }
238
239 int if_index = 0;
240 struct ifaddr **ifnet_addrs = NULL;
241 struct ifnet **ifindex2ifnet = NULL;
242
243 /*
244 * Attach an interface to the
245 * list of "active" interfaces.
246 */
247 void
248 if_attach(ifp)
249 struct ifnet *ifp;
250 {
251 unsigned socksize, ifasize;
252 int namelen, masklen;
253 struct sockaddr_dl *sdl;
254 struct ifaddr *ifa;
255 static size_t if_indexlim = 8;
256
257 if (if_index == 0)
258 TAILQ_INIT(&ifnet);
259 TAILQ_INIT(&ifp->if_addrlist);
260 TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
261 ifp->if_index = ++if_index;
262
263 /*
264 * We have some arrays that should be indexed by if_index.
265 * since if_index will grow dynamically, they should grow too.
266 * struct ifadd **ifnet_addrs
267 * struct ifnet **ifindex2ifnet
268 */
269 if (ifnet_addrs == 0 || ifindex2ifnet == 0 ||
270 ifp->if_index >= if_indexlim) {
271 size_t n;
272 caddr_t q;
273
274 while (ifp->if_index >= if_indexlim)
275 if_indexlim <<= 1;
276
277 /* grow ifnet_addrs */
278 n = if_indexlim * sizeof(ifa);
279 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
280 bzero(q, n);
281 if (ifnet_addrs) {
282 bcopy((caddr_t)ifnet_addrs, q, n/2);
283 free((caddr_t)ifnet_addrs, M_IFADDR);
284 }
285 ifnet_addrs = (struct ifaddr **)q;
286
287 /* grow ifindex2ifnet */
288 n = if_indexlim * sizeof(struct ifnet *);
289 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
290 bzero(q, n);
291 if (ifindex2ifnet) {
292 bcopy((caddr_t)ifindex2ifnet, q, n/2);
293 free((caddr_t)ifindex2ifnet, M_IFADDR);
294 }
295 ifindex2ifnet = (struct ifnet **)q;
296 }
297
298 ifindex2ifnet[ifp->if_index] = ifp;
299
300 /*
301 * create a Link Level name for this device
302 */
303 namelen = strlen(ifp->if_xname);
304 masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
305 socksize = masklen + ifp->if_addrlen;
306 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
307 if (socksize < sizeof(*sdl))
308 socksize = sizeof(*sdl);
309 socksize = ROUNDUP(socksize);
310 ifasize = sizeof(*ifa) + 2 * socksize;
311 ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
312 bzero((caddr_t)ifa, ifasize);
313 sdl = (struct sockaddr_dl *)(ifa + 1);
314 sdl->sdl_len = socksize;
315 sdl->sdl_family = AF_LINK;
316 bcopy(ifp->if_xname, sdl->sdl_data, namelen);
317 sdl->sdl_nlen = namelen;
318 sdl->sdl_index = ifp->if_index;
319 sdl->sdl_type = ifp->if_type;
320 ifnet_addrs[ifp->if_index] = ifa;
321 IFAREF(ifa);
322 ifa->ifa_ifp = ifp;
323 ifa->ifa_rtrequest = link_rtrequest;
324 TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list);
325 IFAREF(ifa);
326 ifa->ifa_addr = (struct sockaddr *)sdl;
327 ifp->if_sadl = sdl;
328 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
329 ifa->ifa_netmask = (struct sockaddr *)sdl;
330 sdl->sdl_len = masklen;
331 while (namelen != 0)
332 sdl->sdl_data[--namelen] = 0xff;
333 if (ifp->if_snd.ifq_maxlen == 0)
334 ifp->if_snd.ifq_maxlen = ifqmaxlen;
335 ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */
336
337 ifp->if_link_state = LINK_STATE_UNKNOWN;
338
339 /* Announce the interface. */
340 rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
341 }
342
343 /*
344 * Deactivate an interface. This points all of the procedure
345 * handles at error stubs. May be called from interrupt context.
346 */
347 void
348 if_deactivate(ifp)
349 struct ifnet *ifp;
350 {
351 int s;
352
353 s = splimp();
354
355 ifp->if_output = if_nulloutput;
356 ifp->if_input = if_nullinput;
357 ifp->if_start = if_nullstart;
358 ifp->if_ioctl = if_nullioctl;
359 ifp->if_reset = if_nullreset;
360 ifp->if_watchdog = if_nullwatchdog;
361 ifp->if_drain = if_nulldrain;
362
363 /* No more packets may be enqueued. */
364 ifp->if_snd.ifq_maxlen = 0;
365
366 splx(s);
367 }
368
369 /*
370 * Detach an interface from the list of "active" interfaces,
371 * freeing any resources as we go along.
372 *
373 * NOTE: This routine must be called with a valid thread context,
374 * as it may block.
375 */
376 void
377 if_detach(ifp)
378 struct ifnet *ifp;
379 {
380 struct socket so;
381 struct ifaddr *ifa;
382 #ifdef IFAREF_DEBUG
383 struct ifaddr *last_ifa = NULL;
384 #endif
385 struct domain *dp;
386 struct protosw *pr;
387 struct radix_node_head *rnh;
388 int s, i, family, purged;
389
390 /*
391 * XXX It's kind of lame that we have to have the
392 * XXX socket structure...
393 */
394 memset(&so, 0, sizeof(so));
395
396 s = splimp();
397
398 /*
399 * Do an if_down() to give protocols a chance to do something.
400 */
401 if_down(ifp);
402
403 /*
404 * Rip all the addresses off the interface. This should make
405 * all of the routes go away.
406 */
407 while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) {
408 family = ifa->ifa_addr->sa_family;
409 #ifdef IFAREF_DEBUG
410 printf("if_detach: ifaddr %p, family %d, refcnt %d\n",
411 ifa, family, ifa->ifa_refcnt);
412 if (last_ifa != NULL && ifa == last_ifa)
413 panic("if_detach: loop detected");
414 last_ifa = ifa;
415 #endif
416 if (family == AF_LINK) {
417 rtinit(ifa, RTM_DELETE, 0);
418 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
419 IFAFREE(ifa);
420 } else {
421 dp = pffinddomain(family);
422 #ifdef DIAGNOSTIC
423 if (dp == NULL)
424 panic("if_detach: no domain for AF %d\n",
425 family);
426 #endif
427 purged = 0;
428 for (pr = dp->dom_protosw;
429 pr < dp->dom_protoswNPROTOSW; pr++) {
430 so.so_proto = pr;
431 if (pr->pr_usrreq != NULL) {
432 (void) (*pr->pr_usrreq)(&so,
433 PRU_PURGEIF, NULL, NULL,
434 (struct mbuf *) ifp, curproc);
435 purged = 1;
436 }
437 }
438 if (purged == 0) {
439 /*
440 * XXX What's really the best thing to do
441 * XXX here? --thorpej (at) netbsd.org
442 */
443 printf("if_detach: WARNING: AF %d not purged\n",
444 family);
445 }
446 }
447 }
448
449 /* Walk the routing table looking for straglers. */
450 for (i = 0; i <= AF_MAX; i++) {
451 if ((rnh = rt_tables[i]) != NULL)
452 (void) (*rnh->rnh_walktree)(rnh, if_rt_walktree, ifp);
453 }
454
455 IFAFREE(ifnet_addrs[ifp->if_index]);
456 ifnet_addrs[ifp->if_index] = NULL;
457
458 /* Announce that the interface is gone. */
459 rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
460
461 TAILQ_REMOVE(&ifnet, ifp, if_list);
462
463 splx(s);
464 }
465
466 /*
467 * Callback for a radix tree walk to delete all references to an
468 * ifnet.
469 */
470 int
471 if_rt_walktree(rn, v)
472 struct radix_node *rn;
473 void *v;
474 {
475 struct ifnet *ifp = (struct ifnet *)v;
476 struct rtentry *rt = (struct rtentry *)rn;
477 int error;
478
479 if (rt->rt_ifp == ifp) {
480 /* Delete the entry. */
481 error = rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway,
482 rt_mask(rt), rt->rt_flags, NULL);
483 if (error)
484 printf("%s: warning: unable to delete rtentry @ %p, "
485 "error = %d\n", ifp->if_xname, rt, error);
486 }
487 return (0);
488 }
489
490 /*
491 * Create a clone network interface.
492 */
493 int
494 if_clone_create(name)
495 const char *name;
496 {
497 struct if_clone *ifc;
498 int unit;
499
500 ifc = if_clone_lookup(name, &unit);
501 if (ifc == NULL)
502 return (EINVAL);
503
504 if (ifunit(name) != NULL)
505 return (EEXIST);
506
507 return ((*ifc->ifc_create)(ifc, unit));
508 }
509
510 /*
511 * Destroy a clone network interface.
512 */
513 int
514 if_clone_destroy(name)
515 const char *name;
516 {
517 struct if_clone *ifc;
518 struct ifnet *ifp;
519
520 ifc = if_clone_lookup(name, NULL);
521 if (ifc == NULL)
522 return (EINVAL);
523
524 ifp = ifunit(name);
525 if (ifp == NULL)
526 return (ENXIO);
527
528 if (ifc->ifc_destroy == NULL)
529 return (EOPNOTSUPP);
530
531 (*ifc->ifc_destroy)(ifp);
532 return (0);
533 }
534
535 /*
536 * Look up a network interface cloner.
537 */
538 struct if_clone *
539 if_clone_lookup(name, unitp)
540 const char *name;
541 int *unitp;
542 {
543 struct if_clone *ifc;
544 const char *cp;
545 int i;
546
547 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) {
548 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) {
549 if (ifc->ifc_name[i] != *cp)
550 goto next_ifc;
551 }
552 goto found_name;
553 next_ifc:
554 ifc = LIST_NEXT(ifc, ifc_list);
555 }
556
557 /* No match. */
558 return (NULL);
559
560 found_name:
561 for (i = 0; *cp != '\0'; cp++) {
562 if (*cp < '0' || *cp > '9') {
563 /* Bogus unit number. */
564 return (NULL);
565 }
566 i = (i * 10) + (*cp - '0');
567 }
568
569 if (unitp != NULL)
570 *unitp = i;
571 return (ifc);
572 }
573
574 /*
575 * Register a network interface cloner.
576 */
577 void
578 if_clone_attach(ifc)
579 struct if_clone *ifc;
580 {
581
582 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
583 if_cloners_count++;
584 }
585
586 /*
587 * Unregister a network interface cloner.
588 */
589 void
590 if_clone_detach(ifc)
591 struct if_clone *ifc;
592 {
593
594 LIST_REMOVE(ifc, ifc_list);
595 if_cloners_count--;
596 }
597
598 /*
599 * Provide list of interface cloners to userspace.
600 */
601 int
602 if_clone_list(ifcr)
603 struct if_clonereq *ifcr;
604 {
605 char outbuf[IFNAMSIZ], *dst;
606 struct if_clone *ifc;
607 int count, error = 0;
608
609 ifcr->ifcr_total = if_cloners_count;
610 if ((dst = ifcr->ifcr_buffer) == NULL) {
611 /* Just asking how many there are. */
612 return (0);
613 }
614
615 if (ifcr->ifcr_count < 0)
616 return (EINVAL);
617
618 count = (if_cloners_count < ifcr->ifcr_count) ?
619 if_cloners_count : ifcr->ifcr_count;
620
621 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
622 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
623 strncpy(outbuf, ifc->ifc_name, IFNAMSIZ);
624 outbuf[IFNAMSIZ - 1] = '\0'; /* sanity */
625 error = copyout(outbuf, dst, IFNAMSIZ);
626 if (error)
627 break;
628 }
629
630 return (error);
631 }
632
633 /*
634 * Locate an interface based on a complete address.
635 */
636 /*ARGSUSED*/
637 struct ifaddr *
638 ifa_ifwithaddr(addr)
639 struct sockaddr *addr;
640 {
641 struct ifnet *ifp;
642 struct ifaddr *ifa;
643
644 #define equal(a1, a2) \
645 (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
646
647 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
648 ifp = TAILQ_NEXT(ifp, if_list)) {
649 if (ifp->if_output == if_nulloutput)
650 continue;
651 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
652 ifa = TAILQ_NEXT(ifa, ifa_list)) {
653 if (ifa->ifa_addr->sa_family != addr->sa_family)
654 continue;
655 if (equal(addr, ifa->ifa_addr))
656 return (ifa);
657 if ((ifp->if_flags & IFF_BROADCAST) &&
658 ifa->ifa_broadaddr &&
659 /* IP6 doesn't have broadcast */
660 ifa->ifa_broadaddr->sa_len != 0 &&
661 equal(ifa->ifa_broadaddr, addr))
662 return (ifa);
663 }
664 }
665 return (NULL);
666 }
667
668 /*
669 * Locate the point to point interface with a given destination address.
670 */
671 /*ARGSUSED*/
672 struct ifaddr *
673 ifa_ifwithdstaddr(addr)
674 struct sockaddr *addr;
675 {
676 struct ifnet *ifp;
677 struct ifaddr *ifa;
678
679 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
680 ifp = TAILQ_NEXT(ifp, if_list)) {
681 if (ifp->if_output == if_nulloutput)
682 continue;
683 if (ifp->if_flags & IFF_POINTOPOINT) {
684 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
685 ifa = TAILQ_NEXT(ifa, ifa_list)) {
686 if (ifa->ifa_addr->sa_family !=
687 addr->sa_family ||
688 ifa->ifa_dstaddr == NULL)
689 continue;
690 if (equal(addr, ifa->ifa_dstaddr))
691 return (ifa);
692 }
693 }
694 }
695 return (NULL);
696 }
697
698 /*
699 * Find an interface on a specific network. If many, choice
700 * is most specific found.
701 */
702 struct ifaddr *
703 ifa_ifwithnet(addr)
704 struct sockaddr *addr;
705 {
706 struct ifnet *ifp;
707 struct ifaddr *ifa;
708 struct sockaddr_dl *sdl;
709 struct ifaddr *ifa_maybe = 0;
710 u_int af = addr->sa_family;
711 char *addr_data = addr->sa_data, *cplim;
712
713 if (af == AF_LINK) {
714 sdl = (struct sockaddr_dl *)addr;
715 if (sdl->sdl_index && sdl->sdl_index <= if_index &&
716 ifindex2ifnet[sdl->sdl_index]->if_output != if_nulloutput)
717 return (ifnet_addrs[sdl->sdl_index]);
718 }
719 #ifdef NETATALK
720 if (af == AF_APPLETALK) {
721 struct sockaddr_at *sat, *sat2;
722 sat = (struct sockaddr_at *)addr;
723 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
724 ifp = TAILQ_NEXT(ifp, if_list)) {
725 if (ifp->if_output == if_nulloutput)
726 continue;
727 ifa = at_ifawithnet((struct sockaddr_at *)addr, ifp);
728 if (ifa == NULL)
729 continue;
730 sat2 = (struct sockaddr_at *)ifa->ifa_addr;
731 if (sat2->sat_addr.s_net == sat->sat_addr.s_net)
732 return (ifa); /* exact match */
733 if (ifa_maybe == NULL) {
734 /* else keep the if with the rigth range */
735 ifa_maybe = ifa;
736 }
737 }
738 return (ifa_maybe);
739 }
740 #endif
741 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
742 ifp = TAILQ_NEXT(ifp, if_list)) {
743 if (ifp->if_output == if_nulloutput)
744 continue;
745 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
746 ifa = TAILQ_NEXT(ifa, ifa_list)) {
747 char *cp, *cp2, *cp3;
748
749 if (ifa->ifa_addr->sa_family != af ||
750 ifa->ifa_netmask == 0)
751 next: continue;
752 cp = addr_data;
753 cp2 = ifa->ifa_addr->sa_data;
754 cp3 = ifa->ifa_netmask->sa_data;
755 cplim = (char *)ifa->ifa_netmask +
756 ifa->ifa_netmask->sa_len;
757 while (cp3 < cplim) {
758 if ((*cp++ ^ *cp2++) & *cp3++) {
759 /* want to continue for() loop */
760 goto next;
761 }
762 }
763 if (ifa_maybe == 0 ||
764 rn_refines((caddr_t)ifa->ifa_netmask,
765 (caddr_t)ifa_maybe->ifa_netmask))
766 ifa_maybe = ifa;
767 }
768 }
769 return (ifa_maybe);
770 }
771
772 /*
773 * Find the interface of the addresss.
774 */
775 struct ifaddr *
776 ifa_ifwithladdr(addr)
777 struct sockaddr *addr;
778 {
779 struct ifaddr *ia;
780
781 if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) ||
782 (ia = ifa_ifwithnet(addr)))
783 return (ia);
784 return (NULL);
785 }
786
787 /*
788 * Find an interface using a specific address family
789 */
790 struct ifaddr *
791 ifa_ifwithaf(af)
792 int af;
793 {
794 struct ifnet *ifp;
795 struct ifaddr *ifa;
796
797 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
798 ifp = TAILQ_NEXT(ifp, if_list)) {
799 if (ifp->if_output == if_nulloutput)
800 continue;
801 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
802 ifa = TAILQ_NEXT(ifa, ifa_list)) {
803 if (ifa->ifa_addr->sa_family == af)
804 return (ifa);
805 }
806 }
807 return (NULL);
808 }
809
810 /*
811 * Find an interface address specific to an interface best matching
812 * a given address.
813 */
814 struct ifaddr *
815 ifaof_ifpforaddr(addr, ifp)
816 struct sockaddr *addr;
817 struct ifnet *ifp;
818 {
819 struct ifaddr *ifa;
820 char *cp, *cp2, *cp3;
821 char *cplim;
822 struct ifaddr *ifa_maybe = 0;
823 u_int af = addr->sa_family;
824
825 if (ifp->if_output == if_nulloutput)
826 return (NULL);
827
828 if (af >= AF_MAX)
829 return (NULL);
830
831 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
832 ifa = TAILQ_NEXT(ifa, ifa_list)) {
833 if (ifa->ifa_addr->sa_family != af)
834 continue;
835 ifa_maybe = ifa;
836 if (ifa->ifa_netmask == 0) {
837 if (equal(addr, ifa->ifa_addr) ||
838 (ifa->ifa_dstaddr &&
839 equal(addr, ifa->ifa_dstaddr)))
840 return (ifa);
841 continue;
842 }
843 cp = addr->sa_data;
844 cp2 = ifa->ifa_addr->sa_data;
845 cp3 = ifa->ifa_netmask->sa_data;
846 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
847 for (; cp3 < cplim; cp3++) {
848 if ((*cp++ ^ *cp2++) & *cp3)
849 break;
850 }
851 if (cp3 == cplim)
852 return (ifa);
853 }
854 return (ifa_maybe);
855 }
856
857 /*
858 * Default action when installing a route with a Link Level gateway.
859 * Lookup an appropriate real ifa to point to.
860 * This should be moved to /sys/net/link.c eventually.
861 */
862 void
863 link_rtrequest(cmd, rt, sa)
864 int cmd;
865 struct rtentry *rt;
866 struct sockaddr *sa;
867 {
868 struct ifaddr *ifa;
869 struct sockaddr *dst;
870 struct ifnet *ifp;
871
872 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
873 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
874 return;
875 if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
876 IFAFREE(rt->rt_ifa);
877 rt->rt_ifa = ifa;
878 IFAREF(ifa);
879 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
880 ifa->ifa_rtrequest(cmd, rt, sa);
881 }
882 }
883
884 /*
885 * Mark an interface down and notify protocols of
886 * the transition.
887 * NOTE: must be called at splsoftnet or equivalent.
888 */
889 void
890 if_down(ifp)
891 struct ifnet *ifp;
892 {
893 struct ifaddr *ifa;
894
895 ifp->if_flags &= ~IFF_UP;
896 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
897 ifa = TAILQ_NEXT(ifa, ifa_list))
898 pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
899 if_qflush(&ifp->if_snd);
900 rt_ifmsg(ifp);
901 }
902
903 /*
904 * Mark an interface up and notify protocols of
905 * the transition.
906 * NOTE: must be called at splsoftnet or equivalent.
907 */
908 void
909 if_up(ifp)
910 struct ifnet *ifp;
911 {
912 #ifdef notyet
913 struct ifaddr *ifa;
914 #endif
915
916 ifp->if_flags |= IFF_UP;
917 #ifdef notyet
918 /* this has no effect on IP, and will kill all ISO connections XXX */
919 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
920 ifa = TAILQ_NEXT(ifa, ifa_list))
921 pfctlinput(PRC_IFUP, ifa->ifa_addr);
922 #endif
923 rt_ifmsg(ifp);
924 #ifdef INET6
925 in6_if_up(ifp);
926 #endif
927 }
928
929 /*
930 * Flush an interface queue.
931 */
932 void
933 if_qflush(ifq)
934 struct ifqueue *ifq;
935 {
936 struct mbuf *m, *n;
937
938 n = ifq->ifq_head;
939 while ((m = n) != NULL) {
940 n = m->m_act;
941 m_freem(m);
942 }
943 ifq->ifq_head = 0;
944 ifq->ifq_tail = 0;
945 ifq->ifq_len = 0;
946 }
947
948 /*
949 * Handle interface watchdog timer routines. Called
950 * from softclock, we decrement timers (if set) and
951 * call the appropriate interface routine on expiration.
952 */
953 void
954 if_slowtimo(arg)
955 void *arg;
956 {
957 struct ifnet *ifp;
958 int s = splimp();
959
960 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
961 ifp = TAILQ_NEXT(ifp, if_list)) {
962 if (ifp->if_timer == 0 || --ifp->if_timer)
963 continue;
964 if (ifp->if_watchdog)
965 (*ifp->if_watchdog)(ifp);
966 }
967 splx(s);
968 callout_reset(&if_slowtimo_ch, hz / IFNET_SLOWHZ,
969 if_slowtimo, NULL);
970 }
971
972 /*
973 * Set/clear promiscuous mode on interface ifp based on the truth value
974 * of pswitch. The calls are reference counted so that only the first
975 * "on" request actually has an effect, as does the final "off" request.
976 * Results are undefined if the "off" and "on" requests are not matched.
977 */
978 int
979 ifpromisc(ifp, pswitch)
980 struct ifnet *ifp;
981 int pswitch;
982 {
983 int pcount, ret;
984 short flags;
985 struct ifreq ifr;
986
987 pcount = ifp->if_pcount;
988 flags = ifp->if_flags;
989 if (pswitch) {
990 /*
991 * Allow the device to be "placed" into promiscuous
992 * mode even if it is not configured up. It will
993 * consult IFF_PROMISC when it is is brought up.
994 */
995 if (ifp->if_pcount++ != 0)
996 return (0);
997 ifp->if_flags |= IFF_PROMISC;
998 if ((ifp->if_flags & IFF_UP) == 0)
999 return (0);
1000 } else {
1001 if (--ifp->if_pcount > 0)
1002 return (0);
1003 ifp->if_flags &= ~IFF_PROMISC;
1004 /*
1005 * If the device is not configured up, we should not need to
1006 * turn off promiscuous mode (device should have turned it
1007 * off when interface went down; and will look at IFF_PROMISC
1008 * again next time interface comes up).
1009 */
1010 if ((ifp->if_flags & IFF_UP) == 0)
1011 return (0);
1012 }
1013 memset(&ifr, 0, sizeof(ifr));
1014 ifr.ifr_flags = ifp->if_flags;
1015 ret = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t) &ifr);
1016 /* Restore interface state if not successful. */
1017 if (ret != 0) {
1018 ifp->if_pcount = pcount;
1019 ifp->if_flags = flags;
1020 }
1021 return (ret);
1022 }
1023
1024 /*
1025 * Map interface name to
1026 * interface structure pointer.
1027 */
1028 struct ifnet *
1029 ifunit(name)
1030 const char *name;
1031 {
1032 struct ifnet *ifp;
1033
1034 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
1035 ifp = TAILQ_NEXT(ifp, if_list)) {
1036 if (ifp->if_output == if_nulloutput)
1037 continue;
1038 if (strcmp(ifp->if_xname, name) == 0)
1039 return (ifp);
1040 }
1041 return (NULL);
1042 }
1043
1044 /*
1045 * Interface ioctls.
1046 */
1047 int
1048 ifioctl(so, cmd, data, p)
1049 struct socket *so;
1050 u_long cmd;
1051 caddr_t data;
1052 struct proc *p;
1053 {
1054 struct ifnet *ifp;
1055 struct ifreq *ifr;
1056 int error = 0;
1057 short oif_flags;
1058
1059 switch (cmd) {
1060
1061 case SIOCGIFCONF:
1062 case OSIOCGIFCONF:
1063 return (ifconf(cmd, data));
1064 }
1065 ifr = (struct ifreq *)data;
1066
1067 switch (cmd) {
1068 case SIOCIFCREATE:
1069 case SIOCIFDESTROY:
1070 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1071 return (error);
1072 return ((cmd == SIOCIFCREATE) ?
1073 if_clone_create(ifr->ifr_name) :
1074 if_clone_destroy(ifr->ifr_name));
1075
1076 case SIOCIFGCLONERS:
1077 return (if_clone_list((struct if_clonereq *)data));
1078 }
1079
1080 ifp = ifunit(ifr->ifr_name);
1081 if (ifp == 0)
1082 return (ENXIO);
1083 oif_flags = ifp->if_flags;
1084 switch (cmd) {
1085
1086 case SIOCGIFFLAGS:
1087 ifr->ifr_flags = ifp->if_flags;
1088 break;
1089
1090 case SIOCGIFMETRIC:
1091 ifr->ifr_metric = ifp->if_metric;
1092 break;
1093
1094 case SIOCGIFMTU:
1095 ifr->ifr_mtu = ifp->if_mtu;
1096 break;
1097
1098 case SIOCSIFFLAGS:
1099 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1100 return (error);
1101 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
1102 int s = splimp();
1103 if_down(ifp);
1104 splx(s);
1105 }
1106 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
1107 int s = splimp();
1108 if_up(ifp);
1109 splx(s);
1110 }
1111 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
1112 (ifr->ifr_flags &~ IFF_CANTCHANGE);
1113 if (ifp->if_ioctl)
1114 (void) (*ifp->if_ioctl)(ifp, cmd, data);
1115 break;
1116
1117 case SIOCSIFMETRIC:
1118 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1119 return (error);
1120 ifp->if_metric = ifr->ifr_metric;
1121 break;
1122
1123 case SIOCSIFMTU:
1124 {
1125 u_long oldmtu = ifp->if_mtu;
1126
1127 error = suser(p->p_ucred, &p->p_acflag);
1128 if (error)
1129 return (error);
1130 if (ifp->if_ioctl == NULL)
1131 return (EOPNOTSUPP);
1132 error = (*ifp->if_ioctl)(ifp, cmd, data);
1133
1134 /*
1135 * If the link MTU changed, do network layer specific procedure.
1136 */
1137 if (ifp->if_mtu != oldmtu) {
1138 #ifdef INET6
1139 nd6_setmtu(ifp);
1140 #endif
1141 }
1142 break;
1143 }
1144 case SIOCADDMULTI:
1145 case SIOCDELMULTI:
1146 case SIOCSIFMEDIA:
1147 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1148 return (error);
1149 /* FALLTHROUGH */
1150 case SIOCGIFMEDIA:
1151 if (ifp->if_ioctl == 0)
1152 return (EOPNOTSUPP);
1153 error = (*ifp->if_ioctl)(ifp, cmd, data);
1154 break;
1155
1156 case SIOCSDRVSPEC:
1157 case SIOCS80211NWID:
1158 case SIOCS80211NWKEY:
1159 /* XXX: need to pass proc pointer through to driver... */
1160 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1161 return (error);
1162 /* FALLTHROUGH */
1163 default:
1164 if (so->so_proto == 0)
1165 return (EOPNOTSUPP);
1166 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4)
1167 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1168 (struct mbuf *)cmd, (struct mbuf *)data,
1169 (struct mbuf *)ifp, p));
1170 #else
1171 {
1172 int ocmd = cmd;
1173
1174 switch (cmd) {
1175
1176 case SIOCSIFADDR:
1177 case SIOCSIFDSTADDR:
1178 case SIOCSIFBRDADDR:
1179 case SIOCSIFNETMASK:
1180 #if BYTE_ORDER != BIG_ENDIAN
1181 if (ifr->ifr_addr.sa_family == 0 &&
1182 ifr->ifr_addr.sa_len < 16) {
1183 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
1184 ifr->ifr_addr.sa_len = 16;
1185 }
1186 #else
1187 if (ifr->ifr_addr.sa_len == 0)
1188 ifr->ifr_addr.sa_len = 16;
1189 #endif
1190 break;
1191
1192 case OSIOCGIFADDR:
1193 cmd = SIOCGIFADDR;
1194 break;
1195
1196 case OSIOCGIFDSTADDR:
1197 cmd = SIOCGIFDSTADDR;
1198 break;
1199
1200 case OSIOCGIFBRDADDR:
1201 cmd = SIOCGIFBRDADDR;
1202 break;
1203
1204 case OSIOCGIFNETMASK:
1205 cmd = SIOCGIFNETMASK;
1206 }
1207
1208 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1209 (struct mbuf *)cmd, (struct mbuf *)data,
1210 (struct mbuf *)ifp, p));
1211
1212 switch (ocmd) {
1213 case OSIOCGIFADDR:
1214 case OSIOCGIFDSTADDR:
1215 case OSIOCGIFBRDADDR:
1216 case OSIOCGIFNETMASK:
1217 *(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
1218 }
1219 }
1220 #endif /* COMPAT_43 */
1221 break;
1222 }
1223
1224 if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
1225 #ifdef INET6
1226 if ((ifp->if_flags & IFF_UP) != 0) {
1227 int s = splimp();
1228 in6_if_up(ifp);
1229 splx(s);
1230 }
1231 #endif
1232 }
1233
1234 return (error);
1235 }
1236
1237 /*
1238 * Return interface configuration
1239 * of system. List may be used
1240 * in later ioctl's (above) to get
1241 * other information.
1242 */
1243 /*ARGSUSED*/
1244 int
1245 ifconf(cmd, data)
1246 u_long cmd;
1247 caddr_t data;
1248 {
1249 struct ifconf *ifc = (struct ifconf *)data;
1250 struct ifnet *ifp;
1251 struct ifaddr *ifa;
1252 struct ifreq ifr, *ifrp;
1253 int space = ifc->ifc_len, error = 0;
1254
1255 ifrp = ifc->ifc_req;
1256 for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {
1257 bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
1258 if ((ifa = ifp->if_addrlist.tqh_first) == 0) {
1259 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
1260 if (space >= (int)sizeof (ifr)) {
1261 error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1262 sizeof(ifr));
1263 if (error)
1264 break;
1265 }
1266 space -= sizeof (ifr), ifrp++;
1267 } else
1268 for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
1269 struct sockaddr *sa = ifa->ifa_addr;
1270 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
1271 if (cmd == OSIOCGIFCONF) {
1272 struct osockaddr *osa =
1273 (struct osockaddr *)&ifr.ifr_addr;
1274 ifr.ifr_addr = *sa;
1275 osa->sa_family = sa->sa_family;
1276 if (space >= (int)sizeof (ifr)) {
1277 error = copyout((caddr_t)&ifr,
1278 (caddr_t)ifrp,
1279 sizeof (ifr));
1280 ifrp++;
1281 }
1282 } else
1283 #endif
1284 if (sa->sa_len <= sizeof(*sa)) {
1285 ifr.ifr_addr = *sa;
1286 if (space >= (int)sizeof (ifr)) {
1287 error = copyout((caddr_t)&ifr,
1288 (caddr_t)ifrp,
1289 sizeof (ifr));
1290 ifrp++;
1291 }
1292 } else {
1293 space -= sa->sa_len - sizeof(*sa);
1294 if (space >= (int)sizeof (ifr)) {
1295 error = copyout((caddr_t)&ifr,
1296 (caddr_t)ifrp,
1297 sizeof (ifr.ifr_name));
1298 if (error == 0) {
1299 error = copyout((caddr_t)sa,
1300 (caddr_t)&ifrp->ifr_addr,
1301 sa->sa_len);
1302 }
1303 ifrp = (struct ifreq *)
1304 (sa->sa_len +
1305 (caddr_t)&ifrp->ifr_addr);
1306 }
1307 }
1308 if (error)
1309 break;
1310 space -= sizeof (ifr);
1311 }
1312 }
1313 ifc->ifc_len -= space;
1314 return (error);
1315 }
1316