[BACK]Return to ipsec.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / netipsec

Annotation of src/sys/netipsec/ipsec.c, Revision 1.39

1.39    ! degroote    1: /*     $NetBSD: ipsec.c,v 1.38 2008/06/27 05:18:58 mlelstv Exp $       */
1.1       jonathan    2: /*     $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $       */
                      3: /*     $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */
                      4:
                      5: /*
                      6:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
1.26      degroote   13:  *     notice, this list of conditions and the following disclaimer.
1.1       jonathan   14:  * 2. Redistributions in binary form must reproduce the above copyright
1.26      degroote   15:  *     notice, this list of conditions and the following disclaimer in the
                     16:  *     documentation and/or other materials provided with the distribution.
1.1       jonathan   17:  * 3. Neither the name of the project nor the names of its contributors
1.26      degroote   18:  *     may be used to endorse or promote products derived from this software
                     19:  *     without specific prior written permission.
1.1       jonathan   20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  */
                     33:
                     34: #include <sys/cdefs.h>
1.39    ! degroote   35: __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.38 2008/06/27 05:18:58 mlelstv Exp $");
1.1       jonathan   36:
                     37: /*
                     38:  * IPsec controller part.
                     39:  */
                     40:
                     41: #include "opt_inet.h"
1.2       jonathan   42: #ifdef __FreeBSD__
1.1       jonathan   43: #include "opt_inet6.h"
1.2       jonathan   44: #endif
1.1       jonathan   45: #include "opt_ipsec.h"
                     46:
                     47: #include <sys/param.h>
                     48: #include <sys/systm.h>
                     49: #include <sys/malloc.h>
                     50: #include <sys/mbuf.h>
                     51: #include <sys/domain.h>
                     52: #include <sys/protosw.h>
                     53: #include <sys/socket.h>
                     54: #include <sys/socketvar.h>
                     55: #include <sys/errno.h>
                     56: #include <sys/time.h>
                     57: #include <sys/kernel.h>
                     58: #include <sys/syslog.h>
                     59: #include <sys/sysctl.h>
                     60: #include <sys/proc.h>
                     61:
                     62: #include <net/if.h>
                     63: #include <net/route.h>
                     64:
                     65: #include <netinet/in.h>
                     66: #include <netinet/in_systm.h>
                     67: #include <netinet/ip.h>
                     68: #include <netinet/ip_var.h>
                     69: #include <netinet/in_var.h>
                     70: #include <netinet/udp.h>
                     71: #include <netinet/udp_var.h>
                     72: #include <netinet/tcp.h>
                     73: #include <netinet/udp.h>
1.38      mlelstv    74: #include <netinet/ip_icmp.h>
1.1       jonathan   75:
                     76: #include <netinet/ip6.h>
                     77: #ifdef INET6
                     78: #include <netinet6/ip6_var.h>
                     79: #endif
                     80: #include <netinet/in_pcb.h>
                     81: #ifdef INET6
1.5       jonathan   82: #include <netinet6/in6_pcb.h>
1.1       jonathan   83: #include <netinet/icmp6.h>
                     84: #endif
                     85:
                     86: #include <netipsec/ipsec.h>
1.13      jonathan   87: #include <netipsec/ipsec_var.h>
1.37      thorpej    88: #include <netipsec/ipsec_private.h>
1.1       jonathan   89: #ifdef INET6
                     90: #include <netipsec/ipsec6.h>
                     91: #endif
                     92: #include <netipsec/ah_var.h>
                     93: #include <netipsec/esp_var.h>
                     94: #include <netipsec/ipcomp.h>           /*XXX*/
                     95: #include <netipsec/ipcomp_var.h>
                     96:
1.4       tls        97: #include <netipsec/key.h>
                     98: #include <netipsec/keydb.h>
                     99: #include <netipsec/key_debug.h>
1.1       jonathan  100:
                    101: #include <netipsec/xform.h>
                    102:
                    103: #include <netipsec/ipsec_osdep.h>
                    104:
                    105: #include <net/net_osdep.h>
                    106:
                    107: #ifdef IPSEC_DEBUG
                    108: int ipsec_debug = 1;
1.21      rpaulo    109:
1.26      degroote  110: /*
1.21      rpaulo    111:  * When set to 1, IPsec will send packets with the same sequence number.
                    112:  * This allows to verify if the other side has proper replay attacks detection.
                    113:  */
                    114: int ipsec_replay = 0;
                    115:
                    116: /*
                    117:  * When set 1, IPsec will send packets with corrupted HMAC.
                    118:  * This allows to verify if the other side properly detects modified packets.
                    119:  */
                    120: int ipsec_integrity = 0;
1.1       jonathan  121: #else
                    122: int ipsec_debug = 0;
                    123: #endif
                    124:
1.37      thorpej   125: percpu_t *ipsecstat_percpu;
1.1       jonathan  126: int ip4_ah_offsetmask = 0;     /* maybe IP_DF? */
1.18      christos  127: int ip4_ipsec_dfbit = 2;       /* DF bit on encap. 0: clear 1: set 2: copy */
1.1       jonathan  128: int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
                    129: int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
                    130: int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
                    131: int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
                    132: struct secpolicy ip4_def_policy;
                    133: int ip4_ipsec_ecn = 0;         /* ECN ignore(-1)/forbidden(0)/allowed(1) */
                    134: int ip4_esp_randpad = -1;
1.9       thorpej   135:
                    136: #ifdef __NetBSD__
                    137: u_int ipsec_spdgen = 1;                /* SPD generation # */
                    138:
1.33      degroote  139: static struct secpolicy *ipsec_checkpcbcache (struct mbuf *,
                    140:        struct inpcbpolicy *, int);
                    141: static int ipsec_fillpcbcache (struct inpcbpolicy *, struct mbuf *,
                    142:        struct secpolicy *, int);
                    143: static int ipsec_invalpcbcache (struct inpcbpolicy *, int);
1.9       thorpej   144: #endif /* __NetBSD__ */
                    145:
1.1       jonathan  146: /*
                    147:  * Crypto support requirements:
                    148:  *
                    149:  *  1  require hardware support
                    150:  * -1  require software support
                    151:  *  0  take anything
                    152:  */
                    153: int    crypto_support = 0;
                    154:
1.5       jonathan  155: static struct secpolicy *ipsec_getpolicybysock(struct mbuf *, u_int,
                    156:        PCB_T *, int *);
                    157:
1.1       jonathan  158: #ifdef __FreeBSD__
                    159: SYSCTL_DECL(_net_inet_ipsec);
                    160:
                    161: /* net.inet.ipsec */
                    162: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY,
                    163:        def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, "");
                    164: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
                    165:        CTLFLAG_RW, &ip4_esp_trans_deflev,      0, "");
                    166: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
                    167:        CTLFLAG_RW, &ip4_esp_net_deflev,        0, "");
                    168: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
                    169:        CTLFLAG_RW, &ip4_ah_trans_deflev,       0, "");
                    170: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
                    171:        CTLFLAG_RW, &ip4_ah_net_deflev, 0, "");
                    172: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
1.30      degroote  173:        ah_cleartos, CTLFLAG_RW,        &ip4_ah_cleartos,       0, "");
1.1       jonathan  174: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
                    175:        ah_offsetmask, CTLFLAG_RW,      &ip4_ah_offsetmask,     0, "");
                    176: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
                    177:        dfbit, CTLFLAG_RW,      &ip4_ipsec_dfbit,       0, "");
                    178: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
                    179:        ecn, CTLFLAG_RW,        &ip4_ipsec_ecn, 0, "");
                    180: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
                    181:        debug, CTLFLAG_RW,      &ipsec_debug,   0, "");
                    182: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
                    183:        esp_randpad, CTLFLAG_RW,        &ip4_esp_randpad,       0, "");
                    184: SYSCTL_INT(_net_inet_ipsec, OID_AUTO,
                    185:        crypto_support, CTLFLAG_RW,     &crypto_support,0, "");
                    186: SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO,
                    187:        ipsecstats,     CTLFLAG_RD,     &newipsecstat,  newipsecstat, "");
1.21      rpaulo    188: SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_replay, CTLFLAG_RW, &ipsec_replay, 0,
1.26      degroote  189:        "Emulate replay attack");
1.21      rpaulo    190: SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_integrity, CTLFLAG_RW,
1.26      degroote  191:        &ipsec_integrity, 0, "Emulate man-in-the-middle attack");
1.4       tls       192: #endif /* __FreeBSD__ */
1.1       jonathan  193:
                    194: #ifdef INET6
                    195: int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
                    196: int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
                    197: int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
                    198: int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
1.5       jonathan  199: struct secpolicy ip6_def_policy;
1.1       jonathan  200: int ip6_ipsec_ecn = 0;         /* ECN ignore(-1)/forbidden(0)/allowed(1) */
                    201: int ip6_esp_randpad = -1;
                    202:
1.5       jonathan  203:
                    204: #ifdef __FreeBSD__
1.1       jonathan  205: SYSCTL_DECL(_net_inet6_ipsec6);
                    206:
                    207: /* net.inet6.ipsec6 */
                    208: #ifdef COMPAT_KAME
                    209: SYSCTL_OID(_net_inet6_ipsec6, IPSECCTL_STATS, stats, CTLFLAG_RD,
                    210:        0,0, compat_ipsecstats_sysctl, "S", "");
                    211: #endif /* COMPAT_KAME */
                    212: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
                    213:        def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, "");
                    214: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
                    215:        CTLFLAG_RW, &ip6_esp_trans_deflev,      0, "");
                    216: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
                    217:        CTLFLAG_RW, &ip6_esp_net_deflev,        0, "");
                    218: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
                    219:        CTLFLAG_RW, &ip6_ah_trans_deflev,       0, "");
                    220: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
                    221:        CTLFLAG_RW, &ip6_ah_net_deflev, 0, "");
                    222: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
                    223:        ecn, CTLFLAG_RW,        &ip6_ipsec_ecn, 0, "");
                    224: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
                    225:        debug, CTLFLAG_RW,      &ipsec_debug,   0, "");
                    226: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
                    227:        esp_randpad, CTLFLAG_RW,        &ip6_esp_randpad,       0, "");
                    228: #endif /* INET6 */
1.6       jonathan  229: #endif /* __FreeBSD__ */
1.1       jonathan  230:
1.33      degroote  231: static int ipsec4_setspidx_inpcb (struct mbuf *, struct inpcb *);
1.1       jonathan  232: #ifdef INET6
1.33      degroote  233: static int ipsec6_setspidx_in6pcb (struct mbuf *, struct in6pcb *);
1.1       jonathan  234: #endif
1.33      degroote  235: static int ipsec_setspidx (struct mbuf *, struct secpolicyindex *, int);
                    236: static void ipsec4_get_ulp (struct mbuf *m, struct secpolicyindex *, int);
                    237: static int ipsec4_setspidx_ipaddr (struct mbuf *, struct secpolicyindex *);
1.1       jonathan  238: #ifdef INET6
1.33      degroote  239: static void ipsec6_get_ulp (struct mbuf *m, struct secpolicyindex *, int);
                    240: static int ipsec6_setspidx_ipaddr (struct mbuf *, struct secpolicyindex *);
1.1       jonathan  241: #endif
1.33      degroote  242: static void ipsec_delpcbpolicy (struct inpcbpolicy *);
                    243: static struct secpolicy *ipsec_deepcopy_policy (struct secpolicy *);
                    244: static int ipsec_set_policy (struct secpolicy **,int , void *, size_t , int );
                    245: static int ipsec_get_policy (struct secpolicy *, struct mbuf **);
                    246: static void vshiftl (unsigned char *, int, int);
                    247: static size_t ipsec_hdrsiz (struct secpolicy *);
