if.c revision 30354
1/*
2 * Copyright (c) 1980, 1986, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *	@(#)if.c	8.3 (Berkeley) 1/4/94
34 *	$Id: if.c,v 1.54 1997/10/07 07:40:35 joerg Exp $
35 */
36
37#include <sys/param.h>
38#include <sys/queue.h>
39#include <sys/malloc.h>
40#include <sys/mbuf.h>
41#include <sys/systm.h>
42#include <sys/proc.h>
43#include <sys/socket.h>
44#include <sys/socketvar.h>
45#include <sys/protosw.h>
46#include <sys/kernel.h>
47#include <sys/sockio.h>
48#include <sys/errno.h>
49#include <sys/syslog.h>
50#include <sys/sysctl.h>
51
52#include <net/if.h>
53#include <net/if_dl.h>
54#include <net/if_types.h>
55#include <net/radix.h>
56
57/*
58 * System initialization
59 */
60
61static int ifconf __P((int, caddr_t));
62static void ifinit __P((void *));
63static void if_qflush __P((struct ifqueue *));
64static void if_slowtimo __P((void *));
65static void link_rtrequest __P((int, struct rtentry *, struct sockaddr *));
66
67SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL)
68
69MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
70MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
71
72int	ifqmaxlen = IFQ_MAXLEN;
73struct	ifnethead ifnet;	/* depend on static init XXX */
74
75/*
76 * Network interface utility routines.
77 *
78 * Routines with ifa_ifwith* names take sockaddr *'s as
79 * parameters.
80 *
81 * This routine assumes that it will be called at splimp() or higher.
82 */
83/* ARGSUSED*/
84void
85ifinit(dummy)
86	void *dummy;
87{
88	register struct ifnet *ifp;
89
90	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
91		if (ifp->if_snd.ifq_maxlen == 0)
92			ifp->if_snd.ifq_maxlen = ifqmaxlen;
93	if_slowtimo(0);
94}
95
96int if_index = 0;
97struct ifaddr **ifnet_addrs;
98
99
100/*
101 * Attach an interface to the
102 * list of "active" interfaces.
103 */
104void
105if_attach(ifp)
106	struct ifnet *ifp;
107{
108	unsigned socksize, ifasize;
109	int namelen, masklen;
110	char workbuf[64];
111	register struct sockaddr_dl *sdl;
112	register struct ifaddr *ifa;
113	static int if_indexlim = 8;
114	static int inited;
115
116	if (!inited) {
117		TAILQ_INIT(&ifnet);
118		inited = 1;
119	}
120
121	TAILQ_INSERT_TAIL(&ifnet, ifp, if_link);
122	ifp->if_index = ++if_index;
123	/*
124	 * XXX -
125	 * The old code would work if the interface passed a pre-existing
126	 * chain of ifaddrs to this code.  We don't trust our callers to
127	 * properly initialize the tailq, however, so we no longer allow
128	 * this unlikely case.
129	 */
130	TAILQ_INIT(&ifp->if_addrhead);
131	LIST_INIT(&ifp->if_multiaddrs);
132	microtime(&ifp->if_lastchange);
133	if (ifnet_addrs == 0 || if_index >= if_indexlim) {
134		unsigned n = (if_indexlim <<= 1) * sizeof(ifa);
135		struct ifaddr **q = (struct ifaddr **)
136					malloc(n, M_IFADDR, M_WAITOK);
137		bzero((caddr_t)q, n);
138		if (ifnet_addrs) {
139			bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2);
140			free((caddr_t)ifnet_addrs, M_IFADDR);
141		}
142		ifnet_addrs = q;
143	}
144	/*
145	 * create a Link Level name for this device
146	 */
147	namelen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit);
148#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
149	masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
150	socksize = masklen + ifp->if_addrlen;
151#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
152	socksize = ROUNDUP(socksize);
153	if (socksize < sizeof(*sdl))
154		socksize = sizeof(*sdl);
155	ifasize = sizeof(*ifa) + 2 * socksize;
156	ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
157	if (ifa) {
158		bzero((caddr_t)ifa, ifasize);
159		sdl = (struct sockaddr_dl *)(ifa + 1);
160		sdl->sdl_len = socksize;
161		sdl->sdl_family = AF_LINK;
162		bcopy(workbuf, sdl->sdl_data, namelen);
163		sdl->sdl_nlen = namelen;
164		sdl->sdl_index = ifp->if_index;
165		sdl->sdl_type = ifp->if_type;
166		ifnet_addrs[if_index - 1] = ifa;
167		ifa->ifa_ifp = ifp;
168		ifa->ifa_rtrequest = link_rtrequest;
169		ifa->ifa_addr = (struct sockaddr *)sdl;
170		sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
171		ifa->ifa_netmask = (struct sockaddr *)sdl;
172		sdl->sdl_len = masklen;
173		while (namelen != 0)
174			sdl->sdl_data[--namelen] = 0xff;
175		TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
176	}
177}
178/*
179 * Locate an interface based on a complete address.
180 */
181/*ARGSUSED*/
182struct ifaddr *
183ifa_ifwithaddr(addr)
184	register struct sockaddr *addr;
185{
186	register struct ifnet *ifp;
187	register struct ifaddr *ifa;
188
189#define	equal(a1, a2) \
190  (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
191	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
192	    for (ifa = ifp->if_addrhead.tqh_first; ifa;
193		 ifa = ifa->ifa_link.tqe_next) {
194		if (ifa->ifa_addr->sa_family != addr->sa_family)
195			continue;
196		if (equal(addr, ifa->ifa_addr))
197			return (ifa);
198		if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
199		    equal(ifa->ifa_broadaddr, addr))
200			return (ifa);
201	}
202	return ((struct ifaddr *)0);
203}
204/*
205 * Locate the point to point interface with a given destination address.
206 */
207/*ARGSUSED*/
208struct ifaddr *
209ifa_ifwithdstaddr(addr)
210	register struct sockaddr *addr;
211{
212	register struct ifnet *ifp;
213	register struct ifaddr *ifa;
214
215	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
216	    if (ifp->if_flags & IFF_POINTOPOINT)
217		for (ifa = ifp->if_addrhead.tqh_first; ifa;
218		     ifa = ifa->ifa_link.tqe_next) {
219			if (ifa->ifa_addr->sa_family != addr->sa_family)
220				continue;
221			if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))
222				return (ifa);
223	}
224	return ((struct ifaddr *)0);
225}
226
227/*
228 * Find an interface on a specific network.  If many, choice
229 * is most specific found.
230 */
231struct ifaddr *
232ifa_ifwithnet(addr)
233	struct sockaddr *addr;
234{
235	register struct ifnet *ifp;
236	register struct ifaddr *ifa;
237	struct ifaddr *ifa_maybe = (struct ifaddr *) 0;
238	u_int af = addr->sa_family;
239	char *addr_data = addr->sa_data, *cplim;
240
241	/*
242	 * AF_LINK addresses can be looked up directly by their index number,
243	 * so do that if we can.
244	 */
245	if (af == AF_LINK) {
246	    register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
247	    if (sdl->sdl_index && sdl->sdl_index <= if_index)
248		return (ifnet_addrs[sdl->sdl_index - 1]);
249	}
250
251	/*
252	 * Scan though each interface, looking for ones that have
253	 * addresses in this address family.
254	 */
255	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
256		for (ifa = ifp->if_addrhead.tqh_first; ifa;
257		     ifa = ifa->ifa_link.tqe_next) {
258			register char *cp, *cp2, *cp3;
259
260			if (ifa->ifa_addr->sa_family != af)
261next:				continue;
262			if (ifp->if_flags & IFF_POINTOPOINT) {
263				/*
264				 * This is a bit broken as it doesn't
265				 * take into account that the remote end may
266				 * be a single node in the network we are
267				 * looking for.
268				 * The trouble is that we don't know the
269				 * netmask for the remote end.
270				 */
271				if (ifa->ifa_dstaddr != 0
272				    && equal(addr, ifa->ifa_dstaddr))
273 					return (ifa);
274			} else {
275				/*
276				 * if we have a special address handler,
277				 * then use it instead of the generic one.
278				 */
279	          		if (ifa->ifa_claim_addr) {
280					if ((*ifa->ifa_claim_addr)(ifa, addr)) {
281						return (ifa);
282					} else {
283						continue;
284					}
285				}
286
287				/*
288				 * Scan all the bits in the ifa's address.
289				 * If a bit dissagrees with what we are
290				 * looking for, mask it with the netmask
291				 * to see if it really matters.
292				 * (A byte at a time)
293				 */
294				if (ifa->ifa_netmask == 0)
295					continue;
296				cp = addr_data;
297				cp2 = ifa->ifa_addr->sa_data;
298				cp3 = ifa->ifa_netmask->sa_data;
299				cplim = ifa->ifa_netmask->sa_len
300					+ (char *)ifa->ifa_netmask;
301				while (cp3 < cplim)
302					if ((*cp++ ^ *cp2++) & *cp3++)
303						goto next; /* next address! */
304				/*
305				 * If the netmask of what we just found
306				 * is more specific than what we had before
307				 * (if we had one) then remember the new one
308				 * before continuing to search
309				 * for an even better one.
310				 */
311				if (ifa_maybe == 0 ||
312				    rn_refines((caddr_t)ifa->ifa_netmask,
313				    (caddr_t)ifa_maybe->ifa_netmask))
314					ifa_maybe = ifa;
315			}
316		}
317	}
318	return (ifa_maybe);
319}
320
321/*
322 * Find an interface address specific to an interface best matching
323 * a given address.
324 */
325struct ifaddr *
326ifaof_ifpforaddr(addr, ifp)
327	struct sockaddr *addr;
328	register struct ifnet *ifp;
329{
330	register struct ifaddr *ifa;
331	register char *cp, *cp2, *cp3;
332	register char *cplim;
333	struct ifaddr *ifa_maybe = 0;
334	u_int af = addr->sa_family;
335
336	if (af >= AF_MAX)
337		return (0);
338	for (ifa = ifp->if_addrhead.tqh_first; ifa;
339	     ifa = ifa->ifa_link.tqe_next) {
340		if (ifa->ifa_addr->sa_family != af)
341			continue;
342		if (ifa_maybe == 0)
343			ifa_maybe = ifa;
344		if (ifa->ifa_netmask == 0) {
345			if (equal(addr, ifa->ifa_addr) ||
346			    (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
347				return (ifa);
348			continue;
349		}
350		if (ifp->if_flags & IFF_POINTOPOINT) {
351			if (equal(addr, ifa->ifa_dstaddr))
352				return (ifa);
353		} else {
354			cp = addr->sa_data;
355			cp2 = ifa->ifa_addr->sa_data;
356			cp3 = ifa->ifa_netmask->sa_data;
357			cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
358			for (; cp3 < cplim; cp3++)
359				if ((*cp++ ^ *cp2++) & *cp3)
360					break;
361			if (cp3 == cplim)
362				return (ifa);
363		}
364	}
365	return (ifa_maybe);
366}
367
368#include <net/route.h>
369
370/*
371 * Default action when installing a route with a Link Level gateway.
372 * Lookup an appropriate real ifa to point to.
373 * This should be moved to /sys/net/link.c eventually.
374 */
375static void
376link_rtrequest(cmd, rt, sa)
377	int cmd;
378	register struct rtentry *rt;
379	struct sockaddr *sa;
380{
381	register struct ifaddr *ifa;
382	struct sockaddr *dst;
383	struct ifnet *ifp;
384
385	if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
386	    ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
387		return;
388	ifa = ifaof_ifpforaddr(dst, ifp);
389	if (ifa) {
390		IFAFREE(rt->rt_ifa);
391		rt->rt_ifa = ifa;
392		ifa->ifa_refcnt++;
393		if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
394			ifa->ifa_rtrequest(cmd, rt, sa);
395	}
396}
397
398/*
399 * Mark an interface down and notify protocols of
400 * the transition.
401 * NOTE: must be called at splnet or eqivalent.
402 */
403void
404if_down(ifp)
405	register struct ifnet *ifp;
406{
407	register struct ifaddr *ifa;
408
409	ifp->if_flags &= ~IFF_UP;
410	microtime(&ifp->if_lastchange);
411	for (ifa = ifp->if_addrhead.tqh_first; ifa;
412	     ifa = ifa->ifa_link.tqe_next)
413		pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
414	if_qflush(&ifp->if_snd);
415	rt_ifmsg(ifp);
416}
417
418/*
419 * Mark an interface up and notify protocols of
420 * the transition.
421 * NOTE: must be called at splnet or eqivalent.
422 */
423void
424if_up(ifp)
425	register struct ifnet *ifp;
426{
427	register struct ifaddr *ifa;
428
429	ifp->if_flags |= IFF_UP;
430	microtime(&ifp->if_lastchange);
431	for (ifa = ifp->if_addrhead.tqh_first; ifa;
432	     ifa = ifa->ifa_link.tqe_next)
433		pfctlinput(PRC_IFUP, ifa->ifa_addr);
434	rt_ifmsg(ifp);
435}
436
437/*
438 * Flush an interface queue.
439 */
440static void
441if_qflush(ifq)
442	register struct ifqueue *ifq;
443{
444	register struct mbuf *m, *n;
445
446	n = ifq->ifq_head;
447	while ((m = n) != 0) {
448		n = m->m_act;
449		m_freem(m);
450	}
451	ifq->ifq_head = 0;
452	ifq->ifq_tail = 0;
453	ifq->ifq_len = 0;
454}
455
456/*
457 * Handle interface watchdog timer routines.  Called
458 * from softclock, we decrement timers (if set) and
459 * call the appropriate interface routine on expiration.
460 */
461static void
462if_slowtimo(arg)
463	void *arg;
464{
465	register struct ifnet *ifp;
466	int s = splimp();
467
468	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
469		if (ifp->if_timer == 0 || --ifp->if_timer)
470			continue;
471		if (ifp->if_watchdog)
472			(*ifp->if_watchdog)(ifp);
473	}
474	splx(s);
475	timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ);
476}
477
478/*
479 * Map interface name to
480 * interface structure pointer.
481 */
482struct ifnet *
483ifunit(name)
484	register char *name;
485{
486	register char *cp;
487	register struct ifnet *ifp;
488	int unit;
489	unsigned len;
490	char *ep, c;
491
492	for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
493		if (*cp >= '0' && *cp <= '9')
494			break;
495	if (*cp == '\0' || cp == name + IFNAMSIZ)
496		return ((struct ifnet *)0);
497	/*
498	 * Save first char of unit, and pointer to it,
499	 * so we can put a null there to avoid matching
500	 * initial substrings of interface names.
501	 */
502	len = cp - name + 1;
503	c = *cp;
504	ep = cp;
505	for (unit = 0; *cp >= '0' && *cp <= '9'; )
506		unit = unit * 10 + *cp++ - '0';
507	if (*cp != '\0')
508		return 0;	/* no trailing garbage allowed */
509	*ep = 0;
510	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
511		if (bcmp(ifp->if_name, name, len))
512			continue;
513		if (unit == ifp->if_unit)
514			break;
515	}
516	*ep = c;
517	return (ifp);
518}
519
520/*
521 * Interface ioctls.
522 */
523int
524ifioctl(so, cmd, data, p)
525	struct socket *so;
526	int cmd;
527	caddr_t data;
528	struct proc *p;
529{
530	register struct ifnet *ifp;
531	register struct ifreq *ifr;
532	int error;
533
534	switch (cmd) {
535
536	case SIOCGIFCONF:
537	case OSIOCGIFCONF:
538		return (ifconf(cmd, data));
539	}
540	ifr = (struct ifreq *)data;
541	ifp = ifunit(ifr->ifr_name);
542	if (ifp == 0)
543		return (ENXIO);
544	switch (cmd) {
545
546	case SIOCGIFFLAGS:
547		ifr->ifr_flags = ifp->if_flags;
548		break;
549
550	case SIOCGIFMETRIC:
551		ifr->ifr_metric = ifp->if_metric;
552		break;
553
554	case SIOCGIFMTU:
555		ifr->ifr_mtu = ifp->if_mtu;
556		break;
557
558	case SIOCGIFPHYS:
559		ifr->ifr_phys = ifp->if_physical;
560		break;
561
562	case SIOCSIFFLAGS:
563		error = suser(p->p_ucred, &p->p_acflag);
564		if (error)
565			return (error);
566		if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
567			int s = splimp();
568			if_down(ifp);
569			splx(s);
570		}
571		if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
572			int s = splimp();
573			if_up(ifp);
574			splx(s);
575		}
576		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
577			(ifr->ifr_flags &~ IFF_CANTCHANGE);
578		if (ifp->if_ioctl)
579			(void) (*ifp->if_ioctl)(ifp, cmd, data);
580		microtime(&ifp->if_lastchange);
581		break;
582
583	case SIOCSIFMETRIC:
584		error = suser(p->p_ucred, &p->p_acflag);
585		if (error)
586			return (error);
587		ifp->if_metric = ifr->ifr_metric;
588		microtime(&ifp->if_lastchange);
589		break;
590
591	case SIOCSIFPHYS:
592		error = suser(p->p_ucred, &p->p_acflag);
593		if (error)
594			return error;
595		if (!ifp->if_ioctl)
596		        return EOPNOTSUPP;
597		error = (*ifp->if_ioctl)(ifp, cmd, data);
598		if (error == 0)
599			microtime(&ifp->if_lastchange);
600		return(error);
601
602	case SIOCSIFMTU:
603		error = suser(p->p_ucred, &p->p_acflag);
604		if (error)
605			return (error);
606		if (ifp->if_ioctl == NULL)
607			return (EOPNOTSUPP);
608		/*
609		 * 72 was chosen below because it is the size of a TCP/IP
610		 * header (40) + the minimum mss (32).
611		 */
612		if (ifr->ifr_mtu < 72 || ifr->ifr_mtu > 65535)
613			return (EINVAL);
614		error = (*ifp->if_ioctl)(ifp, cmd, data);
615		if (error == 0)
616			microtime(&ifp->if_lastchange);
617		return(error);
618
619	case SIOCADDMULTI:
620	case SIOCDELMULTI:
621		error = suser(p->p_ucred, &p->p_acflag);
622		if (error)
623			return (error);
624
625		/* Don't allow group membership on non-multicast interfaces. */
626		if ((ifp->if_flags & IFF_MULTICAST) == 0)
627			return EOPNOTSUPP;
628
629		/* Don't let users screw up protocols' entries. */
630		if (ifr->ifr_addr.sa_family != AF_LINK)
631			return EINVAL;
632
633		if (cmd == SIOCADDMULTI) {
634			struct ifmultiaddr *ifma;
635			error = if_addmulti(ifp, &ifr->ifr_addr, &ifma);
636		} else {
637			error = if_delmulti(ifp, &ifr->ifr_addr);
638		}
639		if (error == 0)
640			microtime(&ifp->if_lastchange);
641		return error;
642
643        case SIOCSIFMEDIA:
644	case SIOCSIFGENERIC:
645		error = suser(p->p_ucred, &p->p_acflag);
646		if (error)
647			return (error);
648		if (ifp->if_ioctl == 0)
649			return (EOPNOTSUPP);
650		error = (*ifp->if_ioctl)(ifp, cmd, data);
651		if (error == 0)
652			microtime(&ifp->if_lastchange);
653		return error;
654
655	case SIOCGIFMEDIA:
656	case SIOCGIFGENERIC:
657		if (ifp->if_ioctl == 0)
658			return (EOPNOTSUPP);
659		return ((*ifp->if_ioctl)(ifp, cmd, data));
660
661	default:
662		if (so->so_proto == 0)
663			return (EOPNOTSUPP);
664#ifndef COMPAT_43
665		return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
666								 data,
667								 ifp, p));
668#else
669	    {
670		int ocmd = cmd;
671
672		switch (cmd) {
673
674		case SIOCSIFDSTADDR:
675		case SIOCSIFADDR:
676		case SIOCSIFBRDADDR:
677		case SIOCSIFNETMASK:
678#if BYTE_ORDER != BIG_ENDIAN
679			if (ifr->ifr_addr.sa_family == 0 &&
680			    ifr->ifr_addr.sa_len < 16) {
681				ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
682				ifr->ifr_addr.sa_len = 16;
683			}
684#else
685			if (ifr->ifr_addr.sa_len == 0)
686				ifr->ifr_addr.sa_len = 16;
687#endif
688			break;
689
690		case OSIOCGIFADDR:
691			cmd = SIOCGIFADDR;
692			break;
693
694		case OSIOCGIFDSTADDR:
695			cmd = SIOCGIFDSTADDR;
696			break;
697
698		case OSIOCGIFBRDADDR:
699			cmd = SIOCGIFBRDADDR;
700			break;
701
702		case OSIOCGIFNETMASK:
703			cmd = SIOCGIFNETMASK;
704		}
705		error =  ((*so->so_proto->pr_usrreqs->pru_control)(so,
706								   cmd,
707								   data,
708								   ifp, p));
709		switch (ocmd) {
710
711		case OSIOCGIFADDR:
712		case OSIOCGIFDSTADDR:
713		case OSIOCGIFBRDADDR:
714		case OSIOCGIFNETMASK:
715			*(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
716		}
717		return (error);
718
719	    }
720#endif
721	}
722	return (0);
723}
724
725/*
726 * Set/clear promiscuous mode on interface ifp based on the truth value
727 * of pswitch.  The calls are reference counted so that only the first
728 * "on" request actually has an effect, as does the final "off" request.
729 * Results are undefined if the "off" and "on" requests are not matched.
730 */
731int
732ifpromisc(ifp, pswitch)
733	struct ifnet *ifp;
734	int pswitch;
735{
736	struct ifreq ifr;
737	int error;
738
739	if (pswitch) {
740		/*
741		 * If the device is not configured up, we cannot put it in
742		 * promiscuous mode.
743		 */
744		if ((ifp->if_flags & IFF_UP) == 0)
745			return (ENETDOWN);
746		if (ifp->if_pcount++ != 0)
747			return (0);
748		ifp->if_flags |= IFF_PROMISC;
749		log(LOG_INFO, "%s%d: promiscuous mode enabled\n",
750		    ifp->if_name, ifp->if_unit);
751	} else {
752		if (--ifp->if_pcount > 0)
753			return (0);
754		ifp->if_flags &= ~IFF_PROMISC;
755	}
756	ifr.ifr_flags = ifp->if_flags;
757	error = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr);
758	if (error == 0)
759		rt_ifmsg(ifp);
760	return error;
761}
762
763/*
764 * Return interface configuration
765 * of system.  List may be used
766 * in later ioctl's (above) to get
767 * other information.
768 */
769/*ARGSUSED*/
770static int
771ifconf(cmd, data)
772	int cmd;
773	caddr_t data;
774{
775	register struct ifconf *ifc = (struct ifconf *)data;
776	register struct ifnet *ifp = ifnet.tqh_first;
777	register struct ifaddr *ifa;
778	struct ifreq ifr, *ifrp;
779	int space = ifc->ifc_len, error = 0;
780
781	ifrp = ifc->ifc_req;
782	for (; space > sizeof (ifr) && ifp; ifp = ifp->if_link.tqe_next) {
783		char workbuf[64];
784		int ifnlen;
785
786		ifnlen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit);
787		if(ifnlen + 1 > sizeof ifr.ifr_name) {
788			error = ENAMETOOLONG;
789		} else {
790			strcpy(ifr.ifr_name, workbuf);
791		}
792
793		if ((ifa = ifp->if_addrhead.tqh_first) == 0) {
794			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
795			error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
796			    sizeof (ifr));
797			if (error)
798				break;
799			space -= sizeof (ifr), ifrp++;
800		} else
801		    for ( ; space > sizeof (ifr) && ifa;
802			 ifa = ifa->ifa_link.tqe_next) {
803			register struct sockaddr *sa = ifa->ifa_addr;
804#ifdef COMPAT_43
805			if (cmd == OSIOCGIFCONF) {
806				struct osockaddr *osa =
807					 (struct osockaddr *)&ifr.ifr_addr;
808				ifr.ifr_addr = *sa;
809				osa->sa_family = sa->sa_family;
810				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
811						sizeof (ifr));
812				ifrp++;
813			} else
814#endif
815			if (sa->sa_len <= sizeof(*sa)) {
816				ifr.ifr_addr = *sa;
817				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
818						sizeof (ifr));
819				ifrp++;
820			} else {
821				space -= sa->sa_len - sizeof(*sa);
822				if (space < sizeof (ifr))
823					break;
824				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
825						sizeof (ifr.ifr_name));
826				if (error == 0)
827				    error = copyout((caddr_t)sa,
828				      (caddr_t)&ifrp->ifr_addr, sa->sa_len);
829				ifrp = (struct ifreq *)
830					(sa->sa_len + (caddr_t)&ifrp->ifr_addr);
831			}
832			if (error)
833				break;
834			space -= sizeof (ifr);
835		}
836	}
837	ifc->ifc_len -= space;
838	return (error);
839}
840
841/*
842 * Just like if_promisc(), but for all-multicast-reception mode.
843 */
844int
845if_allmulti(ifp, onswitch)
846	struct ifnet *ifp;
847	int onswitch;
848{
849	int error = 0;
850	int s = splimp();
851
852	if (onswitch) {
853		if (ifp->if_amcount++ == 0) {
854			ifp->if_flags |= IFF_ALLMULTI;
855			error = ifp->if_ioctl(ifp, SIOCSIFFLAGS, 0);
856		}
857	} else {
858		if (ifp->if_amcount > 1) {
859			ifp->if_amcount--;
860		} else {
861			ifp->if_amcount = 0;
862			ifp->if_flags &= ~IFF_ALLMULTI;
863			error = ifp->if_ioctl(ifp, SIOCSIFFLAGS, 0);
864		}
865	}
866	splx(s);
867
868	if (error == 0)
869		rt_ifmsg(ifp);
870	return error;
871}
872
873/*
874 * Add a multicast listenership to the interface in question.
875 * The link layer provides a routine which converts
876 */
877int
878if_addmulti(ifp, sa, retifma)
879	struct ifnet *ifp;	/* interface to manipulate */
880	struct sockaddr *sa;	/* address to add */
881	struct ifmultiaddr **retifma;
882{
883	struct sockaddr *llsa, *dupsa;
884	int error, s;
885	struct ifmultiaddr *ifma;
886
887	/*
888	 * If the matching multicast address already exists
889	 * then don't add a new one, just add a reference
890	 */
891	for (ifma = ifp->if_multiaddrs.lh_first; ifma;
892	     ifma = ifma->ifma_link.le_next) {
893		if (equal(sa, ifma->ifma_addr)) {
894			ifma->ifma_refcount++;
895			if (retifma)
896				*retifma = ifma;
897			return 0;
898		}
899	}
900
901	/*
902	 * Give the link layer a chance to accept/reject it, and also
903	 * find out which AF_LINK address this maps to, if it isn't one
904	 * already.
905	 */
906	if (ifp->if_resolvemulti) {
907		error = ifp->if_resolvemulti(ifp, &llsa, sa);
908		if (error) return error;
909	} else {
910		llsa = 0;
911	}
912
913	MALLOC(ifma, struct ifmultiaddr *, sizeof *ifma, M_IFMADDR, M_WAITOK);
914	MALLOC(dupsa, struct sockaddr *, sa->sa_len, M_IFMADDR, M_WAITOK);
915	bcopy(sa, dupsa, sa->sa_len);
916
917	ifma->ifma_addr = dupsa;
918	ifma->ifma_lladdr = llsa;
919	ifma->ifma_ifp = ifp;
920	ifma->ifma_refcount = 1;
921	ifma->ifma_protospec = 0;
922	rt_newmaddrmsg(RTM_NEWMADDR, ifma);
923
924	/*
925	 * Some network interfaces can scan the address list at
926	 * interrupt time; lock them out.
927	 */
928	s = splimp();
929	LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link);
930	splx(s);
931	*retifma = ifma;
932
933	if (llsa != 0) {
934		for (ifma = ifp->if_multiaddrs.lh_first; ifma;
935		     ifma = ifma->ifma_link.le_next) {
936			if (equal(ifma->ifma_addr, llsa))
937				break;
938		}
939		if (ifma) {
940			ifma->ifma_refcount++;
941		} else {
942			MALLOC(ifma, struct ifmultiaddr *, sizeof *ifma,
943			       M_IFMADDR, M_WAITOK);
944			MALLOC(dupsa, struct sockaddr *, llsa->sa_len,
945			       M_IFMADDR, M_WAITOK);
946			bcopy(llsa, dupsa, llsa->sa_len);
947			ifma->ifma_addr = dupsa;
948			ifma->ifma_ifp = ifp;
949			ifma->ifma_refcount = 1;
950			s = splimp();
951			LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link);
952			splx(s);
953		}
954	}
955	/*
956	 * We are certain we have added something, so call down to the
957	 * interface to let them know about it.
958	 */
959	s = splimp();
960	ifp->if_ioctl(ifp, SIOCADDMULTI, 0);
961	splx(s);
962
963	return 0;
964}
965
966/*
967 * Remove a reference to a multicast address on this interface.  Yell
968 * if the request does not match an existing membership.
969 */
970int
971if_delmulti(ifp, sa)
972	struct ifnet *ifp;
973	struct sockaddr *sa;
974{
975	struct ifmultiaddr *ifma;
976	int s;
977
978	for (ifma = ifp->if_multiaddrs.lh_first; ifma;
979	     ifma = ifma->ifma_link.le_next)
980		if (equal(sa, ifma->ifma_addr))
981			break;
982	if (ifma == 0)
983		return ENOENT;
984
985	if (ifma->ifma_refcount > 1) {
986		ifma->ifma_refcount--;
987		return 0;
988	}
989
990	rt_newmaddrmsg(RTM_DELMADDR, ifma);
991	sa = ifma->ifma_lladdr;
992	s = splimp();
993	LIST_REMOVE(ifma, ifma_link);
994	splx(s);
995	free(ifma->ifma_addr, M_IFMADDR);
996	free(ifma, M_IFMADDR);
997	if (sa == 0)
998		return 0;
999
1000	/*
1001	 * Now look for the link-layer address which corresponds to
1002	 * this network address.  It had been squirreled away in
1003	 * ifma->ifma_lladdr for this purpose (so we don't have
1004	 * to call ifp->if_resolvemulti() again), and we saved that
1005	 * value in sa above.  If some nasty deleted the
1006	 * link-layer address out from underneath us, we can deal because
1007	 * the address we stored was is not the same as the one which was
1008	 * in the record for the link-layer address.  (So we don't complain
1009	 * in that case.)
1010	 */
1011	for (ifma = ifp->if_multiaddrs.lh_first; ifma;
1012	     ifma = ifma->ifma_link.le_next)
1013		if (equal(sa, ifma->ifma_addr))
1014			break;
1015	if (ifma == 0)
1016		return 0;
1017
1018	if (ifma->ifma_refcount > 1) {
1019		ifma->ifma_refcount--;
1020		return 0;
1021	}
1022
1023	s = splimp();
1024	LIST_REMOVE(ifma, ifma_link);
1025	splx(s);
1026	free(ifma->ifma_addr, M_IFMADDR);
1027	free(sa, M_IFMADDR);
1028	free(ifma, M_IFMADDR);
1029
1030	return 0;
1031}
1032
1033struct ifmultiaddr *
1034ifmaof_ifpforaddr(sa, ifp)
1035	struct sockaddr *sa;
1036	struct ifnet *ifp;
1037{
1038	struct ifmultiaddr *ifma;
1039
1040	for (ifma = ifp->if_multiaddrs.lh_first; ifma;
1041	     ifma = ifma->ifma_link.le_next)
1042		if (equal(ifma->ifma_addr, sa))
1043			break;
1044
1045	return ifma;
1046}
1047
1048SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
1049SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");
1050