The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/bsd/net/if_dummy.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 /*
   26  * Copyright (c) 1982, 1986, 1993
   27  *      The Regents of the University of California.  All rights reserved.
   28  *
   29  * Redistribution and use in source and binary forms, with or without
   30  * modification, are permitted provided that the following conditions
   31  * are met:
   32  * 1. Redistributions of source code must retain the above copyright
   33  *    notice, this list of conditions and the following disclaimer.
   34  * 2. Redistributions in binary form must reproduce the above copyright
   35  *    notice, this list of conditions and the following disclaimer in the
   36  *    documentation and/or other materials provided with the distribution.
   37  * 3. All advertising materials mentioning features or use of this software
   38  *    must display the following acknowledgement:
   39  *      This product includes software developed by the University of
   40  *      California, Berkeley and its contributors.
   41  * 4. Neither the name of the University nor the names of its contributors
   42  *    may be used to endorse or promote products derived from this software
   43  *    without specific prior written permission.
   44  *
   45  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   55  * SUCH DAMAGE.
   56  */
   57 /*
   58  * derived from 
   59  *      @(#)if_loop.c   8.1 (Berkeley) 6/10/93
   60  * Id: if_loop.c,v 1.22 1996/06/19 16:24:10 wollman Exp
   61  */
   62 
   63 /*
   64  * Loopback interface driver for protocol testing and timing.
   65  */
   66 #if BSD310
   67 #include "opt_inet.h"
   68 #endif
   69 #include "dummy.h"
   70 #if NDUMMY > 0
   71 
   72 #include <sys/param.h>
   73 #include <sys/systm.h>
   74 #include <sys/kernel.h>
   75 #include <sys/mbuf.h>
   76 #include <sys/socket.h>
   77 #include <sys/sockio.h>
   78 #include <sys/errno.h>
   79 #include <sys/time.h>
   80 
   81 #include <net/if.h>
   82 #include <net/if_types.h>
   83 #include <net/netisr.h>
   84 #include <net/route.h>
   85 #include <net/bpf.h>
   86 
   87 #if     INET
   88 #include <netinet/in.h>
   89 #include <netinet/in_systm.h>
   90 #include <netinet/in_var.h>
   91 #include <netinet/ip.h>
   92 #endif
   93 
   94 #if IPX
   95 #include <netipx/ipx.h>
   96 #include <netipx/ipx_if.h>
   97 #endif
   98 
   99 #if INET6
  100 #ifndef INET
  101 #include <netinet/in.h>
  102 #endif
  103 #include <netinet6/in6_var.h>
  104 #include <netinet6/ip6.h>
  105 #endif
  106 
  107 #if NETATALK
  108 #include <netinet/if_ether.h>
  109 #include <netatalk/at.h>
  110 #include <netatalk/at_var.h>
  111 #endif NETATALK
  112 
  113 #include "bpfilter.h"
  114 
  115 static int dummyioctl __P((struct ifnet *, u_long, caddr_t));
  116 int dummyoutput __P((struct ifnet *, register struct mbuf *, struct sockaddr *,
  117         register struct rtentry *));
  118 static void dummyrtrequest __P((int, struct rtentry *, struct sockaddr *));
  119 
  120 static void dummyattach __P((void *));
  121 PSEUDO_SET(dummyattach, if_dummy);
  122 
  123 #if TINY_DUMMYMTU
  124 #define DUMMYMTU        (1024+512)
  125 #else
  126 #define DUMMYMTU        16384
  127 #endif
  128 #define HAVE_OLD_BPF 1
  129 
  130 static struct   ifnet dummyif[NDUMMY];
  131 
  132 /* ARGSUSED */
  133 static void
  134 dummyattach(dummy)
  135         void *dummy;
  136 {
  137         register struct ifnet *ifp;
  138         register int i = 0;
  139 
  140         for (i = 0; i < NDUMMY; i++) {
  141                 ifp = &dummyif[i];
  142 #if defined(__NetBSD__) || defined(__OpenBSD__)
  143                 sprintf(ifp->if_xname, "dummy%d", i);
  144 #else
  145                 ifp->if_name = "dummy";
  146                 ifp->if_unit = i;
  147 #endif
  148 #ifndef __bsdi__
  149                 ifp->if_softc = NULL;
  150 #endif
  151                 ifp->if_mtu = DUMMYMTU;
  152                 /* Change to BROADCAST experimentaly to announce its prefix. */
  153                 ifp->if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST;
  154                 ifp->if_ioctl = dummyioctl;
  155                 ifp->if_output = dummyoutput;
  156                 ifp->if_type = IFT_DUMMY;
  157                 ifp->if_hdrlen = 0;
  158                 ifp->if_addrlen = 0;
  159                 if_attach(ifp);
  160 #if NBPFILTER > 0
  161 #ifdef HAVE_OLD_BPF
  162                 bpfattach(ifp, DLT_NULL, sizeof(u_int));
  163 #else
  164                 bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int));
  165 #endif
  166 #endif
  167         }
  168 }
  169 
  170 int
  171 dummyoutput(ifp, m, dst, rt)
  172         struct ifnet *ifp;
  173         register struct mbuf *m;
  174         struct sockaddr *dst;
  175         register struct rtentry *rt;
  176 {
  177         int s, isr;
  178         register struct ifqueue *ifq = 0;
  179 
  180         if ((m->m_flags & M_PKTHDR) == 0)
  181                 panic("dummyoutput no HDR");
  182 #if NBPFILTER > 0
  183         /* BPF write needs to be handled specially */
  184         if (dst->sa_family == AF_UNSPEC) {
  185                 dst->sa_family = *(mtod(m, int *));
  186                 m->m_len -= sizeof(int);
  187                 m->m_pkthdr.len -= sizeof(int);
  188                 m->m_data += sizeof(int);
  189         }
  190 
  191         if (ifp->if_bpf) {
  192                 /*
  193                  * We need to prepend the address family as
  194                  * a four byte field.  Cons up a dummy header
  195                  * to pacify bpf.  This is safe because bpf
  196                  * will only read from the mbuf (i.e., it won't
  197                  * try to free it or keep a pointer a to it).
  198                  */
  199                 struct mbuf m0;
  200                 u_int af = dst->sa_family;
  201 
  202                 m0.m_next = m;
  203                 m0.m_len = 4;
  204                 m0.m_data = (char *)&af;
  205 
  206 #ifdef HAVE_OLD_BPF
  207                 bpf_mtap(ifp, &m0);
  208 #else
  209                 bpf_mtap(ifp->if_bpf, &m0);
  210 #endif
  211         }
  212 #endif
  213         m->m_pkthdr.rcvif = ifp;
  214 
  215         if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
  216                 m_freem(m);
  217                 return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
  218                         rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
  219         }
  220         ifp->if_opackets++;
  221         ifp->if_obytes += m->m_pkthdr.len;
  222         switch (dst->sa_family) {
  223 
  224 #if INET
  225         case AF_INET:
  226                 ifq = &ipintrq;
  227                 isr = NETISR_IP;
  228                 break;
  229 #endif
  230 #if IPX
  231         case AF_IPX:
  232                 ifq = &ipxintrq;
  233                 isr = NETISR_IPX;
  234                 break;
  235 #endif
  236 #if INET6
  237         case AF_INET6:
  238                 ifq = &ip6intrq;
  239                 isr = NETISR_IPV6;
  240                 break;
  241 #endif
  242 #if NS
  243         case AF_NS:
  244                 ifq = &nsintrq;
  245                 isr = NETISR_NS;
  246                 break;
  247 #endif
  248 #if ISO
  249         case AF_ISO:
  250                 ifq = &clnlintrq;
  251                 isr = NETISR_ISO;
  252                 break;
  253 #endif
  254 #if NETATALK
  255         case AF_APPLETALK:
  256                 ifq = &atintrq2;
  257                 isr = NETISR_ATALK;
  258                 break;
  259 #endif NETATALK
  260         default:
  261                 printf("%s: can't handle af%d\n",
  262                        if_name(ifp), dst->sa_family);
  263                 m_freem(m);
  264                 return (EAFNOSUPPORT);
  265         }
  266         s = splimp();
  267         if (IF_QFULL(ifq)) {
  268                 IF_DROP(ifq);
  269                 m_freem(m);
  270                 splx(s);
  271                 return (ENOBUFS);
  272         }
  273         IF_ENQUEUE(ifq, m);
  274         schednetisr(isr);
  275         ifp->if_ipackets++;
  276         ifp->if_ibytes += m->m_pkthdr.len;
  277         splx(s);
  278         return (0);
  279 }
  280 
  281 /* ARGSUSED */
  282 static void
  283 dummyrtrequest(cmd, rt, sa)
  284         int cmd;
  285         struct rtentry *rt;
  286         struct sockaddr *sa;
  287 {
  288         if (rt) {
  289                 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */
  290                 /*
  291                  * For optimal performance, the send and receive buffers
  292                  * should be at least twice the MTU plus a little more for
  293                  * overhead.
  294                  */
  295                 rt->rt_rmx.rmx_recvpipe = 
  296                         rt->rt_rmx.rmx_sendpipe = 3 * DUMMYMTU;
  297         }
  298 }
  299 
  300 /*
  301  * Process an ioctl request.
  302  */
  303 /* ARGSUSED */
  304 static int
  305 dummyioctl(ifp, cmd, data)
  306         register struct ifnet *ifp;
  307         u_long cmd;
  308         caddr_t data;
  309 {
  310         register struct ifaddr *ifa;
  311         register struct ifreq *ifr = (struct ifreq *)data;
  312         register int error = 0;
  313 
  314         switch (cmd) {
  315 
  316         case SIOCSIFADDR:
  317                 ifp->if_flags |= IFF_UP | IFF_RUNNING;
  318                 ifa = (struct ifaddr *)data;
  319                 ifa->ifa_rtrequest = dummyrtrequest;
  320                 /*
  321                  * Everything else is done at a higher level.
  322                  */
  323                 break;
  324 
  325         case SIOCADDMULTI:
  326         case SIOCDELMULTI:
  327                 if (ifr == 0) {
  328                         error = EAFNOSUPPORT;           /* XXX */
  329                         break;
  330                 }
  331                 switch (ifr->ifr_addr.sa_family) {
  332 
  333 #if INET
  334                 case AF_INET:
  335                         break;
  336 #endif
  337 #if INET6
  338                 case AF_INET6:
  339                         break;
  340 #endif
  341 
  342                 default:
  343                         error = EAFNOSUPPORT;
  344                         break;
  345                 }
  346                 break;
  347 
  348         case SIOCSIFMTU:
  349                 ifp->if_mtu = ifr->ifr_mtu;
  350                 break;
  351 
  352         case SIOCSIFFLAGS:
  353                 break;
  354 
  355         default:
  356                 error = EINVAL;
  357         }
  358         return (error);
  359 }
  360 #endif /* NDUMMY > 0 */

Cache object: d085fd1c339149641b7e3bd846021e84


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.