root/net/if_faith.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. faithattach
  2. faith_clone_create
  3. faith_clone_destroy
  4. faithoutput
  5. faithrtrequest
  6. faithioctl

    1 /*      $OpenBSD: if_faith.c,v 1.22 2006/03/25 22:41:47 djm Exp $       */
    2 /*
    3  * Copyright (c) 1982, 1986, 1993
    4  *      The Regents of the University of California.  All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. Neither the name of the University nor the names of its contributors
   15  *    may be used to endorse or promote products derived from this software
   16  *    without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 /*
   31  * derived from 
   32  *      @(#)if_loop.c   8.1 (Berkeley) 6/10/93
   33  * Id: if_loop.c,v 1.22 1996/06/19 16:24:10 wollman Exp
   34  */
   35 
   36 /*
   37  * Loopback interface driver for protocol testing and timing.
   38  */
   39 #include "faith.h"
   40 
   41 #if NFAITH > 0
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/mbuf.h>
   46 #include <sys/socket.h>
   47 #include <sys/ioctl.h>
   48 
   49 #include <net/if.h>
   50 #include <net/if_types.h>
   51 #include <net/netisr.h>
   52 #include <net/route.h>
   53 #include <net/bpf.h>
   54 
   55 #ifdef  INET
   56 #include <netinet/in.h>
   57 #include <netinet/in_var.h>
   58 #endif
   59 
   60 #ifdef INET6
   61 #ifndef INET
   62 #include <netinet/in.h>
   63 #endif
   64 #include <netinet6/in6_var.h>
   65 #endif
   66 
   67 #include "bpfilter.h"
   68 
   69 static int faithioctl(struct ifnet *, u_long, caddr_t);
   70 int faithoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
   71         struct rtentry *);
   72 static void faithrtrequest(int, struct rtentry *, struct rt_addrinfo *);
   73 
   74 void    faithattach(int);
   75 int     faith_clone_create(struct if_clone *, int);
   76 int     faith_clone_destroy(struct ifnet *ifp);
   77 
   78 struct if_clone faith_cloner =
   79     IF_CLONE_INITIALIZER("faith", faith_clone_create, faith_clone_destroy);
   80 
   81 #define FAITHMTU        1500
   82 
   83 /* ARGSUSED */
   84 void
   85 faithattach(faith)
   86         int faith;
   87 {
   88         if_clone_attach(&faith_cloner);
   89 }
   90 
   91 int
   92 faith_clone_create(ifc, unit)
   93         struct if_clone *ifc;
   94         int unit;
   95 {
   96         struct ifnet *ifp;
   97 
   98         ifp = malloc(sizeof(*ifp), M_DEVBUF, M_NOWAIT);
   99         if (!ifp)
  100                 return (ENOMEM);
  101         bzero(ifp, sizeof(*ifp));
  102         snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name, 
  103             unit);
  104         ifp->if_mtu = FAITHMTU;
  105         /* Change to BROADCAST experimentaly to announce its prefix. */
  106         ifp->if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST;
  107         ifp->if_ioctl = faithioctl;
  108         ifp->if_output = faithoutput;
  109         ifp->if_type = IFT_FAITH;
  110         ifp->if_hdrlen = 0;
  111         ifp->if_addrlen = 0;
  112         if_attach(ifp);
  113         if_alloc_sadl(ifp);
  114 #if NBPFILTER > 0
  115         bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int));
  116 #endif
  117         return (0);
  118 }
  119 
  120 int
  121 faith_clone_destroy(ifp)
  122         struct ifnet *ifp;
  123 {
  124         if_detach(ifp);
  125 
  126         free(ifp, M_DEVBUF);
  127         return (0);
  128 }
  129 
  130 int
  131 faithoutput(ifp, m, dst, rt)
  132         struct ifnet *ifp;
  133         struct mbuf *m;
  134         struct sockaddr *dst;
  135         struct rtentry *rt;
  136 {
  137         int s, isr;
  138         struct ifqueue *ifq = 0;
  139 
  140         if ((m->m_flags & M_PKTHDR) == 0)
  141                 panic("faithoutput no HDR");
  142 #if NBPFILTER > 0
  143         /* BPF write needs to be handled specially */
  144         if (dst->sa_family == AF_UNSPEC) {
  145                 dst->sa_family = *(mtod(m, int *));
  146                 m->m_len -= sizeof(int);
  147                 m->m_pkthdr.len -= sizeof(int);
  148                 m->m_data += sizeof(int);
  149         }
  150 
  151         if (ifp->if_bpf)
  152                 bpf_mtap_af(ifp->if_bpf, dst->sa_family, m, BPF_DIRECTION_OUT);
  153 #endif
  154 
  155         if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
  156                 m_freem(m);
  157                 return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
  158                         rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
  159         }
  160         ifp->if_opackets++;
  161         ifp->if_obytes += m->m_pkthdr.len;
  162         switch (dst->sa_family) {
  163 #ifdef INET
  164         case AF_INET:
  165                 ifq = &ipintrq;
  166                 isr = NETISR_IP;
  167                 break;
  168 #endif
  169 #ifdef INET6
  170         case AF_INET6:
  171                 ifq = &ip6intrq;
  172                 isr = NETISR_IPV6;
  173                 break;
  174 #endif
  175         default:
  176                 m_freem(m);
  177                 return EAFNOSUPPORT;
  178         }
  179 
  180         /* XXX do we need more sanity checks? */
  181 
  182         m->m_pkthdr.rcvif = ifp;
  183         s = splnet();
  184         if (IF_QFULL(ifq)) {
  185                 IF_DROP(ifq);
  186                 m_freem(m);
  187                 splx(s);
  188                 return (ENOBUFS);
  189         }
  190         IF_ENQUEUE(ifq, m);
  191         schednetisr(isr);
  192         ifp->if_ipackets++;
  193         ifp->if_ibytes += m->m_pkthdr.len;
  194         splx(s);
  195         return (0);
  196 }
  197 
  198 /* ARGSUSED */
  199 static void
  200 faithrtrequest(cmd, rt, info)
  201         int cmd;
  202         struct rtentry *rt;
  203         struct rt_addrinfo *info;
  204 {
  205         if (rt)
  206                 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */
  207 }
  208 
  209 /*
  210  * Process an ioctl request.
  211  */
  212 /* ARGSUSED */
  213 static int
  214 faithioctl(ifp, cmd, data)
  215         struct ifnet *ifp;
  216         u_long cmd;
  217         caddr_t data;
  218 {
  219         struct ifaddr *ifa;
  220         struct ifreq *ifr = (struct ifreq *)data;
  221         int error = 0;
  222 
  223         switch (cmd) {
  224 
  225         case SIOCSIFADDR:
  226                 ifp->if_flags |= IFF_UP | IFF_RUNNING;
  227                 ifa = (struct ifaddr *)data;
  228                 ifa->ifa_rtrequest = faithrtrequest;
  229                 /*
  230                  * Everything else is done at a higher level.
  231                  */
  232                 break;
  233 
  234         case SIOCADDMULTI:
  235         case SIOCDELMULTI:
  236                 if (ifr == 0) {
  237                         error = EAFNOSUPPORT;           /* XXX */
  238                         break;
  239                 }
  240                 switch (ifr->ifr_addr.sa_family) {
  241 #ifdef INET
  242                 case AF_INET:
  243                         break;
  244 #endif
  245 #ifdef INET6
  246                 case AF_INET6:
  247                         break;
  248 #endif
  249 
  250                 default:
  251                         error = EAFNOSUPPORT;
  252                         break;
  253                 }
  254                 break;
  255 
  256         case SIOCSIFFLAGS:
  257                 break;
  258 
  259         default:
  260                 error = EINVAL;
  261         }
  262         return (error);
  263 }
  264 #endif /* NFAITH > 0 */

/* [<][>][^][v][top][bottom][index][help] */