|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution is only permitted until one year after the first shipment ! 6: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and ! 7: * binary forms are permitted provided that: (1) source distributions retain ! 8: * this entire copyright notice and comment, and (2) distributions including ! 9: * binaries display the following acknowledgement: This product includes ! 10: * software developed by the University of California, Berkeley and its ! 11: * contributors'' in the documentation or other materials provided with the ! 12: * distribution and in all advertising materials mentioning features or use ! 13: * of this software. Neither the name of the University nor the names of ! 14: * its contributors may be used to endorse or promote products derived from ! 15: * this software without specific prior written permission. ! 16: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 19: * ! 20: * @(#)if_loop.c 7.10 (Berkeley) 6/28/90 ! 21: */ ! 22: ! 23: /* ! 24: * Loopback interface driver for protocol testing and timing. ! 25: */ ! 26: ! 27: #include "param.h" ! 28: #include "systm.h" ! 29: #include "mbuf.h" ! 30: #include "socket.h" ! 31: #include "errno.h" ! 32: #include "ioctl.h" ! 33: ! 34: #include "../net/if.h" ! 35: #include "../net/if_types.h" ! 36: #include "../net/netisr.h" ! 37: #include "../net/route.h" ! 38: ! 39: #include "machine/mtpr.h" ! 40: ! 41: #ifdef INET ! 42: #include "../netinet/in.h" ! 43: #include "../netinet/in_systm.h" ! 44: #include "../netinet/in_var.h" ! 45: #include "../netinet/ip.h" ! 46: #endif ! 47: ! 48: #ifdef NS ! 49: #include "../netns/ns.h" ! 50: #include "../netns/ns_if.h" ! 51: #endif ! 52: ! 53: #ifdef ISO ! 54: #include "../netiso/iso.h" ! 55: #include "../netiso/iso_var.h" ! 56: #endif ! 57: ! 58: #define LOMTU (1024+512) ! 59: ! 60: struct ifnet loif; ! 61: int looutput(), loioctl(); ! 62: ! 63: loattach() ! 64: { ! 65: register struct ifnet *ifp = &loif; ! 66: ! 67: ifp->if_name = "lo"; ! 68: ifp->if_mtu = LOMTU; ! 69: ifp->if_flags = IFF_LOOPBACK; ! 70: ifp->if_ioctl = loioctl; ! 71: ifp->if_output = looutput; ! 72: ifp->if_type = IFT_LOOP; ! 73: ifp->if_hdrlen = 0; ! 74: ifp->if_addrlen = 0; ! 75: if_attach(ifp); ! 76: } ! 77: ! 78: struct mbuf *Loop_Sanity; ! 79: ! 80: looutput(ifp, m, dst) ! 81: struct ifnet *ifp; ! 82: register struct mbuf *m; ! 83: struct sockaddr *dst; ! 84: { ! 85: int s; ! 86: register struct ifqueue *ifq; ! 87: ! 88: if ((m->m_flags & M_PKTHDR) == 0) ! 89: panic("looutput no HDR"); ! 90: m->m_pkthdr.rcvif = ifp; ! 91: ! 92: {struct mbuf *mm; int mlen = 0; ! 93: for (mm = m; m; m = m->m_next) /* XXX debugging code -- sklower */ ! 94: mlen += m->m_len; ! 95: m = mm; ! 96: if (mlen != m->m_pkthdr.len) { ! 97: if (Loop_Sanity) ! 98: m_freem(Loop_Sanity); ! 99: Loop_Sanity = m_copy(m, 0, (int)M_COPYALL); ! 100: } ! 101: } ! 102: ! 103: s = splimp(); ! 104: ifp->if_opackets++; ! 105: ifp->if_obytes += m->m_pkthdr.len; ! 106: switch (dst->sa_family) { ! 107: ! 108: #ifdef INET ! 109: case AF_INET: ! 110: ifq = &ipintrq; ! 111: if (IF_QFULL(ifq)) { ! 112: IF_DROP(ifq); ! 113: m_freem(m); ! 114: splx(s); ! 115: return (ENOBUFS); ! 116: } ! 117: IF_ENQUEUE(ifq, m); ! 118: schednetisr(NETISR_IP); ! 119: break; ! 120: #endif ! 121: #ifdef NS ! 122: case AF_NS: ! 123: ifq = &nsintrq; ! 124: if (IF_QFULL(ifq)) { ! 125: IF_DROP(ifq); ! 126: m_freem(m); ! 127: splx(s); ! 128: return (ENOBUFS); ! 129: } ! 130: IF_ENQUEUE(ifq, m); ! 131: schednetisr(NETISR_NS); ! 132: break; ! 133: #endif ! 134: #ifdef ISO ! 135: case AF_ISO: ! 136: ifq = &clnlintrq; ! 137: if (IF_QFULL(ifq)) { ! 138: IF_DROP(ifq); ! 139: m_freem(m); ! 140: splx(s); ! 141: return (ENOBUFS); ! 142: } ! 143: IF_ENQUEUE(ifq, m); ! 144: schednetisr(NETISR_ISO); ! 145: break; ! 146: #endif ! 147: default: ! 148: splx(s); ! 149: printf("lo%d: can't handle af%d\n", ifp->if_unit, ! 150: dst->sa_family); ! 151: m_freem(m); ! 152: return (EAFNOSUPPORT); ! 153: } ! 154: ifp->if_ipackets++; ! 155: ifp->if_ibytes += m->m_pkthdr.len; ! 156: splx(s); ! 157: return (0); ! 158: } ! 159: ! 160: /* ! 161: * Process an ioctl request. ! 162: */ ! 163: /* ARGSUSED */ ! 164: loioctl(ifp, cmd, data) ! 165: register struct ifnet *ifp; ! 166: int cmd; ! 167: caddr_t data; ! 168: { ! 169: int error = 0; ! 170: ! 171: switch (cmd) { ! 172: ! 173: case SIOCSIFADDR: ! 174: ifp->if_flags |= IFF_UP; ! 175: /* ! 176: * Everything else is done at a higher level. ! 177: */ ! 178: break; ! 179: ! 180: default: ! 181: error = EINVAL; ! 182: } ! 183: return (error); ! 184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.