1.1       jonathan  248:
1.9       thorpej   249: #ifdef __NetBSD__
                    250: /*
                    251:  * Try to validate and use cached policy on a PCB.
                    252:  */
                    253: static struct secpolicy *
                    254: ipsec_checkpcbcache(struct mbuf *m, struct inpcbpolicy *pcbsp, int dir)
                    255: {
                    256:        struct secpolicyindex spidx;
                    257:
                    258:        switch (dir) {
                    259:        case IPSEC_DIR_INBOUND:
                    260:        case IPSEC_DIR_OUTBOUND:
                    261:        case IPSEC_DIR_ANY:
                    262:                break;
                    263:        default:
                    264:                return NULL;
                    265:        }
                    266: #ifdef DIAGNOSTIC
1.13      jonathan  267:        if (pcbsp == NULL) {
                    268:                printf("ipsec_checkpcbcache: NULL pcbsp\n");
                    269:                /* XXX panic? */
                    270:                return NULL;
                    271:        }
                    272: #endif
                    273:
                    274: #ifdef DIAGNOSTIC
1.9       thorpej   275:        if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
                    276:                panic("dir too big in ipsec_checkpcbcache");
                    277: #endif
                    278:        /* SPD table change invalidate all the caches. */
                    279:        if (ipsec_spdgen != pcbsp->sp_cache[dir].cachegen) {
                    280:                ipsec_invalpcbcache(pcbsp, dir);
                    281:                return NULL;
                    282:        }
                    283:        if (!pcbsp->sp_cache[dir].cachesp)
                    284:                return NULL;
                    285:        if (pcbsp->sp_cache[dir].cachesp->state != IPSEC_SPSTATE_ALIVE) {
                    286:                ipsec_invalpcbcache(pcbsp, dir);
                    287:                return NULL;
                    288:        }
                    289:        if ((pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) == 0) {
                    290:                if (!pcbsp->sp_cache[dir].cachesp)
                    291:                        return NULL;
                    292:                if (ipsec_setspidx(m, &spidx, 1) != 0)
                    293:                        return NULL;
1.29      degroote  294:
                    295:                /*
                    296:                 * We have to make an exact match here since the cached rule
                    297:                 * might have lower priority than a rule that would otherwise
                    298:                 * have matched the packet.
                    299:                 */
                    300:
                    301:                if (bcmp(&pcbsp->sp_cache[dir].cacheidx, &spidx, sizeof(spidx)))
                    302:                        return NULL;
                    303:
1.9       thorpej   304:        } else {
                    305:                /*
                    306:                 * The pcb is connected, and the L4 code is sure that:
                    307:                 * - outgoing side uses inp_[lf]addr
                    308:                 * - incoming side looks up policy after inpcb lookup
                    309:                 * and address pair is know to be stable.  We do not need
                    310:                 * to generate spidx again, nor check the address match again.
                    311:                 *
                    312:                 * For IPv4/v6 SOCK_STREAM sockets, this assumptions holds
                    313:                 * and there are calls to ipsec_pcbconn() from in_pcbconnect().
                    314:                 */
                    315:        }
                    316:
1.23      kardel    317:        pcbsp->sp_cache[dir].cachesp->lastused = time_second;
1.9       thorpej   318:        pcbsp->sp_cache[dir].cachesp->refcnt++;
                    319:        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
                    320:                printf("DP ipsec_checkpcbcache cause refcnt++:%d SP:%p\n",
                    321:                pcbsp->sp_cache[dir].cachesp->refcnt,
                    322:                pcbsp->sp_cache[dir].cachesp));
                    323:        return pcbsp->sp_cache[dir].cachesp;
                    324: }
                    325:
                    326: static int
                    327: ipsec_fillpcbcache(struct inpcbpolicy *pcbsp, struct mbuf *m,
1.26      degroote  328:        struct secpolicy *sp, int dir)
1.9       thorpej   329: {
                    330:
                    331:        switch (dir) {
                    332:        case IPSEC_DIR_INBOUND:
                    333:        case IPSEC_DIR_OUTBOUND:
                    334:                break;
                    335:        default:
                    336:                return EINVAL;
                    337:        }
                    338: #ifdef DIAGNOSTIC
                    339:        if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
                    340:                panic("dir too big in ipsec_fillpcbcache");
                    341: #endif
                    342:
                    343:        if (pcbsp->sp_cache[dir].cachesp)
                    344:                KEY_FREESP(&pcbsp->sp_cache[dir].cachesp);
                    345:        pcbsp->sp_cache[dir].cachesp = NULL;
                    346:        pcbsp->sp_cache[dir].cachehint = IPSEC_PCBHINT_MAYBE;
                    347:        if (ipsec_setspidx(m, &pcbsp->sp_cache[dir].cacheidx, 1) != 0) {
                    348:                return EINVAL;
                    349:        }
                    350:        pcbsp->sp_cache[dir].cachesp = sp;
                    351:        if (pcbsp->sp_cache[dir].cachesp) {
                    352:                pcbsp->sp_cache[dir].cachesp->refcnt++;
                    353:                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
                    354:                        printf("DP ipsec_fillpcbcache cause refcnt++:%d SP:%p\n",
                    355:                        pcbsp->sp_cache[dir].cachesp->refcnt,
                    356:                        pcbsp->sp_cache[dir].cachesp));
                    357:
                    358:                /*
                    359:                 * If the PCB is connected, we can remember a hint to
                    360:                 * possibly short-circuit IPsec processing in other places.
                    361:                 */
                    362:                if (pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) {
                    363:                        switch (pcbsp->sp_cache[dir].cachesp->policy) {
                    364:                        case IPSEC_POLICY_NONE:
                    365:                        case IPSEC_POLICY_BYPASS:
                    366:                                pcbsp->sp_cache[dir].cachehint =
1.26      degroote  367:                                        IPSEC_PCBHINT_NO;
1.9       thorpej   368:                                break;
                    369:                        default:
                    370:                                pcbsp->sp_cache[dir].cachehint =
1.26      degroote  371:                                        IPSEC_PCBHINT_YES;
1.9       thorpej   372:                        }
                    373:                }
                    374:        }
                    375:        pcbsp->sp_cache[dir].cachegen = ipsec_spdgen;
                    376:
                    377:        return 0;
                    378: }
                    379:
                    380: static int
                    381: ipsec_invalpcbcache(struct inpcbpolicy *pcbsp, int dir)
                    382: {
                    383:        int i;
                    384:
                    385:        for (i = IPSEC_DIR_INBOUND; i <= IPSEC_DIR_OUTBOUND; i++) {
                    386:                if (dir != IPSEC_DIR_ANY && i != dir)
                    387:                        continue;
                    388:                if (pcbsp->sp_cache[i].cachesp)
                    389:                        KEY_FREESP(&pcbsp->sp_cache[i].cachesp);
                    390:                pcbsp->sp_cache[i].cachesp = NULL;
                    391:                pcbsp->sp_cache[i].cachehint = IPSEC_PCBHINT_MAYBE;
                    392:                pcbsp->sp_cache[i].cachegen = 0;
                    393:                bzero(&pcbsp->sp_cache[i].cacheidx,
1.26      degroote  394:                          sizeof(pcbsp->sp_cache[i].cacheidx));
1.9       thorpej   395:        }
                    396:        return 0;
                    397: }
                    398:
                    399: void
                    400: ipsec_pcbconn(struct inpcbpolicy *pcbsp)
                    401: {
                    402:
                    403:        pcbsp->sp_cacheflags |= IPSEC_PCBSP_CONNECTED;
                    404:        ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
                    405: }
                    406:
                    407: void
                    408: ipsec_pcbdisconn(struct inpcbpolicy *pcbsp)
                    409: {
                    410:
                    411:        pcbsp->sp_cacheflags &= ~IPSEC_PCBSP_CONNECTED;
                    412:        ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
                    413: }
                    414:
                    415: void
                    416: ipsec_invalpcbcacheall(void)
                    417: {
                    418:
                    419:        if (ipsec_spdgen == UINT_MAX)
                    420:                ipsec_spdgen = 1;
                    421:        else
                    422:                ipsec_spdgen++;
                    423: }
                    424: #endif /* __NetBSD__ */
                    425:
1.1       jonathan  426: /*
                    427:  * Return a held reference to the default SP.
                    428:  */
                    429: static struct secpolicy *
1.31      degroote  430: key_allocsp_default(int af, const char* where, int tag)
1.1       jonathan  431: {
                    432:        struct secpolicy *sp;
                    433:
                    434:        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
                    435:                printf("DP key_allocsp_default from %s:%u\n", where, tag));
                    436:
1.31      degroote  437:     switch(af) {
                    438:         case AF_INET:
                    439:                sp = &ip4_def_policy;
                    440:             break;
                    441: #ifdef INET6
                    442:         case AF_INET6:
                    443:             sp = &ip6_def_policy;
                    444:             break;
                    445: #endif
                    446:         default:
                    447:                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1.32      degroote  448:                    printf("key_allocsp_default : unexpected protocol family %u\n",
1.31      degroote  449:                    af));
                    450:             return NULL;
                    451:     }
                    452:
1.1       jonathan  453:        if (sp->policy != IPSEC_POLICY_DISCARD &&
1.26      degroote  454:                sp->policy != IPSEC_POLICY_NONE) {
1.1       jonathan  455:                ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
1.26      degroote  456:                        sp->policy, IPSEC_POLICY_NONE));
1.1       jonathan  457:                sp->policy = IPSEC_POLICY_NONE;
                    458:        }
                    459:        sp->refcnt++;
                    460:
                    461:        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
                    462:                printf("DP key_allocsp_default returns SP:%p (%u)\n",
                    463:                        sp, sp->refcnt));
                    464:        return sp;
                    465: }
1.31      degroote  466: #define        KEY_ALLOCSP_DEFAULT(af) \
                    467:        key_allocsp_default((af),__FILE__, __LINE__)
1.1       jonathan  468:
                    469: /*
                    470:  * For OUTBOUND packet having a socket. Searching SPD for packet,
                    471:  * and return a pointer to SP.
                    472:  * OUT:        NULL:   no apropreate SP found, the following value is set to error.
                    473:  *             0       : bypass
                    474:  *             EACCES  : discard packet.
                    475:  *             ENOENT  : ipsec_acquire() in progress, maybe.
1.7       wiz       476:  *             others  : error occurred.
1.1       jonathan  477:  *     others: a pointer to SP
                    478:  *
1.20      wiz       479:  * NOTE: IPv6 mapped address concern is implemented here.
1.1       jonathan  480:  */
                    481: struct secpolicy *
                    482: ipsec_getpolicy(struct tdb_ident *tdbi, u_int dir)
                    483: {
                    484:        struct secpolicy *sp;
                    485:
                    486:        IPSEC_ASSERT(tdbi != NULL, ("ipsec_getpolicy: null tdbi"));
                    487:        IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
                    488:                ("ipsec_getpolicy: invalid direction %u", dir));
                    489:
                    490:        sp = KEY_ALLOCSP2(tdbi->spi, &tdbi->dst, tdbi->proto, dir);
                    491:        if (sp == NULL)                 /*XXX????*/
1.31      degroote  492:                sp = KEY_ALLOCSP_DEFAULT(tdbi->dst.sa.sa_family);
1.1       jonathan  493:        IPSEC_ASSERT(sp != NULL, ("ipsec_getpolicy: null SP"));
                    494:        return sp;
                    495: }
                    496:
                    497: /*
                    498:  * For OUTBOUND packet having a socket. Searching SPD for packet,
                    499:  * and return a pointer to SP.
                    500:  * OUT:        NULL:   no apropreate SP found, the following value is set to error.
                    501:  *             0       : bypass
                    502:  *             EACCES  : discard packet.
                    503:  *             ENOENT  : ipsec_acquire() in progress, maybe.
1.7       wiz       504:  *             others  : error occurred.
1.1       jonathan  505:  *     others: a pointer to SP
                    506:  *
1.20      wiz       507:  * NOTE: IPv6 mapped address concern is implemented here.
1.1       jonathan  508:  */
1.5       jonathan  509: static struct secpolicy *
1.33      degroote  510: ipsec_getpolicybysock(struct mbuf *m, u_int dir, PCB_T *inp, int *error)
1.1       jonathan  511: {
                    512:        struct inpcbpolicy *pcbsp = NULL;
                    513:        struct secpolicy *currsp = NULL;        /* policy on socket */
                    514:        struct secpolicy *sp;
                    515:        int af;
                    516:
                    517:        IPSEC_ASSERT(m != NULL, ("ipsec_getpolicybysock: null mbuf"));
                    518:        IPSEC_ASSERT(inp != NULL, ("ipsec_getpolicybysock: null inpcb"));
                    519:        IPSEC_ASSERT(error != NULL, ("ipsec_getpolicybysock: null error"));
                    520:        IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
                    521:                ("ipsec_getpolicybysock: invalid direction %u", dir));
                    522:
1.9       thorpej   523:        IPSEC_ASSERT(PCB_SOCKET(inp) != NULL,
1.26      degroote  524:                ("ipsec_getppolicybysock: null socket\n"));
1.5       jonathan  525:
                    526:        /* XXX FIXME inpcb/in6pcb  vs socket*/
                    527:        af = PCB_FAMILY(inp);
1.1       jonathan  528:        IPSEC_ASSERT(af == AF_INET || af == AF_INET6,
                    529:                ("ipsec_getpolicybysock: unexpected protocol family %u", af));
                    530:
