xref: /csrg-svn/sys/net/if_loop.c (revision 6556)
1*6556Ssam /*	if_loop.c	4.11	82/04/16	*/
25122Swnj 
35122Swnj /*
45122Swnj  * Loopback interface driver for protocol testing and timing.
55122Swnj  */
65122Swnj 
75122Swnj #include "../h/param.h"
85122Swnj #include "../h/systm.h"
95122Swnj #include "../h/mbuf.h"
105122Swnj #include "../h/socket.h"
115122Swnj #include "../net/in.h"
125122Swnj #include "../net/in_systm.h"
135122Swnj #include "../net/if.h"
145122Swnj #include "../net/ip.h"
155122Swnj #include "../net/ip_var.h"
165122Swnj #include "../h/mtpr.h"
176366Ssam #include "../net/route.h"
18*6556Ssam #include <errno.h>
195122Swnj 
205296Sroot #define	LONET	127
215207Swnj #define	LOMTU	(1024+512)
225122Swnj 
235122Swnj struct	ifnet loif;
245122Swnj int	looutput();
255122Swnj 
265122Swnj loattach()
275122Swnj {
285122Swnj 	register struct ifnet *ifp = &loif;
296337Ssam 	register struct sockaddr_in *sin;
305122Swnj 
316366Ssam COUNT(LOATTACH);
325172Swnj 	ifp->if_name = "lo";
335122Swnj 	ifp->if_mtu = LOMTU;
345122Swnj 	ifp->if_net = LONET;
356337Ssam 	sin = (struct sockaddr_in *)&ifp->if_addr;
366337Ssam 	sin->sin_family = AF_INET;
376337Ssam 	sin->sin_addr = if_makeaddr(ifp->if_net, 0);
386337Ssam 	ifp->if_flags = IFF_UP;
395122Swnj 	ifp->if_output = looutput;
405161Swnj 	if_attach(ifp);
416366Ssam 	if_rtinit(ifp, RTF_DIRECT|RTF_UP);
425122Swnj }
435122Swnj 
446337Ssam looutput(ifp, m0, dst)
455122Swnj 	struct ifnet *ifp;
465122Swnj 	struct mbuf *m0;
476337Ssam 	struct sockaddr *dst;
485122Swnj {
495122Swnj 	int s = splimp();
506209Swnj 	register struct ifqueue *ifq;
515122Swnj 
526366Ssam COUNT(LOOUTPUT);
535172Swnj 	ifp->if_opackets++;
546337Ssam 	switch (dst->sa_family) {
555122Swnj 
565122Swnj #ifdef INET
576337Ssam 	case AF_INET:
586209Swnj 		ifq = &ipintrq;
596209Swnj 		if (IF_QFULL(ifq)) {
606209Swnj 			IF_DROP(ifq);
616337Ssam 			m_freem(m0);
626209Swnj 			splx(s);
636544Sfeldman 			return (ENOBUFS);
646209Swnj 		}
656209Swnj 		IF_ENQUEUE(ifq, m0);
666262Swnj 		schednetisr(NETISR_IP);
675122Swnj 		break;
685122Swnj #endif
695122Swnj 	default:
705122Swnj 		splx(s);
716337Ssam 		printf("lo%d: can't handle af%d\n", ifp->if_unit,
726337Ssam 			dst->sa_family);
736337Ssam 		m_freem(m0);
746544Sfeldman 		return (EAFNOSUPPORT);
755122Swnj 	}
765172Swnj 	ifp->if_ipackets++;
775122Swnj 	splx(s);
786544Sfeldman 	return (0);
795122Swnj }
80