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