1.9       thorpej   531: #ifdef __NetBSD__
1.13      jonathan  532:        IPSEC_ASSERT(inp->inph_sp != NULL, ("null PCB policy cache"));
1.9       thorpej   533:        /* If we have a cached entry, and if it is still valid, use it. */
1.37      thorpej   534:        IPSEC_STATINC(IPSEC_STAT_SPDCACHELOOKUP);
1.9       thorpej   535:        currsp = ipsec_checkpcbcache(m, /*inpcb_hdr*/inp->inph_sp, dir);
                    536:        if (currsp) {
                    537:                *error = 0;
                    538:                return currsp;
                    539:        }
1.37      thorpej   540:        IPSEC_STATINC(IPSEC_STAT_SPDCACHEMISS);
1.9       thorpej   541: #endif /* __NetBSD__ */
                    542:
1.1       jonathan  543:        switch (af) {
1.5       jonathan  544:        case AF_INET: {
                    545:                struct inpcb *in4p = PCB_TO_IN4PCB(inp);
1.1       jonathan  546:                /* set spidx in pcb */
1.5       jonathan  547:                *error = ipsec4_setspidx_inpcb(m, in4p);
                    548:                pcbsp = in4p->inp_sp;
1.1       jonathan  549:                break;
1.5       jonathan  550:                }
                    551:
                    552: #if defined(INET6)
                    553:        case AF_INET6: {
                    554:                struct in6pcb *in6p = PCB_TO_IN6PCB(inp);
1.1       jonathan  555:                /* set spidx in pcb */
1.5       jonathan  556:                *error = ipsec6_setspidx_in6pcb(m, in6p);
                    557:                pcbsp = in6p->in6p_sp;
1.1       jonathan  558:                break;
1.5       jonathan  559:                }
1.1       jonathan  560: #endif
                    561:        default:
                    562:                *error = EPFNOSUPPORT;
                    563:                break;
                    564:        }
                    565:        if (*error)
                    566:                return NULL;
                    567:
                    568:        IPSEC_ASSERT(pcbsp != NULL, ("ipsec_getpolicybysock: null pcbsp"));
                    569:        switch (dir) {
                    570:        case IPSEC_DIR_INBOUND:
                    571:                currsp = pcbsp->sp_in;
                    572:                break;
                    573:        case IPSEC_DIR_OUTBOUND:
                    574:                currsp = pcbsp->sp_out;
                    575:                break;
                    576:        }
                    577:        IPSEC_ASSERT(currsp != NULL, ("ipsec_getpolicybysock: null currsp"));
                    578:
                    579:        if (pcbsp->priv) {                      /* when privilieged socket */
                    580:                switch (currsp->policy) {
                    581:                case IPSEC_POLICY_BYPASS:
                    582:                case IPSEC_POLICY_IPSEC:
                    583:                        currsp->refcnt++;
                    584:                        sp = currsp;
                    585:                        break;
                    586:
                    587:                case IPSEC_POLICY_ENTRUST:
                    588:                        /* look for a policy in SPD */
                    589:                        sp = KEY_ALLOCSP(&currsp->spidx, dir);
                    590:                        if (sp == NULL)         /* no SP found */
1.31      degroote  591:                                sp = KEY_ALLOCSP_DEFAULT(af);
1.1       jonathan  592:                        break;
                    593:
                    594:                default:
                    595:                        ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
1.26      degroote  596:                                  "Invalid policy for PCB %d\n", currsp->policy));
1.1       jonathan  597:                        *error = EINVAL;
                    598:                        return NULL;
                    599:                }
                    600:        } else {                                /* unpriv, SPD has policy */
                    601:                sp = KEY_ALLOCSP(&currsp->spidx, dir);
                    602:                if (sp == NULL) {               /* no SP found */
                    603:                        switch (currsp->policy) {
                    604:                        case IPSEC_POLICY_BYPASS:
                    605:                                ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
1.26      degroote  606:                                           "Illegal policy for non-priviliged defined %d\n",
1.1       jonathan  607:                                        currsp->policy));
                    608:                                *error = EINVAL;
                    609:                                return NULL;
                    610:
                    611:                        case IPSEC_POLICY_ENTRUST:
1.31      degroote  612:                                sp = KEY_ALLOCSP_DEFAULT(af);
1.1       jonathan  613:                                break;
                    614:
                    615:                        case IPSEC_POLICY_IPSEC:
                    616:                                currsp->refcnt++;
                    617:                                sp = currsp;
                    618:                                break;
                    619:
                    620:                        default:
                    621:                                ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
                    622:                                   "Invalid policy for PCB %d\n", currsp->policy));
                    623:                                *error = EINVAL;
                    624:                                return NULL;
                    625:                        }
                    626:                }
                    627:        }
                    628:        IPSEC_ASSERT(sp != NULL,
                    629:                ("ipsec_getpolicybysock: null SP (priv %u policy %u",
                    630:                 pcbsp->priv, currsp->policy));
                    631:        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
                    632:                printf("DP ipsec_getpolicybysock (priv %u policy %u) allocates "
1.26      degroote  633:                           "SP:%p (refcnt %u)\n", pcbsp->priv, currsp->policy,
                    634:                           sp, sp->refcnt));
1.9       thorpej   635: #ifdef __NetBSD__
                    636:        ipsec_fillpcbcache(pcbsp, m, sp, dir);
                    637: #endif /* __NetBSD__ */
1.1       jonathan  638:        return sp;
                    639: }
                    640:
                    641: /*
                    642:  * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
                    643:  * and return a pointer to SP.
                    644:  * OUT:        positive: a pointer to the entry for security policy leaf matched.
                    645:  *     NULL:   no apropreate SP found, the following value is set to error.
                    646:  *             0       : bypass
                    647:  *             EACCES  : discard packet.
                    648:  *             ENOENT  : ipsec_acquire() in progress, maybe.
1.7       wiz       649:  *             others  : error occurred.
1.1       jonathan  650:  */
                    651: struct secpolicy *
1.33      degroote  652: ipsec_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
1.1       jonathan  653: {
                    654:        struct secpolicyindex spidx;
                    655:        struct secpolicy *sp;
                    656:
                    657:        IPSEC_ASSERT(m != NULL, ("ipsec_getpolicybyaddr: null mbuf"));
                    658:        IPSEC_ASSERT(error != NULL, ("ipsec_getpolicybyaddr: null error"));
                    659:        IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
                    660:                ("ipsec4_getpolicybaddr: invalid direction %u", dir));
                    661:
                    662:        sp = NULL;
1.32      degroote  663:
                    664:        /* Make an index to look for a policy. */
                    665:        *error = ipsec_setspidx(m, &spidx, (flag & IP_FORWARDING) ? 0 : 1);
                    666:        if (*error != 0) {
                    667:                DPRINTF(("ipsec_getpolicybyaddr: setpidx failed,"
                    668:                        " dir %u flag %u\n", dir, flag));
                    669:                bzero(&spidx, sizeof (spidx));
                    670:                return NULL;
                    671:        }
                    672:
                    673:        spidx.dir = dir;
                    674:
1.1       jonathan  675:        if (key_havesp(dir)) {
                    676:                sp = KEY_ALLOCSP(&spidx, dir);
                    677:        }
1.32      degroote  678:
1.1       jonathan  679:        if (sp == NULL)                 /* no SP found, use system default */
1.31      degroote  680:                sp = KEY_ALLOCSP_DEFAULT(spidx.dst.sa.sa_family);
1.1       jonathan  681:        IPSEC_ASSERT(sp != NULL, ("ipsec_getpolicybyaddr: null SP"));
                    682:        return sp;
                    683: }
                    684:
                    685: struct secpolicy *
1.33      degroote  686: ipsec4_checkpolicy(struct mbuf *m, u_int dir, u_int flag, int *error,
                    687:                   struct inpcb *inp)
1.1       jonathan  688: {
                    689:        struct secpolicy *sp;
                    690:
                    691:        *error = 0;
1.5       jonathan  692:
                    693:
                    694:        /* XXX KAME IPv6 calls us with non-null inp but bogus inp_socket? */
                    695:        if (inp == NULL || inp->inp_socket == NULL) {
1.1       jonathan  696:                sp = ipsec_getpolicybyaddr(m, dir, flag, error);
1.5       jonathan  697:        } else
                    698:                sp = ipsec_getpolicybysock(m, dir, IN4PCB_TO_PCB(inp), error);
1.1       jonathan  699:        if (sp == NULL) {
                    700:                IPSEC_ASSERT(*error != 0,
                    701:                        ("ipsec4_checkpolicy: getpolicy failed w/o error"));
1.37      thorpej   702:                IPSEC_STATINC(IPSEC_STAT_OUT_INVAL);
1.1       jonathan  703:                return NULL;
                    704:        }
                    705:        IPSEC_ASSERT(*error == 0,
                    706:                ("ipsec4_checkpolicy: sp w/ error set to %u", *error));
                    707:        switch (sp->policy) {
                    708:        case IPSEC_POLICY_ENTRUST:
                    709:        default:
                    710:                printf("ipsec4_checkpolicy: invalid policy %u\n", sp->policy);
                    711:                /* fall thru... */
                    712:        case IPSEC_POLICY_DISCARD:
1.37      thorpej   713:                IPSEC_STATINC(IPSEC_STAT_OUT_POLVIO);
1.1       jonathan  714:                *error = -EINVAL;       /* packet is discarded by caller */
                    715:                break;
                    716:        case IPSEC_POLICY_BYPASS:
                    717:        case IPSEC_POLICY_NONE:
                    718:                KEY_FREESP(&sp);
                    719:                sp = NULL;              /* NB: force NULL result */
                    720:                break;
                    721:        case IPSEC_POLICY_IPSEC:
                    722:                if (sp->req == NULL)    /* acquire an SA */
                    723:                        *error = key_spdacquire(sp);
                    724:                break;
                    725:        }
                    726:        if (*error != 0) {
                    727:                KEY_FREESP(&sp);
                    728:                sp = NULL;
                    729:        }
1.5       jonathan  730:        DPRINTF(("ipsecpol: done, sp %p error %d, \n", sp, *error));
1.1       jonathan  731:        return sp;
                    732: }
                    733:
1.26      degroote  734: #ifdef INET6
                    735: struct secpolicy *
1.33      degroote  736: ipsec6_checkpolicy(struct mbuf *m, u_int dir, u_int flag, int *error,
                    737:                   struct in6pcb *in6p)
1.26      degroote  738: {
                    739:        struct secpolicy *sp;
                    740:
                    741:        *error = 0;
                    742:
                    743:
                    744:        /* XXX KAME IPv6 calls us with non-null inp but bogus inp_socket? */
                    745:        if (in6p == NULL || in6p->in6p_socket == NULL) {
                    746:                sp = ipsec_getpolicybyaddr(m, dir, flag, error);
                    747:        } else
                    748:                sp = ipsec_getpolicybysock(m, dir, IN6PCB_TO_PCB(in6p), error);
                    749:        if (sp == NULL) {
                    750:                IPSEC_ASSERT(*error != 0,
                    751:                        ("ipsec6_checkpolicy: getpolicy failed w/o error"));
1.37      thorpej   752:                IPSEC_STATINC(IPSEC_STAT_OUT_INVAL);
1.26      degroote  753:                return NULL;
                    754:        }
                    755:        IPSEC_ASSERT(*error == 0,
                    756:                ("ipsec6_checkpolicy: sp w/ error set to %u", *error));
                    757:        switch (sp->policy) {
                    758:        case IPSEC_POLICY_ENTRUST:
                    759:        default:
                    760:                printf("ipsec6_checkpolicy: invalid policy %u\n", sp->policy);
                    761:                /* fall thru... */
                    762:        case IPSEC_POLICY_DISCARD:
1.37      thorpej   763:                IPSEC_STATINC(IPSEC_STAT_OUT_POLVIO);
1.26      degroote  764:                *error = -EINVAL;   /* packet is discarded by caller */
                    765:                break;
                    766:        case IPSEC_POLICY_BYPASS:
                    767:        case IPSEC_POLICY_NONE:
                    768:                KEY_FREESP(&sp);
                    769:                sp = NULL;        /* NB: force NULL result */
                    770:                break;
                    771:        case IPSEC_POLICY_IPSEC:
                    772:                if (sp->req == NULL)    /* acquire an SA */
                    773:                        *error = key_spdacquire(sp);
                    774:                break;
                    775:        }
                    776:        if (*error != 0) {
                    777:                KEY_FREESP(&sp);
                    778:                sp = NULL;
                    779:        }
                    780:        DPRINTF(("ipsecpol: done, sp %p error %d, \n", sp, *error));
                    781:        return sp;
                    782: }
                    783: #endif /* INET6 */
                    784:
