root/netinet/in_gif.c

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

DEFINITIONS

This source file includes following definitions.
  1. in_gif_output
  2. in_gif_input

    1 /*      $OpenBSD: in_gif.c,v 1.33 2007/02/15 22:40:02 claudio Exp $     */
    2 /*      $KAME: in_gif.c,v 1.50 2001/01/22 07:27:16 itojun Exp $ */
    3 
    4 /*
    5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the project nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/socket.h>
   36 #include <sys/mbuf.h>
   37 
   38 #include <net/if.h>
   39 #include <net/route.h>
   40 #include <net/if_gif.h>
   41 
   42 #include <netinet/in.h>
   43 #include <netinet/in_systm.h>
   44 #include <netinet/ip.h>
   45 #include <netinet/ip_var.h>
   46 #include <netinet/in_gif.h>
   47 #include <netinet/ip_ipsp.h>
   48 
   49 #ifdef INET6
   50 #include <netinet/ip6.h>
   51 #endif
   52 
   53 #include "gif.h"
   54 #include "bridge.h"
   55 
   56 int
   57 in_gif_output(ifp, family, m)
   58         struct ifnet    *ifp;
   59         int             family;
   60         struct mbuf     *m;
   61 {
   62         struct gif_softc *sc = (struct gif_softc*)ifp;
   63         struct sockaddr_in *sin_src = (struct sockaddr_in *)sc->gif_psrc;
   64         struct sockaddr_in *sin_dst = (struct sockaddr_in *)sc->gif_pdst;
   65         struct tdb tdb;
   66         struct xformsw xfs;
   67         int error;
   68         struct mbuf *mp;
   69 
   70         if (sin_src == NULL || sin_dst == NULL ||
   71             sin_src->sin_family != AF_INET ||
   72             sin_dst->sin_family != AF_INET) {
   73                 m_freem(m);
   74                 return EAFNOSUPPORT;
   75         }
   76 
   77         /* setup dummy tdb.  it highly depends on ipipoutput() code. */
   78         bzero(&tdb, sizeof(tdb));
   79         bzero(&xfs, sizeof(xfs));
   80         tdb.tdb_src.sin.sin_family = AF_INET;
   81         tdb.tdb_src.sin.sin_len = sizeof(struct sockaddr_in);
   82         tdb.tdb_src.sin.sin_addr = sin_src->sin_addr;
   83         tdb.tdb_dst.sin.sin_family = AF_INET;
   84         tdb.tdb_dst.sin.sin_len = sizeof(struct sockaddr_in);
   85         tdb.tdb_dst.sin.sin_addr = sin_dst->sin_addr;
   86         tdb.tdb_xform = &xfs;
   87         xfs.xf_type = -1;       /* not XF_IP4 */
   88 
   89         switch (family) {
   90         case AF_INET:
   91                 break;
   92 #ifdef INET6
   93         case AF_INET6:
   94                 break;
   95 #endif
   96 #if NBRIDGE > 0
   97         case AF_LINK:
   98                 break;
   99 #endif /* NBRIDGE */
  100         default:
  101 #ifdef DEBUG
  102                 printf("in_gif_output: warning: unknown family %d passed\n",
  103                         family);
  104 #endif
  105                 m_freem(m);
  106                 return EAFNOSUPPORT;
  107         }
  108 
  109         /* encapsulate into IPv4 packet */
  110         mp = NULL;
  111 #if NBRIDGE > 0
  112         if (family == AF_LINK)
  113                 error = etherip_output(m, &tdb, &mp, 0, 0);
  114         else
  115 #endif /* NBRIDGE */
  116         error = ipip_output(m, &tdb, &mp, 0, 0);
  117         if (error)
  118                 return error;
  119         else if (mp == NULL)
  120                 return EFAULT;
  121 
  122         m = mp;
  123 
  124         return ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL,
  125             (void *)NULL);
  126 }
  127 
  128 void
  129 in_gif_input(struct mbuf *m, ...)
  130 {
  131         int off;
  132         struct gif_softc *sc;
  133         struct ifnet *gifp = NULL;
  134         struct ip *ip;
  135         va_list ap;
  136 
  137         va_start(ap, m);
  138         off = va_arg(ap, int);
  139         va_end(ap);
  140 
  141         /* IP-in-IP header is caused by tunnel mode, so skip gif lookup */
  142         if (m->m_flags & M_TUNNEL) {
  143                 m->m_flags &= ~M_TUNNEL;
  144                 goto inject;
  145         }
  146 
  147         ip = mtod(m, struct ip *);
  148 
  149         /* this code will be soon improved. */
  150 #define satosin(sa)     ((struct sockaddr_in *)(sa))
  151         LIST_FOREACH(sc, &gif_softc_list, gif_list) {
  152                 if (sc->gif_psrc == NULL || sc->gif_pdst == NULL ||
  153                     sc->gif_psrc->sa_family != AF_INET ||
  154                     sc->gif_pdst->sa_family != AF_INET) {
  155                         continue;
  156                 }
  157 
  158                 if ((sc->gif_if.if_flags & IFF_UP) == 0)
  159                         continue;
  160 
  161                 if (in_hosteq(satosin(sc->gif_psrc)->sin_addr, ip->ip_dst) &&
  162                     in_hosteq(satosin(sc->gif_pdst)->sin_addr, ip->ip_src))
  163                 {
  164                         gifp = &sc->gif_if;
  165                         break;
  166                 }
  167         }
  168 
  169         if (gifp) {
  170                 m->m_pkthdr.rcvif = gifp;
  171                 gifp->if_ipackets++;
  172                 gifp->if_ibytes += m->m_pkthdr.len;
  173                 ipip_input(m, off, gifp); /* We have a configured GIF */
  174                 return;
  175         }
  176 
  177 inject:
  178         ip4_input(m, off); /* No GIF interface was configured */
  179         return;
  180 }

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