[BACK]Return to ip_ipip.c CVS log [TXT][DIR] Up to [local] / sys / netinet

Annotation of sys/netinet/ip_ipip.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ip_ipip.c,v 1.39 2007/02/10 15:34:22 claudio Exp $ */
                      2: /*
                      3:  * The authors of this code are John Ioannidis (ji@tla.org),
                      4:  * Angelos D. Keromytis (kermit@csd.uch.gr) and
                      5:  * Niels Provos (provos@physnet.uni-hamburg.de).
                      6:  *
                      7:  * The original version of this code was written by John Ioannidis
                      8:  * for BSD/OS in Athens, Greece, in November 1995.
                      9:  *
                     10:  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
                     11:  * by Angelos D. Keromytis.
                     12:  *
                     13:  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
                     14:  * and Niels Provos.
                     15:  *
                     16:  * Additional features in 1999 by Angelos D. Keromytis.
                     17:  *
                     18:  * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
                     19:  * Angelos D. Keromytis and Niels Provos.
                     20:  * Copyright (c) 2001, Angelos D. Keromytis.
                     21:  *
                     22:  * Permission to use, copy, and modify this software with or without fee
                     23:  * is hereby granted, provided that this entire notice is included in
                     24:  * all copies of any software which is or includes a copy or
                     25:  * modification of this software.
                     26:  * You may use this code under the GNU public license if you so wish. Please
                     27:  * contribute changes back to the authors under this freer than GPL license
                     28:  * so that we may further the use of strong encryption without limitations to
                     29:  * all.
                     30:  *
                     31:  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
                     32:  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
                     33:  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
                     34:  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
                     35:  * PURPOSE.
                     36:  */
                     37:
                     38: /*
                     39:  * IP-inside-IP processing
                     40:  */
                     41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/mbuf.h>
                     45: #include <sys/socket.h>
                     46: #include <sys/sysctl.h>
                     47:
                     48: #include <net/if.h>
                     49: #include <net/route.h>
                     50: #include <net/netisr.h>
                     51: #include <net/bpf.h>
                     52:
                     53: #include <netinet/in.h>
                     54: #include <netinet/in_systm.h>
                     55: #include <netinet/ip.h>
                     56: #include <netinet/in_pcb.h>
                     57: #include <netinet/in_var.h>
                     58: #include <netinet/ip_var.h>
                     59: #include <netinet/ip_ecn.h>
                     60:
                     61: #ifdef MROUTING
                     62: #include <netinet/ip_mroute.h>
                     63: #endif
                     64:
                     65: #include <netinet/ip_ipsp.h>
                     66: #include <netinet/ip_ipip.h>
                     67:
                     68: #include "bpfilter.h"
                     69:
                     70: #ifdef ENCDEBUG
                     71: #define DPRINTF(x)     if (encdebug) printf x
                     72: #else
                     73: #define DPRINTF(x)
                     74: #endif
                     75:
                     76: /*
                     77:  * We can control the acceptance of IP4 packets by altering the sysctl
                     78:  * net.inet.ipip.allow value.  Zero means drop them, all else is acceptance.
                     79:  */
                     80: int ipip_allow = 0;
                     81:
                     82: struct ipipstat ipipstat;
                     83:
                     84: #ifdef INET6
                     85: /*
                     86:  * Really only a wrapper for ipip_input(), for use with IPv6.
                     87:  */
                     88: int
                     89: ip4_input6(struct mbuf **m, int *offp, int proto)
                     90: {
                     91:        /* If we do not accept IP-in-IP explicitly, drop.  */
                     92:        if (!ipip_allow && ((*m)->m_flags & (M_AUTH|M_CONF)) == 0) {
                     93:                DPRINTF(("ip4_input6(): dropped due to policy\n"));
                     94:                ipipstat.ipips_pdrops++;
                     95:                m_freem(*m);
                     96:                return IPPROTO_DONE;
                     97:        }
                     98:
                     99:        ipip_input(*m, *offp, NULL);
                    100:        return IPPROTO_DONE;
                    101: }
                    102: #endif /* INET6 */
                    103:
                    104: #ifdef INET
                    105: /*
                    106:  * Really only a wrapper for ipip_input(), for use with IPv4.
                    107:  */
                    108: void
                    109: ip4_input(struct mbuf *m, ...)
                    110: {
                    111:        va_list ap;
                    112:        int iphlen;
                    113:
                    114:        /* If we do not accept IP-in-IP explicitly, drop.  */
                    115:        if (!ipip_allow && (m->m_flags & (M_AUTH|M_CONF)) == 0) {
                    116:                DPRINTF(("ip4_input(): dropped due to policy\n"));
                    117:                ipipstat.ipips_pdrops++;
                    118:                m_freem(m);
                    119:                return;
                    120:        }
                    121:
                    122:        va_start(ap, m);
                    123:        iphlen = va_arg(ap, int);
                    124:        va_end(ap);
                    125:
                    126:        ipip_input(m, iphlen, NULL);
                    127: }
                    128: #endif /* INET */
                    129:
                    130: /*
                    131:  * ipip_input gets called when we receive an IP{46} encapsulated packet,
                    132:  * either because we got it at a real interface, or because AH or ESP
                    133:  * were being used in tunnel mode (in which case the rcvif element will
                    134:  * contain the address of the encX interface associated with the tunnel.
                    135:  */
                    136:
                    137: void
                    138: ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
                    139: {
                    140:        struct sockaddr_in *sin;
                    141:        struct ifnet *ifp;
                    142:        struct ifaddr *ifa;
                    143:        struct ifqueue *ifq = NULL;
                    144:        struct ip *ipo;
                    145: #ifdef INET6
                    146:        struct sockaddr_in6 *sin6;
                    147:        struct ip6_hdr *ip6 = NULL;
                    148:        u_int8_t itos;
                    149: #endif
                    150:        u_int8_t nxt;
                    151:        int isr;
                    152:        u_int8_t otos;
                    153:        u_int8_t v;
                    154:        int hlen, s;
                    155:
                    156:        ipipstat.ipips_ipackets++;
                    157:
                    158:        m_copydata(m, 0, 1, &v);
                    159:
                    160:        switch (v >> 4) {
                    161: #ifdef INET
                    162:         case 4:
                    163:                hlen = sizeof(struct ip);
                    164:                break;
                    165: #endif /* INET */
                    166: #ifdef INET6
                    167:         case 6:
                    168:                hlen = sizeof(struct ip6_hdr);
                    169:                break;
                    170: #endif
                    171:         default:
                    172:                ipipstat.ipips_family++;
                    173:                m_freem(m);
                    174:                return /* EAFNOSUPPORT */;
                    175:        }
                    176:
                    177:        /* Bring the IP header in the first mbuf, if not there already */
                    178:        if (m->m_len < hlen) {
                    179:                if ((m = m_pullup(m, hlen)) == NULL) {
                    180:                        DPRINTF(("ipip_input(): m_pullup() failed\n"));
                    181:                        ipipstat.ipips_hdrops++;
                    182:                        return;
                    183:                }
                    184:        }
                    185:
                    186:        ipo = mtod(m, struct ip *);
                    187:
                    188:        /* Keep outer ecn field. */
                    189:        switch (v >> 4) {
                    190: #ifdef INET
                    191:        case 4:
                    192:                otos = ipo->ip_tos;
                    193:                break;
                    194: #endif /* INET */
                    195: #ifdef INET6
                    196:        case 6:
                    197:                otos = (ntohl(mtod(m, struct ip6_hdr *)->ip6_flow) >> 20) & 0xff;
                    198:                break;
                    199: #endif
                    200:        default:
                    201:                panic("ipip_input: should never reach here");
                    202:        }
                    203:
                    204:        /* Remove outer IP header */
                    205:        m_adj(m, iphlen);
                    206:
                    207:        /* Sanity check */
                    208:        if (m->m_pkthdr.len < sizeof(struct ip)) {
                    209:                ipipstat.ipips_hdrops++;
                    210:                m_freem(m);
                    211:                return;
                    212:        }
                    213:
                    214:        m_copydata(m, 0, 1, &v);
                    215:
                    216:        switch (v >> 4) {
                    217: #ifdef INET
                    218:         case 4:
                    219:                hlen = sizeof(struct ip);
                    220:                break;
                    221: #endif /* INET */
                    222:
                    223: #ifdef INET6
                    224:         case 6:
                    225:                hlen = sizeof(struct ip6_hdr);
                    226:                break;
                    227: #endif
                    228:        default:
                    229:                ipipstat.ipips_family++;
                    230:                m_freem(m);
                    231:                return; /* EAFNOSUPPORT */
                    232:        }
                    233:
                    234:        /*
                    235:         * Bring the inner IP header in the first mbuf, if not there already.
                    236:         */
                    237:        if (m->m_len < hlen) {
                    238:                if ((m = m_pullup(m, hlen)) == NULL) {
                    239:                        DPRINTF(("ipip_input(): m_pullup() failed\n"));
                    240:                        ipipstat.ipips_hdrops++;
                    241:                        return;
                    242:                }
                    243:        }
                    244:
                    245:        /*
                    246:         * RFC 1853 specifies that the inner TTL should not be touched on
                    247:         * decapsulation. There's no reason this comment should be here, but
                    248:         * this is as good as any a position.
                    249:         */
                    250:
                    251:        /* Some sanity checks in the inner IP header */
                    252:        switch (v >> 4) {
                    253: #ifdef INET
                    254:        case 4:
                    255:                 ipo = mtod(m, struct ip *);
                    256:                 nxt = ipo->ip_p;
                    257:                if (!ip_ecn_egress(ECN_ALLOWED, &otos, &ipo->ip_tos)) {
                    258:                        m_freem(m);
                    259:                        return;
                    260:                }
                    261:                 break;
                    262: #endif /* INET */
                    263: #ifdef INET6
                    264:        case 6:
                    265:                 ip6 = (struct ip6_hdr *) ipo;
                    266:                 nxt = ip6->ip6_nxt;
                    267:                itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
                    268:                if (!ip_ecn_egress(ECN_ALLOWED, &otos, &itos)) {
                    269:                        m_freem(m);
                    270:                        return;
                    271:                }
                    272:                ip6->ip6_flow &= ~htonl(0xff << 20);
                    273:                ip6->ip6_flow |= htonl((u_int32_t) itos << 20);
                    274:                 break;
                    275: #endif
                    276:        default:
                    277:                panic("ipip_input: should never reach here");
                    278:        }
                    279:
                    280:        /* Check for local address spoofing. */
                    281:        if ((m->m_pkthdr.rcvif == NULL ||
                    282:            !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) &&
                    283:            ipip_allow != 2) {
                    284:                TAILQ_FOREACH(ifp, &ifnet, if_list) {
                    285:                        TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
                    286: #ifdef INET
                    287:                                if (ipo) {
                    288:                                        if (ifa->ifa_addr->sa_family !=
                    289:                                            AF_INET)
                    290:                                                continue;
                    291:
                    292:                                        sin = (struct sockaddr_in *) ifa->ifa_addr;
                    293:
                    294:                                        if (sin->sin_addr.s_addr ==
                    295:                                            ipo->ip_src.s_addr) {
                    296:                                                ipipstat.ipips_spoof++;
                    297:                                                m_freem(m);
                    298:                                                return;
                    299:                                        }
                    300:                                }
                    301: #endif /* INET */
                    302:
                    303: #ifdef INET6
                    304:                                if (ip6) {
                    305:                                        if (ifa->ifa_addr->sa_family !=
                    306:                                            AF_INET6)
                    307:                                                continue;
                    308:
                    309:                                        sin6 = (struct sockaddr_in6 *) ifa->ifa_addr;
                    310:
                    311:                                        if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_src)) {
                    312:                                                ipipstat.ipips_spoof++;
                    313:                                                m_freem(m);
                    314:                                                return;
                    315:                                        }
                    316:
                    317:                                }
                    318: #endif /* INET6 */
                    319:                        }
                    320:                }
                    321:        }
                    322:
                    323:        /* Statistics */
                    324:        ipipstat.ipips_ibytes += m->m_pkthdr.len - iphlen;
                    325:
                    326:        /*
                    327:         * Interface pointer stays the same; if no IPsec processing has
                    328:         * been done (or will be done), this will point to a normal
                    329:         * interface. Otherwise, it'll point to an enc interface, which
                    330:         * will allow a packet filter to distinguish between secure and
                    331:         * untrusted packets.
                    332:         */
                    333:
                    334:        switch (v >> 4) {
                    335: #ifdef INET
                    336:        case 4:
                    337:                ifq = &ipintrq;
                    338:                isr = NETISR_IP;
                    339:                break;
                    340: #endif
                    341: #ifdef INET6
                    342:        case 6:
                    343:                ifq = &ip6intrq;
                    344:                isr = NETISR_IPV6;
                    345:                break;
                    346: #endif
                    347:        default:
                    348:                panic("ipip_input: should never reach here");
                    349:        }
                    350:
                    351: #if NBPFILTER > 0
                    352:        if (gifp && gifp->if_bpf)
                    353:                bpf_mtap_af(gifp->if_bpf, ifq == &ipintrq ? AF_INET : AF_INET6,
                    354:                    m, BPF_DIRECTION_IN);
                    355: #endif
                    356:
                    357:        s = splnet();                   /* isn't it already? */
                    358:        if (IF_QFULL(ifq)) {
                    359:                IF_DROP(ifq);
                    360:                m_freem(m);
                    361:                ipipstat.ipips_qfull++;
                    362:
                    363:                splx(s);
                    364:
                    365:                DPRINTF(("ipip_input(): packet dropped because of full "
                    366:                    "queue\n"));
                    367:                return;
                    368:        }
                    369:
                    370:        IF_ENQUEUE(ifq, m);
                    371:        schednetisr(isr);
                    372:        splx(s);
                    373:        return;
                    374: }
                    375:
                    376: int
                    377: ipip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int dummy,
                    378:     int dummy2)
                    379: {
                    380:        u_int8_t tp, otos;
                    381:
                    382: #ifdef INET
                    383:        u_int8_t itos;
                    384:        struct ip *ipo;
                    385: #endif /* INET */
                    386:
                    387: #ifdef INET6
                    388:        struct ip6_hdr *ip6, *ip6o;
                    389: #endif /* INET6 */
                    390:
                    391:        /* XXX Deal with empty TDB source/destination addresses. */
                    392:
                    393:        m_copydata(m, 0, 1, &tp);
                    394:        tp = (tp >> 4) & 0xff;  /* Get the IP version number. */
                    395:
                    396:        switch (tdb->tdb_dst.sa.sa_family) {
                    397: #ifdef INET
                    398:        case AF_INET:
                    399:                if (tdb->tdb_src.sa.sa_family != AF_INET ||
                    400:                    tdb->tdb_src.sin.sin_addr.s_addr == INADDR_ANY ||
                    401:                    tdb->tdb_dst.sin.sin_addr.s_addr == INADDR_ANY) {
                    402:
                    403:                        DPRINTF(("ipip_output(): unspecified tunnel endpoind "
                    404:                            "address in SA %s/%08x\n",
                    405:                            ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    406:
                    407:                        ipipstat.ipips_unspec++;
                    408:                        m_freem(m);
                    409:                        *mp = NULL;
                    410:                        return EINVAL;
                    411:                }
                    412:
                    413:                M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
                    414:                if (m == 0) {
                    415:                        DPRINTF(("ipip_output(): M_PREPEND failed\n"));
                    416:                        ipipstat.ipips_hdrops++;
                    417:                        *mp = NULL;
                    418:                        return ENOBUFS;
                    419:                }
                    420:
                    421:                ipo = mtod(m, struct ip *);
                    422:
                    423:                ipo->ip_v = IPVERSION;
                    424:                ipo->ip_hl = 5;
                    425:                ipo->ip_len = htons(m->m_pkthdr.len);
                    426:                ipo->ip_ttl = ip_defttl;
                    427:                ipo->ip_sum = 0;
                    428:                ipo->ip_src = tdb->tdb_src.sin.sin_addr;
                    429:                ipo->ip_dst = tdb->tdb_dst.sin.sin_addr;
                    430:
                    431:                /*
                    432:                 * We do the htons() to prevent snoopers from determining our
                    433:                 * endianness.
                    434:                 */
                    435:                ipo->ip_id = htons(ip_randomid());
                    436:
                    437:                /* If the inner protocol is IP... */
                    438:                if (tp == IPVERSION) {
                    439:                        /* Save ECN notification */
                    440:                        m_copydata(m, sizeof(struct ip) +
                    441:                            offsetof(struct ip, ip_tos),
                    442:                            sizeof(u_int8_t), (caddr_t) &itos);
                    443:
                    444:                        ipo->ip_p = IPPROTO_IPIP;
                    445:
                    446:                        /*
                    447:                         * We should be keeping tunnel soft-state and
                    448:                         * send back ICMPs if needed.
                    449:                         */
                    450:                        m_copydata(m, sizeof(struct ip) +
                    451:                            offsetof(struct ip, ip_off),
                    452:                            sizeof(u_int16_t), (caddr_t) &ipo->ip_off);
                    453:                        NTOHS(ipo->ip_off);
                    454:                        ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK);
                    455:                        HTONS(ipo->ip_off);
                    456:                }
                    457: #ifdef INET6
                    458:                else if (tp == (IPV6_VERSION >> 4)) {
                    459:                        u_int32_t itos32;
                    460:
                    461:                        /* Save ECN notification. */
                    462:                        m_copydata(m, sizeof(struct ip) +
                    463:                            offsetof(struct ip6_hdr, ip6_flow),
                    464:                            sizeof(u_int32_t), (caddr_t) &itos32);
                    465:                        itos = ntohl(itos32) >> 20;
                    466:                        ipo->ip_p = IPPROTO_IPV6;
                    467:                        ipo->ip_off = 0;
                    468:                }
                    469: #endif /* INET6 */
                    470:                else {
                    471:                        m_freem(m);
                    472:                        *mp = NULL;
                    473:                        ipipstat.ipips_family++;
                    474:                        return EAFNOSUPPORT;
                    475:                }
                    476:
                    477:                otos = 0;
                    478:                ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
                    479:                ipo->ip_tos = otos;
                    480:                break;
                    481: #endif /* INET */
                    482:
                    483: #ifdef INET6
                    484:        case AF_INET6:
                    485:                if (IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_dst.sin6.sin6_addr) ||
                    486:                    tdb->tdb_src.sa.sa_family != AF_INET6 ||
                    487:                    IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_src.sin6.sin6_addr)) {
                    488:
                    489:                        DPRINTF(("ipip_output(): unspecified tunnel endpoind "
                    490:                            "address in SA %s/%08x\n",
                    491:                            ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    492:
                    493:                        ipipstat.ipips_unspec++;
                    494:                        m_freem(m);
                    495:                        *mp = NULL;
                    496:                        return ENOBUFS;
                    497:                }
                    498:
                    499:                /* scoped address handling */
                    500:                ip6 = mtod(m, struct ip6_hdr *);
                    501:                if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
                    502:                        ip6->ip6_src.s6_addr16[1] = 0;
                    503:                if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
                    504:                        ip6->ip6_dst.s6_addr16[1] = 0;
                    505:
                    506:                M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
                    507:                if (m == 0) {
                    508:                        DPRINTF(("ipip_output(): M_PREPEND failed\n"));
                    509:                        ipipstat.ipips_hdrops++;
                    510:                        *mp = NULL;
                    511:                        return ENOBUFS;
                    512:                }
                    513:
                    514:                /* Initialize IPv6 header */
                    515:                ip6o = mtod(m, struct ip6_hdr *);
                    516:                ip6o->ip6_flow = 0;
                    517:                ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
                    518:                ip6o->ip6_vfc |= IPV6_VERSION;
                    519:                ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6o));
                    520:                ip6o->ip6_hlim = ip_defttl;
                    521:                in6_embedscope(&ip6o->ip6_src, &tdb->tdb_src.sin6, NULL, NULL);
                    522:                in6_embedscope(&ip6o->ip6_dst, &tdb->tdb_dst.sin6, NULL, NULL);
                    523:
                    524: #ifdef INET
                    525:                if (tp == IPVERSION) {
                    526:                        /* Save ECN notification */
                    527:                        m_copydata(m, sizeof(struct ip6_hdr) +
                    528:                            offsetof(struct ip, ip_tos), sizeof(u_int8_t),
                    529:                            (caddr_t) &itos);
                    530:
                    531:                        /* This is really IPVERSION. */
                    532:                        ip6o->ip6_nxt = IPPROTO_IPIP;
                    533:                }
                    534:                else
                    535: #endif /* INET */
                    536:                        if (tp == (IPV6_VERSION >> 4)) {
                    537:                                u_int32_t itos32;
                    538:
                    539:                                /* Save ECN notification. */
                    540:                                m_copydata(m, sizeof(struct ip6_hdr) +
                    541:                                    offsetof(struct ip6_hdr, ip6_flow),
                    542:                                    sizeof(u_int32_t), (caddr_t) &itos32);
                    543:                                itos = ntohl(itos32) >> 20;
                    544:
                    545:                                ip6o->ip6_nxt = IPPROTO_IPV6;
                    546:                        } else {
                    547:                                m_freem(m);
                    548:                                *mp = NULL;
                    549:                                ipipstat.ipips_family++;
                    550:                                return EAFNOSUPPORT;
                    551:                        }
                    552:
                    553:                otos = 0;
                    554:                ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
                    555:                ip6o->ip6_flow |= htonl((u_int32_t) otos << 20);
                    556:                break;
                    557: #endif /* INET6 */
                    558:
                    559:        default:
                    560:                DPRINTF(("ipip_output(): unsupported protocol family %d\n",
                    561:                    tdb->tdb_dst.sa.sa_family));
                    562:                m_freem(m);
                    563:                *mp = NULL;
                    564:                ipipstat.ipips_family++;
                    565:                return EAFNOSUPPORT;
                    566:        }
                    567:
                    568:        ipipstat.ipips_opackets++;
                    569:        *mp = m;
                    570:
                    571: #ifdef INET
                    572:        if (tdb->tdb_dst.sa.sa_family == AF_INET) {
                    573:                if (tdb->tdb_xform->xf_type == XF_IP4)
                    574:                        tdb->tdb_cur_bytes +=
                    575:                            m->m_pkthdr.len - sizeof(struct ip);
                    576:
                    577:                ipipstat.ipips_obytes += m->m_pkthdr.len - sizeof(struct ip);
                    578:        }
                    579: #endif /* INET */
                    580:
                    581: #ifdef INET6
                    582:        if (tdb->tdb_dst.sa.sa_family == AF_INET6) {
                    583:                if (tdb->tdb_xform->xf_type == XF_IP4)
                    584:                        tdb->tdb_cur_bytes +=
                    585:                            m->m_pkthdr.len - sizeof(struct ip6_hdr);
                    586:
                    587:                ipipstat.ipips_obytes +=
                    588:                    m->m_pkthdr.len - sizeof(struct ip6_hdr);
                    589:        }
                    590: #endif /* INET6 */
                    591:
                    592:        return 0;
                    593: }
                    594:
                    595: #ifdef IPSEC
                    596: int
                    597: ipe4_attach()
                    598: {
                    599:        return 0;
                    600: }
                    601:
                    602: int
                    603: ipe4_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
                    604: {
                    605:        tdbp->tdb_xform = xsp;
                    606:        return 0;
                    607: }
                    608:
                    609: int
                    610: ipe4_zeroize(struct tdb *tdbp)
                    611: {
                    612:        return 0;
                    613: }
                    614:
                    615: void
                    616: ipe4_input(struct mbuf *m, ...)
                    617: {
                    618:        /* This is a rather serious mistake, so no conditional printing. */
                    619:        printf("ipe4_input(): should never be called\n");
                    620:        if (m)
                    621:                m_freem(m);
                    622: }
                    623: #endif /* IPSEC */
                    624:
                    625: int
                    626: ipip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
                    627:     size_t newlen)
                    628: {
                    629:        /* All sysctl names at this level are terminal. */
                    630:        if (namelen != 1)
                    631:                return (ENOTDIR);
                    632:
                    633:        switch (name[0]) {
                    634:        case IPIPCTL_ALLOW:
                    635:                return (sysctl_int(oldp, oldlenp, newp, newlen, &ipip_allow));
                    636:        default:
                    637:                return (ENOPROTOOPT);
                    638:        }
                    639:        /* NOTREACHED */
                    640: }

CVSweb