1.1       jonathan  785: static int
1.33      degroote  786: ipsec4_setspidx_inpcb(struct mbuf *m ,struct inpcb *pcb)
1.1       jonathan  787: {
                    788:        int error;
                    789:
                    790:        IPSEC_ASSERT(pcb != NULL, ("ipsec4_setspidx_inpcb: null pcb"));
                    791:        IPSEC_ASSERT(pcb->inp_sp != NULL, ("ipsec4_setspidx_inpcb: null inp_sp"));
                    792:        IPSEC_ASSERT(pcb->inp_sp->sp_out != NULL && pcb->inp_sp->sp_in != NULL,
                    793:                ("ipsec4_setspidx_inpcb: null sp_in || sp_out"));
                    794:
                    795:        error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1);
                    796:        if (error == 0) {
                    797:                pcb->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
                    798:                pcb->inp_sp->sp_out->spidx = pcb->inp_sp->sp_in->spidx;
                    799:                pcb->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
                    800:        } else {
                    801:                bzero(&pcb->inp_sp->sp_in->spidx,
                    802:                        sizeof (pcb->inp_sp->sp_in->spidx));
                    803:                bzero(&pcb->inp_sp->sp_out->spidx,
                    804:                        sizeof (pcb->inp_sp->sp_in->spidx));
                    805:        }
                    806:        return error;
                    807: }
                    808:
                    809: #ifdef INET6
                    810: static int
1.33      degroote  811: ipsec6_setspidx_in6pcb(struct mbuf *m, struct in6pcb *pcb)
1.1       jonathan  812: {
                    813:        struct secpolicyindex *spidx;
                    814:        int error;
                    815:
                    816:        IPSEC_ASSERT(pcb != NULL, ("ipsec6_setspidx_in6pcb: null pcb"));
                    817:        IPSEC_ASSERT(pcb->in6p_sp != NULL, ("ipsec6_setspidx_in6pcb: null inp_sp"));
                    818:        IPSEC_ASSERT(pcb->in6p_sp->sp_out != NULL && pcb->in6p_sp->sp_in != NULL,
                    819:                ("ipsec6_setspidx_in6pcb: null sp_in || sp_out"));
                    820:
                    821:        bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
                    822:        bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
                    823:
                    824:        spidx = &pcb->in6p_sp->sp_in->spidx;
                    825:        error = ipsec_setspidx(m, spidx, 1);
                    826:        if (error)
                    827:                goto bad;
                    828:        spidx->dir = IPSEC_DIR_INBOUND;
                    829:
                    830:        spidx = &pcb->in6p_sp->sp_out->spidx;
                    831:        error = ipsec_setspidx(m, spidx, 1);
                    832:        if (error)
                    833:                goto bad;
                    834:        spidx->dir = IPSEC_DIR_OUTBOUND;
                    835:
                    836:        return 0;
                    837:
                    838: bad:
                    839:        bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
                    840:        bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
                    841:        return error;
                    842: }
                    843: #endif
                    844:
                    845: /*
                    846:  * configure security policy index (src/dst/proto/sport/dport)
                    847:  * by looking at the content of mbuf.
                    848:  * the caller is responsible for error recovery (like clearing up spidx).
                    849:  */
                    850: static int
1.33      degroote  851: ipsec_setspidx(struct mbuf *m, struct secpolicyindex *spidx, int needport)
1.1       jonathan  852: {
                    853:        struct ip *ip = NULL;
                    854:        struct ip ipbuf;
                    855:        u_int v;
                    856:        struct mbuf *n;
                    857:        int len;
                    858:        int error;
                    859:
                    860:        IPSEC_ASSERT(m != NULL, ("ipsec_setspidx: null mbuf"));
                    861:
                    862:        /*
                    863:         * validate m->m_pkthdr.len.  we see incorrect length if we
                    864:         * mistakenly call this function with inconsistent mbuf chain
                    865:         * (like 4.4BSD tcp/udp processing).  XXX should we panic here?
                    866:         */
                    867:        len = 0;
                    868:        for (n = m; n; n = n->m_next)
                    869:                len += n->m_len;
                    870:        if (m->m_pkthdr.len != len) {
                    871:                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
                    872:                        printf("ipsec_setspidx: "
1.26      degroote  873:                                   "total of m_len(%d) != pkthdr.len(%d), "
                    874:                                   "ignored.\n",
1.1       jonathan  875:                                len, m->m_pkthdr.len));
                    876:                return EINVAL;
                    877:        }
                    878:
                    879:        if (m->m_pkthdr.len < sizeof(struct ip)) {
                    880:                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
                    881:                        printf("ipsec_setspidx: "
1.26      degroote  882:                                "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
                    883:                                m->m_pkthdr.len));
1.1       jonathan  884:                return EINVAL;
                    885:        }
                    886:
                    887:        if (m->m_len >= sizeof(*ip))
                    888:                ip = mtod(m, struct ip *);
                    889:        else {
1.28      degroote  890:                m_copydata(m, 0, sizeof(ipbuf), &ipbuf);
1.1       jonathan  891:                ip = &ipbuf;
                    892:        }
                    893:        v = ip->ip_v;
                    894:        switch (v) {
                    895:        case 4:
                    896:                error = ipsec4_setspidx_ipaddr(m, spidx);
                    897:                if (error)
                    898:                        return error;
                    899:                ipsec4_get_ulp(m, spidx, needport);
                    900:                return 0;
                    901: #ifdef INET6
                    902:        case 6:
                    903:                if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
                    904:                        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
                    905:                                printf("ipsec_setspidx: "
1.26      degroote  906:                                        "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
                    907:                                        "ignored.\n", m->m_pkthdr.len));
1.1       jonathan  908:                        return EINVAL;
                    909:                }
                    910:                error = ipsec6_setspidx_ipaddr(m, spidx);
                    911:                if (error)
                    912:                        return error;
                    913:                ipsec6_get_ulp(m, spidx, needport);
                    914:                return 0;
                    915: #endif
                    916:        default:
                    917:                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
                    918:                        printf("ipsec_setspidx: "
1.26      degroote  919:                                "unknown IP version %u, ignored.\n", v));
1.1       jonathan  920:                return EINVAL;
                    921:        }
                    922: }
                    923:
                    924: static void
                    925: ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
                    926: {
                    927:        u_int8_t nxt;
                    928:        int off;
                    929:
                    930:        /* sanity check */
                    931:        IPSEC_ASSERT(m != NULL, ("ipsec4_get_ulp: null mbuf"));
                    932:        IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),
                    933:                ("ipsec4_get_ulp: packet too short"));
                    934:
                    935:        /* NB: ip_input() flips it into host endian XXX need more checking */
1.8       thorpej   936:        if (m->m_len >= sizeof(struct ip)) {
1.1       jonathan  937:                struct ip *ip = mtod(m, struct ip *);
1.34      adrianp   938:                if (ip->ip_off & IP_OFF_CONVERT(IP_MF | IP_OFFMASK))
1.1       jonathan  939:                        goto done;
                    940:                off = ip->ip_hl << 2;
                    941:                nxt = ip->ip_p;
                    942:        } else {
                    943:                struct ip ih;
                    944:
1.28      degroote  945:                m_copydata(m, 0, sizeof (struct ip), &ih);
1.34      adrianp   946:                if (ih.ip_off & IP_OFF_CONVERT(IP_MF | IP_OFFMASK))
1.1       jonathan  947:                        goto done;
                    948:                off = ih.ip_hl << 2;
                    949:                nxt = ih.ip_p;
                    950:        }
                    951:
                    952:        while (off < m->m_pkthdr.len) {
                    953:                struct ip6_ext ip6e;
                    954:                struct tcphdr th;
                    955:                struct udphdr uh;
1.38      mlelstv   956:                struct icmp icmph;
1.1       jonathan  957:
                    958:                switch (nxt) {
                    959:                case IPPROTO_TCP:
                    960:                        spidx->ul_proto = nxt;
                    961:                        if (!needport)
                    962:                                goto done_proto;
                    963:                        if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
                    964:                                goto done;
1.28      degroote  965:                        m_copydata(m, off, sizeof (th), &th);
1.1       jonathan  966:                        spidx->src.sin.sin_port = th.th_sport;
                    967:                        spidx->dst.sin.sin_port = th.th_dport;
                    968:                        return;
                    969:                case IPPROTO_UDP:
                    970:                        spidx->ul_proto = nxt;
                    971:                        if (!needport)
                    972:                                goto done_proto;
                    973:                        if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
                    974:                                goto done;
1.28      degroote  975:                        m_copydata(m, off, sizeof (uh), &uh);
1.1       jonathan  976:                        spidx->src.sin.sin_port = uh.uh_sport;
                    977:                        spidx->dst.sin.sin_port = uh.uh_dport;
                    978:                        return;
                    979:                case IPPROTO_AH:
                    980:                        if (m->m_pkthdr.len > off + sizeof(ip6e))
                    981:                                goto done;
                    982:                        /* XXX sigh, this works but is totally bogus */
1.28      degroote  983:                        m_copydata(m, off, sizeof(ip6e), &ip6e);
1.1       jonathan  984:                        off += (ip6e.ip6e_len + 2) << 2;
                    985:                        nxt = ip6e.ip6e_nxt;
                    986:                        break;
                    987:                case IPPROTO_ICMP:
1.38      mlelstv   988:                        spidx->ul_proto = nxt;
                    989:                        if (off + sizeof(struct icmp) > m->m_pkthdr.len)
                    990:                                return;
1.39    ! degroote  991:                        m_copydata(m, off, sizeof(icmph), &icmph);
1.38      mlelstv   992:                        ((struct sockaddr_in *)&spidx->src)->sin_port =
                    993:                            htons((uint16_t)icmph.icmp_type);
                    994:                        ((struct sockaddr_in *)&spidx->dst)->sin_port =
                    995:                            htons((uint16_t)icmph.icmp_code);
                    996:                        return;
1.1       jonathan  997:                default:
                    998:                        /* XXX intermediate headers??? */
                    999:                        spidx->ul_proto = nxt;
                   1000:                        goto done_proto;
                   1001:                }
                   1002:        }
                   1003: done:
                   1004:        spidx->ul_proto = IPSEC_ULPROTO_ANY;
                   1005: done_proto:
                   1006:        spidx->src.sin.sin_port = IPSEC_PORT_ANY;
                   1007:        spidx->dst.sin.sin_port = IPSEC_PORT_ANY;
                   1008: }
                   1009:
                   1010: /* assumes that m is sane */
                   1011: static int
                   1012: ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
                   1013: {
                   1014:        static const struct sockaddr_in template = {
                   1015:                sizeof (struct sockaddr_in),
                   1016:                AF_INET,
                   1017:                0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }
                   1018:        };
                   1019:
                   1020:        spidx->src.sin = template;
                   1021:        spidx->dst.sin = template;
                   1022:
                   1023:        if (m->m_len < sizeof (struct ip)) {
                   1024:                m_copydata(m, offsetof(struct ip, ip_src),
                   1025:                           sizeof (struct  in_addr),
1.28      degroote 1026:                           &spidx->src.sin.sin_addr);
1.1       jonathan 1027:                m_copydata(m, offsetof(struct ip, ip_dst),
                   1028:                           sizeof (struct  in_addr),
1.28      degroote 1029:                           &spidx->dst.sin.sin_addr);
1.1       jonathan 1030:        } else {
                   1031:                struct ip *ip = mtod(m, struct ip *);
                   1032:                spidx->src.sin.sin_addr = ip->ip_src;
                   1033:                spidx->dst.sin.sin_addr = ip->ip_dst;
                   1034:        }
                   1035:
                   1036:        spidx->prefs = sizeof(struct in_addr) << 3;
                   1037:        spidx->prefd = sizeof(struct in_addr) << 3;
                   1038:
                   1039:        return 0;
                   1040: }
                   1041:
                   1042: #ifdef INET6
                   1043: static void
1.33      degroote 1044: ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *spidx,
                   1045:               int needport)
