|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)if_loop.c 7.1 (Berkeley) 6/4/86 ! 7: */ ! 8: ! 9: /* ! 10: * Loopback interface driver for protocol testing and timing. ! 11: */ ! 12: ! 13: #include "param.h" ! 14: #include "systm.h" ! 15: #include "mbuf.h" ! 16: #include "socket.h" ! 17: #include "errno.h" ! 18: #include "ioctl.h" ! 19: ! 20: #include "../net/if.h" ! 21: #include "../net/netisr.h" ! 22: #include "../net/route.h" ! 23: ! 24: #ifdef INET ! 25: #include "../netinet/in.h" ! 26: #include "../netinet/in_systm.h" ! 27: #include "../netinet/in_var.h" ! 28: #include "../netinet/ip.h" ! 29: #endif ! 30: ! 31: #ifdef vax ! 32: #include "../vax/mtpr.h" ! 33: #endif ! 34: ! 35: #ifdef NS ! 36: #include "../netns/ns.h" ! 37: #include "../netns/ns_if.h" ! 38: #endif ! 39: ! 40: #define LOMTU (1024+512) ! 41: ! 42: struct ifnet loif; ! 43: int looutput(), loioctl(); ! 44: ! 45: loattach() ! 46: { ! 47: register struct ifnet *ifp = &loif; ! 48: ! 49: ifp->if_name = "lo"; ! 50: ifp->if_mtu = LOMTU; ! 51: ifp->if_flags = IFF_LOOPBACK; ! 52: ifp->if_ioctl = loioctl; ! 53: ifp->if_output = looutput; ! 54: if_attach(ifp); ! 55: } ! 56: ! 57: looutput(ifp, m0, dst) ! 58: struct ifnet *ifp; ! 59: register struct mbuf *m0; ! 60: struct sockaddr *dst; ! 61: { ! 62: int s; ! 63: register struct ifqueue *ifq; ! 64: struct mbuf *m; ! 65: ! 66: /* ! 67: * Place interface pointer before the data ! 68: * for the receiving protocol. ! 69: */ ! 70: if (m0->m_off <= MMAXOFF && ! 71: m0->m_off >= MMINOFF + sizeof(struct ifnet *)) { ! 72: m0->m_off -= sizeof(struct ifnet *); ! 73: m0->m_len += sizeof(struct ifnet *); ! 74: } else { ! 75: MGET(m, M_DONTWAIT, MT_HEADER); ! 76: if (m == (struct mbuf *)0) ! 77: return (ENOBUFS); ! 78: m->m_off = MMINOFF; ! 79: m->m_len = sizeof(struct ifnet *); ! 80: m->m_next = m0; ! 81: m0 = m; ! 82: } ! 83: *(mtod(m0, struct ifnet **)) = ifp; ! 84: s = splimp(); ! 85: ifp->if_opackets++; ! 86: switch (dst->sa_family) { ! 87: ! 88: #ifdef INET ! 89: case AF_INET: ! 90: ifq = &ipintrq; ! 91: if (IF_QFULL(ifq)) { ! 92: IF_DROP(ifq); ! 93: m_freem(m0); ! 94: splx(s); ! 95: return (ENOBUFS); ! 96: } ! 97: IF_ENQUEUE(ifq, m0); ! 98: schednetisr(NETISR_IP); ! 99: break; ! 100: #endif ! 101: #ifdef NS ! 102: case AF_NS: ! 103: ifq = &nsintrq; ! 104: if (IF_QFULL(ifq)) { ! 105: IF_DROP(ifq); ! 106: m_freem(m0); ! 107: splx(s); ! 108: return (ENOBUFS); ! 109: } ! 110: IF_ENQUEUE(ifq, m0); ! 111: schednetisr(NETISR_NS); ! 112: break; ! 113: #endif ! 114: default: ! 115: splx(s); ! 116: printf("lo%d: can't handle af%d\n", ifp->if_unit, ! 117: dst->sa_family); ! 118: m_freem(m0); ! 119: return (EAFNOSUPPORT); ! 120: } ! 121: ifp->if_ipackets++; ! 122: splx(s); ! 123: return (0); ! 124: } ! 125: ! 126: /* ! 127: * Process an ioctl request. ! 128: */ ! 129: /* ARGSUSED */ ! 130: loioctl(ifp, cmd, data) ! 131: register struct ifnet *ifp; ! 132: int cmd; ! 133: caddr_t data; ! 134: { ! 135: int error = 0; ! 136: ! 137: switch (cmd) { ! 138: ! 139: case SIOCSIFADDR: ! 140: ifp->if_flags |= IFF_UP; ! 141: /* ! 142: * Everything else is done at a higher level. ! 143: */ ! 144: break; ! 145: ! 146: default: ! 147: error = EINVAL; ! 148: } ! 149: return (error); ! 150: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.