xref: /csrg-svn/sys/net/if_loop.c (revision 18370)
1*18370Skarels /*	if_loop.c	6.3	85/03/18	*/
25122Swnj 
35122Swnj /*
45122Swnj  * Loopback interface driver for protocol testing and timing.
55122Swnj  */
65122Swnj 
717058Sbloom #include "param.h"
817058Sbloom #include "systm.h"
917058Sbloom #include "mbuf.h"
1017058Sbloom #include "socket.h"
1117058Sbloom #include "errno.h"
1217058Sbloom #include "ioctl.h"
1310907Ssam 
1410907Ssam #include "../net/if.h"
1510907Ssam #include "../net/netisr.h"
1610907Ssam #include "../net/route.h"
1710907Ssam 
1817058Sbloom #include "in.h"
1917058Sbloom #include "in_systm.h"
2017058Sbloom #include "ip.h"
2117058Sbloom #include "ip_var.h"
225122Swnj 
2312460Ssam #ifdef vax
2412460Ssam #include "../vax/mtpr.h"
2512460Ssam #endif
2610907Ssam 
275296Sroot #define	LONET	127
2812761Ssam #define	LOHOST	1			/* can't be 0, that's broadcast */
295207Swnj #define	LOMTU	(1024+512)
305122Swnj 
315122Swnj struct	ifnet loif;
3213066Ssam int	looutput(), loioctl();
335122Swnj 
345122Swnj loattach()
355122Swnj {
365122Swnj 	register struct ifnet *ifp = &loif;
376337Ssam 	register struct sockaddr_in *sin;
385122Swnj 
395172Swnj 	ifp->if_name = "lo";
405122Swnj 	ifp->if_mtu = LOMTU;
4113066Ssam 	ifp->if_ioctl = loioctl;
425122Swnj 	ifp->if_output = looutput;
435161Swnj 	if_attach(ifp);
445122Swnj }
455122Swnj 
466337Ssam looutput(ifp, m0, dst)
475122Swnj 	struct ifnet *ifp;
485122Swnj 	struct mbuf *m0;
496337Ssam 	struct sockaddr *dst;
505122Swnj {
515122Swnj 	int s = splimp();
526209Swnj 	register struct ifqueue *ifq;
535122Swnj 
545172Swnj 	ifp->if_opackets++;
556337Ssam 	switch (dst->sa_family) {
565122Swnj 
575122Swnj #ifdef INET
586337Ssam 	case AF_INET:
596209Swnj 		ifq = &ipintrq;
606209Swnj 		if (IF_QFULL(ifq)) {
616209Swnj 			IF_DROP(ifq);
626337Ssam 			m_freem(m0);
636209Swnj 			splx(s);
646544Sfeldman 			return (ENOBUFS);
656209Swnj 		}
666209Swnj 		IF_ENQUEUE(ifq, m0);
676262Swnj 		schednetisr(NETISR_IP);
685122Swnj 		break;
695122Swnj #endif
705122Swnj 	default:
715122Swnj 		splx(s);
726337Ssam 		printf("lo%d: can't handle af%d\n", ifp->if_unit,
736337Ssam 			dst->sa_family);
746337Ssam 		m_freem(m0);
756544Sfeldman 		return (EAFNOSUPPORT);
765122Swnj 	}
775172Swnj 	ifp->if_ipackets++;
785122Swnj 	splx(s);
796544Sfeldman 	return (0);
805122Swnj }
8113066Ssam 
8213066Ssam /*
8313066Ssam  * Process an ioctl request.
8413066Ssam  */
85*18370Skarels /* ARGSUSED */
8613066Ssam loioctl(ifp, cmd, data)
8713066Ssam 	register struct ifnet *ifp;
8813066Ssam 	int cmd;
8913066Ssam 	caddr_t data;
9013066Ssam {
91*18370Skarels 	int error = 0;
9213066Ssam 
9313066Ssam 	switch (cmd) {
9413066Ssam 
9513066Ssam 	case SIOCSIFADDR:
96*18370Skarels 		ifp->if_flags |= IFF_UP;
97*18370Skarels 		/*
98*18370Skarels 		 * Everything else is done at a higher level.
99*18370Skarels 		 */
10013066Ssam 		break;
10113066Ssam 
10213066Ssam 	default:
10313066Ssam 		error = EINVAL;
10413066Ssam 	}
10513066Ssam 	return (error);
10613066Ssam }
107