1.1       jonathan 1046: {
                   1047:        int off, nxt;
                   1048:        struct tcphdr th;
                   1049:        struct udphdr uh;
1.38      mlelstv  1050:        struct icmp6_hdr icmph;
1.1       jonathan 1051:
                   1052:        /* sanity check */
                   1053:        if (m == NULL)
1.16      christos 1054:                panic("ipsec6_get_ulp: NULL pointer was passed");
1.1       jonathan 1055:
                   1056:        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
                   1057:                printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
                   1058:
                   1059:        /* set default */
                   1060:        spidx->ul_proto = IPSEC_ULPROTO_ANY;
                   1061:        ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
                   1062:        ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
                   1063:
                   1064:        nxt = -1;
                   1065:        off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
                   1066:        if (off < 0 || m->m_pkthdr.len < off)
                   1067:                return;
                   1068:
                   1069:        switch (nxt) {
                   1070:        case IPPROTO_TCP:
                   1071:                spidx->ul_proto = nxt;
                   1072:                if (!needport)
                   1073:                        break;
                   1074:                if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
                   1075:                        break;
1.28      degroote 1076:                m_copydata(m, off, sizeof(th), &th);
1.1       jonathan 1077:                ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
                   1078:                ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
                   1079:                break;
                   1080:        case IPPROTO_UDP:
                   1081:                spidx->ul_proto = nxt;
                   1082:                if (!needport)
                   1083:                        break;
                   1084:                if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
                   1085:                        break;
1.28      degroote 1086:                m_copydata(m, off, sizeof(uh), &uh);
1.1       jonathan 1087:                ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
                   1088:                ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
                   1089:                break;
                   1090:        case IPPROTO_ICMPV6:
1.38      mlelstv  1091:                spidx->ul_proto = nxt;
                   1092:                if (off + sizeof(struct icmp6_hdr) > m->m_pkthdr.len)
                   1093:                        break;
1.39    ! degroote 1094:                m_copydata(m, off, sizeof(icmph), &icmph);
1.38      mlelstv  1095:                ((struct sockaddr_in6 *)&spidx->src)->sin6_port =
                   1096:                    htons((uint16_t)icmph.icmp6_type);
                   1097:                ((struct sockaddr_in6 *)&spidx->dst)->sin6_port =
                   1098:                    htons((uint16_t)icmph.icmp6_code);
                   1099:                break;
1.1       jonathan 1100:        default:
                   1101:                /* XXX intermediate headers??? */
                   1102:                spidx->ul_proto = nxt;
                   1103:                break;
                   1104:        }
                   1105: }
                   1106:
                   1107: /* assumes that m is sane */
                   1108: static int
1.33      degroote 1109: ipsec6_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
1.1       jonathan 1110: {
                   1111:        struct ip6_hdr *ip6 = NULL;
                   1112:        struct ip6_hdr ip6buf;
                   1113:        struct sockaddr_in6 *sin6;
                   1114:
                   1115:        if (m->m_len >= sizeof(*ip6))
                   1116:                ip6 = mtod(m, struct ip6_hdr *);
                   1117:        else {
1.28      degroote 1118:                m_copydata(m, 0, sizeof(ip6buf), &ip6buf);
1.1       jonathan 1119:                ip6 = &ip6buf;
                   1120:        }
                   1121:
                   1122:        sin6 = (struct sockaddr_in6 *)&spidx->src;
                   1123:        bzero(sin6, sizeof(*sin6));
                   1124:        sin6->sin6_family = AF_INET6;
                   1125:        sin6->sin6_len = sizeof(struct sockaddr_in6);
                   1126:        bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
                   1127:        if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
                   1128:                sin6->sin6_addr.s6_addr16[1] = 0;
                   1129:                sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
                   1130:        }
                   1131:        spidx->prefs = sizeof(struct in6_addr) << 3;
                   1132:
                   1133:        sin6 = (struct sockaddr_in6 *)&spidx->dst;
                   1134:        bzero(sin6, sizeof(*sin6));
                   1135:        sin6->sin6_family = AF_INET6;
                   1136:        sin6->sin6_len = sizeof(struct sockaddr_in6);
                   1137:        bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
                   1138:        if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
                   1139:                sin6->sin6_addr.s6_addr16[1] = 0;
                   1140:                sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
                   1141:        }
                   1142:        spidx->prefd = sizeof(struct in6_addr) << 3;
                   1143:
                   1144:        return 0;
                   1145: }
                   1146: #endif
                   1147:
                   1148: static void
1.33      degroote 1149: ipsec_delpcbpolicy(struct inpcbpolicy *p)
1.1       jonathan 1150: {
                   1151:        free(p, M_SECA);
                   1152: }
                   1153:
                   1154: /* initialize policy in PCB */
                   1155: int
1.33      degroote 1156: ipsec_init_policy(struct socket *so, struct inpcbpolicy **pcb_sp)
1.1       jonathan 1157: {
                   1158:        struct inpcbpolicy *new;
                   1159:
                   1160:        /* sanity check. */
                   1161:        if (so == NULL || pcb_sp == NULL)
1.16      christos 1162:                panic("ipsec_init_policy: NULL pointer was passed");
1.1       jonathan 1163:
                   1164:        new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
1.26      degroote 1165:                                                M_SECA, M_NOWAIT|M_ZERO);
1.1       jonathan 1166:        if (new == NULL) {
                   1167:                ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
                   1168:                return ENOBUFS;
                   1169:        }
                   1170:
                   1171:        if (IPSEC_PRIVILEGED_SO(so))
                   1172:                new->priv = 1;
                   1173:        else
                   1174:                new->priv = 0;
                   1175:
                   1176:        if ((new->sp_in = KEY_NEWSP()) == NULL) {
                   1177:                ipsec_delpcbpolicy(new);
                   1178:                return ENOBUFS;
                   1179:        }
                   1180:        new->sp_in->state = IPSEC_SPSTATE_ALIVE;
                   1181:        new->sp_in->policy = IPSEC_POLICY_ENTRUST;
                   1182:
                   1183:        if ((new->sp_out = KEY_NEWSP()) == NULL) {
                   1184:                KEY_FREESP(&new->sp_in);
                   1185:                ipsec_delpcbpolicy(new);
                   1186:                return ENOBUFS;
                   1187:        }
                   1188:        new->sp_out->state = IPSEC_SPSTATE_ALIVE;
                   1189:        new->sp_out->policy = IPSEC_POLICY_ENTRUST;
                   1190:
                   1191:        *pcb_sp = new;
                   1192:
                   1193:        return 0;
                   1194: }
                   1195:
                   1196: /* copy old ipsec policy into new */
                   1197: int
1.33      degroote 1198: ipsec_copy_policy(struct inpcbpolicy *old, struct inpcbpolicy *new)
1.1       jonathan 1199: {
                   1200:        struct secpolicy *sp;
                   1201:
                   1202:        sp = ipsec_deepcopy_policy(old->sp_in);
                   1203:        if (sp) {
                   1204:                KEY_FREESP(&new->sp_in);
                   1205:                new->sp_in = sp;
                   1206:        } else
                   1207:                return ENOBUFS;
                   1208:
                   1209:        sp = ipsec_deepcopy_policy(old->sp_out);
                   1210:        if (sp) {
                   1211:                KEY_FREESP(&new->sp_out);
                   1212:                new->sp_out = sp;
                   1213:        } else
                   1214:                return ENOBUFS;
                   1215:
                   1216:        new->priv = old->priv;
                   1217:
                   1218:        return 0;
                   1219: }
                   1220:
                   1221: /* deep-copy a policy in PCB */
                   1222: static struct secpolicy *
1.33      degroote 1223: ipsec_deepcopy_policy(struct secpolicy *src)
1.1       jonathan 1224: {
                   1225:        struct ipsecrequest *newchain = NULL;
                   1226:        struct ipsecrequest *p;
                   1227:        struct ipsecrequest **q;
                   1228:        struct ipsecrequest *r;
                   1229:        struct secpolicy *dst;
                   1230:
                   1231:        if (src == NULL)
                   1232:                return NULL;
                   1233:        dst = KEY_NEWSP();
                   1234:        if (dst == NULL)
                   1235:                return NULL;
                   1236:
                   1237:        /*
                   1238:         * deep-copy IPsec request chain.  This is required since struct
                   1239:         * ipsecrequest is not reference counted.
                   1240:         */
                   1241:        q = &newchain;
                   1242:        for (p = src->req; p; p = p->next) {
                   1243:                *q = (struct ipsecrequest *)malloc(sizeof(struct ipsecrequest),
                   1244:                        M_SECA, M_NOWAIT);
                   1245:                if (*q == NULL)
                   1246:                        goto fail;
                   1247:                bzero(*q, sizeof(**q));
                   1248:                (*q)->next = NULL;
                   1249:
                   1250:                (*q)->saidx.proto = p->saidx.proto;
                   1251:                (*q)->saidx.mode = p->saidx.mode;
                   1252:                (*q)->level = p->level;
                   1253:                (*q)->saidx.reqid = p->saidx.reqid;
                   1254:
                   1255:                bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
                   1256:                bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
                   1257:
                   1258:                (*q)->sav = NULL;
                   1259:                (*q)->sp = dst;
                   1260:
                   1261:                q = &((*q)->next);
                   1262:        }
                   1263:
                   1264:        dst->req = newchain;
                   1265:        dst->state = src->state;
                   1266:        dst->policy = src->policy;
                   1267:        /* do not touch the refcnt fields */
                   1268:
                   1269:        return dst;
                   1270:
                   1271: fail:
                   1272:        for (p = newchain; p; p = r) {
                   1273:                r = p->next;
                   1274:                free(p, M_SECA);
                   1275:                p = NULL;
                   1276:        }
                   1277:        return NULL;
                   1278: }
                   1279:
                   1280: /* set policy and ipsec request if present. */
                   1281: static int
1.24      christos 1282: ipsec_set_policy(
1.26      degroote 1283:        struct secpolicy **pcb_sp,
                   1284:        int optname,
1.27      christos 1285:        void *request,
1.26      degroote 1286:        size_t len,
                   1287:        int priv
1.24      christos 1288: )
1.1       jonathan 1289: {
                   1290:        struct sadb_x_policy *xpl;
                   1291:        struct secpolicy *newsp = NULL;
                   1292:        int error;
                   1293:
                   1294:        /* sanity check. */
                   1295:        if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
                   1296:                return EINVAL;
                   1297:        if (len < sizeof(*xpl))
                   1298:                return EINVAL;
                   1299:        xpl = (struct sadb_x_policy *)request;
                   1300:
                   1301:        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
                   1302:                printf("ipsec_set_policy: passed policy\n");
                   1303:                kdebug_sadb_x_policy((struct sadb_ext *)xpl));
                   1304:
                   1305:        /* check policy type */
                   1306:        /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
                   1307:        if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
                   1308:         || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
                   1309:                return EINVAL;
                   1310:
                   1311:        /* check privileged socket */
                   1312:        if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
                   1313:                return EACCES;
                   1314:
                   1315:        /* allocation new SP entry */
                   1316:        if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
                   1317:                return error;
                   1318:
                   1319:        newsp->state = IPSEC_SPSTATE_ALIVE;
                   1320:
                   1321:        /* clear old SP and set new SP */
                   1322:        KEY_FREESP(pcb_sp);
                   1323:        *pcb_sp = newsp;
                   1324:        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
                   1325:                printf("ipsec_set_policy: new policy\n");
                   1326:                kdebug_secpolicy(newsp));
                   1327:
                   1328:        return 0;
                   1329: }
                   1330:
                   1331: static int
1.33      degroote 1332: ipsec_get_policy(struct secpolicy *pcb_sp, struct mbuf **mp)
1.1       jonathan 1333: {
                   1334:
                   1335:        /* sanity check. */
                   1336:        if (pcb_sp == NULL || mp == NULL)
                   1337:                return EINVAL;
                   1338:
                   1339:        *mp = key_sp2msg(pcb_sp);
                   1340:        if (!*mp) {
                   1341:                ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
                   1342:                return ENOBUFS;
                   1343:        }
                   1344:
                   1345:        (*mp)->m_type = MT_DATA;
                   1346:        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
                   1347:                printf("ipsec_get_policy:\n");
                   1348:                kdebug_mbuf(*mp));
                   1349:
                   1350:        return 0;
                   1351: }
                   1352:
                   1353: int
1.33      degroote 1354: ipsec4_set_policy(struct inpcb *inp, int optname ,void *request,
                   1355:                  size_t len, int priv)
1.1       jonathan 1356: {
                   1357:        struct sadb_x_policy *xpl;
                   1358:        struct secpolicy **pcb_sp;
                   1359:
                   1360:        /* sanity check. */
                   1361:        if (inp == NULL || request == NULL)
                   1362:                return EINVAL;
                   1363:        if (len < sizeof(*xpl))
                   1364:                return EINVAL;
                   1365:        xpl = (struct sadb_x_policy *)request;
                   1366:
                   1367:        IPSEC_ASSERT(inp->inp_sp != NULL,
1.26      degroote 1368:                         ("ipsec4_set_policy(): null inp->in_sp"));
1.1       jonathan 1369:
                   1370:        /* select direction */
                   1371:        switch (xpl->sadb_x_policy_dir) {
                   1372:        case IPSEC_DIR_INBOUND:
                   1373:                pcb_sp = &inp->inp_sp->sp_in;
                   1374:                break;
                   1375:        case IPSEC_DIR_OUTBOUND:
                   1376:                pcb_sp = &inp->inp_sp->sp_out;
                   1377:                break;
                   1378:        default:
                   1379:                ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
                   1380:                        xpl->sadb_x_policy_dir));
                   1381:                return EINVAL;
                   1382:        }
                   1383:
                   1384:        return ipsec_set_policy(pcb_sp, optname, request, len, priv);
                   1385: }
                   1386:
                   1387: int
