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