xref: /netbsd-src/sys/net/if.c (revision 4472dbe5e3bd91ef2540bada7a7ca7384627ff9b)
1 /*	$NetBSD: if.c,v 1.62 2000/04/26 13:38:13 bouyer 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_types.h>
125 #include <net/radix.h>
126 #include <net/route.h>
127 #ifdef NETATALK
128 #include <netatalk/at_extern.h>
129 #include <netatalk/at.h>
130 #endif
131 
132 #ifdef INET6
133 /*XXX*/
134 #include <netinet/in.h>
135 #endif
136 
137 int	ifqmaxlen = IFQ_MAXLEN;
138 struct	callout if_slowtimo_ch;
139 
140 #ifdef INET6
141 /*
142  * XXX: declare here to avoid to include many inet6 related files..
143  * should be more generalized?
144  */
145 extern void nd6_setmtu __P((struct ifnet *));
146 #endif
147 
148 int	if_rt_walktree __P((struct radix_node *, void *));
149 
150 /*
151  * Network interface utility routines.
152  *
153  * Routines with ifa_ifwith* names take sockaddr *'s as
154  * parameters.
155  */
156 void
157 ifinit()
158 {
159 
160 	callout_init(&if_slowtimo_ch);
161 	if_slowtimo(NULL);
162 }
163 
164 /*
165  * Null routines used while an interface is going away.  These routines
166  * just return an error.
167  */
168 
169 int
170 if_nulloutput(ifp, m, so, rt)
171 	struct ifnet *ifp;
172 	struct mbuf *m;
173 	struct sockaddr *so;
174 	struct rtentry *rt;
175 {
176 
177 	return (ENXIO);
178 }
179 
180 void
181 if_nullinput(ifp, m)
182 	struct ifnet *ifp;
183 	struct mbuf *m;
184 {
185 
186 	/* Nothing. */
187 }
188 
189 void
190 if_nullstart(ifp)
191 	struct ifnet *ifp;
192 {
193 
194 	/* Nothing. */
195 }
196 
197 int
198 if_nullioctl(ifp, cmd, data)
199 	struct ifnet *ifp;
200 	u_long cmd;
201 	caddr_t data;
202 {
203 
204 	return (ENXIO);
205 }
206 
207 int
208 if_nullreset(ifp)
209 	struct ifnet *ifp;
210 {
211 
212 	return (ENXIO);
213 }
214 
215 void
216 if_nullwatchdog(ifp)
217 	struct ifnet *ifp;
218 {
219 
220 	/* Nothing. */
221 }
222 
223 void
224 if_nulldrain(ifp)
225 	struct ifnet *ifp;
226 {
227 
228 	/* Nothing. */
229 }
230 
231 int if_index = 0;
232 struct ifaddr **ifnet_addrs = NULL;
233 struct ifnet **ifindex2ifnet = NULL;
234 
235 /*
236  * Attach an interface to the
237  * list of "active" interfaces.
238  */
239 void
240 if_attach(ifp)
241 	struct ifnet *ifp;
242 {
243 	unsigned socksize, ifasize;
244 	int namelen, masklen;
245 	struct sockaddr_dl *sdl;
246 	struct ifaddr *ifa;
247 	static size_t if_indexlim = 8;
248 
249 	if (if_index == 0)
250 		TAILQ_INIT(&ifnet);
251 	TAILQ_INIT(&ifp->if_addrlist);
252 	TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
253 	ifp->if_index = ++if_index;
254 
255 	/*
256 	 * We have some arrays that should be indexed by if_index.
257 	 * since if_index will grow dynamically, they should grow too.
258 	 *	struct ifadd **ifnet_addrs
259 	 *	struct ifnet **ifindex2ifnet
260 	 */
261 	if (ifnet_addrs == 0 || ifindex2ifnet == 0 ||
262 	    ifp->if_index >= if_indexlim) {
263 		size_t n;
264 		caddr_t q;
265 
266 		while (ifp->if_index >= if_indexlim)
267 			if_indexlim <<= 1;
268 
269 		/* grow ifnet_addrs */
270 		n = if_indexlim * sizeof(ifa);
271 		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
272 		bzero(q, n);
273 		if (ifnet_addrs) {
274 			bcopy((caddr_t)ifnet_addrs, q, n/2);
275 			free((caddr_t)ifnet_addrs, M_IFADDR);
276 		}
277 		ifnet_addrs = (struct ifaddr **)q;
278 
279 		/* grow ifindex2ifnet */
280 		n = if_indexlim * sizeof(struct ifnet *);
281 		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
282 		bzero(q, n);
283 		if (ifindex2ifnet) {
284 			bcopy((caddr_t)ifindex2ifnet, q, n/2);
285 			free((caddr_t)ifindex2ifnet, M_IFADDR);
286 		}
287 		ifindex2ifnet = (struct ifnet **)q;
288 	}
289 
290 	ifindex2ifnet[ifp->if_index] = ifp;
291 
292 	/*
293 	 * create a Link Level name for this device
294 	 */
295 	namelen = strlen(ifp->if_xname);
296 	masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
297 	socksize = masklen + ifp->if_addrlen;
298 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
299 	if (socksize < sizeof(*sdl))
300 		socksize = sizeof(*sdl);
301 	socksize = ROUNDUP(socksize);
302 	ifasize = sizeof(*ifa) + 2 * socksize;
303 	ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
304 	bzero((caddr_t)ifa, ifasize);
305 	sdl = (struct sockaddr_dl *)(ifa + 1);
306 	sdl->sdl_len = socksize;
307 	sdl->sdl_family = AF_LINK;
308 	bcopy(ifp->if_xname, sdl->sdl_data, namelen);
309 	sdl->sdl_nlen = namelen;
310 	sdl->sdl_index = ifp->if_index;
311 	sdl->sdl_type = ifp->if_type;
312 	ifnet_addrs[ifp->if_index] = ifa;
313 	IFAREF(ifa);
314 	ifa->ifa_ifp = ifp;
315 	ifa->ifa_rtrequest = link_rtrequest;
316 	TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list);
317 	IFAREF(ifa);
318 	ifa->ifa_addr = (struct sockaddr *)sdl;
319 	ifp->if_sadl = sdl;
320 	sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
321 	ifa->ifa_netmask = (struct sockaddr *)sdl;
322 	sdl->sdl_len = masklen;
323 	while (namelen != 0)
324 		sdl->sdl_data[--namelen] = 0xff;
325 	if (ifp->if_snd.ifq_maxlen == 0)
326 	    ifp->if_snd.ifq_maxlen = ifqmaxlen;
327 	ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */
328 
329 	ifp->if_link_state = LINK_STATE_UNKNOWN;
330 
331 	/* Announce the interface. */
332 	rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
333 }
334 
335 /*
336  * Deactivate an interface.  This points all of the procedure
337  * handles at error stubs.  May be called from interrupt context.
338  */
339 void
340 if_deactivate(ifp)
341 	struct ifnet *ifp;
342 {
343 	int s;
344 
345 	s = splimp();
346 
347 	ifp->if_output	 = if_nulloutput;
348 	ifp->if_input	 = if_nullinput;
349 	ifp->if_start	 = if_nullstart;
350 	ifp->if_ioctl	 = if_nullioctl;
351 	ifp->if_reset	 = if_nullreset;
352 	ifp->if_watchdog = if_nullwatchdog;
353 	ifp->if_drain	 = if_nulldrain;
354 
355 	/* No more packets may be enqueued. */
356 	ifp->if_snd.ifq_maxlen = 0;
357 
358 	splx(s);
359 }
360 
361 /*
362  * Detach an interface from the list of "active" interfaces,
363  * freeing any resources as we go along.
364  *
365  * NOTE: This routine must be called with a valid thread context,
366  * as it may block.
367  */
368 void
369 if_detach(ifp)
370 	struct ifnet *ifp;
371 {
372 	struct socket so;
373 	struct ifaddr *ifa;
374 #ifdef IFAREF_DEBUG
375 	struct ifaddr *last_ifa = NULL;
376 #endif
377 	struct domain *dp;
378 	struct protosw *pr;
379 	struct radix_node_head *rnh;
380 	int s, i, family, purged;
381 
382 	/*
383 	 * XXX It's kind of lame that we have to have the
384 	 * XXX socket structure...
385 	 */
386 	memset(&so, 0, sizeof(so));
387 
388 	s = splimp();
389 
390 	/*
391 	 * Do an if_down() to give protocols a chance to do something.
392 	 */
393 	if_down(ifp);
394 
395 	/*
396 	 * Rip all the addresses off the interface.  This should make
397 	 * all of the routes go away.
398 	 */
399 	while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) {
400 		family = ifa->ifa_addr->sa_family;
401 #ifdef IFAREF_DEBUG
402 		printf("if_detach: ifaddr %p, family %d, refcnt %d\n",
403 		    ifa, family, ifa->ifa_refcnt);
404 		if (last_ifa != NULL && ifa == last_ifa)
405 			panic("if_detach: loop detected");
406 		last_ifa = ifa;
407 #endif
408 		if (family == AF_LINK) {
409 			rtinit(ifa, RTM_DELETE, 0);
410 			TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
411 			IFAFREE(ifa);
412 		} else {
413 			dp = pffinddomain(family);
414 #ifdef DIAGNOSTIC
415 			if (dp == NULL)
416 				panic("if_detach: no domain for AF %d\n",
417 				    family);
418 #endif
419 			purged = 0;
420 			for (pr = dp->dom_protosw;
421 			     pr < dp->dom_protoswNPROTOSW; pr++) {
422 				so.so_proto = pr;
423 				if (pr->pr_usrreq != NULL) {
424 					(void) (*pr->pr_usrreq)(&so,
425 					    PRU_PURGEIF, NULL, NULL,
426 					    (struct mbuf *) ifp, curproc);
427 					purged = 1;
428 				}
429 			}
430 			if (purged == 0) {
431 				/*
432 				 * XXX What's really the best thing to do
433 				 * XXX here?  --thorpej@netbsd.org
434 				 */
435 				printf("if_detach: WARNING: AF %d not purged\n",
436 				    family);
437 			}
438 		}
439 	}
440 
441 	/* Walk the routing table looking for straglers. */
442 	for (i = 0; i <= AF_MAX; i++) {
443 		if ((rnh = rt_tables[i]) != NULL)
444 			(void) (*rnh->rnh_walktree)(rnh, if_rt_walktree, ifp);
445 	}
446 
447 	IFAFREE(ifnet_addrs[ifp->if_index]);
448 	ifnet_addrs[ifp->if_index] = NULL;
449 
450 	/* Announce that the interface is gone. */
451 	rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
452 
453 	TAILQ_REMOVE(&ifnet, ifp, if_list);
454 
455 	splx(s);
456 }
457 
458 /*
459  * Callback for a radix tree walk to delete all references to an
460  * ifnet.
461  */
462 int
463 if_rt_walktree(rn, v)
464 	struct radix_node *rn;
465 	void *v;
466 {
467 	struct ifnet *ifp = (struct ifnet *)v;
468 	struct rtentry *rt = (struct rtentry *)rn;
469 	int error;
470 
471 	if (rt->rt_ifp == ifp) {
472 		/* Delete the entry. */
473 		error = rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway,
474 		    rt_mask(rt), rt->rt_flags, NULL);
475 		if (error)
476 			printf("%s: warning: unable to delete rtentry @ %p, "
477 			    "error = %d\n", ifp->if_xname, rt, error);
478 	}
479 	return (0);
480 }
481 
482 /*
483  * Locate an interface based on a complete address.
484  */
485 /*ARGSUSED*/
486 struct ifaddr *
487 ifa_ifwithaddr(addr)
488 	struct sockaddr *addr;
489 {
490 	struct ifnet *ifp;
491 	struct ifaddr *ifa;
492 
493 #define	equal(a1, a2) \
494   (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
495 
496 	for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
497 	     ifp = TAILQ_NEXT(ifp, if_list)) {
498 		if (ifp->if_output == if_nulloutput)
499 			continue;
500 		for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
501 		     ifa = TAILQ_NEXT(ifa, ifa_list)) {
502 			if (ifa->ifa_addr->sa_family != addr->sa_family)
503 				continue;
504 			if (equal(addr, ifa->ifa_addr))
505 				return (ifa);
506 			if ((ifp->if_flags & IFF_BROADCAST) &&
507 			    ifa->ifa_broadaddr &&
508 			    /* IP6 doesn't have broadcast */
509 			    ifa->ifa_broadaddr->sa_len != 0 &&
510 			    equal(ifa->ifa_broadaddr, addr))
511 				return (ifa);
512 		}
513 	}
514 	return (NULL);
515 }
516 
517 /*
518  * Locate the point to point interface with a given destination address.
519  */
520 /*ARGSUSED*/
521 struct ifaddr *
522 ifa_ifwithdstaddr(addr)
523 	struct sockaddr *addr;
524 {
525 	struct ifnet *ifp;
526 	struct ifaddr *ifa;
527 
528 	for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
529 	     ifp = TAILQ_NEXT(ifp, if_list)) {
530 		if (ifp->if_output == if_nulloutput)
531 			continue;
532 		if (ifp->if_flags & IFF_POINTOPOINT) {
533 			for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
534 			     ifa = TAILQ_NEXT(ifa, ifa_list)) {
535 				if (ifa->ifa_addr->sa_family !=
536 				      addr->sa_family ||
537 				    ifa->ifa_dstaddr == NULL)
538 					continue;
539 				if (equal(addr, ifa->ifa_dstaddr))
540 					return (ifa);
541 			}
542 		}
543 	}
544 	return (NULL);
545 }
546 
547 /*
548  * Find an interface on a specific network.  If many, choice
549  * is most specific found.
550  */
551 struct ifaddr *
552 ifa_ifwithnet(addr)
553 	struct sockaddr *addr;
554 {
555 	struct ifnet *ifp;
556 	struct ifaddr *ifa;
557 	struct sockaddr_dl *sdl;
558 	struct ifaddr *ifa_maybe = 0;
559 	u_int af = addr->sa_family;
560 	char *addr_data = addr->sa_data, *cplim;
561 
562 	if (af == AF_LINK) {
563 		sdl = (struct sockaddr_dl *)addr;
564 		if (sdl->sdl_index && sdl->sdl_index <= if_index &&
565 		    ifindex2ifnet[sdl->sdl_index]->if_output != if_nulloutput)
566 			return (ifnet_addrs[sdl->sdl_index]);
567 	}
568 #ifdef NETATALK
569 	if (af == AF_APPLETALK) {
570 		struct sockaddr_at *sat, *sat2;
571 		sat = (struct sockaddr_at *)addr;
572 		for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
573 		     ifp = TAILQ_NEXT(ifp, if_list)) {
574 			if (ifp->if_output == if_nulloutput)
575 				continue;
576 			ifa = at_ifawithnet((struct sockaddr_at *)addr, ifp);
577 			if (ifa == NULL)
578 				continue;
579 			sat2 = (struct sockaddr_at *)ifa->ifa_addr;
580 			if (sat2->sat_addr.s_net == sat->sat_addr.s_net)
581 				return (ifa); /* exact match */
582 			if (ifa_maybe == NULL) {
583 				/* else keep the if with the rigth range */
584 				ifa_maybe = ifa;
585 			}
586 		}
587 		return (ifa_maybe);
588 	}
589 #endif
590 	for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
591 	     ifp = TAILQ_NEXT(ifp, if_list)) {
592 		if (ifp->if_output == if_nulloutput)
593 			continue;
594 		for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
595 		     ifa = TAILQ_NEXT(ifa, ifa_list)) {
596 			char *cp, *cp2, *cp3;
597 
598 			if (ifa->ifa_addr->sa_family != af ||
599 			    ifa->ifa_netmask == 0)
600  next:				continue;
601 			cp = addr_data;
602 			cp2 = ifa->ifa_addr->sa_data;
603 			cp3 = ifa->ifa_netmask->sa_data;
604 			cplim = (char *)ifa->ifa_netmask +
605 			    ifa->ifa_netmask->sa_len;
606 			while (cp3 < cplim) {
607 				if ((*cp++ ^ *cp2++) & *cp3++) {
608 					/* want to continue for() loop */
609 					goto next;
610 				}
611 			}
612 			if (ifa_maybe == 0 ||
613 			    rn_refines((caddr_t)ifa->ifa_netmask,
614 			    (caddr_t)ifa_maybe->ifa_netmask))
615 				ifa_maybe = ifa;
616 		}
617 	}
618 	return (ifa_maybe);
619 }
620 
621 /*
622  * Find the interface of the addresss.
623  */
624 struct ifaddr *
625 ifa_ifwithladdr(addr)
626 	struct sockaddr *addr;
627 {
628 	struct ifaddr *ia;
629 
630 	if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) ||
631 	    (ia = ifa_ifwithnet(addr)))
632 		return (ia);
633 	return (NULL);
634 }
635 
636 /*
637  * Find an interface using a specific address family
638  */
639 struct ifaddr *
640 ifa_ifwithaf(af)
641 	int af;
642 {
643 	struct ifnet *ifp;
644 	struct ifaddr *ifa;
645 
646 	for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
647 	     ifp = TAILQ_NEXT(ifp, if_list)) {
648 		if (ifp->if_output == if_nulloutput)
649 			continue;
650 		for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
651 		     ifa = TAILQ_NEXT(ifa, ifa_list)) {
652 			if (ifa->ifa_addr->sa_family == af)
653 				return (ifa);
654 		}
655 	}
656 	return (NULL);
657 }
658 
659 /*
660  * Find an interface address specific to an interface best matching
661  * a given address.
662  */
663 struct ifaddr *
664 ifaof_ifpforaddr(addr, ifp)
665 	struct sockaddr *addr;
666 	struct ifnet *ifp;
667 {
668 	struct ifaddr *ifa;
669 	char *cp, *cp2, *cp3;
670 	char *cplim;
671 	struct ifaddr *ifa_maybe = 0;
672 	u_int af = addr->sa_family;
673 
674 	if (ifp->if_output == if_nulloutput)
675 		return (NULL);
676 
677 	if (af >= AF_MAX)
678 		return (NULL);
679 
680 	for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
681 	     ifa = TAILQ_NEXT(ifa, ifa_list)) {
682 		if (ifa->ifa_addr->sa_family != af)
683 			continue;
684 		ifa_maybe = ifa;
685 		if (ifa->ifa_netmask == 0) {
686 			if (equal(addr, ifa->ifa_addr) ||
687 			    (ifa->ifa_dstaddr &&
688 			     equal(addr, ifa->ifa_dstaddr)))
689 				return (ifa);
690 			continue;
691 		}
692 		cp = addr->sa_data;
693 		cp2 = ifa->ifa_addr->sa_data;
694 		cp3 = ifa->ifa_netmask->sa_data;
695 		cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
696 		for (; cp3 < cplim; cp3++) {
697 			if ((*cp++ ^ *cp2++) & *cp3)
698 				break;
699 		}
700 		if (cp3 == cplim)
701 			return (ifa);
702 	}
703 	return (ifa_maybe);
704 }
705 
706 /*
707  * Default action when installing a route with a Link Level gateway.
708  * Lookup an appropriate real ifa to point to.
709  * This should be moved to /sys/net/link.c eventually.
710  */
711 void
712 link_rtrequest(cmd, rt, sa)
713 	int cmd;
714 	struct rtentry *rt;
715 	struct sockaddr *sa;
716 {
717 	struct ifaddr *ifa;
718 	struct sockaddr *dst;
719 	struct ifnet *ifp;
720 
721 	if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
722 	    ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
723 		return;
724 	if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
725 		IFAFREE(rt->rt_ifa);
726 		rt->rt_ifa = ifa;
727 		IFAREF(ifa);
728 		if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
729 			ifa->ifa_rtrequest(cmd, rt, sa);
730 	}
731 }
732 
733 /*
734  * Mark an interface down and notify protocols of
735  * the transition.
736  * NOTE: must be called at splsoftnet or equivalent.
737  */
738 void
739 if_down(ifp)
740 	struct ifnet *ifp;
741 {
742 	struct ifaddr *ifa;
743 
744 	ifp->if_flags &= ~IFF_UP;
745 	for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
746 	     ifa = TAILQ_NEXT(ifa, ifa_list))
747 		pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
748 	if_qflush(&ifp->if_snd);
749 	rt_ifmsg(ifp);
750 }
751 
752 /*
753  * Mark an interface up and notify protocols of
754  * the transition.
755  * NOTE: must be called at splsoftnet or equivalent.
756  */
757 void
758 if_up(ifp)
759 	struct ifnet *ifp;
760 {
761 #ifdef notyet
762 	struct ifaddr *ifa;
763 #endif
764 
765 	ifp->if_flags |= IFF_UP;
766 #ifdef notyet
767 	/* this has no effect on IP, and will kill all ISO connections XXX */
768 	for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
769 	     ifa = TAILQ_NEXT(ifa, ifa_list))
770 		pfctlinput(PRC_IFUP, ifa->ifa_addr);
771 #endif
772 	rt_ifmsg(ifp);
773 #ifdef INET6
774 	in6_if_up(ifp);
775 #endif
776 }
777 
778 /*
779  * Flush an interface queue.
780  */
781 void
782 if_qflush(ifq)
783 	struct ifqueue *ifq;
784 {
785 	struct mbuf *m, *n;
786 
787 	n = ifq->ifq_head;
788 	while ((m = n) != NULL) {
789 		n = m->m_act;
790 		m_freem(m);
791 	}
792 	ifq->ifq_head = 0;
793 	ifq->ifq_tail = 0;
794 	ifq->ifq_len = 0;
795 }
796 
797 /*
798  * Handle interface watchdog timer routines.  Called
799  * from softclock, we decrement timers (if set) and
800  * call the appropriate interface routine on expiration.
801  */
802 void
803 if_slowtimo(arg)
804 	void *arg;
805 {
806 	struct ifnet *ifp;
807 	int s = splimp();
808 
809 	for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
810 	     ifp = TAILQ_NEXT(ifp, if_list)) {
811 		if (ifp->if_timer == 0 || --ifp->if_timer)
812 			continue;
813 		if (ifp->if_watchdog)
814 			(*ifp->if_watchdog)(ifp);
815 	}
816 	splx(s);
817 	callout_reset(&if_slowtimo_ch, hz / IFNET_SLOWHZ,
818 	    if_slowtimo, NULL);
819 }
820 
821 /*
822  * Map interface name to
823  * interface structure pointer.
824  */
825 struct ifnet *
826 ifunit(name)
827 	const char *name;
828 {
829 	struct ifnet *ifp;
830 
831 	for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
832 	     ifp = TAILQ_NEXT(ifp, if_list)) {
833 		if (ifp->if_output == if_nulloutput)
834 			continue;
835 	 	if (strcmp(ifp->if_xname, name) == 0)
836 			return (ifp);
837 	}
838 	return (NULL);
839 }
840 
841 /*
842  * Interface ioctls.
843  */
844 int
845 ifioctl(so, cmd, data, p)
846 	struct socket *so;
847 	u_long cmd;
848 	caddr_t data;
849 	struct proc *p;
850 {
851 	struct ifnet *ifp;
852 	struct ifreq *ifr;
853 	int error = 0;
854 	short oif_flags;
855 
856 	switch (cmd) {
857 
858 	case SIOCGIFCONF:
859 	case OSIOCGIFCONF:
860 		return (ifconf(cmd, data));
861 	}
862 	ifr = (struct ifreq *)data;
863 	ifp = ifunit(ifr->ifr_name);
864 	if (ifp == 0)
865 		return (ENXIO);
866 	oif_flags = ifp->if_flags;
867 	switch (cmd) {
868 
869 	case SIOCGIFFLAGS:
870 		ifr->ifr_flags = ifp->if_flags;
871 		break;
872 
873 	case SIOCGIFMETRIC:
874 		ifr->ifr_metric = ifp->if_metric;
875 		break;
876 
877 	case SIOCGIFMTU:
878 		ifr->ifr_mtu = ifp->if_mtu;
879 		break;
880 
881 	case SIOCSIFFLAGS:
882 		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
883 			return (error);
884 		if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
885 			int s = splimp();
886 			if_down(ifp);
887 			splx(s);
888 		}
889 		if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
890 			int s = splimp();
891 			if_up(ifp);
892 			splx(s);
893 		}
894 		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
895 			(ifr->ifr_flags &~ IFF_CANTCHANGE);
896 		if (ifp->if_ioctl)
897 			(void) (*ifp->if_ioctl)(ifp, cmd, data);
898 		break;
899 
900 	case SIOCSIFMETRIC:
901 		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
902 			return (error);
903 		ifp->if_metric = ifr->ifr_metric;
904 		break;
905 
906 	case SIOCSIFMTU:
907 	{
908 		u_long oldmtu = ifp->if_mtu;
909 
910 		error = suser(p->p_ucred, &p->p_acflag);
911 		if (error)
912 			return (error);
913 		if (ifp->if_ioctl == NULL)
914 			return (EOPNOTSUPP);
915 		error = (*ifp->if_ioctl)(ifp, cmd, data);
916 
917 		/*
918 		 * If the link MTU changed, do network layer specific procedure.
919 		 */
920 		if (ifp->if_mtu != oldmtu) {
921 #ifdef INET6
922 			nd6_setmtu(ifp);
923 #endif
924 		}
925 		break;
926 	}
927 	case SIOCADDMULTI:
928 	case SIOCDELMULTI:
929 	case SIOCSIFMEDIA:
930 		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
931 			return (error);
932 		/* FALLTHROUGH */
933 	case SIOCGIFMEDIA:
934 		if (ifp->if_ioctl == 0)
935 			return (EOPNOTSUPP);
936 		error = (*ifp->if_ioctl)(ifp, cmd, data);
937 		break;
938 
939 	case SIOCSDRVSPEC:
940 		/* XXX:  need to pass proc pointer through to driver... */
941 		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
942 			return (error);
943 	/* FALLTHROUGH */
944 	default:
945 		if (so->so_proto == 0)
946 			return (EOPNOTSUPP);
947 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4)
948 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
949 		    (struct mbuf *)cmd, (struct mbuf *)data,
950 		    (struct mbuf *)ifp, p));
951 #else
952 	    {
953 		int ocmd = cmd;
954 
955 		switch (cmd) {
956 
957 		case SIOCSIFADDR:
958 		case SIOCSIFDSTADDR:
959 		case SIOCSIFBRDADDR:
960 		case SIOCSIFNETMASK:
961 #if BYTE_ORDER != BIG_ENDIAN
962 			if (ifr->ifr_addr.sa_family == 0 &&
963 			    ifr->ifr_addr.sa_len < 16) {
964 				ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
965 				ifr->ifr_addr.sa_len = 16;
966 			}
967 #else
968 			if (ifr->ifr_addr.sa_len == 0)
969 				ifr->ifr_addr.sa_len = 16;
970 #endif
971 			break;
972 
973 		case OSIOCGIFADDR:
974 			cmd = SIOCGIFADDR;
975 			break;
976 
977 		case OSIOCGIFDSTADDR:
978 			cmd = SIOCGIFDSTADDR;
979 			break;
980 
981 		case OSIOCGIFBRDADDR:
982 			cmd = SIOCGIFBRDADDR;
983 			break;
984 
985 		case OSIOCGIFNETMASK:
986 			cmd = SIOCGIFNETMASK;
987 		}
988 
989 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
990 		    (struct mbuf *)cmd, (struct mbuf *)data,
991 		    (struct mbuf *)ifp, p));
992 
993 		switch (ocmd) {
994 		case OSIOCGIFADDR:
995 		case OSIOCGIFDSTADDR:
996 		case OSIOCGIFBRDADDR:
997 		case OSIOCGIFNETMASK:
998 			*(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
999 		}
1000 	    }
1001 #endif /* COMPAT_43 */
1002 		break;
1003 	}
1004 
1005 	if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
1006 #ifdef INET6
1007 		if ((ifp->if_flags & IFF_UP) != 0) {
1008 			int s = splimp();
1009 			in6_if_up(ifp);
1010 			splx(s);
1011 		}
1012 #endif
1013 	}
1014 
1015 	return (error);
1016 }
1017 
1018 /*
1019  * Return interface configuration
1020  * of system.  List may be used
1021  * in later ioctl's (above) to get
1022  * other information.
1023  */
1024 /*ARGSUSED*/
1025 int
1026 ifconf(cmd, data)
1027 	u_long cmd;
1028 	caddr_t data;
1029 {
1030 	struct ifconf *ifc = (struct ifconf *)data;
1031 	struct ifnet *ifp;
1032 	struct ifaddr *ifa;
1033 	struct ifreq ifr, *ifrp;
1034 	int space = ifc->ifc_len, error = 0;
1035 
1036 	ifrp = ifc->ifc_req;
1037 	for (ifp = ifnet.tqh_first;
1038 	    space >= sizeof (ifr) && ifp != 0; ifp = ifp->if_list.tqe_next) {
1039 		bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
1040 		if ((ifa = ifp->if_addrlist.tqh_first) == 0) {
1041 			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
1042 			error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1043 			    sizeof(ifr));
1044 			if (error)
1045 				break;
1046 			space -= sizeof (ifr), ifrp++;
1047 		} else
1048 		    for (; space >= sizeof (ifr) && ifa != 0; ifa = ifa->ifa_list.tqe_next) {
1049 			struct sockaddr *sa = ifa->ifa_addr;
1050 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
1051 			if (cmd == OSIOCGIFCONF) {
1052 				struct osockaddr *osa =
1053 					 (struct osockaddr *)&ifr.ifr_addr;
1054 				ifr.ifr_addr = *sa;
1055 				osa->sa_family = sa->sa_family;
1056 				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1057 						sizeof (ifr));
1058 				ifrp++;
1059 			} else
1060 #endif
1061 			if (sa->sa_len <= sizeof(*sa)) {
1062 				ifr.ifr_addr = *sa;
1063 				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1064 						sizeof (ifr));
1065 				ifrp++;
1066 			} else {
1067 				space -= sa->sa_len - sizeof(*sa);
1068 				if (space < sizeof (ifr))
1069 					break;
1070 				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1071 						sizeof (ifr.ifr_name));
1072 				if (error == 0)
1073 				    error = copyout((caddr_t)sa,
1074 				      (caddr_t)&ifrp->ifr_addr, sa->sa_len);
1075 				ifrp = (struct ifreq *)
1076 					(sa->sa_len + (caddr_t)&ifrp->ifr_addr);
1077 			}
1078 			if (error)
1079 				break;
1080 			space -= sizeof (ifr);
1081 		}
1082 	}
1083 	ifc->ifc_len -= space;
1084 	return (error);
1085 }
1086