1.33      degroote 1388: ipsec4_get_policy(struct inpcb *inp, void *request, size_t len,
                   1389:                  struct mbuf **mp)
1.1       jonathan 1390: {
                   1391:        struct sadb_x_policy *xpl;
                   1392:        struct secpolicy *pcb_sp;
                   1393:
                   1394:        /* sanity check. */
                   1395:        if (inp == NULL || request == NULL || mp == NULL)
                   1396:                return EINVAL;
                   1397:        IPSEC_ASSERT(inp->inp_sp != NULL, ("ipsec4_get_policy: null inp_sp"));
                   1398:        if (len < sizeof(*xpl))
                   1399:                return EINVAL;
                   1400:        xpl = (struct sadb_x_policy *)request;
                   1401:
                   1402:        /* select direction */
                   1403:        switch (xpl->sadb_x_policy_dir) {
                   1404:        case IPSEC_DIR_INBOUND:
                   1405:                pcb_sp = inp->inp_sp->sp_in;
                   1406:                break;
                   1407:        case IPSEC_DIR_OUTBOUND:
                   1408:                pcb_sp = inp->inp_sp->sp_out;
                   1409:                break;
                   1410:        default:
                   1411:                ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
                   1412:                        xpl->sadb_x_policy_dir));
                   1413:                return EINVAL;
                   1414:        }
                   1415:
                   1416:        return ipsec_get_policy(pcb_sp, mp);
                   1417: }
                   1418:
                   1419: /* delete policy in PCB */
                   1420: int
1.33      degroote 1421: ipsec4_delete_pcbpolicy(struct inpcb *inp)
1.1       jonathan 1422: {
                   1423:        IPSEC_ASSERT(inp != NULL, ("ipsec4_delete_pcbpolicy: null inp"));
                   1424:
                   1425:        if (inp->inp_sp == NULL)
                   1426:                return 0;
                   1427:
                   1428:        if (inp->inp_sp->sp_in != NULL)
                   1429:                KEY_FREESP(&inp->inp_sp->sp_in);
                   1430:
                   1431:        if (inp->inp_sp->sp_out != NULL)
                   1432:                KEY_FREESP(&inp->inp_sp->sp_out);
                   1433:
                   1434:        ipsec_delpcbpolicy(inp->inp_sp);
                   1435:        inp->inp_sp = NULL;
                   1436:
                   1437:        return 0;
                   1438: }
                   1439:
                   1440: #ifdef INET6
                   1441: int
1.33      degroote 1442: ipsec6_set_policy(struct in6pcb *in6p, int optname, void *request,
                   1443:                  size_t len, int priv)
1.1       jonathan 1444: {
                   1445:        struct sadb_x_policy *xpl;
                   1446:        struct secpolicy **pcb_sp;
                   1447:
                   1448:        /* sanity check. */
                   1449:        if (in6p == NULL || request == NULL)
                   1450:                return EINVAL;
                   1451:        if (len < sizeof(*xpl))
                   1452:                return EINVAL;
                   1453:        xpl = (struct sadb_x_policy *)request;
                   1454:
                   1455:        /* select direction */
                   1456:        switch (xpl->sadb_x_policy_dir) {
                   1457:        case IPSEC_DIR_INBOUND:
                   1458:                pcb_sp = &in6p->in6p_sp->sp_in;
                   1459:                break;
                   1460:        case IPSEC_DIR_OUTBOUND:
                   1461:                pcb_sp = &in6p->in6p_sp->sp_out;
                   1462:                break;
                   1463:        default:
                   1464:                ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
                   1465:                        xpl->sadb_x_policy_dir));
                   1466:                return EINVAL;
                   1467:        }
                   1468:
                   1469:        return ipsec_set_policy(pcb_sp, optname, request, len, priv);
                   1470: }
                   1471:
                   1472: int
1.33      degroote 1473: ipsec6_get_policy(struct in6pcb *in6p, void *request, size_t len,
                   1474:                  struct mbuf **mp)
1.1       jonathan 1475: {
                   1476:        struct sadb_x_policy *xpl;
                   1477:        struct secpolicy *pcb_sp;
                   1478:
                   1479:        /* sanity check. */
                   1480:        if (in6p == NULL || request == NULL || mp == NULL)
                   1481:                return EINVAL;
                   1482:        IPSEC_ASSERT(in6p->in6p_sp != NULL, ("ipsec6_get_policy: null in6p_sp"));
                   1483:        if (len < sizeof(*xpl))
                   1484:                return EINVAL;
                   1485:        xpl = (struct sadb_x_policy *)request;
                   1486:
                   1487:        /* select direction */
                   1488:        switch (xpl->sadb_x_policy_dir) {
                   1489:        case IPSEC_DIR_INBOUND:
                   1490:                pcb_sp = in6p->in6p_sp->sp_in;
                   1491:                break;
                   1492:        case IPSEC_DIR_OUTBOUND:
                   1493:                pcb_sp = in6p->in6p_sp->sp_out;
                   1494:                break;
                   1495:        default:
                   1496:                ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
                   1497:                        xpl->sadb_x_policy_dir));
                   1498:                return EINVAL;
                   1499:        }
                   1500:
                   1501:        return ipsec_get_policy(pcb_sp, mp);
                   1502: }
                   1503:
                   1504: int
1.33      degroote 1505: ipsec6_delete_pcbpolicy(struct in6pcb *in6p)
1.1       jonathan 1506: {
                   1507:        IPSEC_ASSERT(in6p != NULL, ("ipsec6_delete_pcbpolicy: null in6p"));
                   1508:
                   1509:        if (in6p->in6p_sp == NULL)
                   1510:                return 0;
                   1511:
                   1512:        if (in6p->in6p_sp->sp_in != NULL)
                   1513:                KEY_FREESP(&in6p->in6p_sp->sp_in);
                   1514:
                   1515:        if (in6p->in6p_sp->sp_out != NULL)
                   1516:                KEY_FREESP(&in6p->in6p_sp->sp_out);
                   1517:
                   1518:        ipsec_delpcbpolicy(in6p->in6p_sp);
                   1519:        in6p->in6p_sp = NULL;
                   1520:
                   1521:        return 0;
                   1522: }
                   1523: #endif
                   1524:
                   1525: /*
                   1526:  * return current level.
                   1527:  * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
                   1528:  */
                   1529: u_int
1.33      degroote 1530: ipsec_get_reqlevel(struct ipsecrequest *isr)
1.1       jonathan 1531: {
                   1532:        u_int level = 0;
                   1533:        u_int esp_trans_deflev, esp_net_deflev;
                   1534:        u_int ah_trans_deflev, ah_net_deflev;
                   1535:
                   1536:        IPSEC_ASSERT(isr != NULL && isr->sp != NULL,
                   1537:                ("ipsec_get_reqlevel: null argument"));
                   1538:        IPSEC_ASSERT(isr->sp->spidx.src.sa.sa_family == isr->sp->spidx.dst.sa.sa_family,
                   1539:                ("ipsec_get_reqlevel: af family mismatch, src %u, dst %u",
                   1540:                 isr->sp->spidx.src.sa.sa_family,
                   1541:                 isr->sp->spidx.dst.sa.sa_family));
                   1542:
                   1543: /* XXX note that we have ipseclog() expanded here - code sync issue */
                   1544: #define IPSEC_CHECK_DEFAULT(lev) \
1.26      degroote 1545:        (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE                \
                   1546:                        && (lev) != IPSEC_LEVEL_UNIQUE)                           \
                   1547:                ? (ipsec_debug                                                    \
1.1       jonathan 1548:                        ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1.26      degroote 1549:                                (lev), IPSEC_LEVEL_REQUIRE)                       \
                   1550:                        : 0),                                                     \
                   1551:                        (lev) = IPSEC_LEVEL_REQUIRE,                              \
                   1552:                        (lev)                                                     \
1.1       jonathan 1553:                : (lev))
                   1554:
                   1555:        /* set default level */
                   1556:        switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
                   1557: #ifdef INET
                   1558:        case AF_INET:
                   1559:                esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
                   1560:                esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
                   1561:                ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
                   1562:                ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
                   1563:                break;
                   1564: #endif
                   1565: #ifdef INET6
                   1566:        case AF_INET6:
                   1567:                esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
                   1568:                esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
                   1569:                ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
                   1570:                ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
                   1571:                break;
                   1572: #endif /* INET6 */
                   1573:        default:
                   1574:                panic("key_get_reqlevel: unknown af %u",
1.26      degroote 1575:                        isr->sp->spidx.src.sa.sa_family);
1.1       jonathan 1576:        }
                   1577:
                   1578: #undef IPSEC_CHECK_DEFAULT
                   1579:
                   1580:        /* set level */
                   1581:        switch (isr->level) {
                   1582:        case IPSEC_LEVEL_DEFAULT:
                   1583:                switch (isr->saidx.proto) {
                   1584:                case IPPROTO_ESP:
                   1585:                        if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
                   1586:                                level = esp_net_deflev;
                   1587:                        else
                   1588:                                level = esp_trans_deflev;
                   1589:                        break;
                   1590:                case IPPROTO_AH:
                   1591:                        if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
                   1592:                                level = ah_net_deflev;
                   1593:                        else
                   1594:                                level = ah_trans_deflev;
1.14      jonathan 1595:                        break;
1.1       jonathan 1596:                case IPPROTO_IPCOMP:
                   1597:                        /*
                   1598:                         * we don't really care, as IPcomp document says that
                   1599:                         * we shouldn't compress small packets
                   1600:                         */
                   1601:                        level = IPSEC_LEVEL_USE;
                   1602:                        break;
                   1603:                default:
1.16      christos 1604:                        panic("ipsec_get_reqlevel: Illegal protocol defined %u",
1.26      degroote 1605:                                isr->saidx.proto);
1.1       jonathan 1606:                }
                   1607:                break;
                   1608:
                   1609:        case IPSEC_LEVEL_USE:
                   1610:        case IPSEC_LEVEL_REQUIRE:
                   1611:                level = isr->level;
                   1612:                break;
                   1613:        case IPSEC_LEVEL_UNIQUE:
                   1614:                level = IPSEC_LEVEL_REQUIRE;
                   1615:                break;
                   1616:
                   1617:        default:
1.16      christos 1618:                panic("ipsec_get_reqlevel: Illegal IPsec level %u",
1.1       jonathan 1619:                        isr->level);
                   1620:        }
                   1621:
                   1622:        return level;
                   1623: }
                   1624:
                   1625: /*
                   1626:  * Check security policy requirements against the actual
                   1627:  * packet contents.  Return one if the packet should be
                   1628:  * reject as "invalid"; otherwiser return zero to have the
                   1629:  * packet treated as "valid".
                   1630:  *
                   1631:  * OUT:
                   1632:  *     0: valid
                   1633:  *     1: invalid
                   1634:  */
                   1635: int
                   1636: ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
                   1637: {
                   1638:        struct ipsecrequest *isr;
                   1639:        int need_auth;
                   1640:
                   1641:        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
                   1642:                printf("ipsec_in_reject: using SP\n");
                   1643:                kdebug_secpolicy(sp));
                   1644:
                   1645:        /* check policy */
                   1646:        switch (sp->policy) {
                   1647:        case IPSEC_POLICY_DISCARD:
                   1648:                return 1;
                   1649:        case IPSEC_POLICY_BYPASS:
                   1650:        case IPSEC_POLICY_NONE:
                   1651:                return 0;
                   1652:        }
                   1653:
                   1654:        IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
                   1655:                ("ipsec_in_reject: invalid policy %u", sp->policy));
                   1656:
                   1657:        /* XXX should compare policy against ipsec header history */
                   1658:
                   1659:        need_auth = 0;
                   1660:        for (isr = sp->req; isr != NULL; isr = isr->next) {
                   1661:                if (ipsec_get_reqlevel(isr) != IPSEC_LEVEL_REQUIRE)
                   1662:                        continue;
                   1663:                switch (isr->saidx.proto) {
                   1664:                case IPPROTO_ESP:
                   1665:                        if ((m->m_flags & M_DECRYPTED) == 0) {
                   1666:                                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1.26      degroote 1667:                                        printf("ipsec_in_reject: ESP m_flags:%x\n",
                   1668:                                                m->m_flags));
1.1       jonathan 1669:                                return 1;
                   1670:                        }
                   1671:
                   1672:                        if (!need_auth &&
1.26      degroote 1673:                                isr->sav != NULL &&
                   1674:                                isr->sav->tdb_authalgxform != NULL &&
                   1675:                                (m->m_flags & M_AUTHIPDGM) == 0) {
1.1       jonathan 1676:                                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1.26      degroote 1677:                                        printf("ipsec_in_reject: ESP/AH m_flags:%x\n",
                   1678:                                                m->m_flags));
1.1       jonathan 1679:                                return 1;
                   1680:                        }
                   1681:                        break;
                   1682:                case IPPROTO_AH:
                   1683:                        need_auth = 1;
                   1684:                        if ((m->m_flags & M_AUTHIPHDR) == 0) {
                   1685:                                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1.26      degroote 1686:                                        printf("ipsec_in_reject: AH m_flags:%x\n",
                   1687:                                                m->m_flags));
