if.c revision 1.77 1 /* $NetBSD: if.c,v 1.77 2000/12/13 22:06:05 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
948 IFQ_PURGE(ifq);
949 }
950
951 /*
952 * Handle interface watchdog timer routines. Called
953 * from softclock, we decrement timers (if set) and
954 * call the appropriate interface routine on expiration.
955 */
956 void
957 if_slowtimo(arg)
958 void *arg;
959 {
960 struct ifnet *ifp;
961 int s = splimp();
962
963 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
964 ifp = TAILQ_NEXT(ifp, if_list)) {
965 if (ifp->if_timer == 0 || --ifp->if_timer)
966 continue;
967 if (ifp->if_watchdog)
968 (*ifp->if_watchdog)(ifp);
969 }
970 splx(s);
971 callout_reset(&if_slowtimo_ch, hz / IFNET_SLOWHZ,
972 if_slowtimo, NULL);
973 }
974
975 /*
976 * Set/clear promiscuous mode on interface ifp based on the truth value
977 * of pswitch. The calls are reference counted so that only the first
978 * "on" request actually has an effect, as does the final "off" request.
979 * Results are undefined if the "off" and "on" requests are not matched.
980 */
981 int
982 ifpromisc(ifp, pswitch)
983 struct ifnet *ifp;
984 int pswitch;
985 {
986 int pcount, ret;
987 short flags;
988 struct ifreq ifr;
989
990 pcount = ifp->if_pcount;
991 flags = ifp->if_flags;
992 if (pswitch) {
993 /*
994 * Allow the device to be "placed" into promiscuous
995 * mode even if it is not configured up. It will
996 * consult IFF_PROMISC when it is is brought up.
997 */
998 if (ifp->if_pcount++ != 0)
999 return (0);
1000 ifp->if_flags |= IFF_PROMISC;
1001 if ((ifp->if_flags & IFF_UP) == 0)
1002 return (0);
1003 } else {
1004 if (--ifp->if_pcount > 0)
1005 return (0);
1006 ifp->if_flags &= ~IFF_PROMISC;
1007 /*
1008 * If the device is not configured up, we should not need to
1009 * turn off promiscuous mode (device should have turned it
1010 * off when interface went down; and will look at IFF_PROMISC
1011 * again next time interface comes up).
1012 */
1013 if ((ifp->if_flags & IFF_UP) == 0)
1014 return (0);
1015 }
1016 memset(&ifr, 0, sizeof(ifr));
1017 ifr.ifr_flags = ifp->if_flags;
1018 ret = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t) &ifr);
1019 /* Restore interface state if not successful. */
1020 if (ret != 0) {
1021 ifp->if_pcount = pcount;
1022 ifp->if_flags = flags;
1023 }
1024 return (ret);
1025 }
1026
1027 /*
1028 * Map interface name to
1029 * interface structure pointer.
1030 */
1031 struct ifnet *
1032 ifunit(name)
1033 const char *name;
1034 {
1035 struct ifnet *ifp;
1036
1037 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
1038 ifp = TAILQ_NEXT(ifp, if_list)) {
1039 if (ifp->if_output == if_nulloutput)
1040 continue;
1041 if (strcmp(ifp->if_xname, name) == 0)
1042 return (ifp);
1043 }
1044 return (NULL);
1045 }
1046
1047 /*
1048 * Interface ioctls.
1049 */
1050 int
1051 ifioctl(so, cmd, data, p)
1052 struct socket *so;
1053 u_long cmd;
1054 caddr_t data;
1055 struct proc *p;
1056 {
1057 struct ifnet *ifp;
1058 struct ifreq *ifr;
1059 int error = 0;
1060 short oif_flags;
1061
1062 switch (cmd) {
1063
1064 case SIOCGIFCONF:
1065 case OSIOCGIFCONF:
1066 return (ifconf(cmd, data));
1067 }
1068 ifr = (struct ifreq *)data;
1069
1070 switch (cmd) {
1071 case SIOCIFCREATE:
1072 case SIOCIFDESTROY:
1073 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1074 return (error);
1075 return ((cmd == SIOCIFCREATE) ?
1076 if_clone_create(ifr->ifr_name) :
1077 if_clone_destroy(ifr->ifr_name));
1078
1079 case SIOCIFGCLONERS:
1080 return (if_clone_list((struct if_clonereq *)data));
1081 }
1082
1083 ifp = ifunit(ifr->ifr_name);
1084 if (ifp == 0)
1085 return (ENXIO);
1086 oif_flags = ifp->if_flags;
1087 switch (cmd) {
1088
1089 case SIOCGIFFLAGS:
1090 ifr->ifr_flags = ifp->if_flags;
1091 break;
1092
1093 case SIOCGIFMETRIC:
1094 ifr->ifr_metric = ifp->if_metric;
1095 break;
1096
1097 case SIOCGIFMTU:
1098 ifr->ifr_mtu = ifp->if_mtu;
1099 break;
1100
1101 case SIOCSIFFLAGS:
1102 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1103 return (error);
1104 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
1105 int s = splimp();
1106 if_down(ifp);
1107 splx(s);
1108 }
1109 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
1110 int s = splimp();
1111 if_up(ifp);
1112 splx(s);
1113 }
1114 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
1115 (ifr->ifr_flags &~ IFF_CANTCHANGE);
1116 if (ifp->if_ioctl)
1117 (void) (*ifp->if_ioctl)(ifp, cmd, data);
1118 break;
1119
1120 case SIOCSIFMETRIC:
1121 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1122 return (error);
1123 ifp->if_metric = ifr->ifr_metric;
1124 break;
1125
1126 case SIOCSIFMTU:
1127 {
1128 u_long oldmtu = ifp->if_mtu;
1129
1130 error = suser(p->p_ucred, &p->p_acflag);
1131 if (error)
1132 return (error);
1133 if (ifp->if_ioctl == NULL)
1134 return (EOPNOTSUPP);
1135 error = (*ifp->if_ioctl)(ifp, cmd, data);
1136
1137 /*
1138 * If the link MTU changed, do network layer specific procedure.
1139 */
1140 if (ifp->if_mtu != oldmtu) {
1141 #ifdef INET6
1142 nd6_setmtu(ifp);
1143 #endif
1144 }
1145 break;
1146 }
1147 case SIOCSIFPHYADDR:
1148 case SIOCDIFPHYADDR:
1149 #ifdef INET6
1150 case SIOCSIFPHYADDR_IN6:
1151 #endif
1152 case SIOCADDMULTI:
1153 case SIOCDELMULTI:
1154 case SIOCSIFMEDIA:
1155 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1156 return (error);
1157 /* FALLTHROUGH */
1158 case SIOCGIFPSRCADDR:
1159 case SIOCGIFPDSTADDR:
1160 case SIOCGIFMEDIA:
1161 if (ifp->if_ioctl == 0)
1162 return (EOPNOTSUPP);
1163 error = (*ifp->if_ioctl)(ifp, cmd, data);
1164 break;
1165
1166 case SIOCSDRVSPEC:
1167 case SIOCS80211NWID:
1168 case SIOCS80211NWKEY:
1169 case SIOCS80211POWER:
1170 /* XXX: need to pass proc pointer through to driver... */
1171 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
1172 return (error);
1173 /* FALLTHROUGH */
1174 default:
1175 if (so->so_proto == 0)
1176 return (EOPNOTSUPP);
1177 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4)
1178 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1179 (struct mbuf *)cmd, (struct mbuf *)data,
1180 (struct mbuf *)ifp, p));
1181 #else
1182 {
1183 int ocmd = cmd;
1184
1185 switch (cmd) {
1186
1187 case SIOCSIFADDR:
1188 case SIOCSIFDSTADDR:
1189 case SIOCSIFBRDADDR:
1190 case SIOCSIFNETMASK:
1191 #if BYTE_ORDER != BIG_ENDIAN
1192 if (ifr->ifr_addr.sa_family == 0 &&
1193 ifr->ifr_addr.sa_len < 16) {
1194 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
1195 ifr->ifr_addr.sa_len = 16;
1196 }
1197 #else
1198 if (ifr->ifr_addr.sa_len == 0)
1199 ifr->ifr_addr.sa_len = 16;
1200 #endif
1201 break;
1202
1203 case OSIOCGIFADDR:
1204 cmd = SIOCGIFADDR;
1205 break;
1206
1207 case OSIOCGIFDSTADDR:
1208 cmd = SIOCGIFDSTADDR;
1209 break;
1210
1211 case OSIOCGIFBRDADDR:
1212 cmd = SIOCGIFBRDADDR;
1213 break;
1214
1215 case OSIOCGIFNETMASK:
1216 cmd = SIOCGIFNETMASK;
1217 }
1218
1219 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1220 (struct mbuf *)cmd, (struct mbuf *)data,
1221 (struct mbuf *)ifp, p));
1222
1223 switch (ocmd) {
1224 case OSIOCGIFADDR:
1225 case OSIOCGIFDSTADDR:
1226 case OSIOCGIFBRDADDR:
1227 case OSIOCGIFNETMASK:
1228 *(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
1229 }
1230 }
1231 #endif /* COMPAT_43 */
1232 break;
1233 }
1234
1235 if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
1236 #ifdef INET6
1237 if ((ifp->if_flags & IFF_UP) != 0) {
1238 int s = splimp();
1239 in6_if_up(ifp);
1240 splx(s);
1241 }
1242 #endif
1243 }
1244
1245 return (error);
1246 }
1247
1248 /*
1249 * Return interface configuration
1250 * of system. List may be used
1251 * in later ioctl's (above) to get
1252 * other information.
1253 */
1254 /*ARGSUSED*/
1255 int
1256 ifconf(cmd, data)
1257 u_long cmd;
1258 caddr_t data;
1259 {
1260 struct ifconf *ifc = (struct ifconf *)data;
1261 struct ifnet *ifp;
1262 struct ifaddr *ifa;
1263 struct ifreq ifr, *ifrp;
1264 int space = ifc->ifc_len, error = 0;
1265
1266 ifrp = ifc->ifc_req;
1267 for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {
1268 bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
1269 if ((ifa = ifp->if_addrlist.tqh_first) == 0) {
1270 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
1271 if (space >= (int)sizeof (ifr)) {
1272 error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1273 sizeof(ifr));
1274 if (error)
1275 break;
1276 }
1277 space -= sizeof (ifr), ifrp++;
1278 } else
1279 for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
1280 struct sockaddr *sa = ifa->ifa_addr;
1281 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
1282 if (cmd == OSIOCGIFCONF) {
1283 struct osockaddr *osa =
1284 (struct osockaddr *)&ifr.ifr_addr;
1285 ifr.ifr_addr = *sa;
1286 osa->sa_family = sa->sa_family;
1287 if (space >= (int)sizeof (ifr)) {
1288 error = copyout((caddr_t)&ifr,
1289 (caddr_t)ifrp,
1290 sizeof (ifr));
1291 ifrp++;
1292 }
1293 } else
1294 #endif
1295 if (sa->sa_len <= sizeof(*sa)) {
1296 ifr.ifr_addr = *sa;
1297 if (space >= (int)sizeof (ifr)) {
1298 error = copyout((caddr_t)&ifr,
1299 (caddr_t)ifrp,
1300 sizeof (ifr));
1301 ifrp++;
1302 }
1303 } else {
1304 space -= sa->sa_len - sizeof(*sa);
1305 if (space >= (int)sizeof (ifr)) {
1306 error = copyout((caddr_t)&ifr,
1307 (caddr_t)ifrp,
1308 sizeof (ifr.ifr_name));
1309 if (error == 0) {
1310 error = copyout((caddr_t)sa,
1311 (caddr_t)&ifrp->ifr_addr,
1312 sa->sa_len);
1313 }
1314 ifrp = (struct ifreq *)
1315 (sa->sa_len +
1316 (caddr_t)&ifrp->ifr_addr);
1317 }
1318 }
1319 if (error)
1320 break;
1321 space -= sizeof (ifr);
1322 }
1323 }
1324 ifc->ifc_len -= space;
1325 return (error);
1326 }
1327