xref: /csrg-svn/sys/net/if_loop.c (revision 23174)
1*23174Smckusick /*
2*23174Smckusick  * Copyright (c) 1982 Regents of the University of California.
3*23174Smckusick  * All rights reserved.  The Berkeley software License Agreement
4*23174Smckusick  * specifies the terms and conditions for redistribution.
5*23174Smckusick  *
6*23174Smckusick  *	@(#)if_loop.c	6.6 (Berkeley) 06/08/85
7*23174Smckusick  */
85122Swnj 
95122Swnj /*
105122Swnj  * Loopback interface driver for protocol testing and timing.
115122Swnj  */
125122Swnj 
1317058Sbloom #include "param.h"
1417058Sbloom #include "systm.h"
1517058Sbloom #include "mbuf.h"
1617058Sbloom #include "socket.h"
1717058Sbloom #include "errno.h"
1817058Sbloom #include "ioctl.h"
1910907Ssam 
2010907Ssam #include "../net/if.h"
2110907Ssam #include "../net/netisr.h"
2210907Ssam #include "../net/route.h"
2310907Ssam 
2417058Sbloom #include "in.h"
2517058Sbloom #include "in_systm.h"
2617058Sbloom #include "ip.h"
2717058Sbloom #include "ip_var.h"
285122Swnj 
2912460Ssam #ifdef vax
3012460Ssam #include "../vax/mtpr.h"
3112460Ssam #endif
3210907Ssam 
3318815Ssklower #ifdef NS
3418815Ssklower #include "../netns/ns.h"
3518815Ssklower #include "../netns/ns_if.h"
3618815Ssklower #endif
3718815Ssklower 
385207Swnj #define	LOMTU	(1024+512)
395122Swnj 
405122Swnj struct	ifnet loif;
4113066Ssam int	looutput(), loioctl();
425122Swnj 
435122Swnj loattach()
445122Swnj {
455122Swnj 	register struct ifnet *ifp = &loif;
466337Ssam 	register struct sockaddr_in *sin;
475122Swnj 
485172Swnj 	ifp->if_name = "lo";
495122Swnj 	ifp->if_mtu = LOMTU;
5013066Ssam 	ifp->if_ioctl = loioctl;
515122Swnj 	ifp->if_output = looutput;
525161Swnj 	if_attach(ifp);
535122Swnj }
545122Swnj 
556337Ssam looutput(ifp, m0, dst)
565122Swnj 	struct ifnet *ifp;
575122Swnj 	struct mbuf *m0;
586337Ssam 	struct sockaddr *dst;
595122Swnj {
605122Swnj 	int s = splimp();
616209Swnj 	register struct ifqueue *ifq;
625122Swnj 
635172Swnj 	ifp->if_opackets++;
646337Ssam 	switch (dst->sa_family) {
655122Swnj 
665122Swnj #ifdef INET
676337Ssam 	case AF_INET:
686209Swnj 		ifq = &ipintrq;
696209Swnj 		if (IF_QFULL(ifq)) {
706209Swnj 			IF_DROP(ifq);
716337Ssam 			m_freem(m0);
726209Swnj 			splx(s);
736544Sfeldman 			return (ENOBUFS);
746209Swnj 		}
756209Swnj 		IF_ENQUEUE(ifq, m0);
766262Swnj 		schednetisr(NETISR_IP);
775122Swnj 		break;
785122Swnj #endif
7918815Ssklower #ifdef NS
8018815Ssklower 	case AF_NS:
8118815Ssklower 		ifq = &nsintrq;
8218815Ssklower 		if (IF_QFULL(ifq)) {
8318815Ssklower 			IF_DROP(ifq);
8418815Ssklower 			m_freem(m0);
8518815Ssklower 			splx(s);
8618815Ssklower 			return (ENOBUFS);
8718815Ssklower 		}
8818815Ssklower 		IF_ENQUEUE(ifq, m0);
8918815Ssklower 		schednetisr(NETISR_NS);
9018815Ssklower 		break;
9118815Ssklower #endif
925122Swnj 	default:
935122Swnj 		splx(s);
946337Ssam 		printf("lo%d: can't handle af%d\n", ifp->if_unit,
956337Ssam 			dst->sa_family);
966337Ssam 		m_freem(m0);
976544Sfeldman 		return (EAFNOSUPPORT);
985122Swnj 	}
995172Swnj 	ifp->if_ipackets++;
1005122Swnj 	splx(s);
1016544Sfeldman 	return (0);
1025122Swnj }
10313066Ssam 
10413066Ssam /*
10513066Ssam  * Process an ioctl request.
10613066Ssam  */
10718370Skarels /* ARGSUSED */
10813066Ssam loioctl(ifp, cmd, data)
10913066Ssam 	register struct ifnet *ifp;
11013066Ssam 	int cmd;
11113066Ssam 	caddr_t data;
11213066Ssam {
11318370Skarels 	int error = 0;
11413066Ssam 
11513066Ssam 	switch (cmd) {
11613066Ssam 
11713066Ssam 	case SIOCSIFADDR:
11818370Skarels 		ifp->if_flags |= IFF_UP;
11918370Skarels 		/*
12018370Skarels 		 * Everything else is done at a higher level.
12118370Skarels 		 */
12213066Ssam 		break;
12313066Ssam 
12413066Ssam 	default:
12513066Ssam 		error = EINVAL;
12613066Ssam 	}
12713066Ssam 	return (error);
12813066Ssam }
129