1.1       jonathan 1688:                                return 1;
                   1689:                        }
                   1690:                        break;
                   1691:                case IPPROTO_IPCOMP:
                   1692:                        /*
                   1693:                         * we don't really care, as IPcomp document
                   1694:                         * says that we shouldn't compress small
                   1695:                         * packets, IPComp policy should always be
                   1696:                         * treated as being in "use" level.
                   1697:                         */
                   1698:                        break;
                   1699:                }
                   1700:        }
                   1701:        return 0;               /* valid */
                   1702: }
                   1703:
                   1704: /*
                   1705:  * Check AH/ESP integrity.
                   1706:  * This function is called from tcp_input(), udp_input(),
                   1707:  * and {ah,esp}4_input for tunnel mode
                   1708:  */
                   1709: int
1.33      degroote 1710: ipsec4_in_reject(struct mbuf *m, struct inpcb *inp)
1.1       jonathan 1711: {
                   1712:        struct secpolicy *sp;
                   1713:        int error;
                   1714:        int result;
                   1715:
                   1716:        IPSEC_ASSERT(m != NULL, ("ipsec4_in_reject_so: null mbuf"));
                   1717:
                   1718:        /* get SP for this packet.
                   1719:         * When we are called from ip_forward(), we call
                   1720:         * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
                   1721:         */
                   1722:        if (inp == NULL)
                   1723:                sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
                   1724:        else
1.5       jonathan 1725:                sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND,
                   1726:                                           IN4PCB_TO_PCB(inp), &error);
1.1       jonathan 1727:
                   1728:        if (sp != NULL) {
                   1729:                result = ipsec_in_reject(sp, m);
                   1730:                if (result)
1.37      thorpej  1731:                        IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
1.1       jonathan 1732:                KEY_FREESP(&sp);
                   1733:        } else {
                   1734:                result = 0;     /* XXX should be panic ?
                   1735:                                 * -> No, there may be error. */
                   1736:        }
                   1737:        return result;
                   1738: }
                   1739:
                   1740:
                   1741: #ifdef INET6
                   1742: /*
                   1743:  * Check AH/ESP integrity.
                   1744:  * This function is called from tcp6_input(), udp6_input(),
                   1745:  * and {ah,esp}6_input for tunnel mode
                   1746:  */
                   1747: int
1.33      degroote 1748: ipsec6_in_reject(struct mbuf *m, struct in6pcb *in6p)
1.1       jonathan 1749: {
                   1750:        struct secpolicy *sp = NULL;
                   1751:        int error;
                   1752:        int result;
                   1753:
                   1754:        /* sanity check */
                   1755:        if (m == NULL)
                   1756:                return 0;       /* XXX should be panic ? */
                   1757:
                   1758:        /* get SP for this packet.
                   1759:         * When we are called from ip_forward(), we call
                   1760:         * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
                   1761:         */
1.5       jonathan 1762:        if (in6p == NULL)
1.1       jonathan 1763:                sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
                   1764:        else
1.5       jonathan 1765:                sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND,
                   1766:                        IN6PCB_TO_PCB(in6p),
                   1767:                        &error);
1.1       jonathan 1768:
                   1769:        if (sp != NULL) {
                   1770:                result = ipsec_in_reject(sp, m);
                   1771:                if (result)
1.37      thorpej  1772:                        IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
1.1       jonathan 1773:                KEY_FREESP(&sp);
                   1774:        } else {
                   1775:                result = 0;
                   1776:        }
                   1777:        return result;
                   1778: }
                   1779: #endif
                   1780:
                   1781: /*
                   1782:  * compute the byte size to be occupied by IPsec header.
                   1783:  * in case it is tunneled, it includes the size of outer IP header.
                   1784:  * NOTE: SP passed is free in this function.
                   1785:  */
                   1786: static size_t
                   1787: ipsec_hdrsiz(struct secpolicy *sp)
                   1788: {
                   1789:        struct ipsecrequest *isr;
                   1790:        size_t siz;
                   1791:
                   1792:        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
                   1793:                printf("ipsec_hdrsiz: using SP\n");
                   1794:                kdebug_secpolicy(sp));
                   1795:
                   1796:        switch (sp->policy) {
                   1797:        case IPSEC_POLICY_DISCARD:
                   1798:        case IPSEC_POLICY_BYPASS:
                   1799:        case IPSEC_POLICY_NONE:
                   1800:                return 0;
                   1801:        }
                   1802:
                   1803:        IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
                   1804:                ("ipsec_hdrsiz: invalid policy %u", sp->policy));
                   1805:
                   1806:        siz = 0;
                   1807:        for (isr = sp->req; isr != NULL; isr = isr->next) {
                   1808:                size_t clen = 0;
                   1809:
                   1810:                switch (isr->saidx.proto) {
                   1811:                case IPPROTO_ESP:
                   1812:                        clen = esp_hdrsiz(isr->sav);
                   1813:                        break;
                   1814:                case IPPROTO_AH:
                   1815:                        clen = ah_hdrsiz(isr->sav);
                   1816:                        break;
                   1817:                case IPPROTO_IPCOMP:
                   1818:                        clen = sizeof(struct ipcomp);
                   1819:                        break;
                   1820:                }
                   1821:
                   1822:                if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
                   1823:                        switch (isr->saidx.dst.sa.sa_family) {
                   1824:                        case AF_INET:
                   1825:                                clen += sizeof(struct ip);
                   1826:                                break;
                   1827: #ifdef INET6
                   1828:                        case AF_INET6:
                   1829:                                clen += sizeof(struct ip6_hdr);
                   1830:                                break;
                   1831: #endif
                   1832:                        default:
                   1833:                                ipseclog((LOG_ERR, "ipsec_hdrsiz: "
1.26      degroote 1834:                                        "unknown AF %d in IPsec tunnel SA\n",
                   1835:                                        ((struct sockaddr *)&isr->saidx.dst)->sa_family));
1.1       jonathan 1836:                                break;
                   1837:                        }
                   1838:                }
                   1839:                siz += clen;
                   1840:        }
                   1841:
                   1842:        return siz;
                   1843: }
                   1844:
                   1845: /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
                   1846: size_t
1.33      degroote 1847: ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp)
1.1       jonathan 1848: {
                   1849:        struct secpolicy *sp;
                   1850:        int error;
                   1851:        size_t size;
                   1852:
                   1853:        IPSEC_ASSERT(m != NULL, ("ipsec4_hdrsiz: null mbuf"));
                   1854:        IPSEC_ASSERT(inp == NULL || inp->inp_socket != NULL,
                   1855:                ("ipsec4_hdrsize: socket w/o inpcb"));
                   1856:
                   1857:        /* get SP for this packet.
                   1858:         * When we are called from ip_forward(), we call
                   1859:         * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
                   1860:         */
                   1861:        if (inp == NULL)
                   1862:                sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
                   1863:        else
1.5       jonathan 1864:                sp = ipsec_getpolicybysock(m, dir,
                   1865:                                           IN4PCB_TO_PCB(inp), &error);
1.1       jonathan 1866:
                   1867:        if (sp != NULL) {
                   1868:                size = ipsec_hdrsiz(sp);
                   1869:                KEYDEBUG(KEYDEBUG_IPSEC_DATA,
                   1870:                        printf("ipsec4_hdrsiz: size:%lu.\n",
                   1871:                                (unsigned long)size));
                   1872:
                   1873:                KEY_FREESP(&sp);
                   1874:        } else {
                   1875:                size = 0;       /* XXX should be panic ? */
                   1876:        }
                   1877:        return size;
                   1878: }
                   1879:
                   1880: #ifdef INET6
                   1881: /* This function is called from ipsec6_hdrsize_tcp(),
                   1882:  * and maybe from ip6_forward.()
                   1883:  */
                   1884: size_t
1.33      degroote 1885: ipsec6_hdrsiz(struct mbuf *m, u_int dir, struct in6pcb *in6p)
1.1       jonathan 1886: {
                   1887:        struct secpolicy *sp;
                   1888:        int error;
                   1889:        size_t size;
                   1890:
                   1891:        IPSEC_ASSERT(m != NULL, ("ipsec6_hdrsiz: null mbuf"));
                   1892:        IPSEC_ASSERT(in6p == NULL || in6p->in6p_socket != NULL,
                   1893:                ("ipsec6_hdrsize: socket w/o inpcb"));
                   1894:
                   1895:        /* get SP for this packet */
                   1896:        /* XXX Is it right to call with IP_FORWARDING. */
                   1897:        if (in6p == NULL)
                   1898:                sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
                   1899:        else
1.15      perry    1900:                sp = ipsec_getpolicybysock(m, dir,
1.5       jonathan 1901:                        IN6PCB_TO_PCB(in6p),
                   1902:                        &error);
1.1       jonathan 1903:
                   1904:        if (sp == NULL)
                   1905:                return 0;
                   1906:        size = ipsec_hdrsiz(sp);
                   1907:        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
                   1908:                printf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
                   1909:        KEY_FREESP(&sp);
                   1910:
                   1911:        return size;
                   1912: }
                   1913: #endif /*INET6*/
                   1914:
                   1915: /*
                   1916:  * Check the variable replay window.
                   1917:  * ipsec_chkreplay() performs replay check before ICV verification.
                   1918:  * ipsec_updatereplay() updates replay bitmap.  This must be called after
                   1919:  * ICV verification (it also performs replay check, which is usually done
                   1920:  * beforehand).
                   1921:  * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
                   1922:  *
                   1923:  * based on RFC 2401.
                   1924:  */
                   1925: int
1.33      degroote 1926: ipsec_chkreplay(u_int32_t seq, struct secasvar *sav)
1.1       jonathan 1927: {
                   1928:        const struct secreplay *replay;
                   1929:        u_int32_t diff;
                   1930:        int fr;
                   1931:        u_int32_t wsizeb;       /* constant: bits of window size */
                   1932:        int frlast;             /* constant: last frame */
                   1933:
                   1934:        IPSEC_SPLASSERT_SOFTNET("ipsec_chkreplay");
                   1935:
                   1936:        IPSEC_ASSERT(sav != NULL, ("ipsec_chkreplay: Null SA"));
                   1937:        IPSEC_ASSERT(sav->replay != NULL, ("ipsec_chkreplay: Null replay state"));
                   1938:
                   1939:        replay = sav->replay;
                   1940:
                   1941:        if (replay->wsize == 0)
                   1942:                return 1;       /* no need to check replay. */
                   1943:
                   1944:        /* constant */
                   1945:        frlast = replay->wsize - 1;
                   1946:        wsizeb = replay->wsize << 3;
                   1947:
                   1948:        /* sequence number of 0 is invalid */
                   1949:        if (seq == 0)
                   1950:                return 0;
                   1951:
                   1952:        /* first time is always okay */
                   1953:        if (replay->count == 0)
                   1954:                return 1;
                   1955:
                   1956:        if (seq > replay->lastseq) {
                   1957:                /* larger sequences are okay */
                   1958:                return 1;
                   1959:        } else {
                   1960:                /* seq is equal or less than lastseq. */
                   1961:                diff = replay->lastseq - seq;
                   1962:
                   1963:                /* over range to check, i.e. too old or wrapped */
                   1964:                if (diff >= wsizeb)
                   1965:                        return 0;
                   1966:
                   1967:                fr = frlast - diff / 8;
                   1968:
                   1969:                /* this packet already seen ? */
                   1970:                if ((replay->bitmap)[fr] & (1 << (diff % 8)))
                   1971:                        return 0;
                   1972:
                   1973:                /* out of order but good */
                   1974:                return 1;
                   1975:        }
                   1976: }
                   1977:
                   1978: /*
                   1979:  * check replay counter whether to update or not.
                   1980:  * OUT:        0:      OK
                   1981:  *     1:      NG
                   1982:  */
                   1983: int
