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

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

1.1       nbrk        1: /*     $OpenBSD: ip_ipsp.c,v 1.168 2007/02/14 00:53:48 jsg Exp $       */
                      2: /*
                      3:  * The authors of this code are John Ioannidis (ji@tla.org),
                      4:  * Angelos D. Keromytis (kermit@csd.uch.gr),
                      5:  * Niels Provos (provos@physnet.uni-hamburg.de) and
                      6:  * Niklas Hallqvist (niklas@appli.se).
                      7:  *
                      8:  * The original version of this code was written by John Ioannidis
                      9:  * for BSD/OS in Athens, Greece, in November 1995.
                     10:  *
                     11:  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
                     12:  * by Angelos D. Keromytis.
                     13:  *
                     14:  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
                     15:  * and Niels Provos.
                     16:  *
                     17:  * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist.
                     18:  *
                     19:  * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
                     20:  * Angelos D. Keromytis and Niels Provos.
                     21:  * Copyright (c) 1999 Niklas Hallqvist.
                     22:  * Copyright (c) 2001, Angelos D. Keromytis.
                     23:  *
                     24:  * Permission to use, copy, and modify this software with or without fee
                     25:  * is hereby granted, provided that this entire notice is included in
                     26:  * all copies of any software which is or includes a copy or
                     27:  * modification of this software.
                     28:  * You may use this code under the GNU public license if you so wish. Please
                     29:  * contribute changes back to the authors under this freer than GPL license
                     30:  * so that we may further the use of strong encryption without limitations to
                     31:  * all.
                     32:  *
                     33:  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
                     34:  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
                     35:  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
                     36:  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
                     37:  * PURPOSE.
                     38:  */
                     39:
                     40: #include "pf.h"
                     41:
                     42: #include <sys/param.h>
                     43: #include <sys/mbuf.h>
                     44: #include <sys/socket.h>
                     45: #include <sys/kernel.h>
                     46: #include <sys/sysctl.h>
                     47:
                     48: #include <net/if.h>
                     49: #include <net/route.h>
                     50:
                     51: #if NPF > 0
                     52: #include <net/pfvar.h>
                     53: #endif
                     54:
                     55: #ifdef INET
                     56: #include <netinet/in.h>
                     57: #include <netinet/in_systm.h>
                     58: #include <netinet/ip.h>
                     59: #include <netinet/in_pcb.h>
                     60: #endif /* INET */
                     61:
                     62: #ifdef INET6
                     63: #ifndef INET
                     64: #include <netinet/in.h>
                     65: #endif
                     66: #include <netinet6/in6_var.h>
                     67: #endif /* INET6 */
                     68:
                     69: #include <netinet/ip_ipsp.h>
                     70: #include <net/pfkeyv2.h>
                     71: #include <crypto/xform.h>
                     72: #include <dev/rndvar.h>
                     73:
                     74: #ifdef DDB
                     75: #include <ddb/db_output.h>
                     76: void tdb_hashstats(void);
                     77: #endif
                     78:
                     79: #ifdef ENCDEBUG
                     80: #define        DPRINTF(x)      if (encdebug) printf x
                     81: #else
                     82: #define        DPRINTF(x)
                     83: #endif
                     84:
                     85: int            ipsp_kern(int, char **, int);
                     86: u_int8_t       get_sa_require(struct inpcb *);
                     87: void           tdb_rehash(void);
                     88: void           tdb_timeout(void *v);
                     89: void           tdb_firstuse(void *v);
                     90: void           tdb_soft_timeout(void *v);
                     91: void           tdb_soft_firstuse(void *v);
                     92:
                     93: extern int     ipsec_auth_default_level;
                     94: extern int     ipsec_esp_trans_default_level;
                     95: extern int     ipsec_esp_network_default_level;
                     96: extern int     ipsec_ipcomp_default_level;
                     97:
                     98: extern int encdebug;
                     99: int ipsec_in_use = 0;
                    100: u_int64_t ipsec_last_added = 0;
                    101:
                    102: struct ipsec_policy_head ipsec_policy_head =
                    103:     TAILQ_HEAD_INITIALIZER(ipsec_policy_head);
                    104: struct ipsec_acquire_head ipsec_acquire_head =
                    105:     TAILQ_HEAD_INITIALIZER(ipsec_acquire_head);
                    106:
                    107: /*
                    108:  * This is the proper place to define the various encapsulation transforms.
                    109:  */
                    110:
                    111: struct xformsw xformsw[] = {
                    112: #ifdef IPSEC
                    113:        { XF_IP4,            0,               "IPv4 Simple Encapsulation",
                    114:          ipe4_attach,       ipe4_init,       ipe4_zeroize,
                    115:          (int (*)(struct mbuf *, struct tdb *, int, int))ipe4_input,
                    116:          ipip_output, },
                    117:        { XF_AH,         XFT_AUTH,          "IPsec AH",
                    118:          ah_attach,    ah_init,   ah_zeroize,
                    119:          ah_input,             ah_output, },
                    120:        { XF_ESP,        XFT_CONF|XFT_AUTH, "IPsec ESP",
                    121:          esp_attach,   esp_init,  esp_zeroize,
                    122:          esp_input,    esp_output, },
                    123:        { XF_IPCOMP,    XFT_COMP, "IPcomp",
                    124:          ipcomp_attach,    ipcomp_init, ipcomp_zeroize,
                    125:          ipcomp_input,     ipcomp_output, },
                    126: #endif /* IPSEC */
                    127: #ifdef TCP_SIGNATURE
                    128:        { XF_TCPSIGNATURE,       XFT_AUTH, "TCP MD5 Signature Option, RFC 2385",
                    129:          tcp_signature_tdb_attach,     tcp_signature_tdb_init,
                    130:          tcp_signature_tdb_zeroize,    tcp_signature_tdb_input,
                    131:          tcp_signature_tdb_output, }
                    132: #endif /* TCP_SIGNATURE */
                    133: };
                    134:
                    135: struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])];
                    136:
                    137: unsigned char ipseczeroes[IPSEC_ZEROES_SIZE]; /* zeroes! */
                    138:
                    139: #define        TDB_HASHSIZE_INIT       32
                    140:
                    141: static struct tdb **tdbh = NULL;
                    142: static struct tdb **tdbaddr = NULL;
                    143: static struct tdb **tdbsrc = NULL;
                    144: static u_int tdb_hashmask = TDB_HASHSIZE_INIT - 1;
                    145: static int tdb_count;
                    146:
                    147: /*
                    148:  * Our hashing function needs to stir things with a non-zero random multiplier
                    149:  * so we cannot be DoS-attacked via choosing of the data to hash.
                    150:  */
                    151: int
                    152: tdb_hash(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
                    153: {
                    154:        static u_int32_t mult1 = 0, mult2 = 0;
                    155:        u_int8_t *ptr = (u_int8_t *) dst;
                    156:        int i, shift;
                    157:        u_int64_t hash;
                    158:        int val32 = 0;
                    159:
                    160:        while (mult1 == 0)
                    161:                mult1 = arc4random();
                    162:        while (mult2 == 0)
                    163:                mult2 = arc4random();
                    164:
                    165:        hash = (spi ^ proto) * mult1;
                    166:        for (i = 0; i < SA_LEN(&dst->sa); i++) {
                    167:                val32 = (val32 << 8) | ptr[i];
                    168:                if (i % 4 == 3) {
                    169:                        hash ^= val32 * mult2;
                    170:                        val32 = 0;
                    171:                }
                    172:        }
                    173:
                    174:        if (i % 4 != 0)
                    175:                hash ^= val32 * mult2;
                    176:
                    177:        shift = ffs(tdb_hashmask + 1);
                    178:        while ((hash & ~tdb_hashmask) != 0)
                    179:                hash = (hash >> shift) ^ (hash & tdb_hashmask);
                    180:
                    181:        return hash;
                    182: }
                    183:
                    184: /*
                    185:  * Reserve an SPI; the SA is not valid yet though.  We use 0 as
                    186:  * an error return value.
                    187:  */
                    188: u_int32_t
                    189: reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
                    190:     union sockaddr_union *dst, u_int8_t sproto, int *errval)
                    191: {
                    192:        struct tdb *tdbp;
                    193:        u_int32_t spi;
                    194:        int nums, s;
                    195:
                    196:        /* Don't accept ranges only encompassing reserved SPIs. */
                    197:        if (sproto != IPPROTO_IPCOMP &&
                    198:            (tspi < sspi || tspi <= SPI_RESERVED_MAX)) {
                    199:                (*errval) = EINVAL;
                    200:                return 0;
                    201:        }
                    202:        if (sproto == IPPROTO_IPCOMP && (tspi < sspi ||
                    203:            tspi <= CPI_RESERVED_MAX ||
                    204:            tspi >= CPI_PRIVATE_MIN)) {
                    205:                (*errval) = EINVAL;
                    206:                return 0;
                    207:        }
                    208:
                    209:        /* Limit the range to not include reserved areas. */
                    210:        if (sspi <= SPI_RESERVED_MAX)
                    211:                sspi = SPI_RESERVED_MAX + 1;
                    212:
                    213:        /* For IPCOMP the CPI is only 16 bits long, what a good idea.... */
                    214:
                    215:        if (sproto == IPPROTO_IPCOMP) {
                    216:                u_int32_t t;
                    217:                if (sspi >= 0x10000)
                    218:                        sspi = 0xffff;
                    219:                if (tspi >= 0x10000)
                    220:                        tspi = 0xffff;
                    221:                if (sspi > tspi) {
                    222:                        t = sspi; sspi = tspi; tspi = t;
                    223:                }
                    224:        }
                    225:
                    226:        if (sspi == tspi)   /* Asking for a specific SPI. */
                    227:                nums = 1;
                    228:        else
                    229:                nums = 100;  /* Arbitrarily chosen */
                    230:
                    231:        while (nums--) {
                    232:                if (sspi == tspi)  /* Specific SPI asked. */
                    233:                        spi = tspi;
                    234:                else    /* Range specified */
                    235:                        spi = sspi + (arc4random() % (tspi - sspi));
                    236:
                    237:                /* Don't allocate reserved SPIs.  */
                    238:                if (spi >= SPI_RESERVED_MIN && spi <= SPI_RESERVED_MAX)
                    239:                        continue;
                    240:                else
                    241:                        spi = htonl(spi);
                    242:
                    243:                /* Check whether we're using this SPI already. */
                    244:                s = spltdb();
                    245:                tdbp = gettdb(spi, dst, sproto);
                    246:                splx(s);
                    247:
                    248:                if (tdbp != (struct tdb *) NULL)
                    249:                        continue;
                    250:
                    251:                tdbp = tdb_alloc();
                    252:
                    253:                tdbp->tdb_spi = spi;
                    254:                bcopy(&dst->sa, &tdbp->tdb_dst.sa, SA_LEN(&dst->sa));
                    255:                bcopy(&src->sa, &tdbp->tdb_src.sa, SA_LEN(&src->sa));
                    256:                tdbp->tdb_sproto = sproto;
                    257:                tdbp->tdb_flags |= TDBF_INVALID; /* Mark SA invalid for now. */
                    258:                tdbp->tdb_satype = SADB_SATYPE_UNSPEC;
                    259:                puttdb(tdbp);
                    260:
                    261:                /* Setup a "silent" expiration (since TDBF_INVALID's set). */
                    262:                if (ipsec_keep_invalid > 0) {
                    263:                        tdbp->tdb_flags |= TDBF_TIMER;
                    264:                        tdbp->tdb_exp_timeout = ipsec_keep_invalid;
                    265:                        timeout_add(&tdbp->tdb_timer_tmo,
                    266:                            hz * ipsec_keep_invalid);
                    267:                }
                    268:
                    269:                return spi;
                    270:        }
                    271:
                    272:        (*errval) = EEXIST;
                    273:        return 0;
                    274: }
                    275:
                    276: /*
                    277:  * An IPSP SAID is really the concatenation of the SPI found in the
                    278:  * packet, the destination address of the packet and the IPsec protocol.
                    279:  * When we receive an IPSP packet, we need to look up its tunnel descriptor
                    280:  * block, based on the SPI in the packet and the destination address (which
                    281:  * is really one of our addresses if we received the packet!
                    282:  *
                    283:  * Caller is responsible for setting at least spltdb().
                    284:  */
                    285: struct tdb *
                    286: gettdb(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
                    287: {
                    288:        u_int32_t hashval;
                    289:        struct tdb *tdbp;
                    290:
                    291:        if (tdbh == NULL)
                    292:                return (struct tdb *) NULL;
                    293:
                    294:        hashval = tdb_hash(spi, dst, proto);
                    295:
                    296:        for (tdbp = tdbh[hashval]; tdbp != NULL; tdbp = tdbp->tdb_hnext)
                    297:                if ((tdbp->tdb_spi == spi) && (tdbp->tdb_sproto == proto) &&
                    298:                    !bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)))
                    299:                        break;
                    300:
                    301:        return tdbp;
                    302: }
                    303:
                    304: /*
                    305:  * Same as gettdb() but compare SRC as well, so we
                    306:  * use the tdbsrc[] hash table.  Setting spi to 0
                    307:  * matches all SPIs.
                    308:  */
                    309: struct tdb *
                    310: gettdbbysrcdst(u_int32_t spi, union sockaddr_union *src,
                    311:     union sockaddr_union *dst, u_int8_t proto)
                    312: {
                    313:        u_int32_t hashval;
                    314:        struct tdb *tdbp;
                    315:        union sockaddr_union su_null;
                    316:
                    317:        if (tdbsrc == NULL)
                    318:                return (struct tdb *) NULL;
                    319:
                    320:        hashval = tdb_hash(0, src, proto);
                    321:
                    322:        for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
                    323:                if (tdbp->tdb_sproto == proto &&
                    324:                    (spi == 0 || tdbp->tdb_spi == spi) &&
                    325:                    ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
                    326:                    (tdbp->tdb_dst.sa.sa_family == AF_UNSPEC ||
                    327:                    !bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa))) &&
                    328:                    !bcmp(&tdbp->tdb_src, src, SA_LEN(&src->sa)))
                    329:                        break;
                    330:
                    331:        if (tdbp != NULL)
                    332:                return (tdbp);
                    333:
                    334:        bzero(&su_null, sizeof(su_null));
                    335:        su_null.sa.sa_len = sizeof(struct sockaddr);
                    336:        hashval = tdb_hash(0, &su_null, proto);
                    337:
                    338:        for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
                    339:                if (tdbp->tdb_sproto == proto &&
                    340:                    (spi == 0 || tdbp->tdb_spi == spi) &&
                    341:                    ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
                    342:                    (tdbp->tdb_dst.sa.sa_family == AF_UNSPEC ||
                    343:                    !bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa))) &&
                    344:                    tdbp->tdb_src.sa.sa_family == AF_UNSPEC)
                    345:                        break;
                    346:
                    347:        return (tdbp);
                    348: }
                    349:
                    350: /*
                    351:  * Check that credentials and IDs match. Return true if so. The t*
                    352:  * range of arguments contains information from TDBs; the p*
                    353:  * range of arguments contains information from policies or
                    354:  * already established TDBs.
                    355:  */
                    356: int
                    357: ipsp_aux_match(struct tdb *tdb,
                    358:     struct ipsec_ref *psrcid,
                    359:     struct ipsec_ref *pdstid,
                    360:     struct ipsec_ref *plcred,
                    361:     struct ipsec_ref *prcred,
                    362:     struct sockaddr_encap *pfilter,
                    363:     struct sockaddr_encap *pfiltermask)
                    364: {
                    365:        if (psrcid != NULL)
                    366:                if (tdb->tdb_srcid == NULL ||
                    367:                    !ipsp_ref_match(tdb->tdb_srcid, psrcid))
                    368:                        return 0;
                    369:
                    370:        if (pdstid != NULL)
                    371:                if (tdb->tdb_dstid == NULL ||
                    372:                    !ipsp_ref_match(tdb->tdb_dstid, pdstid))
                    373:                        return 0;
                    374:
                    375:        if (plcred != NULL)
                    376:                if (tdb->tdb_local_cred == NULL ||
                    377:                   !ipsp_ref_match(tdb->tdb_local_cred, plcred))
                    378:                        return 0;
                    379:
                    380:        if (prcred != NULL)
                    381:                if (tdb->tdb_remote_cred == NULL ||
                    382:                    !ipsp_ref_match(tdb->tdb_remote_cred, prcred))
                    383:                        return 0;
                    384:
                    385:        /* Check for filter matches. */
                    386:        if (tdb->tdb_filter.sen_type) {
                    387:                /*
                    388:                 * XXX We should really be doing a subnet-check (see
                    389:                 * whether the TDB-associated filter is a subset
                    390:                 * of the policy's. For now, an exact match will solve
                    391:                 * most problems (all this will do is make every
                    392:                 * policy get its own SAs).
                    393:                 */
                    394:                if (bcmp(&tdb->tdb_filter, pfilter,
                    395:                    sizeof(struct sockaddr_encap)) ||
                    396:                    bcmp(&tdb->tdb_filtermask, pfiltermask,
                    397:                    sizeof(struct sockaddr_encap)))
                    398:                        return 0;
                    399:        }
                    400:
                    401:        return 1;
                    402: }
                    403:
                    404: /*
                    405:  * Get an SA given the remote address, the security protocol type, and
                    406:  * the desired IDs.
                    407:  */
                    408: struct tdb *
                    409: gettdbbyaddr(union sockaddr_union *dst, u_int8_t sproto,
                    410:     struct ipsec_ref *srcid, struct ipsec_ref *dstid,
                    411:     struct ipsec_ref *local_cred, struct mbuf *m, int af,
                    412:     struct sockaddr_encap *filter, struct sockaddr_encap *filtermask)
                    413: {
                    414:        u_int32_t hashval;
                    415:        struct tdb *tdbp;
                    416:
                    417:        if (tdbaddr == NULL)
                    418:                return (struct tdb *) NULL;
                    419:
                    420:        hashval = tdb_hash(0, dst, sproto);
                    421:
                    422:        for (tdbp = tdbaddr[hashval]; tdbp != NULL; tdbp = tdbp->tdb_anext)
                    423:                if ((tdbp->tdb_sproto == sproto) &&
                    424:                    ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
                    425:                    (!bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)))) {
                    426:                        /* Do IDs and local credentials match ? */
                    427:                        if (!ipsp_aux_match(tdbp, srcid, dstid,
                    428:                            local_cred, NULL, filter, filtermask))
                    429:                                continue;
                    430:                        break;
                    431:                }
                    432:
                    433:        return tdbp;
                    434: }
                    435:
                    436: /*
                    437:  * Get an SA given the source address, the security protocol type, and
                    438:  * the desired IDs.
                    439:  */
                    440: struct tdb *
                    441: gettdbbysrc(union sockaddr_union *src, u_int8_t sproto,
                    442:     struct ipsec_ref *srcid, struct ipsec_ref *dstid,
                    443:     struct mbuf *m, int af, struct sockaddr_encap *filter,
                    444:     struct sockaddr_encap *filtermask)
                    445: {
                    446:        u_int32_t hashval;
                    447:        struct tdb *tdbp;
                    448:
                    449:        if (tdbsrc == NULL)
                    450:                return (struct tdb *) NULL;
                    451:
                    452:        hashval = tdb_hash(0, src, sproto);
                    453:
                    454:        for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
                    455:                if ((tdbp->tdb_sproto == sproto) &&
                    456:                    ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
                    457:                    (!bcmp(&tdbp->tdb_src, src, SA_LEN(&src->sa)))) {
                    458:                        /* Check whether IDs match */
                    459:                        if (!ipsp_aux_match(tdbp, dstid, srcid, NULL, NULL,
                    460:                            filter, filtermask))
                    461:                                continue;
                    462:                        break;
                    463:                }
                    464:
                    465:        return tdbp;
                    466: }
                    467:
                    468: #if DDB
                    469: void
                    470: tdb_hashstats(void)
                    471: {
                    472:        int i, cnt, buckets[16];
                    473:        struct tdb *tdbp;
                    474:
                    475:        if (tdbh == NULL) {
                    476:                db_printf("no tdb hash table\n");
                    477:                return;
                    478:        }
                    479:
                    480:        bzero (buckets, sizeof(buckets));
                    481:        for (i = 0; i <= tdb_hashmask; i++) {
                    482:                cnt = 0;
                    483:                for (tdbp = tdbh[i]; cnt < 16 && tdbp != NULL;
                    484:                    tdbp = tdbp->tdb_hnext)
                    485:                        cnt++;
                    486:                buckets[cnt]++;
                    487:        }
                    488:
                    489:        db_printf("tdb cnt\t\tbucket cnt\n");
                    490:        for (i = 0; i < 16; i++)
                    491:                if (buckets[i] > 0)
                    492:                        db_printf("%d%c\t\t%d\n", i, i == 15 ? "+" : "",
                    493:                            buckets[i]);
                    494: }
                    495: #endif /* DDB */
                    496:
                    497: /*
                    498:  * Caller is responsible for setting at least spltdb().
                    499:  */
                    500: int
                    501: tdb_walk(int (*walker)(struct tdb *, void *, int), void *arg)
                    502: {
                    503:        int i, rval = 0;
                    504:        struct tdb *tdbp, *next;
                    505:
                    506:        if (tdbh == NULL)
                    507:                return ENOENT;
                    508:
                    509:        for (i = 0; i <= tdb_hashmask; i++)
                    510:                for (tdbp = tdbh[i]; rval == 0 && tdbp != NULL; tdbp = next) {
                    511:                        next = tdbp->tdb_hnext;
                    512:                        if (i == tdb_hashmask && next == NULL)
                    513:                                rval = walker(tdbp, (void *)arg, 1);
                    514:                        else
                    515:                                rval = walker(tdbp, (void *)arg, 0);
                    516:                }
                    517:
                    518:        return rval;
                    519: }
                    520:
                    521: /*
                    522:  * Called at splsoftclock().
                    523:  */
                    524: void
                    525: tdb_timeout(void *v)
                    526: {
                    527:        struct tdb *tdb = v;
                    528:
                    529:        if (!(tdb->tdb_flags & TDBF_TIMER))
                    530:                return;
                    531:
                    532:        /* If it's an "invalid" TDB do a silent expiration. */
                    533:        if (!(tdb->tdb_flags & TDBF_INVALID))
                    534:                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                    535:        tdb_delete(tdb);
                    536: }
                    537:
                    538: void
                    539: tdb_firstuse(void *v)
                    540: {
                    541:        struct tdb *tdb = v;
                    542:
                    543:        if (!(tdb->tdb_flags & TDBF_SOFT_FIRSTUSE))
                    544:                return;
                    545:
                    546:        /* If the TDB hasn't been used, don't renew it. */
                    547:        if (tdb->tdb_first_use != 0)
                    548:                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                    549:        tdb_delete(tdb);
                    550: }
                    551:
                    552: void
                    553: tdb_soft_timeout(void *v)
                    554: {
                    555:        struct tdb *tdb = v;
                    556:
                    557:        if (!(tdb->tdb_flags & TDBF_SOFT_TIMER))
                    558:                return;
                    559:
                    560:        /* Soft expirations. */
                    561:        pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
                    562:        tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
                    563: }
                    564:
                    565: void
                    566: tdb_soft_firstuse(void *v)
                    567: {
                    568:        struct tdb *tdb = v;
                    569:
                    570:        if (!(tdb->tdb_flags & TDBF_SOFT_FIRSTUSE))
                    571:                return;
                    572:
                    573:        /* If the TDB hasn't been used, don't renew it. */
                    574:        if (tdb->tdb_first_use != 0)
                    575:                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
                    576:        tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
                    577: }
                    578:
                    579: /*
                    580:  * Caller is responsible for spltdb().
                    581:  */
                    582: void
                    583: tdb_rehash(void)
                    584: {
                    585:        struct tdb **new_tdbh, **new_tdbaddr, **new_srcaddr, *tdbp, *tdbnp;
                    586:        u_int i, old_hashmask = tdb_hashmask;
                    587:        u_int32_t hashval;
                    588:
                    589:        tdb_hashmask = (tdb_hashmask << 1) | 1;
                    590:
                    591:        MALLOC(new_tdbh, struct tdb **,
                    592:            sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
                    593:        MALLOC(new_tdbaddr, struct tdb **,
                    594:            sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
                    595:        MALLOC(new_srcaddr, struct tdb **,
                    596:            sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
                    597:
                    598:        bzero(new_tdbh, sizeof(struct tdb *) * (tdb_hashmask + 1));
                    599:        bzero(new_tdbaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
                    600:        bzero(new_srcaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
                    601:
                    602:        for (i = 0; i <= old_hashmask; i++) {
                    603:                for (tdbp = tdbh[i]; tdbp != NULL; tdbp = tdbnp) {
                    604:                        tdbnp = tdbp->tdb_hnext;
                    605:                        hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst,
                    606:                            tdbp->tdb_sproto);
                    607:                        tdbp->tdb_hnext = new_tdbh[hashval];
                    608:                        new_tdbh[hashval] = tdbp;
                    609:                }
                    610:
                    611:                for (tdbp = tdbaddr[i]; tdbp != NULL; tdbp = tdbnp) {
                    612:                        tdbnp = tdbp->tdb_anext;
                    613:                        hashval = tdb_hash(0, &tdbp->tdb_dst,
                    614:                            tdbp->tdb_sproto);
                    615:                        tdbp->tdb_anext = new_tdbaddr[hashval];
                    616:                        new_tdbaddr[hashval] = tdbp;
                    617:                }
                    618:
                    619:                for (tdbp = tdbsrc[i]; tdbp != NULL; tdbp = tdbnp) {
                    620:                        tdbnp = tdbp->tdb_snext;
                    621:                        hashval = tdb_hash(0, &tdbp->tdb_src,
                    622:                            tdbp->tdb_sproto);
                    623:                        tdbp->tdb_snext = new_srcaddr[hashval];
                    624:                        new_srcaddr[hashval] = tdbp;
                    625:                }
                    626:        }
                    627:
                    628:        FREE(tdbh, M_TDB);
                    629:        tdbh = new_tdbh;
                    630:
                    631:        FREE(tdbaddr, M_TDB);
                    632:        tdbaddr = new_tdbaddr;
                    633:
                    634:        FREE(tdbsrc, M_TDB);
                    635:        tdbsrc = new_srcaddr;
                    636: }
                    637:
                    638: /*
                    639:  * Add TDB in the hash table.
                    640:  */
                    641: void
                    642: puttdb(struct tdb *tdbp)
                    643: {
                    644:        u_int32_t hashval;
                    645:        int s = spltdb();
                    646:
                    647:        if (tdbh == NULL) {
                    648:                MALLOC(tdbh, struct tdb **,
                    649:                    sizeof(struct tdb *) * (tdb_hashmask + 1),
                    650:                    M_TDB, M_WAITOK);
                    651:                MALLOC(tdbaddr, struct tdb **,
                    652:                    sizeof(struct tdb *) * (tdb_hashmask + 1),
                    653:                    M_TDB, M_WAITOK);
                    654:                MALLOC(tdbsrc, struct tdb **,
                    655:                    sizeof(struct tdb *) * (tdb_hashmask + 1),
                    656:                    M_TDB, M_WAITOK);
                    657:
                    658:                bzero(tdbh, sizeof(struct tdb *) * (tdb_hashmask + 1));
                    659:                bzero(tdbaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
                    660:                bzero(tdbsrc, sizeof(struct tdb *) * (tdb_hashmask + 1));
                    661:        }
                    662:
                    663:        hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
                    664:
                    665:        /*
                    666:         * Rehash if this tdb would cause a bucket to have more than
                    667:         * two items and if the number of tdbs exceed 10% of the
                    668:         * bucket count.  This number is arbitratily chosen and is
                    669:         * just a measure to not keep rehashing when adding and
                    670:         * removing tdbs which happens to always end up in the same
                    671:         * bucket, which is not uncommon when doing manual keying.
                    672:         */
                    673:        if (tdbh[hashval] != NULL && tdbh[hashval]->tdb_hnext != NULL &&
                    674:            tdb_count * 10 > tdb_hashmask + 1) {
                    675:                tdb_rehash();
                    676:                hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst,
                    677:                    tdbp->tdb_sproto);
                    678:        }
                    679:
                    680:        tdbp->tdb_hnext = tdbh[hashval];
                    681:        tdbh[hashval] = tdbp;
                    682:
                    683:        hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
                    684:        tdbp->tdb_anext = tdbaddr[hashval];
                    685:        tdbaddr[hashval] = tdbp;
                    686:
                    687:        hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
                    688:        tdbp->tdb_snext = tdbsrc[hashval];
                    689:        tdbsrc[hashval] = tdbp;
                    690:
                    691:        tdb_count++;
                    692:
                    693:        ipsec_last_added = time_second;
                    694:
                    695:        splx(s);
                    696: }
                    697:
                    698: /*
                    699:  * Caller is responsible to set at least spltdb().
                    700:  */
                    701: void
                    702: tdb_delete(struct tdb *tdbp)
                    703: {
                    704:        struct tdb *tdbpp;
                    705:        u_int32_t hashval;
                    706:        int s;
                    707:
                    708:        if (tdbh == NULL)
                    709:                return;
                    710:
                    711:        hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
                    712:
                    713:        s = spltdb();
                    714:        if (tdbh[hashval] == tdbp) {
                    715:                tdbpp = tdbp;
                    716:                tdbh[hashval] = tdbp->tdb_hnext;
                    717:        } else {
                    718:                for (tdbpp = tdbh[hashval]; tdbpp != NULL;
                    719:                    tdbpp = tdbpp->tdb_hnext) {
                    720:                        if (tdbpp->tdb_hnext == tdbp) {
                    721:                                tdbpp->tdb_hnext = tdbp->tdb_hnext;
                    722:                                tdbpp = tdbp;
                    723:                                break;
                    724:                        }
                    725:                }
                    726:        }
                    727:
                    728:        tdbp->tdb_hnext = NULL;
                    729:
                    730:        hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
                    731:
                    732:        if (tdbaddr[hashval] == tdbp) {
                    733:                tdbpp = tdbp;
                    734:                tdbaddr[hashval] = tdbp->tdb_anext;
                    735:        } else {
                    736:                for (tdbpp = tdbaddr[hashval]; tdbpp != NULL;
                    737:                    tdbpp = tdbpp->tdb_anext) {
                    738:                        if (tdbpp->tdb_anext == tdbp) {
                    739:                                tdbpp->tdb_anext = tdbp->tdb_anext;
                    740:                                tdbpp = tdbp;
                    741:                                break;
                    742:                        }
                    743:                }
                    744:        }
                    745:
                    746:        hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
                    747:
                    748:        if (tdbsrc[hashval] == tdbp) {
                    749:                tdbpp = tdbp;
                    750:                tdbsrc[hashval] = tdbp->tdb_snext;
                    751:        }
                    752:        else {
                    753:                for (tdbpp = tdbsrc[hashval]; tdbpp != NULL;
                    754:                    tdbpp = tdbpp->tdb_snext) {
                    755:                        if (tdbpp->tdb_snext == tdbp) {
                    756:                                tdbpp->tdb_snext = tdbp->tdb_snext;
                    757:                                tdbpp = tdbp;
                    758:                                break;
                    759:                        }
                    760:                }
                    761:        }
                    762:
                    763:        tdbp->tdb_snext = NULL;
                    764:        tdb_free(tdbp);
                    765:        tdb_count--;
                    766:
                    767:        splx(s);
                    768: }
                    769:
                    770: /*
                    771:  * Allocate a TDB and initialize a few basic fields.
                    772:  */
                    773: struct tdb *
                    774: tdb_alloc(void)
                    775: {
                    776:        struct tdb *tdbp;
                    777:
                    778:        MALLOC(tdbp, struct tdb *, sizeof(struct tdb), M_TDB, M_WAITOK);
                    779:        bzero((caddr_t) tdbp, sizeof(struct tdb));
                    780:
                    781:        /* Init Incoming SA-Binding Queues. */
                    782:        TAILQ_INIT(&tdbp->tdb_inp_out);
                    783:        TAILQ_INIT(&tdbp->tdb_inp_in);
                    784:
                    785:        TAILQ_INIT(&tdbp->tdb_policy_head);
                    786:
                    787:        /* Record establishment time. */
                    788:        tdbp->tdb_established = time_second;
                    789:
                    790:        /* Initialize timeouts. */
                    791:        timeout_set(&tdbp->tdb_timer_tmo, tdb_timeout, tdbp);
                    792:        timeout_set(&tdbp->tdb_first_tmo, tdb_firstuse, tdbp);
                    793:        timeout_set(&tdbp->tdb_stimer_tmo, tdb_soft_timeout, tdbp);
                    794:        timeout_set(&tdbp->tdb_sfirst_tmo, tdb_soft_firstuse, tdbp);
                    795:
                    796:        return tdbp;
                    797: }
                    798:
                    799: void
                    800: tdb_free(struct tdb *tdbp)
                    801: {
                    802:        struct ipsec_policy *ipo;
                    803:        struct inpcb *inp;
                    804:
                    805:        if (tdbp->tdb_xform) {
                    806:                (*(tdbp->tdb_xform->xf_zeroize))(tdbp);
                    807:                tdbp->tdb_xform = NULL;
                    808:        }
                    809:
                    810:        /* Cleanup inp references. */
                    811:        for (inp = TAILQ_FIRST(&tdbp->tdb_inp_in); inp;
                    812:            inp = TAILQ_FIRST(&tdbp->tdb_inp_in)) {
                    813:                TAILQ_REMOVE(&tdbp->tdb_inp_in, inp, inp_tdb_in_next);
                    814:                inp->inp_tdb_in = NULL;
                    815:        }
                    816:
                    817:        for (inp = TAILQ_FIRST(&tdbp->tdb_inp_out); inp;
                    818:            inp = TAILQ_FIRST(&tdbp->tdb_inp_out)) {
                    819:                TAILQ_REMOVE(&tdbp->tdb_inp_out, inp, inp_tdb_out_next);
                    820:                inp->inp_tdb_out = NULL;
                    821:        }
                    822:
                    823:        /* Cleanup SPD references. */
                    824:        for (ipo = TAILQ_FIRST(&tdbp->tdb_policy_head); ipo;
                    825:            ipo = TAILQ_FIRST(&tdbp->tdb_policy_head))  {
                    826:                TAILQ_REMOVE(&tdbp->tdb_policy_head, ipo, ipo_tdb_next);
                    827:                ipo->ipo_tdb = NULL;
                    828:                ipo->ipo_last_searched = 0; /* Force a re-search. */
                    829:        }
                    830:
                    831:        /* Remove expiration timeouts. */
                    832:        tdbp->tdb_flags &= ~(TDBF_FIRSTUSE | TDBF_SOFT_FIRSTUSE | TDBF_TIMER |
                    833:            TDBF_SOFT_TIMER);
                    834:        timeout_del(&tdbp->tdb_timer_tmo);
                    835:        timeout_del(&tdbp->tdb_first_tmo);
                    836:        timeout_del(&tdbp->tdb_stimer_tmo);
                    837:        timeout_del(&tdbp->tdb_sfirst_tmo);
                    838:
                    839:        if (tdbp->tdb_local_auth) {
                    840:                ipsp_reffree(tdbp->tdb_local_auth);
                    841:                tdbp->tdb_local_auth = NULL;
                    842:        }
                    843:
                    844:        if (tdbp->tdb_remote_auth) {
                    845:                ipsp_reffree(tdbp->tdb_remote_auth);
                    846:                tdbp->tdb_remote_auth = NULL;
                    847:        }
                    848:
                    849:        if (tdbp->tdb_srcid) {
                    850:                ipsp_reffree(tdbp->tdb_srcid);
                    851:                tdbp->tdb_srcid = NULL;
                    852:        }
                    853:
                    854:        if (tdbp->tdb_dstid) {
                    855:                ipsp_reffree(tdbp->tdb_dstid);
                    856:                tdbp->tdb_dstid = NULL;
                    857:        }
                    858:
                    859:        if (tdbp->tdb_local_cred) {
                    860:                ipsp_reffree(tdbp->tdb_local_cred);
                    861:                tdbp->tdb_local_cred = NULL;
                    862:        }
                    863:
                    864:        if (tdbp->tdb_remote_cred) {
                    865:                ipsp_reffree(tdbp->tdb_remote_cred);
                    866:                tdbp->tdb_remote_cred = NULL;
                    867:        }
                    868:
                    869: #if NPF > 0
                    870:        if (tdbp->tdb_tag) {
                    871:                pf_tag_unref(tdbp->tdb_tag);
                    872:                tdbp->tdb_tag = 0;
                    873:        }
                    874: #endif
                    875:
                    876:        if ((tdbp->tdb_onext) && (tdbp->tdb_onext->tdb_inext == tdbp))
                    877:                tdbp->tdb_onext->tdb_inext = NULL;
                    878:
                    879:        if ((tdbp->tdb_inext) && (tdbp->tdb_inext->tdb_onext == tdbp))
                    880:                tdbp->tdb_inext->tdb_onext = NULL;
                    881:
                    882:        FREE(tdbp, M_TDB);
                    883: }
                    884:
                    885: /*
                    886:  * Do further initializations of a TDB.
                    887:  */
                    888: int
                    889: tdb_init(struct tdb *tdbp, u_int16_t alg, struct ipsecinit *ii)
                    890: {
                    891:        struct xformsw *xsp;
                    892:        int err;
                    893:
                    894:        for (xsp = xformsw; xsp < xformswNXFORMSW; xsp++) {
                    895:                if (xsp->xf_type == alg) {
                    896:                        err = (*(xsp->xf_init))(tdbp, xsp, ii);
                    897:                        return err;
                    898:                }
                    899:        }
                    900:
                    901:        DPRINTF(("tdb_init(): no alg %d for spi %08x, addr %s, proto %d\n",
                    902:            alg, ntohl(tdbp->tdb_spi), ipsp_address(tdbp->tdb_dst),
                    903:            tdbp->tdb_sproto));
                    904:
                    905:        return EINVAL;
                    906: }
                    907:
                    908: /*
                    909:  * Check which transformations are required.
                    910:  */
                    911: u_int8_t
                    912: get_sa_require(struct inpcb *inp)
                    913: {
                    914:        u_int8_t sareq = 0;
                    915:
                    916:        if (inp != NULL) {
                    917:                sareq |= inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_USE ?
                    918:                    NOTIFY_SATYPE_AUTH : 0;
                    919:                sareq |= inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_USE ?
                    920:                    NOTIFY_SATYPE_CONF : 0;
                    921:                sareq |= inp->inp_seclevel[SL_ESP_NETWORK] >= IPSEC_LEVEL_USE ?
                    922:                    NOTIFY_SATYPE_TUNNEL : 0;
                    923:        } else {
                    924:                sareq |= ipsec_auth_default_level >= IPSEC_LEVEL_USE ?
                    925:                    NOTIFY_SATYPE_AUTH : 0;
                    926:                sareq |= ipsec_esp_trans_default_level >= IPSEC_LEVEL_USE ?
                    927:                    NOTIFY_SATYPE_CONF : 0;
                    928:                sareq |= ipsec_esp_network_default_level >= IPSEC_LEVEL_USE ?
                    929:                    NOTIFY_SATYPE_TUNNEL : 0;
                    930:        }
                    931:
                    932:        return (sareq);
                    933: }
                    934:
                    935: /*
                    936:  * Add an inpcb to the list of inpcb which reference this tdb directly.
                    937:  */
                    938: void
                    939: tdb_add_inp(struct tdb *tdb, struct inpcb *inp, int inout)
                    940: {
                    941:        if (inout) {
                    942:                if (inp->inp_tdb_in) {
                    943:                        if (inp->inp_tdb_in == tdb)
                    944:                                return;
                    945:
                    946:                        TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp,
                    947:                            inp_tdb_in_next);
                    948:                }
                    949:
                    950:                inp->inp_tdb_in = tdb;
                    951:                TAILQ_INSERT_TAIL(&tdb->tdb_inp_in, inp, inp_tdb_in_next);
                    952:        } else {
                    953:                if (inp->inp_tdb_out) {
                    954:                        if (inp->inp_tdb_out == tdb)
                    955:                                return;
                    956:
                    957:                        TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp,
                    958:                            inp_tdb_out_next);
                    959:                }
                    960:
                    961:                inp->inp_tdb_out = tdb;
                    962:                TAILQ_INSERT_TAIL(&tdb->tdb_inp_out, inp, inp_tdb_out_next);
                    963:        }
                    964: }
                    965:
                    966: /* Return a printable string for the IPv4 address. */
                    967: char *
                    968: inet_ntoa4(struct in_addr ina)
                    969: {
                    970:        static char buf[4][4 * sizeof "123" + 4];
                    971:        unsigned char *ucp = (unsigned char *) &ina;
                    972:        static int i = 3;
                    973:
                    974:        i = (i + 1) % 4;
                    975:        snprintf(buf[i], sizeof buf[0], "%d.%d.%d.%d",
                    976:            ucp[0] & 0xff, ucp[1] & 0xff,
                    977:            ucp[2] & 0xff, ucp[3] & 0xff);
                    978:        return (buf[i]);
                    979: }
                    980:
                    981: /* Return a printable string for the address. */
                    982: char *
                    983: ipsp_address(union sockaddr_union sa)
                    984: {
                    985:        switch (sa.sa.sa_family) {
                    986: #if INET
                    987:        case AF_INET:
                    988:                return inet_ntoa4(sa.sin.sin_addr);
                    989: #endif /* INET */
                    990:
                    991: #if INET6
                    992:        case AF_INET6:
                    993:                return ip6_sprintf(&sa.sin6.sin6_addr);
                    994: #endif /* INET6 */
                    995:
                    996:        default:
                    997:                return "(unknown address family)";
                    998:        }
                    999: }
                   1000:
                   1001: /* Check whether an IP{4,6} address is unspecified. */
                   1002: int
                   1003: ipsp_is_unspecified(union sockaddr_union addr)
                   1004: {
                   1005:        switch (addr.sa.sa_family) {
                   1006: #ifdef INET
                   1007:        case AF_INET:
                   1008:                if (addr.sin.sin_addr.s_addr == INADDR_ANY)
                   1009:                        return 1;
                   1010:                else
                   1011:                        return 0;
                   1012: #endif /* INET */
                   1013:
                   1014: #ifdef INET6
                   1015:        case AF_INET6:
                   1016:                if (IN6_IS_ADDR_UNSPECIFIED(&addr.sin6.sin6_addr))
                   1017:                        return 1;
                   1018:                else
                   1019:                        return 0;
                   1020: #endif /* INET6 */
                   1021:
                   1022:        case 0: /* No family set. */
                   1023:        default:
                   1024:                return 1;
                   1025:        }
                   1026: }
                   1027:
                   1028: /* Free reference-counted structure. */
                   1029: void
                   1030: ipsp_reffree(struct ipsec_ref *ipr)
                   1031: {
                   1032: #ifdef DIAGNOSTIC
                   1033:        if (ipr->ref_count <= 0)
                   1034:                printf("ipsp_reffree: illegal reference count %d for "
                   1035:                    "object %p (len = %d, malloctype = %d)\n",
                   1036:                    ipr->ref_count, ipr, ipr->ref_len, ipr->ref_malloctype);
                   1037: #endif
                   1038:        if (--ipr->ref_count <= 0)
                   1039:                FREE(ipr, ipr->ref_malloctype);
                   1040: }
                   1041:
                   1042: /* Mark a TDB as TDBF_SKIPCRYPTO. */
                   1043: void
                   1044: ipsp_skipcrypto_mark(struct tdb_ident *tdbi)
                   1045: {
                   1046:        struct tdb *tdb;
                   1047:        int s = spltdb();
                   1048:
                   1049:        tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
                   1050:        if (tdb != NULL) {
                   1051:                tdb->tdb_flags |= TDBF_SKIPCRYPTO;
                   1052:                tdb->tdb_last_marked = time_second;
                   1053:        }
                   1054:        splx(s);
                   1055: }
                   1056:
                   1057: /* Unmark a TDB as TDBF_SKIPCRYPTO. */
                   1058: void
                   1059: ipsp_skipcrypto_unmark(struct tdb_ident *tdbi)
                   1060: {
                   1061:        struct tdb *tdb;
                   1062:        int s = spltdb();
                   1063:
                   1064:        tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
                   1065:        if (tdb != NULL) {
                   1066:                tdb->tdb_flags &= ~TDBF_SKIPCRYPTO;
                   1067:                tdb->tdb_last_marked = time_second;
                   1068:        }
                   1069:        splx(s);
                   1070: }
                   1071:
                   1072: /* Return true if the two structures match. */
                   1073: int
                   1074: ipsp_ref_match(struct ipsec_ref *ref1, struct ipsec_ref *ref2)
                   1075: {
                   1076:        if (ref1->ref_type != ref2->ref_type ||
                   1077:            ref1->ref_len != ref2->ref_len ||
                   1078:            bcmp(ref1 + 1, ref2 + 1, ref1->ref_len))
                   1079:                return 0;
                   1080:
                   1081:        return 1;
                   1082: }
                   1083:
                   1084: #ifdef notyet
                   1085: /*
                   1086:  * Go down a chain of IPv4/IPv6/ESP/AH/IPiP chains creating an tag for each
                   1087:  * IPsec header encountered. The offset where the first header, as well
                   1088:  * as its type are given to us.
                   1089:  */
                   1090: struct m_tag *
                   1091: ipsp_parse_headers(struct mbuf *m, int off, u_int8_t proto)
                   1092: {
                   1093:        int ipv4sa = 0, s, esphlen = 0, trail = 0, i;
                   1094:        SLIST_HEAD(packet_tags, m_tag) tags;
                   1095:        unsigned char lasteight[8];
                   1096:        struct tdb_ident *tdbi;
                   1097:        struct m_tag *mtag;
                   1098:        struct tdb *tdb;
                   1099:
                   1100: #ifdef INET
                   1101:        struct ip iph;
                   1102: #endif /* INET */
                   1103:
                   1104: #ifdef INET6
                   1105:        struct in6_addr ip6_dst;
                   1106: #endif /* INET6 */
                   1107:
                   1108:        /* We have to start with a known network protocol. */
                   1109:        if (proto != IPPROTO_IPV4 && proto != IPPROTO_IPV6)
                   1110:                return NULL;
                   1111:
                   1112:        SLIST_INIT(&tags);
                   1113:
                   1114:        while (1) {
                   1115:                switch (proto) {
                   1116: #ifdef INET
                   1117:                case IPPROTO_IPV4: /* Also IPPROTO_IPIP */
                   1118:                {
                   1119:                        /*
                   1120:                         * Save the IP header (we need both the
                   1121:                         * address and ip_hl).
                   1122:                         */
                   1123:                        m_copydata(m, off, sizeof(struct ip), (caddr_t) &iph);
                   1124:                        ipv4sa = 1;
                   1125:                        proto = iph.ip_p;
                   1126:                        off += iph.ip_hl << 2;
                   1127:                        break;
                   1128:                }
                   1129: #endif /* INET */
                   1130:
                   1131: #ifdef INET6
                   1132:                case IPPROTO_IPV6:
                   1133:                {
                   1134:                        int nxtp, l;
                   1135:
                   1136:                        /* Copy the IPv6 address. */
                   1137:                        m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst),
                   1138:                            sizeof(struct ip6_hdr), (caddr_t) &ip6_dst);
                   1139:                        ipv4sa = 0;
                   1140:
                   1141:                        /*
                   1142:                         * Go down the chain of headers until we encounter a
                   1143:                         * non-option.
                   1144:                         */
                   1145:                        for (l = ip6_nexthdr(m, off, proto, &nxtp); l != -1;
                   1146:                            l = ip6_nexthdr(m, off, proto, &nxtp)) {
                   1147:                                off += l;
                   1148:                                proto = nxtp;
                   1149:
                   1150:                                /* Construct a tag. */
                   1151:                                if (nxtp == IPPROTO_AH) {
                   1152:                                        mtag = m_tag_get(PACKET_TAG_IPSEC_IN_CRYPTO_DONE,
                   1153:                                            sizeof(struct tdb_ident),
                   1154:                                            M_NOWAIT);
                   1155:
                   1156:                                        if (mtag == NULL)
                   1157:                                                return SLIST_FIRST(&tags);
                   1158:
                   1159:                                        tdbi = (struct tdb_ident *) (mtag + 1);
                   1160:                                        bzero(tdbi, sizeof(struct tdb_ident));
                   1161:
                   1162:                                        m_copydata(m, off + sizeof(u_int32_t),
                   1163:                                            sizeof(u_int32_t),
                   1164:                                            (caddr_t) &tdbi->spi);
                   1165:
                   1166:                                        tdbi->proto = IPPROTO_AH;
                   1167:                                        tdbi->dst.sin6.sin6_family = AF_INET6;
                   1168:                                        tdbi->dst.sin6.sin6_len =
                   1169:                                            sizeof(struct sockaddr_in6);
                   1170:                                        tdbi->dst.sin6.sin6_addr = ip6_dst;
                   1171:                                        SLIST_INSERT_HEAD(&tags,
                   1172:                                            mtag, m_tag_link);
                   1173:                                }
                   1174:                                else
                   1175:                                        if (nxtp == IPPROTO_IPV6)
                   1176:                                                m_copydata(m, off +
                   1177:                                                    offsetof(struct ip6_hdr,
                   1178:                                                        ip6_dst),
                   1179:                                                    sizeof(struct ip6_hdr),
                   1180:                                                    (caddr_t) &ip6_dst);
                   1181:                        }
                   1182:                        break;
                   1183:                }
                   1184: #endif /* INET6 */
                   1185:
                   1186:                case IPPROTO_ESP:
                   1187:                /* Verify that this has been decrypted. */
                   1188:                {
                   1189:                        union sockaddr_union su;
                   1190:                        u_int32_t spi;
                   1191:
                   1192:                        m_copydata(m, off, sizeof(u_int32_t), (caddr_t) &spi);
                   1193:                        bzero(&su, sizeof(union sockaddr_union));
                   1194:
                   1195:                        s = spltdb();
                   1196:
                   1197: #ifdef INET
                   1198:                        if (ipv4sa) {
                   1199:                                su.sin.sin_family = AF_INET;
                   1200:                                su.sin.sin_len = sizeof(struct sockaddr_in);
                   1201:                                su.sin.sin_addr = iph.ip_dst;
                   1202:                        }
                   1203: #endif /* INET */
                   1204:
                   1205: #ifdef INET6
                   1206:                        if (!ipv4sa) {
                   1207:                                su.sin6.sin6_family = AF_INET6;
                   1208:                                su.sin6.sin6_len = sizeof(struct sockaddr_in6);
                   1209:                                su.sin6.sin6_addr = ip6_dst;
                   1210:                        }
                   1211: #endif /* INET6 */
                   1212:
                   1213:                        tdb = gettdb(spi, &su, IPPROTO_ESP);
                   1214:                        if (tdb == NULL) {
                   1215:                                splx(s);
                   1216:                                return SLIST_FIRST(&tags);
                   1217:                        }
                   1218:
                   1219:                        /* How large is the ESP header ? We use this later. */
                   1220:                        if (tdb->tdb_flags & TDBF_NOREPLAY)
                   1221:                                esphlen = sizeof(u_int32_t) + tdb->tdb_ivlen;
                   1222:                        else
                   1223:                                esphlen = 2 * sizeof(u_int32_t) +
                   1224:                                    tdb->tdb_ivlen;
                   1225:
                   1226:                        /*
                   1227:                         * Verify decryption. If the SA is using
                   1228:                         * random padding (as the "old" ESP SAs were
                   1229:                         * bound to do, there's nothing we can do to
                   1230:                         * see if the payload has been decrypted.
                   1231:                         */
                   1232:                        if (tdb->tdb_flags & TDBF_RANDOMPADDING) {
                   1233:                                splx(s);
                   1234:                                return SLIST_FIRST(&tags);
                   1235:                        }
                   1236:
                   1237:                        /* Update the length of trailing ESP authenticators. */
                   1238:                        if (tdb->tdb_authalgxform)
                   1239:                                trail += AH_HMAC_HASHLEN;
                   1240:
                   1241:                        splx(s);
                   1242:
                   1243:                        /* Copy the last 10 bytes. */
                   1244:                        m_copydata(m, m->m_pkthdr.len - trail - 8, 8,
                   1245:                            lasteight);
                   1246:
                   1247:                        /* Verify the self-describing padding values. */
                   1248:                        if (lasteight[6] != 0) {
                   1249:                                if (lasteight[6] != lasteight[5])
                   1250:                                        return SLIST_FIRST(&tags);
                   1251:
                   1252:                                for (i = 4; lasteight[i + 1] != 1 && i >= 0;
                   1253:                                    i--)
                   1254:                                        if (lasteight[i + 1] !=
                   1255:                                            lasteight[i] + 1)
                   1256:                                                return SLIST_FIRST(&tags);
                   1257:                        }
                   1258:                }
                   1259:                /* FALLTHROUGH */
                   1260:                case IPPROTO_AH:
                   1261:                        mtag = m_tag_get(PACKET_TAG_IPSEC_IN_CRYPTO_DONE,
                   1262:                            sizeof(struct tdb_ident), M_NOWAIT);
                   1263:                        if (mtag == NULL)
                   1264:                                return SLIST_FIRST(&tags);
                   1265:
                   1266:                        tdbi = (struct tdb_ident *) (mtag + 1);
                   1267:                        bzero(tdbi, sizeof(struct tdb_ident));
                   1268:
                   1269:                        /* Get SPI off the relevant header. */
                   1270:                        if (proto == IPPROTO_AH)
                   1271:                                m_copydata(m, off + sizeof(u_int32_t),
                   1272:                                    sizeof(u_int32_t), (caddr_t) &tdbi->spi);
                   1273:                        else /* IPPROTO_ESP */
                   1274:                                m_copydata(m, off, sizeof(u_int32_t),
                   1275:                                    (caddr_t) &tdbi->spi);
                   1276:
                   1277:                        tdbi->proto = proto; /* AH or ESP */
                   1278:
                   1279: #ifdef INET
                   1280:                        /* Last network header was IPv4. */
                   1281:                        if (ipv4sa) {
                   1282:                                tdbi->dst.sin.sin_family = AF_INET;
                   1283:                                tdbi->dst.sin.sin_len =
                   1284:                                    sizeof(struct sockaddr_in);
                   1285:                                tdbi->dst.sin.sin_addr = iph.ip_dst;
                   1286:                        }
                   1287: #endif /* INET */
                   1288:
                   1289: #ifdef INET6
                   1290:                        /* Last network header was IPv6. */
                   1291:                        if (!ipv4sa) {
                   1292:                                tdbi->dst.sin6.sin6_family = AF_INET6;
                   1293:                                tdbi->dst.sin6.sin6_len =
                   1294:                                    sizeof(struct sockaddr_in6);
                   1295:                                tdbi->dst.sin6.sin6_addr = ip6_dst;
                   1296:                        }
                   1297: #endif /* INET6 */
                   1298:
                   1299:                        SLIST_INSERT_HEAD(&tags, mtag, m_tag_link);
                   1300:
                   1301:                        /* Update next protocol/header and header offset. */
                   1302:                        if (proto == IPPROTO_AH) {
                   1303:                                u_int8_t foo[2];
                   1304:
                   1305:                                m_copydata(m, off, 2 * sizeof(u_int8_t), foo);
                   1306:                                proto = foo[0];
                   1307:                                off += (foo[1] + 2) << 2;
                   1308:                        } else {/* IPPROTO_ESP */
                   1309:                                /* Initialized in IPPROTO_ESP case. */
                   1310:                                off += esphlen;
                   1311:                                proto = lasteight[7];
                   1312:                        }
                   1313:                        break;
                   1314:
                   1315:                default:
                   1316:                        return SLIST_FIRST(&tags); /* We're done. */
                   1317:                }
                   1318:        }
                   1319: }
                   1320: #endif /* notyet */

CVSweb