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