1.33      degroote 1984: ipsec_updatereplay(u_int32_t seq, struct secasvar *sav)
1.1       jonathan 1985: {
                   1986:        struct secreplay *replay;
                   1987:        u_int32_t diff;
                   1988:        int fr;
                   1989:        u_int32_t wsizeb;       /* constant: bits of window size */
                   1990:        int frlast;             /* constant: last frame */
                   1991:
                   1992:        IPSEC_SPLASSERT_SOFTNET("ipsec_updatereplay");
                   1993:
                   1994:        IPSEC_ASSERT(sav != NULL, ("ipsec_updatereplay: Null SA"));
                   1995:        IPSEC_ASSERT(sav->replay != NULL, ("ipsec_updatereplay: Null replay state"));
                   1996:
                   1997:        replay = sav->replay;
                   1998:
                   1999:        if (replay->wsize == 0)
                   2000:                goto ok;        /* no need to check replay. */
                   2001:
                   2002:        /* constant */
                   2003:        frlast = replay->wsize - 1;
                   2004:        wsizeb = replay->wsize << 3;
                   2005:
                   2006:        /* sequence number of 0 is invalid */
                   2007:        if (seq == 0)
                   2008:                return 1;
                   2009:
                   2010:        /* first time */
                   2011:        if (replay->count == 0) {
                   2012:                replay->lastseq = seq;
                   2013:                bzero(replay->bitmap, replay->wsize);
                   2014:                (replay->bitmap)[frlast] = 1;
                   2015:                goto ok;
                   2016:        }
                   2017:
                   2018:        if (seq > replay->lastseq) {
                   2019:                /* seq is larger than lastseq. */
                   2020:                diff = seq - replay->lastseq;
                   2021:
                   2022:                /* new larger sequence number */
                   2023:                if (diff < wsizeb) {
                   2024:                        /* In window */
                   2025:                        /* set bit for this packet */
                   2026:                        vshiftl(replay->bitmap, diff, replay->wsize);
                   2027:                        (replay->bitmap)[frlast] |= 1;
                   2028:                } else {
                   2029:                        /* this packet has a "way larger" */
                   2030:                        bzero(replay->bitmap, replay->wsize);
                   2031:                        (replay->bitmap)[frlast] = 1;
                   2032:                }
                   2033:                replay->lastseq = seq;
                   2034:
                   2035:                /* larger is good */
                   2036:        } else {
                   2037:                /* seq is equal or less than lastseq. */
                   2038:                diff = replay->lastseq - seq;
                   2039:
                   2040:                /* over range to check, i.e. too old or wrapped */
                   2041:                if (diff >= wsizeb)
                   2042:                        return 1;
                   2043:
                   2044:                fr = frlast - diff / 8;
                   2045:
                   2046:                /* this packet already seen ? */
                   2047:                if ((replay->bitmap)[fr] & (1 << (diff % 8)))
                   2048:                        return 1;
                   2049:
                   2050:                /* mark as seen */
                   2051:                (replay->bitmap)[fr] |= (1 << (diff % 8));
                   2052:
                   2053:                /* out of order but good */
                   2054:        }
                   2055:
                   2056: ok:
                   2057:        if (replay->count == ~0) {
                   2058:
                   2059:                /* set overflow flag */
                   2060:                replay->overflow++;
                   2061:
                   2062:                /* don't increment, no more packets accepted */
                   2063:                if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
                   2064:                        return 1;
                   2065:
                   2066:                ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
1.26      degroote 2067:                        replay->overflow, ipsec_logsastr(sav)));
1.1       jonathan 2068:        }
                   2069:
                   2070:        replay->count++;
                   2071:
                   2072:        return 0;
                   2073: }
                   2074:
                   2075: /*
                   2076:  * shift variable length bunffer to left.
                   2077:  * IN: bitmap: pointer to the buffer
                   2078:  *     nbit:   the number of to shift.
                   2079:  *     wsize:  buffer size (bytes).
                   2080:  */
                   2081: static void
1.33      degroote 2082: vshiftl(unsigned char *bitmap, int nbit, int wsize)
1.1       jonathan 2083: {
                   2084:        int s, j, i;
                   2085:        unsigned char over;
                   2086:
                   2087:        for (j = 0; j < nbit; j += 8) {
                   2088:                s = (nbit - j < 8) ? (nbit - j): 8;
                   2089:                bitmap[0] <<= s;
                   2090:                for (i = 1; i < wsize; i++) {
                   2091:                        over = (bitmap[i] >> (8 - s));
                   2092:                        bitmap[i] <<= s;
                   2093:                        bitmap[i-1] |= over;
                   2094:                }
                   2095:        }
                   2096:
                   2097:        return;
                   2098: }
                   2099:
                   2100: /* Return a printable string for the IPv4 address. */
                   2101: static char *
                   2102: inet_ntoa4(struct in_addr ina)
                   2103: {
                   2104:        static char buf[4][4 * sizeof "123" + 4];
                   2105:        unsigned char *ucp = (unsigned char *) &ina;
                   2106:        static int i = 3;
                   2107:
                   2108:        i = (i + 1) % 4;
1.11      itojun   2109:        snprintf(buf[i], sizeof(buf[i]), "%d.%d.%d.%d",
1.26      degroote 2110:                ucp[0] & 0xff, ucp[1] & 0xff, ucp[2] & 0xff, ucp[3] & 0xff);
1.1       jonathan 2111:        return (buf[i]);
                   2112: }
                   2113:
                   2114: /* Return a printable string for the address. */
1.17      christos 2115: const char *
1.1       jonathan 2116: ipsec_address(union sockaddr_union* sa)
                   2117: {
                   2118:        switch (sa->sa.sa_family) {
                   2119: #if INET
                   2120:        case AF_INET:
                   2121:                return inet_ntoa4(sa->sin.sin_addr);
                   2122: #endif /* INET */
                   2123:
                   2124: #if INET6
                   2125:        case AF_INET6:
                   2126:                return ip6_sprintf(&sa->sin6.sin6_addr);
                   2127: #endif /* INET6 */
                   2128:
                   2129:        default:
                   2130:                return "(unknown address family)";
                   2131:        }
                   2132: }
                   2133:
                   2134: const char *
1.33      degroote 2135: ipsec_logsastr(struct secasvar *sav)
1.1       jonathan 2136: {
                   2137:        static char buf[256];
                   2138:        char *p;
                   2139:        struct secasindex *saidx = &sav->sah->saidx;
                   2140:
                   2141:        IPSEC_ASSERT(saidx->src.sa.sa_family == saidx->dst.sa.sa_family,
                   2142:                ("ipsec_logsastr: address family mismatch"));
                   2143:
                   2144:        p = buf;
                   2145:        snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
                   2146:        while (p && *p)
                   2147:                p++;
                   2148:        /* NB: only use ipsec_address on one address at a time */
                   2149:        snprintf(p, sizeof (buf) - (p - buf), "src=%s ",
                   2150:                ipsec_address(&saidx->src));
                   2151:        while (p && *p)
                   2152:                p++;
                   2153:        snprintf(p, sizeof (buf) - (p - buf), "dst=%s)",
                   2154:                ipsec_address(&saidx->dst));
                   2155:
                   2156:        return buf;
                   2157: }
                   2158:
                   2159: void
1.33      degroote 2160: ipsec_dumpmbuf(struct mbuf *m)
1.1       jonathan 2161: {
                   2162:        int totlen;
                   2163:        int i;
                   2164:        u_char *p;
                   2165:
                   2166:        totlen = 0;
                   2167:        printf("---\n");
                   2168:        while (m) {
                   2169:                p = mtod(m, u_char *);
                   2170:                for (i = 0; i < m->m_len; i++) {
                   2171:                        printf("%02x ", p[i]);
                   2172:                        totlen++;
                   2173:                        if (totlen % 16 == 0)
                   2174:                                printf("\n");
                   2175:                }
                   2176:                m = m->m_next;
                   2177:        }
                   2178:        if (totlen % 16 != 0)
                   2179:                printf("\n");
                   2180:        printf("---\n");
                   2181: }
                   2182:
1.26      degroote 2183: #ifdef INET6
                   2184: struct secpolicy *
1.33      degroote 2185: ipsec6_check_policy(struct mbuf * m, const struct socket * so,
                   2186:                    int flags, int * needipsecp, int * errorp)
1.26      degroote 2187: {
                   2188:        struct in6pcb *in6p = NULL;
                   2189:        struct secpolicy *sp = NULL;
                   2190:        int s;
                   2191:        int error = 0;
                   2192:        int needipsec = 0;
                   2193:
                   2194:        if (so != NULL && so->so_proto->pr_domain->dom_family == AF_INET6)
                   2195:                in6p = sotoin6pcb(so);
                   2196:
1.36      degroote 2197:        if (!ipsec_outdone(m)) {
                   2198:                s = splsoftnet();
1.26      degroote 2199:                if (in6p != NULL &&
1.36      degroote 2200:                                IPSEC_PCB_SKIP_IPSEC(in6p->in6p_sp, IPSEC_DIR_OUTBOUND))
1.26      degroote 2201:                        goto skippolicycheck;
                   2202:                sp = ipsec6_checkpolicy(m, IPSEC_DIR_OUTBOUND, flags, &error,in6p);
                   2203:
1.36      degroote 2204:                /*
                   2205:                 * There are four return cases:
                   2206:                 *      sp != NULL                      apply IPsec policy
                   2207:                 *      sp == NULL, error == 0          no IPsec handling needed
                   2208:                 *      sp == NULL, error == -EINVAL  discard packet w/o error
                   2209:                 *      sp == NULL, error != 0          discard packet, report error
                   2210:                 */
                   2211:
1.26      degroote 2212:                splx(s);
1.36      degroote 2213:                if (sp == NULL) {
                   2214:                        /*
                   2215:                         * Caller must check the error return to see if it needs to discard
                   2216:                         * the packet.
                   2217:                         */
1.26      degroote 2218:                        needipsec = 0;
                   2219:                } else {
1.36      degroote 2220:                        needipsec = 1;
1.26      degroote 2221:                }
                   2222:        }
                   2223: skippolicycheck:;
                   2224:
                   2225:        *errorp = error;
                   2226:        *needipsecp = needipsec;
                   2227:        return sp;
                   2228: }
                   2229: #endif
                   2230:
                   2231:
                   2232:
1.1       jonathan 2233: /* XXX this stuff doesn't belong here... */
                   2234:
                   2235: static struct xformsw* xforms = NULL;
                   2236:
                   2237: /*
                   2238:  * Register a transform; typically at system startup.
                   2239:  */
                   2240: void
                   2241: xform_register(struct xformsw* xsp)
                   2242: {
                   2243:        xsp->xf_next = xforms;
                   2244:        xforms = xsp;
                   2245: }
                   2246:
                   2247: /*
                   2248:  * Initialize transform support in an sav.
                   2249:  */
                   2250: int
                   2251: xform_init(struct secasvar *sav, int xftype)
                   2252: {
                   2253:        struct xformsw *xsp;
                   2254:
                   2255:        if (sav->tdb_xform != NULL)     /* previously initialized */
                   2256:                return 0;
                   2257:        for (xsp = xforms; xsp; xsp = xsp->xf_next)
                   2258:                if (xsp->xf_type == xftype)
                   2259:                        return (*xsp->xf_init)(sav, xsp);
                   2260:
                   2261:        DPRINTF(("xform_init: no match for xform type %d\n", xftype));
                   2262:        return EINVAL;
                   2263: }
                   2264:
                   2265: #ifdef __NetBSD__
1.37      thorpej  2266: /*
                   2267:  * XXXJRT This should be done as a protosw init call.
                   2268:  */
1.1       jonathan 2269: void
                   2270: ipsec_attach(void)
                   2271: {
1.37      thorpej  2272:
                   2273:        ipsecstat_percpu = percpu_alloc(sizeof(uint64_t) * IPSEC_NSTATS);
                   2274:
1.1       jonathan 2275:        printf("initializing IPsec...");
                   2276:        ah_attach();
                   2277:        esp_attach();
                   2278:        ipcomp_attach();
                   2279:        ipe4_attach();
1.12      jonathan 2280: #ifdef TCP_SIGNATURE
                   2281:        tcpsignature_attach();
                   2282: #endif
1.1       jonathan 2283:        printf(" done\n");
                   2284: }
                   2285: #endif /* __NetBSD__ */

CVSweb <webmaster@jp.NetBSD.org>