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