|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ ! 26: /* ! 27: * Copyright (c) 1982, 1986, 1993 ! 28: * The Regents of the University of California. All rights reserved. ! 29: * ! 30: * Redistribution and use in source and binary forms, with or without ! 31: * modification, are permitted provided that the following conditions ! 32: * are met: ! 33: * 1. Redistributions of source code must retain the above copyright ! 34: * notice, this list of conditions and the following disclaimer. ! 35: * 2. Redistributions in binary form must reproduce the above copyright ! 36: * notice, this list of conditions and the following disclaimer in the ! 37: * documentation and/or other materials provided with the distribution. ! 38: * 3. All advertising materials mentioning features or use of this software ! 39: * must display the following acknowledgement: ! 40: * This product includes software developed by the University of ! 41: * California, Berkeley and its contributors. ! 42: * 4. Neither the name of the University nor the names of its contributors ! 43: * may be used to endorse or promote products derived from this software ! 44: * without specific prior written permission. ! 45: * ! 46: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 47: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 48: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 49: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 50: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 51: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 52: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 53: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 54: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 55: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 56: * SUCH DAMAGE. ! 57: * ! 58: * @(#)if_loop.c 8.2 (Berkeley) 1/9/95 ! 59: */ ! 60: ! 61: /* ! 62: * Loopback interface driver for protocol testing and timing. ! 63: */ ! 64: ! 65: #include "bpfilter.h" ! 66: #include "loop.h" ! 67: ! 68: #include <sys/param.h> ! 69: #include <sys/systm.h> ! 70: #include <sys/kernel.h> ! 71: #include <sys/mbuf.h> ! 72: #include <sys/socket.h> ! 73: #include <sys/errno.h> ! 74: #include <sys/ioctl.h> ! 75: #include <sys/time.h> ! 76: ! 77: #include <machine/cpu.h> ! 78: ! 79: #include <net/if.h> ! 80: #include <net/if_types.h> ! 81: #include <net/netisr.h> ! 82: #include <net/route.h> ! 83: #include <net/bpf.h> ! 84: ! 85: #if INET ! 86: #include <netinet/in.h> ! 87: #include <netinet/in_systm.h> ! 88: #include <netinet/in_var.h> ! 89: #include <netinet/ip.h> ! 90: #endif ! 91: ! 92: #if NS ! 93: #include <netns/ns.h> ! 94: #include <netns/ns_if.h> ! 95: #endif ! 96: ! 97: #if ISO ! 98: #include <netiso/iso.h> ! 99: #include <netiso/iso_var.h> ! 100: #endif ! 101: ! 102: #if NBPFILTER > 0 ! 103: #include <net/bpf.h> ! 104: #endif ! 105: ! 106: #define LOMTU (32768) ! 107: ! 108: struct ifnet loif; ! 109: ! 110: /* Should be in spl.h */ ! 111: int splimp(void); ! 112: int splnet(void); ! 113: int splx(int); ! 114: ! 115: void ! 116: loopattach(n) ! 117: int n; ! 118: { ! 119: register struct ifnet *ifp = &loif; ! 120: ! 121: #ifdef lint ! 122: n = n; /* Highlander: there can only be one... */ ! 123: #endif ! 124: ifp->if_name = "lo"; ! 125: ifp->if_mtu = LOMTU; ! 126: ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; ! 127: ifp->if_ioctl = loioctl; ! 128: ifp->if_output = looutput; ! 129: ifp->if_type = IFT_LOOP; ! 130: ifp->if_hdrlen = 0; ! 131: ifp->if_addrlen = 0; ! 132: if_attach(ifp); ! 133: #if NBPFILTER > 0 ! 134: bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int)); ! 135: #endif ! 136: } ! 137: ! 138: int ! 139: looutput(ifp, m, dst, rt) ! 140: struct ifnet *ifp; ! 141: register struct mbuf *m; ! 142: struct sockaddr *dst; ! 143: register struct rtentry *rt; ! 144: { ! 145: int s, isr; ! 146: register struct ifqueue *ifq = 0; ! 147: ! 148: if ((m->m_flags & M_PKTHDR) == 0) ! 149: panic("looutput no HDR"); ! 150: ifp->if_lastchange = time; ! 151: #if NBPFILTER > 0 ! 152: if (loif.if_bpf) { ! 153: /* ! 154: * We need to prepend the address family as ! 155: * a four byte field. Cons up a dummy header ! 156: * to pacify bpf. This is safe because bpf ! 157: * will only read from the mbuf (i.e., it won't ! 158: * try to free it or keep a pointer to it). ! 159: */ ! 160: struct mbuf m0; ! 161: u_int af = dst->sa_family; ! 162: ! 163: m0.m_next = m; ! 164: m0.m_len = 4; ! 165: m0.m_data = (char *)⁡ ! 166: ! 167: BPF_MTAP(loif.if_bpf, &m0); ! 168: } ! 169: #endif ! 170: m->m_pkthdr.rcvif = ifp; ! 171: ! 172: if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) { ! 173: m_freem(m); ! 174: return (rt->rt_flags & RTF_BLACKHOLE ? 0 : ! 175: rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); ! 176: } ! 177: ifp->if_opackets++; ! 178: ifp->if_obytes += m->m_pkthdr.len; ! 179: switch (dst->sa_family) { ! 180: ! 181: #if INET ! 182: case AF_INET: ! 183: ifq = &ipintrq; ! 184: isr = NETISR_IP; ! 185: break; ! 186: #endif ! 187: #if NS ! 188: case AF_NS: ! 189: ifq = &nsintrq; ! 190: isr = NETISR_NS; ! 191: break; ! 192: #endif ! 193: #if ISO ! 194: case AF_ISO: ! 195: ifq = &clnlintrq; ! 196: isr = NETISR_ISO; ! 197: break; ! 198: #endif ! 199: default: ! 200: printf("lo%d: can't handle af%d\n", ifp->if_unit, ! 201: dst->sa_family); ! 202: m_freem(m); ! 203: return (EAFNOSUPPORT); ! 204: } ! 205: s = splimp(); ! 206: if (IF_QFULL(ifq)) { ! 207: IF_DROP(ifq); ! 208: m_freem(m); ! 209: splx(s); ! 210: return (ENOBUFS); ! 211: } ! 212: IF_ENQUEUE(ifq, m); ! 213: schednetisr(isr); ! 214: ifp->if_ipackets++; ! 215: ifp->if_ibytes += m->m_pkthdr.len; ! 216: splx(s); ! 217: return (0); ! 218: } ! 219: ! 220: /* ARGSUSED */ ! 221: void ! 222: lortrequest(cmd, rt, sa) ! 223: int cmd; ! 224: struct rtentry *rt; ! 225: struct sockaddr *sa; ! 226: { ! 227: ! 228: if (rt) ! 229: rt->rt_rmx.rmx_mtu = LOMTU; ! 230: } ! 231: ! 232: /* ! 233: * Process an ioctl request. ! 234: */ ! 235: /* ARGSUSED */ ! 236: int ! 237: loioctl(ifp, cmd, data) ! 238: register struct ifnet *ifp; ! 239: u_long cmd; ! 240: caddr_t data; ! 241: { ! 242: register struct ifaddr *ifa; ! 243: register struct ifreq *ifr; ! 244: register int error = 0; ! 245: ! 246: switch (cmd) { ! 247: ! 248: case SIOCSIFADDR: ! 249: ifp->if_flags |= IFF_UP; ! 250: ifa = (struct ifaddr *)data; ! 251: if (ifa != 0 && ifa->ifa_addr->sa_family == AF_ISO) ! 252: ifa->ifa_rtrequest = lortrequest; ! 253: /* ! 254: * Everything else is done at a higher level. ! 255: */ ! 256: break; ! 257: ! 258: case SIOCADDMULTI: ! 259: case SIOCDELMULTI: ! 260: ifr = (struct ifreq *)data; ! 261: if (ifr == 0) { ! 262: error = EAFNOSUPPORT; /* XXX */ ! 263: break; ! 264: } ! 265: switch (ifr->ifr_addr.sa_family) { ! 266: ! 267: #if INET ! 268: case AF_INET: ! 269: break; ! 270: #endif ! 271: ! 272: default: ! 273: error = EAFNOSUPPORT; ! 274: break; ! 275: } ! 276: break; ! 277: ! 278: default: ! 279: error = EINVAL; ! 280: } ! 281: return (error); ! 282: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.