|
|
1.1 ! root 1: /* if_loop.c 6.1 83/07/29 */ ! 2: ! 3: /* ! 4: * Loopback interface driver for protocol testing and timing. ! 5: */ ! 6: ! 7: #include "../h/param.h" ! 8: #include "../h/systm.h" ! 9: #include "../h/mbuf.h" ! 10: #include "../h/socket.h" ! 11: #include "../h/errno.h" ! 12: #include "../h/ioctl.h" ! 13: ! 14: #include "../net/if.h" ! 15: #include "../net/netisr.h" ! 16: #include "../net/route.h" ! 17: ! 18: #include "../netinet/in.h" ! 19: #include "../netinet/in_systm.h" ! 20: #include "../netinet/ip.h" ! 21: #include "../netinet/ip_var.h" ! 22: ! 23: #ifdef vax ! 24: #include "../vax/mtpr.h" ! 25: #endif ! 26: ! 27: #define LONET 127 ! 28: #define LOHOST 1 /* can't be 0, that's broadcast */ ! 29: #define LOMTU (1024+512) ! 30: ! 31: struct ifnet loif; ! 32: int looutput(), loioctl(); ! 33: ! 34: loattach() ! 35: { ! 36: register struct ifnet *ifp = &loif; ! 37: register struct sockaddr_in *sin; ! 38: ! 39: ifp->if_name = "lo"; ! 40: ifp->if_mtu = LOMTU; ! 41: ifp->if_net = LONET; ! 42: ifp->if_host[0] = LOHOST; ! 43: sin = (struct sockaddr_in *)&ifp->if_addr; ! 44: sin->sin_family = AF_INET; ! 45: sin->sin_addr = if_makeaddr(LONET, LOHOST); ! 46: ifp->if_flags = IFF_UP | IFF_RUNNING; ! 47: ifp->if_ioctl = loioctl; ! 48: ifp->if_output = looutput; ! 49: if_attach(ifp); ! 50: if_rtinit(ifp, RTF_UP); ! 51: } ! 52: ! 53: looutput(ifp, m0, dst) ! 54: struct ifnet *ifp; ! 55: struct mbuf *m0; ! 56: struct sockaddr *dst; ! 57: { ! 58: int s = splimp(); ! 59: register struct ifqueue *ifq; ! 60: ! 61: ifp->if_opackets++; ! 62: switch (dst->sa_family) { ! 63: ! 64: #ifdef INET ! 65: case AF_INET: ! 66: ifq = &ipintrq; ! 67: if (IF_QFULL(ifq)) { ! 68: IF_DROP(ifq); ! 69: m_freem(m0); ! 70: splx(s); ! 71: return (ENOBUFS); ! 72: } ! 73: IF_ENQUEUE(ifq, m0); ! 74: schednetisr(NETISR_IP); ! 75: break; ! 76: #endif ! 77: default: ! 78: splx(s); ! 79: printf("lo%d: can't handle af%d\n", ifp->if_unit, ! 80: dst->sa_family); ! 81: m_freem(m0); ! 82: return (EAFNOSUPPORT); ! 83: } ! 84: ifp->if_ipackets++; ! 85: splx(s); ! 86: return (0); ! 87: } ! 88: ! 89: /* ! 90: * Process an ioctl request. ! 91: */ ! 92: loioctl(ifp, cmd, data) ! 93: register struct ifnet *ifp; ! 94: int cmd; ! 95: caddr_t data; ! 96: { ! 97: struct ifreq *ifr = (struct ifreq *)data; ! 98: struct sockaddr_in *sin; ! 99: int s = splimp(), error = 0; ! 100: ! 101: switch (cmd) { ! 102: ! 103: case SIOCSIFADDR: ! 104: if (ifp->if_flags & IFF_RUNNING) ! 105: if_rtinit(ifp, -1); /* delete previous route */ ! 106: ifp->if_addr = ifr->ifr_addr; ! 107: sin = (struct sockaddr_in *)&ifp->if_addr; ! 108: ifp->if_net = in_netof(sin->sin_addr); ! 109: ifp->if_host[0] = in_lnaof(sin->sin_addr); ! 110: if_rtinit(ifp, RTF_UP); ! 111: break; ! 112: ! 113: default: ! 114: error = EINVAL; ! 115: } ! 116: splx(s); ! 117: return (error); ! 118: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.