[BACK]Return to pfkeyv2.c CVS log [TXT][DIR] Up to [local] / sys / net

Annotation of sys/net/pfkeyv2.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: pfkeyv2.c,v 1.115 2007/06/22 12:14:05 markus Exp $ */
                      2:
                      3: /*
                      4:  *     @(#)COPYRIGHT   1.1 (NRL) 17 January 1995
                      5:  *
                      6:  * NRL grants permission for redistribution and use in source and binary
                      7:  * forms, with or without modification, of the software and documentation
                      8:  * created at NRL provided that the following conditions are met:
                      9:  *
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgements:
                     17:  *     This product includes software developed by the University of
                     18:  *     California, Berkeley and its contributors.
                     19:  *     This product includes software developed at the Information
                     20:  *     Technology Division, US Naval Research Laboratory.
                     21:  * 4. Neither the name of the NRL nor the names of its contributors
                     22:  *    may be used to endorse or promote products derived from this software
                     23:  *    without specific prior written permission.
                     24:  *
                     25:  * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
                     26:  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     27:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
                     28:  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
                     29:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     30:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     31:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
                     32:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
                     33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
                     34:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
                     35:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     36:  *
                     37:  * The views and conclusions contained in the software and documentation
                     38:  * are those of the authors and should not be interpreted as representing
                     39:  * official policies, either expressed or implied, of the US Naval
                     40:  * Research Laboratory (NRL).
                     41:  */
                     42:
                     43: /*
                     44:  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved.
                     45:  *
                     46:  * Redistribution and use in source and binary forms, with or without
                     47:  * modification, are permitted provided that the following conditions
                     48:  * are met:
                     49:  * 1. Redistributions of source code must retain the above copyright
                     50:  *    notice, this list of conditions and the following disclaimer.
                     51:  * 2. Redistributions in binary form must reproduce the above copyright
                     52:  *    notice, this list of conditions and the following disclaimer in the
                     53:  *    documentation and/or other materials provided with the distribution.
                     54:  * 3. Neither the name of the author nor the names of any contributors
                     55:  *    may be used to endorse or promote products derived from this software
                     56:  *    without specific prior written permission.
                     57:  *
                     58:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     59:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     60:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     61:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     62:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     63:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     64:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     65:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     66:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     67:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     68:  * SUCH DAMAGE.
                     69:  */
                     70:
                     71: #include "pf.h"
                     72:
                     73: #include <sys/types.h>
                     74: #include <sys/param.h>
                     75: #include <sys/socket.h>
                     76: #include <sys/systm.h>
                     77: #include <sys/mbuf.h>
                     78: #include <sys/kernel.h>
                     79: #include <sys/proc.h>
                     80: #include <net/route.h>
                     81: #include <netinet/ip_ipsp.h>
                     82: #include <net/pfkeyv2.h>
                     83: #include <netinet/ip_ah.h>
                     84: #include <netinet/ip_esp.h>
                     85: #include <netinet/ip_ipcomp.h>
                     86: #include <crypto/blf.h>
                     87:
                     88: #if NPF > 0
                     89: #include <net/if.h>
                     90: #include <net/pfvar.h>
                     91: #endif
                     92:
                     93: #define PFKEYV2_PROTOCOL 2
                     94: #define GETSPI_TRIES 10
                     95:
                     96: /* Static globals */
                     97: static struct pfkeyv2_socket *pfkeyv2_sockets = NULL;
                     98: static struct pfkey_version pfkeyv2_version;
                     99: static uint32_t pfkeyv2_seq = 1;
                    100: static int nregistered = 0;
                    101: static int npromisc = 0;
                    102:
                    103: static const struct sadb_alg ealgs[] = {
                    104:        { SADB_EALG_NULL, 0, 0, 0 },
                    105:        { SADB_EALG_DESCBC, 64, 64, 64 },
                    106:        { SADB_EALG_3DESCBC, 64, 192, 192 },
                    107:        { SADB_X_EALG_BLF, 64, 40, BLF_MAXKEYLEN * 8},
                    108:        { SADB_X_EALG_CAST, 64, 40, 128},
                    109:        { SADB_X_EALG_SKIPJACK, 64, 80, 80},
                    110:        { SADB_X_EALG_AES, 128, 128, 256},
                    111:        { SADB_X_EALG_AESCTR, 128, 128 + 32, 256 + 32}
                    112: };
                    113:
                    114: static const struct sadb_alg aalgs[] = {
                    115:        { SADB_AALG_SHA1HMAC, 0, 160, 160 },
                    116:        { SADB_AALG_MD5HMAC, 0, 128, 128 },
                    117:        { SADB_X_AALG_RIPEMD160HMAC, 0, 160, 160 },
                    118:        { SADB_X_AALG_SHA2_256, 0, 256, 256 },
                    119:        { SADB_X_AALG_SHA2_384, 0, 384, 384 },
                    120:        { SADB_X_AALG_SHA2_512, 0, 512, 512 }
                    121: };
                    122:
                    123: static const struct sadb_alg calgs[] = {
                    124:        { SADB_X_CALG_DEFLATE, 0, 0, 0},
                    125:        { SADB_X_CALG_LZS, 0, 0, 0}
                    126: };
                    127:
                    128: extern uint64_t sadb_exts_allowed_out[SADB_MAX+1];
                    129: extern uint64_t sadb_exts_required_out[SADB_MAX+1];
                    130:
                    131: extern struct pool ipsec_policy_pool;
                    132:
                    133: /*
                    134:  * Wrapper around m_devget(); copy data from contiguous buffer to mbuf
                    135:  * chain.
                    136:  */
                    137: int
                    138: pfdatatopacket(void *data, int len, struct mbuf **packet)
                    139: {
                    140:        if (!(*packet = m_devget(data, len, 0, NULL, NULL)))
                    141:                return (ENOMEM);
                    142:        return (0);
                    143: }
                    144:
                    145: /*
                    146:  * Create a new PF_KEYv2 socket.
                    147:  */
                    148: int
                    149: pfkeyv2_create(struct socket *socket)
                    150: {
                    151:        struct pfkeyv2_socket *pfkeyv2_socket;
                    152:
                    153:        if (!(pfkeyv2_socket = malloc(sizeof(struct pfkeyv2_socket),
                    154:            M_PFKEY, M_DONTWAIT)))
                    155:                return (ENOMEM);
                    156:
                    157:        bzero(pfkeyv2_socket, sizeof(struct pfkeyv2_socket));
                    158:        pfkeyv2_socket->next = pfkeyv2_sockets;
                    159:        pfkeyv2_socket->socket = socket;
                    160:        pfkeyv2_socket->pid = curproc->p_pid;
                    161:
                    162:        pfkeyv2_sockets = pfkeyv2_socket;
                    163:
                    164:        return (0);
                    165: }
                    166:
                    167: /*
                    168:  * Close a PF_KEYv2 socket.
                    169:  */
                    170: int
                    171: pfkeyv2_release(struct socket *socket)
                    172: {
                    173:        struct pfkeyv2_socket **pp;
                    174:
                    175:        for (pp = &pfkeyv2_sockets; *pp && ((*pp)->socket != socket);
                    176:            pp = &((*pp)->next))
                    177:                /*EMPTY*/;
                    178:
                    179:        if (*pp) {
                    180:                struct pfkeyv2_socket *pfkeyv2_socket;
                    181:
                    182:                pfkeyv2_socket = *pp;
                    183:                *pp = (*pp)->next;
                    184:
                    185:                if (pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)
                    186:                        nregistered--;
                    187:
                    188:                if (pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_PROMISC)
                    189:                        npromisc--;
                    190:
                    191:                free(pfkeyv2_socket, M_PFKEY);
                    192:        }
                    193:
                    194:        return (0);
                    195: }
                    196:
                    197: /*
                    198:  * Send a PFKEYv2 message, possibly to many receivers, based on the
                    199:  * satype of the socket (which is set by the REGISTER message), and the
                    200:  * third argument.
                    201:  */
                    202: int
                    203: pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
                    204:     u_int8_t satype, int count)
                    205: {
                    206:        int i, j, rval;
                    207:        void *p, *buffer = NULL;
                    208:        struct mbuf *packet;
                    209:        struct pfkeyv2_socket *s;
                    210:        struct sadb_msg *smsg;
                    211:
                    212:        /* Find out how much space we'll need... */
                    213:        j = sizeof(struct sadb_msg);
                    214:
                    215:        for (i = 1; i <= SADB_EXT_MAX; i++)
                    216:                if (headers[i])
                    217:                        j += ((struct sadb_ext *)headers[i])->sadb_ext_len *
                    218:                            sizeof(uint64_t);
                    219:
                    220:        /* ...and allocate it */
                    221:        if (!(buffer = malloc(j + sizeof(struct sadb_msg), M_PFKEY,
                    222:            M_DONTWAIT))) {
                    223:                rval = ENOMEM;
                    224:                goto ret;
                    225:        }
                    226:
                    227:        p = buffer + sizeof(struct sadb_msg);
                    228:        bcopy(headers[0], p, sizeof(struct sadb_msg));
                    229:        ((struct sadb_msg *) p)->sadb_msg_len = j / sizeof(uint64_t);
                    230:        p += sizeof(struct sadb_msg);
                    231:
                    232:        /* Copy payloads in the packet */
                    233:        for (i = 1; i <= SADB_EXT_MAX; i++)
                    234:                if (headers[i]) {
                    235:                        ((struct sadb_ext *) headers[i])->sadb_ext_type = i;
                    236:                        bcopy(headers[i], p, EXTLEN(headers[i]));
                    237:                        p += EXTLEN(headers[i]);
                    238:                }
                    239:
                    240:        if ((rval = pfdatatopacket(buffer + sizeof(struct sadb_msg),
                    241:            j, &packet)) != 0)
                    242:                goto ret;
                    243:
                    244:        switch (mode) {
                    245:        case PFKEYV2_SENDMESSAGE_UNICAST:
                    246:                /*
                    247:                 * Send message to the specified socket, plus all
                    248:                 * promiscuous listeners.
                    249:                 */
                    250:                pfkey_sendup(socket, packet, 0);
                    251:
                    252:                /*
                    253:                 * Promiscuous messages contain the original message
                    254:                 * encapsulated in another sadb_msg header.
                    255:                 */
                    256:                bzero(buffer, sizeof(struct sadb_msg));
                    257:                smsg = (struct sadb_msg *) buffer;
                    258:                smsg->sadb_msg_version = PF_KEY_V2;
                    259:                smsg->sadb_msg_type = SADB_X_PROMISC;
                    260:                smsg->sadb_msg_len = (sizeof(struct sadb_msg) + j) /
                    261:                    sizeof(uint64_t);
                    262:                smsg->sadb_msg_seq = 0;
                    263:
                    264:                /* Copy to mbuf chain */
                    265:                if ((rval = pfdatatopacket(buffer, sizeof(struct sadb_msg) + j,
                    266:                    &packet)) != 0)
                    267:                        goto ret;
                    268:
                    269:                /*
                    270:                 * Search for promiscuous listeners, skipping the
                    271:                 * original destination.
                    272:                 */
                    273:                for (s = pfkeyv2_sockets; s; s = s->next)
                    274:                        if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
                    275:                            (s->socket != socket))
                    276:                                pfkey_sendup(s->socket, packet, 1);
                    277:
                    278:                /* Done, let's be a bit paranoid */
                    279:                m_zero(packet);
                    280:                m_freem(packet);
                    281:                break;
                    282:
                    283:        case PFKEYV2_SENDMESSAGE_REGISTERED:
                    284:                /*
                    285:                 * Send the message to all registered sockets that match
                    286:                 * the specified satype (e.g., all IPSEC-ESP negotiators)
                    287:                 */
                    288:                for (s = pfkeyv2_sockets; s; s = s->next)
                    289:                        if (s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED) {
                    290:                                if (!satype)    /* Just send to everyone registered */
                    291:                                        pfkey_sendup(s->socket, packet, 1);
                    292:                                else {
                    293:                                        /* Check for specified satype */
                    294:                                        if ((1 << satype) & s->registration)
                    295:                                                pfkey_sendup(s->socket, packet, 1);
                    296:                                }
                    297:                        }
                    298:
                    299:                /* Free last/original copy of the packet */
                    300:                m_freem(packet);
                    301:
                    302:                /* Encapsulate the original message "inside" an sadb_msg header */
                    303:                bzero(buffer, sizeof(struct sadb_msg));
                    304:                smsg = (struct sadb_msg *) buffer;
                    305:                smsg->sadb_msg_version = PF_KEY_V2;
                    306:                smsg->sadb_msg_type = SADB_X_PROMISC;
                    307:                smsg->sadb_msg_len = (sizeof(struct sadb_msg) + j) /
                    308:                    sizeof(uint64_t);
                    309:                smsg->sadb_msg_seq = 0;
                    310:
                    311:                /* Convert to mbuf chain */
                    312:                if ((rval = pfdatatopacket(buffer, sizeof(struct sadb_msg) + j,
                    313:                    &packet)) != 0)
                    314:                        goto ret;
                    315:
                    316:                /* Send to all registered promiscuous listeners */
                    317:                for (s = pfkeyv2_sockets; s; s = s->next)
                    318:                        if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
                    319:                            !(s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED))
                    320:                                pfkey_sendup(s->socket, packet, 1);
                    321:
                    322:                m_freem(packet);
                    323:                break;
                    324:
                    325:        case PFKEYV2_SENDMESSAGE_BROADCAST:
                    326:                /* Send message to all sockets */
                    327:                for (s = pfkeyv2_sockets; s; s = s->next)
                    328:                        pfkey_sendup(s->socket, packet, 1);
                    329:
                    330:                m_freem(packet);
                    331:                break;
                    332:        }
                    333:
                    334: ret:
                    335:        if (buffer != NULL) {
                    336:                bzero(buffer, j + sizeof(struct sadb_msg));
                    337:                free(buffer, M_PFKEY);
                    338:        }
                    339:
                    340:        return (rval);
                    341: }
                    342:
                    343: /*
                    344:  * Get SPD information for an ACQUIRE. We setup the message such that
                    345:  * the SRC/DST payloads are relative to us (regardless of whether the
                    346:  * SPD rule was for incoming or outgoing packets).
                    347:  */
                    348: int
                    349: pfkeyv2_policy(struct ipsec_acquire *ipa, void **headers, void **buffer)
                    350: {
                    351:        union sockaddr_union sunion;
                    352:        struct sadb_protocol *sp;
                    353:        int rval, i, dir;
                    354:        void *p;
                    355:
                    356:        /* Find out how big a buffer we need */
                    357:        i = 4 * sizeof(struct sadb_address) + sizeof(struct sadb_protocol);
                    358:        bzero(&sunion, sizeof(union sockaddr_union));
                    359:
                    360:        switch (ipa->ipa_info.sen_type) {
                    361: #ifdef INET
                    362:        case SENT_IP4:
                    363:                i += 4 * PADUP(sizeof(struct sockaddr_in));
                    364:                sunion.sa.sa_family = AF_INET;
                    365:                sunion.sa.sa_len = sizeof(struct sockaddr_in);
                    366:                dir = ipa->ipa_info.sen_direction;
                    367:                break;
                    368: #endif /* INET */
                    369:
                    370: #ifdef INET6
                    371:        case SENT_IP6:
                    372:                i += 4 * PADUP(sizeof(struct sockaddr_in6));
                    373:                sunion.sa.sa_family = AF_INET6;
                    374:                sunion.sa.sa_len = sizeof(struct sockaddr_in6);
                    375:                dir = ipa->ipa_info.sen_ip6_direction;
                    376:                break;
                    377: #endif /* INET6 */
                    378:
                    379:        default:
                    380:                return (EINVAL);
                    381:        }
                    382:
                    383:        if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
                    384:                rval = ENOMEM;
                    385:                goto ret;
                    386:        } else {
                    387:                *buffer = p;
                    388:                bzero(p, i);
                    389:        }
                    390:
                    391:        if (dir == IPSP_DIRECTION_OUT)
                    392:                headers[SADB_X_EXT_SRC_FLOW] = p;
                    393:        else
                    394:                headers[SADB_X_EXT_DST_FLOW] = p;
                    395:        switch (sunion.sa.sa_family) {
                    396: #ifdef INET
                    397:        case AF_INET:
                    398:                sunion.sin.sin_addr = ipa->ipa_info.sen_ip_src;
                    399:                sunion.sin.sin_port = ipa->ipa_info.sen_sport;
                    400:                break;
                    401: #endif /* INET */
                    402:
                    403: #ifdef INET6
                    404:        case AF_INET6:
                    405:                sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_src;
                    406:                sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_sport;
                    407:                break;
                    408: #endif /* INET6 */
                    409:        }
                    410:        export_address(&p, (struct sockaddr *) &sunion);
                    411:
                    412:        if (dir == IPSP_DIRECTION_OUT)
                    413:                headers[SADB_X_EXT_SRC_MASK] = p;
                    414:        else
                    415:                headers[SADB_X_EXT_DST_MASK] = p;
                    416:        switch (sunion.sa.sa_family) {
                    417: #ifdef INET
                    418:        case AF_INET:
                    419:                sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_src;
                    420:                sunion.sin.sin_port = ipa->ipa_mask.sen_sport;
                    421:                break;
                    422: #endif /* INET */
                    423:
                    424: #ifdef INET6
                    425:        case AF_INET6:
                    426:                sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_src;
                    427:                sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_sport;
                    428:                break;
                    429: #endif /* INET6 */
                    430:        }
                    431:        export_address(&p, (struct sockaddr *) &sunion);
                    432:
                    433:        if (dir == IPSP_DIRECTION_OUT)
                    434:                headers[SADB_X_EXT_DST_FLOW] = p;
                    435:        else
                    436:                headers[SADB_X_EXT_SRC_FLOW] = p;
                    437:        switch (sunion.sa.sa_family) {
                    438: #ifdef INET
                    439:        case AF_INET:
                    440:                sunion.sin.sin_addr = ipa->ipa_info.sen_ip_dst;
                    441:                sunion.sin.sin_port = ipa->ipa_info.sen_dport;
                    442:                break;
                    443: #endif /* INET */
                    444:
                    445: #ifdef INET6
                    446:        case AF_INET6:
                    447:                sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_dst;
                    448:                sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_dport;
                    449:                break;
                    450: #endif /* INET6 */
                    451:        }
                    452:        export_address(&p, (struct sockaddr *) &sunion);
                    453:
                    454:        if (dir == IPSP_DIRECTION_OUT)
                    455:                headers[SADB_X_EXT_DST_MASK] = p;
                    456:        else
                    457:                headers[SADB_X_EXT_SRC_MASK] = p;
                    458:        switch (sunion.sa.sa_family) {
                    459: #ifdef INET
                    460:        case AF_INET:
                    461:                sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_dst;
                    462:                sunion.sin.sin_port = ipa->ipa_mask.sen_dport;
                    463:                break;
                    464: #endif /* INET */
                    465:
                    466: #ifdef INET6
                    467:        case AF_INET6:
                    468:                sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_dst;
                    469:                sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_dport;
                    470:                break;
                    471: #endif /* INET6 */
                    472:        }
                    473:        export_address(&p, (struct sockaddr *) &sunion);
                    474:
                    475:        headers[SADB_X_EXT_FLOW_TYPE] = p;
                    476:        sp = p;
                    477:        sp->sadb_protocol_len = sizeof(struct sadb_protocol) /
                    478:            sizeof(u_int64_t);
                    479:        switch (sunion.sa.sa_family) {
                    480: #ifdef INET
                    481:        case AF_INET:
                    482:                if (ipa->ipa_mask.sen_proto)
                    483:                        sp->sadb_protocol_proto = ipa->ipa_info.sen_proto;
                    484:                sp->sadb_protocol_direction = ipa->ipa_info.sen_direction;
                    485:                break;
                    486: #endif /* INET */
                    487:
                    488: #ifdef INET6
                    489:        case AF_INET6:
                    490:                if (ipa->ipa_mask.sen_ip6_proto)
                    491:                        sp->sadb_protocol_proto = ipa->ipa_info.sen_ip6_proto;
                    492:                sp->sadb_protocol_direction = ipa->ipa_info.sen_ip6_direction;
                    493:                break;
                    494: #endif /* INET6 */
                    495:        }
                    496:
                    497:        rval = 0;
                    498:
                    499: ret:
                    500:        return (rval);
                    501: }
                    502:
                    503: /*
                    504:  * Get all the information contained in an SA to a PFKEYV2 message.
                    505:  */
                    506: int
                    507: pfkeyv2_get(struct tdb *sa, void **headers, void **buffer, int *lenp)
                    508: {
                    509:        int rval, i;
                    510:        void *p;
                    511:
                    512:        /* Find how much space we need */
                    513:        i = sizeof(struct sadb_sa) + sizeof(struct sadb_lifetime);
                    514:
                    515:        if (sa->tdb_soft_allocations || sa->tdb_soft_bytes ||
                    516:            sa->tdb_soft_timeout || sa->tdb_soft_first_use)
                    517:                i += sizeof(struct sadb_lifetime);
                    518:
                    519:        if (sa->tdb_exp_allocations || sa->tdb_exp_bytes ||
                    520:            sa->tdb_exp_timeout || sa->tdb_exp_first_use)
                    521:                i += sizeof(struct sadb_lifetime);
                    522:
                    523:        if (sa->tdb_last_used)
                    524:                i += sizeof(struct sadb_lifetime);
                    525:
                    526:        if (sa->tdb_src.sa.sa_family)
                    527:                i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_src.sa));
                    528:
                    529:        if (sa->tdb_dst.sa.sa_family)
                    530:                i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_dst.sa));
                    531:
                    532:        if (sa->tdb_proxy.sa.sa_family)
                    533:                i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_proxy.sa));
                    534:
                    535:        if (sa->tdb_srcid)
                    536:                i += PADUP(sa->tdb_srcid->ref_len) + sizeof(struct sadb_ident);
                    537:
                    538:        if (sa->tdb_dstid)
                    539:                i += PADUP(sa->tdb_dstid->ref_len) + sizeof(struct sadb_ident);
                    540:
                    541:        if (sa->tdb_local_cred)
                    542:                i += PADUP(sa->tdb_local_cred->ref_len) + sizeof(struct sadb_x_cred);
                    543:
                    544:        if (sa->tdb_remote_cred)
                    545:                i += PADUP(sa->tdb_remote_cred->ref_len) + sizeof(struct sadb_x_cred);
                    546:
                    547:        if (sa->tdb_local_auth)
                    548:                i += PADUP(sa->tdb_local_auth->ref_len) + sizeof(struct sadb_x_cred);
                    549:
                    550:        if (sa->tdb_remote_auth)
                    551:                i += PADUP(sa->tdb_remote_auth->ref_len) + sizeof(struct sadb_x_cred);
                    552:
                    553:        if (sa->tdb_amxkey)
                    554:                i+= PADUP(sa->tdb_amxkeylen) + sizeof(struct sadb_key);
                    555:
                    556:        if (sa->tdb_emxkey)
                    557:                i+= PADUP(sa->tdb_emxkeylen) + sizeof(struct sadb_key);
                    558:
                    559:        if (sa->tdb_filter.sen_type) {
                    560:                i += 2 * sizeof(struct sadb_protocol);
                    561:
                    562:                /* We'll need four of them: src, src mask, dst, dst mask. */
                    563:                switch (sa->tdb_filter.sen_type) {
                    564: #ifdef INET
                    565:                case SENT_IP4:
                    566:                        i += 4 * PADUP(sizeof(struct sockaddr_in));
                    567:                        i += 4 * sizeof(struct sadb_address);
                    568:                        break;
                    569: #endif /* INET */
                    570: #ifdef INET6
                    571:                case SENT_IP6:
                    572:                        i += 4 * PADUP(sizeof(struct sockaddr_in6));
                    573:                        i += 4 * sizeof(struct sadb_address);
                    574:                        break;
                    575: #endif /* INET6 */
                    576:                default:
                    577:                        rval = EINVAL;
                    578:                        goto ret;
                    579:                }
                    580:        }
                    581:
                    582:        if (sa->tdb_udpencap_port)
                    583:                i+= sizeof(struct sadb_x_udpencap);
                    584:
                    585: #if NPF > 0
                    586:        if (sa->tdb_tag)
                    587:                i+= PADUP(PF_TAG_NAME_SIZE) + sizeof(struct sadb_x_tag);
                    588: #endif
                    589:
                    590:        if (lenp)
                    591:                *lenp = i;
                    592:
                    593:        if (buffer == NULL) {
                    594:                rval = 0;
                    595:                goto ret;
                    596:        }
                    597:
                    598:        if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
                    599:                rval = ENOMEM;
                    600:                goto ret;
                    601:        } else {
                    602:                *buffer = p;
                    603:                bzero(p, i);
                    604:        }
                    605:
                    606:        headers[SADB_EXT_SA] = p;
                    607:
                    608:        export_sa(&p, sa);  /* Export SA information (mostly flags) */
                    609:
                    610:        /* Export lifetimes where applicable */
                    611:        headers[SADB_EXT_LIFETIME_CURRENT] = p;
                    612:        export_lifetime(&p, sa, PFKEYV2_LIFETIME_CURRENT);
                    613:
                    614:        if (sa->tdb_soft_allocations || sa->tdb_soft_bytes ||
                    615:            sa->tdb_soft_first_use || sa->tdb_soft_timeout) {
                    616:                headers[SADB_EXT_LIFETIME_SOFT] = p;
                    617:                export_lifetime(&p, sa, PFKEYV2_LIFETIME_SOFT);
                    618:        }
                    619:
                    620:        if (sa->tdb_exp_allocations || sa->tdb_exp_bytes ||
                    621:            sa->tdb_exp_first_use || sa->tdb_exp_timeout) {
                    622:                headers[SADB_EXT_LIFETIME_HARD] = p;
                    623:                export_lifetime(&p, sa, PFKEYV2_LIFETIME_HARD);
                    624:        }
                    625:
                    626:        if (sa->tdb_last_used) {
                    627:                headers[SADB_X_EXT_LIFETIME_LASTUSE] = p;
                    628:                export_lifetime(&p, sa, PFKEYV2_LIFETIME_LASTUSE);
                    629:        }
                    630:
                    631:        /* Export TDB source address */
                    632:        headers[SADB_EXT_ADDRESS_SRC] = p;
                    633:        export_address(&p, (struct sockaddr *) &sa->tdb_src);
                    634:
                    635:        /* Export TDB destination address */
                    636:        headers[SADB_EXT_ADDRESS_DST] = p;
                    637:        export_address(&p, (struct sockaddr *) &sa->tdb_dst);
                    638:
                    639:        /* Export TDB proxy address, if present */
                    640:        if (SA_LEN(&sa->tdb_proxy.sa)) {
                    641:                headers[SADB_EXT_ADDRESS_PROXY] = p;
                    642:                export_address(&p, (struct sockaddr *) &sa->tdb_proxy);
                    643:        }
                    644:
                    645:        /* Export source identity, if present */
                    646:        if (sa->tdb_srcid) {
                    647:                headers[SADB_EXT_IDENTITY_SRC] = p;
                    648:                export_identity(&p, sa, PFKEYV2_IDENTITY_SRC);
                    649:        }
                    650:
                    651:        /* Export destination identity, if present */
                    652:        if (sa->tdb_dstid) {
                    653:                headers[SADB_EXT_IDENTITY_DST] = p;
                    654:                export_identity(&p, sa, PFKEYV2_IDENTITY_DST);
                    655:        }
                    656:
                    657:        /* Export credentials, if present */
                    658:        if (sa->tdb_local_cred) {
                    659:                headers[SADB_X_EXT_LOCAL_CREDENTIALS] = p;
                    660:                export_credentials(&p, sa, PFKEYV2_CRED_LOCAL);
                    661:        }
                    662:
                    663:        if (sa->tdb_remote_cred) {
                    664:                headers[SADB_X_EXT_REMOTE_CREDENTIALS] = p;
                    665:                export_credentials(&p, sa, PFKEYV2_CRED_REMOTE);
                    666:        }
                    667:
                    668:        /* Export authentication information, if present */
                    669:        if (sa->tdb_local_auth) {
                    670:                headers[SADB_X_EXT_LOCAL_AUTH] = p;
                    671:                export_auth(&p, sa, PFKEYV2_AUTH_LOCAL);
                    672:        }
                    673:
                    674:        if (sa->tdb_remote_auth) {
                    675:                headers[SADB_X_EXT_REMOTE_AUTH] = p;
                    676:                export_auth(&p, sa, PFKEYV2_AUTH_REMOTE);
                    677:        }
                    678:
                    679:        /* Export authentication key, if present */
                    680:        if (sa->tdb_amxkey) {
                    681:                headers[SADB_EXT_KEY_AUTH] = p;
                    682:                export_key(&p, sa, PFKEYV2_AUTHENTICATION_KEY);
                    683:        }
                    684:
                    685:        /* Export encryption key, if present */
                    686:        if (sa->tdb_emxkey) {
                    687:                headers[SADB_EXT_KEY_ENCRYPT] = p;
                    688:                export_key(&p, sa, PFKEYV2_ENCRYPTION_KEY);
                    689:        }
                    690:
                    691:        /* Export flow/filter, if present */
                    692:        if (sa->tdb_filter.sen_type)
                    693:                export_flow(&p, IPSP_IPSEC_USE, &sa->tdb_filter,
                    694:                    &sa->tdb_filtermask, headers);
                    695:
                    696:        /* Export UDP encapsulation port, if present */
                    697:        if (sa->tdb_udpencap_port) {
                    698:                headers[SADB_X_EXT_UDPENCAP] = p;
                    699:                export_udpencap(&p, sa);
                    700:        }
                    701:
                    702: #if NPF > 0
                    703:        /* Export tag information, if present */
                    704:        if (sa->tdb_tag) {
                    705:                headers[SADB_X_EXT_TAG] = p;
                    706:                export_tag(&p, sa);
                    707:        }
                    708: #endif
                    709:
                    710:        rval = 0;
                    711:
                    712:  ret:
                    713:        return (rval);
                    714: }
                    715:
                    716: /*
                    717:  * Dump a TDB.
                    718:  */
                    719: int
                    720: pfkeyv2_dump_walker(struct tdb *sa, void *state, int last)
                    721: {
                    722:        struct dump_state *dump_state = (struct dump_state *) state;
                    723:        void *headers[SADB_EXT_MAX+1], *buffer;
                    724:        int rval;
                    725:
                    726:        /* If not satype was specified, dump all TDBs */
                    727:        if (!dump_state->sadb_msg->sadb_msg_satype ||
                    728:            (sa->tdb_satype == dump_state->sadb_msg->sadb_msg_satype)) {
                    729:                bzero(headers, sizeof(headers));
                    730:                headers[0] = (void *) dump_state->sadb_msg;
                    731:
                    732:                /* Get the information from the TDB to a PFKEYv2 message */
                    733:                if ((rval = pfkeyv2_get(sa, headers, &buffer, NULL)) != 0)
                    734:                        return (rval);
                    735:
                    736:                if (last)
                    737:                        ((struct sadb_msg *)headers[0])->sadb_msg_seq = 0;
                    738:
                    739:                /* Send the message to the specified socket */
                    740:                rval = pfkeyv2_sendmessage(headers,
                    741:                    PFKEYV2_SENDMESSAGE_UNICAST, dump_state->socket, 0, 0);
                    742:
                    743:                free(buffer, M_PFKEY);
                    744:                if (rval)
                    745:                        return (rval);
                    746:        }
                    747:
                    748:        return (0);
                    749: }
                    750:
                    751: /*
                    752:  * Delete an SA.
                    753:  */
                    754: int
                    755: pfkeyv2_flush_walker(struct tdb *sa, void *satype_vp, int last)
                    756: {
                    757:        if (!(*((u_int8_t *) satype_vp)) ||
                    758:            sa->tdb_satype == *((u_int8_t *) satype_vp))
                    759:                tdb_delete(sa);
                    760:        return (0);
                    761: }
                    762:
                    763: /*
                    764:  * Convert between SATYPEs and IPsec protocols, taking into consideration
                    765:  * sysctl variables enabling/disabling ESP/AH and the presence of the old
                    766:  * IPsec transforms.
                    767:  */
                    768: int
                    769: pfkeyv2_get_proto_alg(u_int8_t satype, u_int8_t *sproto, int *alg)
                    770: {
                    771:        switch (satype) {
                    772: #ifdef IPSEC
                    773:        case SADB_SATYPE_AH:
                    774:                if (!ah_enable)
                    775:                        return (EOPNOTSUPP);
                    776:
                    777:                *sproto = IPPROTO_AH;
                    778:
                    779:                if(alg != NULL)
                    780:                        *alg = satype = XF_AH;
                    781:
                    782:                break;
                    783:
                    784:        case SADB_SATYPE_ESP:
                    785:                if (!esp_enable)
                    786:                        return (EOPNOTSUPP);
                    787:
                    788:                *sproto = IPPROTO_ESP;
                    789:
                    790:                if(alg != NULL)
                    791:                        *alg = satype = XF_ESP;
                    792:
                    793:                break;
                    794:
                    795:        case SADB_X_SATYPE_IPIP:
                    796:                *sproto = IPPROTO_IPIP;
                    797:
                    798:                if (alg != NULL)
                    799:                        *alg = XF_IP4;
                    800:
                    801:                break;
                    802:
                    803:        case SADB_X_SATYPE_IPCOMP:
                    804:                if (!ipcomp_enable)
                    805:                        return (EOPNOTSUPP);
                    806:
                    807:                *sproto = IPPROTO_IPCOMP;
                    808:
                    809:                if(alg != NULL)
                    810:                        *alg = satype = XF_IPCOMP;
                    811:
                    812:                break;
                    813: #endif /* IPSEC */
                    814: #ifdef TCP_SIGNATURE
                    815:        case SADB_X_SATYPE_TCPSIGNATURE:
                    816:                *sproto = IPPROTO_TCP;
                    817:
                    818:                if (alg != NULL)
                    819:                        *alg = XF_TCPSIGNATURE;
                    820:
                    821:                break;
                    822: #endif /* TCP_SIGNATURE */
                    823:
                    824:        default: /* Nothing else supported */
                    825:                return (EOPNOTSUPP);
                    826:        }
                    827:
                    828:        return (0);
                    829: }
                    830:
                    831: /*
                    832:  * Handle all messages from userland to kernel.
                    833:  */
                    834: int
                    835: pfkeyv2_send(struct socket *socket, void *message, int len)
                    836: {
                    837:        int i, j, rval = 0, mode = PFKEYV2_SENDMESSAGE_BROADCAST;
                    838:        int delflag = 0, s;
                    839:        struct sockaddr_encap encapdst, encapnetmask, encapgw;
                    840:        struct ipsec_policy *ipo, *tmpipo;
                    841:        struct ipsec_acquire *ipa;
                    842:
                    843:        struct pfkeyv2_socket *pfkeyv2_socket, *so = NULL;
                    844:
                    845:        void *freeme = NULL, *bckptr = NULL;
                    846:        void *headers[SADB_EXT_MAX + 1];
                    847:
                    848:        union sockaddr_union *sunionp;
                    849:
                    850:        struct tdb sa, *sa2 = NULL;
                    851:
                    852:        struct sadb_msg *smsg;
                    853:        struct sadb_spirange *sprng;
                    854:        struct sadb_sa *ssa;
                    855:        struct sadb_supported *ssup;
                    856:        struct sadb_ident *sid;
                    857:
                    858:        /* Verify that we received this over a legitimate pfkeyv2 socket */
                    859:        bzero(headers, sizeof(headers));
                    860:
                    861:        for (pfkeyv2_socket = pfkeyv2_sockets; pfkeyv2_socket;
                    862:            pfkeyv2_socket = pfkeyv2_socket->next)
                    863:                if (pfkeyv2_socket->socket == socket)
                    864:                        break;
                    865:
                    866:        if (!pfkeyv2_socket) {
                    867:                rval = EINVAL;
                    868:                goto ret;
                    869:        }
                    870:
                    871:        /* If we have any promiscuous listeners, send them a copy of the message */
                    872:        if (npromisc) {
                    873:                struct mbuf *packet;
                    874:
                    875:                if (!(freeme = malloc(sizeof(struct sadb_msg) + len, M_PFKEY,
                    876:                    M_DONTWAIT))) {
                    877:                        rval = ENOMEM;
                    878:                        goto ret;
                    879:                }
                    880:
                    881:                /* Initialize encapsulating header */
                    882:                bzero(freeme, sizeof(struct sadb_msg));
                    883:                smsg = (struct sadb_msg *) freeme;
                    884:                smsg->sadb_msg_version = PF_KEY_V2;
                    885:                smsg->sadb_msg_type = SADB_X_PROMISC;
                    886:                smsg->sadb_msg_len = (sizeof(struct sadb_msg) + len) /
                    887:                    sizeof(uint64_t);
                    888:                smsg->sadb_msg_seq = curproc->p_pid;
                    889:
                    890:                bcopy(message, freeme + sizeof(struct sadb_msg), len);
                    891:
                    892:                /* Convert to mbuf chain */
                    893:                if ((rval = pfdatatopacket(freeme,
                    894:                    sizeof(struct sadb_msg) + len, &packet)) != 0)
                    895:                        goto ret;
                    896:
                    897:                /* Send to all promiscuous listeners */
                    898:                for (so = pfkeyv2_sockets; so; so = so->next)
                    899:                        if (so->flags & PFKEYV2_SOCKETFLAGS_PROMISC)
                    900:                                pfkey_sendup(so->socket, packet, 1);
                    901:
                    902:                /* Paranoid */
                    903:                m_zero(packet);
                    904:                m_freem(packet);
                    905:
                    906:                /* Even more paranoid */
                    907:                bzero(freeme, sizeof(struct sadb_msg) + len);
                    908:                free(freeme, M_PFKEY);
                    909:                freeme = NULL;
                    910:        }
                    911:
                    912:        /* Validate message format */
                    913:        if ((rval = pfkeyv2_parsemessage(message, len, headers)) != 0)
                    914:                goto ret;
                    915:
                    916:        smsg = (struct sadb_msg *) headers[0];
                    917:        switch (smsg->sadb_msg_type) {
                    918:        case SADB_GETSPI:  /* Reserve an SPI */
                    919:                bzero(&sa, sizeof(struct tdb));
                    920:
                    921:                sa.tdb_satype = smsg->sadb_msg_satype;
                    922:                if ((rval = pfkeyv2_get_proto_alg(sa.tdb_satype,
                    923:                    &sa.tdb_sproto, 0)))
                    924:                        goto ret;
                    925:
                    926:                import_address((struct sockaddr *) &sa.tdb_src,
                    927:                    headers[SADB_EXT_ADDRESS_SRC]);
                    928:                import_address((struct sockaddr *) &sa.tdb_dst,
                    929:                    headers[SADB_EXT_ADDRESS_DST]);
                    930:
                    931:                /* Find an unused SA identifier */
                    932:                sprng = (struct sadb_spirange *) headers[SADB_EXT_SPIRANGE];
                    933:                sa.tdb_spi = reserve_spi(sprng->sadb_spirange_min,
                    934:                    sprng->sadb_spirange_max, &sa.tdb_src, &sa.tdb_dst,
                    935:                    sa.tdb_sproto, &rval);
                    936:                if (sa.tdb_spi == 0)
                    937:                        goto ret;
                    938:
                    939:                /* Send a message back telling what the SA (the SPI really) is */
                    940:                if (!(freeme = malloc(sizeof(struct sadb_sa), M_PFKEY,
                    941:                    M_DONTWAIT))) {
                    942:                        rval = ENOMEM;
                    943:                        goto ret;
                    944:                }
                    945:
                    946:                bzero(freeme, sizeof(struct sadb_sa));
                    947:                headers[SADB_EXT_SPIRANGE] = NULL;
                    948:                headers[SADB_EXT_SA] = freeme;
                    949:                bckptr = freeme;
                    950:
                    951:                /* We really only care about the SPI, but we'll export the SA */
                    952:                export_sa((void **) &bckptr, &sa);
                    953:                break;
                    954:
                    955:        case SADB_UPDATE:
                    956:                ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
                    957:                sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
                    958:                    sizeof(struct sadb_address));
                    959:
                    960:                /* Either all or none of the flow must be included */
                    961:                if ((headers[SADB_X_EXT_SRC_FLOW] ||
                    962:                    headers[SADB_X_EXT_PROTOCOL] ||
                    963:                    headers[SADB_X_EXT_FLOW_TYPE] ||
                    964:                    headers[SADB_X_EXT_DST_FLOW] ||
                    965:                    headers[SADB_X_EXT_SRC_MASK] ||
                    966:                    headers[SADB_X_EXT_DST_MASK]) &&
                    967:                    !(headers[SADB_X_EXT_SRC_FLOW] &&
                    968:                    headers[SADB_X_EXT_PROTOCOL] &&
                    969:                    headers[SADB_X_EXT_FLOW_TYPE] &&
                    970:                    headers[SADB_X_EXT_DST_FLOW] &&
                    971:                    headers[SADB_X_EXT_SRC_MASK] &&
                    972:                    headers[SADB_X_EXT_DST_MASK])) {
                    973:                        rval = EINVAL;
                    974:                        goto ret;
                    975:                }
                    976: #ifdef IPSEC
                    977:                /* UDP encap has to be enabled and is only supported for ESP */
                    978:                if (headers[SADB_X_EXT_UDPENCAP] &&
                    979:                    (!udpencap_enable ||
                    980:                    smsg->sadb_msg_satype != SADB_SATYPE_ESP)) {
                    981:                        rval = EINVAL;
                    982:                        goto ret;
                    983:                }
                    984: #endif /* IPSEC */
                    985:
                    986:                s = spltdb();
                    987:
                    988:                /* Find TDB */
                    989:                sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
                    990:                    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
                    991:
                    992:                /* If there's no such SA, we're done */
                    993:                if (sa2 == NULL) {
                    994:                        rval = ESRCH;
                    995:                        goto splxret;
                    996:                }
                    997:
                    998:                /* If this is a reserved SA */
                    999:                if (sa2->tdb_flags & TDBF_INVALID) {
                   1000:                        struct tdb *newsa;
                   1001:                        struct ipsecinit ii;
                   1002:                        int alg;
                   1003:
                   1004:                        /* Create new TDB */
                   1005:                        freeme = tdb_alloc();
                   1006:                        bzero(&ii, sizeof(struct ipsecinit));
                   1007:
                   1008:                        newsa = (struct tdb *) freeme;
                   1009:                        newsa->tdb_satype = smsg->sadb_msg_satype;
                   1010:
                   1011:                        if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype,
                   1012:                            &newsa->tdb_sproto, &alg))) {
                   1013:                                tdb_free(freeme);
                   1014:                                freeme = NULL;
                   1015:                                goto splxret;
                   1016:                        }
                   1017:
                   1018:                        /* Initialize SA */
                   1019:                        import_sa(newsa, headers[SADB_EXT_SA], &ii);
                   1020:                        import_address((struct sockaddr *) &newsa->tdb_src,
                   1021:                            headers[SADB_EXT_ADDRESS_SRC]);
                   1022:                        import_address((struct sockaddr *) &newsa->tdb_dst,
                   1023:                            headers[SADB_EXT_ADDRESS_DST]);
                   1024:                        import_address((struct sockaddr *) &newsa->tdb_proxy,
                   1025:                            headers[SADB_EXT_ADDRESS_PROXY]);
                   1026:                        import_lifetime(newsa,
                   1027:                            headers[SADB_EXT_LIFETIME_CURRENT],
                   1028:                            PFKEYV2_LIFETIME_CURRENT);
                   1029:                        import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT],
                   1030:                            PFKEYV2_LIFETIME_SOFT);
                   1031:                        import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD],
                   1032:                            PFKEYV2_LIFETIME_HARD);
                   1033:                        import_key(&ii, headers[SADB_EXT_KEY_AUTH],
                   1034:                            PFKEYV2_AUTHENTICATION_KEY);
                   1035:                        import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT],
                   1036:                            PFKEYV2_ENCRYPTION_KEY);
                   1037:                        import_identity(newsa, headers[SADB_EXT_IDENTITY_SRC],
                   1038:                            PFKEYV2_IDENTITY_SRC);
                   1039:                        import_identity(newsa, headers[SADB_EXT_IDENTITY_DST],
                   1040:                            PFKEYV2_IDENTITY_DST);
                   1041:                        import_credentials(newsa,
                   1042:                            headers[SADB_X_EXT_LOCAL_CREDENTIALS],
                   1043:                            PFKEYV2_CRED_LOCAL);
                   1044:                        import_credentials(newsa,
                   1045:                            headers[SADB_X_EXT_REMOTE_CREDENTIALS],
                   1046:                            PFKEYV2_CRED_REMOTE);
                   1047:                        import_auth(newsa, headers[SADB_X_EXT_LOCAL_AUTH],
                   1048:                            PFKEYV2_AUTH_LOCAL);
                   1049:                        import_auth(newsa, headers[SADB_X_EXT_REMOTE_AUTH],
                   1050:                            PFKEYV2_AUTH_REMOTE);
                   1051:                        import_flow(&newsa->tdb_filter, &newsa->tdb_filtermask,
                   1052:                            headers[SADB_X_EXT_SRC_FLOW],
                   1053:                            headers[SADB_X_EXT_SRC_MASK],
                   1054:                            headers[SADB_X_EXT_DST_FLOW],
                   1055:                            headers[SADB_X_EXT_DST_MASK],
                   1056:                            headers[SADB_X_EXT_PROTOCOL],
                   1057:                            headers[SADB_X_EXT_FLOW_TYPE]);
                   1058:                        import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
                   1059: #if NPF > 0
                   1060:                        import_tag(newsa, headers[SADB_X_EXT_TAG]);
                   1061: #endif
                   1062:
                   1063:                        headers[SADB_EXT_KEY_AUTH] = NULL;
                   1064:                        headers[SADB_EXT_KEY_ENCRYPT] = NULL;
                   1065:                        headers[SADB_X_EXT_LOCAL_AUTH] = NULL;
                   1066:
                   1067:                        newsa->tdb_seq = smsg->sadb_msg_seq;
                   1068:
                   1069:                        rval = tdb_init(newsa, alg, &ii);
                   1070:                        if (rval) {
                   1071:                                rval = EINVAL;
                   1072:                                tdb_free(freeme);
                   1073:                                freeme = NULL;
                   1074:                                goto splxret;
                   1075:                        }
                   1076:
                   1077:                        newsa->tdb_cur_allocations = sa2->tdb_cur_allocations;
                   1078:
                   1079:                        /* Delete old version of the SA, insert new one */
                   1080:                        tdb_delete(sa2);
                   1081:                        puttdb((struct tdb *) freeme);
                   1082:                        sa2 = freeme = NULL;
                   1083:                } else {
                   1084:                        /*
                   1085:                         * The SA is already initialized, so we're only allowed to
                   1086:                         * change lifetimes and some other information; we're
                   1087:                         * not allowed to change keys, addresses or identities.
                   1088:                         */
                   1089:                        if (headers[SADB_EXT_ADDRESS_PROXY] ||
                   1090:                            headers[SADB_EXT_KEY_AUTH] ||
                   1091:                            headers[SADB_EXT_KEY_ENCRYPT] ||
                   1092:                            headers[SADB_EXT_IDENTITY_SRC] ||
                   1093:                            headers[SADB_EXT_IDENTITY_DST] ||
                   1094:                            headers[SADB_EXT_SENSITIVITY]) {
                   1095:                                rval = EINVAL;
                   1096:                                goto splxret;
                   1097:                        }
                   1098:
                   1099:                        import_sa(sa2, headers[SADB_EXT_SA], NULL);
                   1100:                        import_lifetime(sa2,
                   1101:                            headers[SADB_EXT_LIFETIME_CURRENT],
                   1102:                            PFKEYV2_LIFETIME_CURRENT);
                   1103:                        import_lifetime(sa2, headers[SADB_EXT_LIFETIME_SOFT],
                   1104:                            PFKEYV2_LIFETIME_SOFT);
                   1105:                        import_lifetime(sa2, headers[SADB_EXT_LIFETIME_HARD],
                   1106:                            PFKEYV2_LIFETIME_HARD);
                   1107:                        import_udpencap(sa2, headers[SADB_X_EXT_UDPENCAP]);
                   1108: #if NPF > 0
                   1109:                        import_tag(sa2, headers[SADB_X_EXT_TAG]);
                   1110: #endif
                   1111:                }
                   1112:
                   1113:                splx(s);
                   1114:                break;
                   1115:        case SADB_ADD:
                   1116:                ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
                   1117:                sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
                   1118:                    sizeof(struct sadb_address));
                   1119:
                   1120:                /* Either all or none of the flow must be included */
                   1121:                if ((headers[SADB_X_EXT_SRC_FLOW] ||
                   1122:                    headers[SADB_X_EXT_PROTOCOL] ||
                   1123:                    headers[SADB_X_EXT_FLOW_TYPE] ||
                   1124:                    headers[SADB_X_EXT_DST_FLOW] ||
                   1125:                    headers[SADB_X_EXT_SRC_MASK] ||
                   1126:                    headers[SADB_X_EXT_DST_MASK]) &&
                   1127:                    !(headers[SADB_X_EXT_SRC_FLOW] &&
                   1128:                    headers[SADB_X_EXT_PROTOCOL] &&
                   1129:                    headers[SADB_X_EXT_FLOW_TYPE] &&
                   1130:                    headers[SADB_X_EXT_DST_FLOW] &&
                   1131:                    headers[SADB_X_EXT_SRC_MASK] &&
                   1132:                    headers[SADB_X_EXT_DST_MASK])) {
                   1133:                        rval = EINVAL;
                   1134:                        goto ret;
                   1135:                }
                   1136: #ifdef IPSEC
                   1137:                /* UDP encap has to be enabled and is only supported for ESP */
                   1138:                if (headers[SADB_X_EXT_UDPENCAP] &&
                   1139:                    (!udpencap_enable ||
                   1140:                    smsg->sadb_msg_satype != SADB_SATYPE_ESP)) {
                   1141:                        rval = EINVAL;
                   1142:                        goto ret;
                   1143:                }
                   1144: #endif /* IPSEC */
                   1145:
                   1146:                s = spltdb();
                   1147:
                   1148:                sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
                   1149:                    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
                   1150:
                   1151:                /* We can't add an existing SA! */
                   1152:                if (sa2 != NULL) {
                   1153:                        rval = EEXIST;
                   1154:                        goto splxret;
                   1155:                }
                   1156:
                   1157:                /* We can only add "mature" SAs */
                   1158:                if (ssa->sadb_sa_state != SADB_SASTATE_MATURE) {
                   1159:                        rval = EINVAL;
                   1160:                        goto splxret;
                   1161:                }
                   1162:
                   1163:                /* Allocate and initialize new TDB */
                   1164:                freeme = tdb_alloc();
                   1165:
                   1166:                {
                   1167:                        struct tdb *newsa = (struct tdb *) freeme;
                   1168:                        struct ipsecinit ii;
                   1169:                        int alg;
                   1170:
                   1171:                        bzero(&ii, sizeof(struct ipsecinit));
                   1172:
                   1173:                        newsa->tdb_satype = smsg->sadb_msg_satype;
                   1174:                        if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype,
                   1175:                            &newsa->tdb_sproto, &alg))) {
                   1176:                                tdb_free(freeme);
                   1177:                                freeme = NULL;
                   1178:                                goto splxret;
                   1179:                        }
                   1180:
                   1181:                        import_sa(newsa, headers[SADB_EXT_SA], &ii);
                   1182:                        import_address((struct sockaddr *) &newsa->tdb_src,
                   1183:                            headers[SADB_EXT_ADDRESS_SRC]);
                   1184:                        import_address((struct sockaddr *) &newsa->tdb_dst,
                   1185:                            headers[SADB_EXT_ADDRESS_DST]);
                   1186:                        import_address((struct sockaddr *) &newsa->tdb_proxy,
                   1187:                            headers[SADB_EXT_ADDRESS_PROXY]);
                   1188:
                   1189:                        import_lifetime(newsa,
                   1190:                            headers[SADB_EXT_LIFETIME_CURRENT],
                   1191:                            PFKEYV2_LIFETIME_CURRENT);
                   1192:                        import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT],
                   1193:                            PFKEYV2_LIFETIME_SOFT);
                   1194:                        import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD],
                   1195:                            PFKEYV2_LIFETIME_HARD);
                   1196:
                   1197:                        import_key(&ii, headers[SADB_EXT_KEY_AUTH],
                   1198:                            PFKEYV2_AUTHENTICATION_KEY);
                   1199:                        import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT],
                   1200:                            PFKEYV2_ENCRYPTION_KEY);
                   1201:
                   1202:                        import_identity(newsa, headers[SADB_EXT_IDENTITY_SRC],
                   1203:                            PFKEYV2_IDENTITY_SRC);
                   1204:                        import_identity(newsa, headers[SADB_EXT_IDENTITY_DST],
                   1205:                            PFKEYV2_IDENTITY_DST);
                   1206:
                   1207:                        import_credentials(newsa,
                   1208:                            headers[SADB_X_EXT_LOCAL_CREDENTIALS],
                   1209:                            PFKEYV2_CRED_LOCAL);
                   1210:                        import_credentials(newsa,
                   1211:                            headers[SADB_X_EXT_REMOTE_CREDENTIALS],
                   1212:                            PFKEYV2_CRED_REMOTE);
                   1213:                        import_auth(newsa, headers[SADB_X_EXT_LOCAL_AUTH],
                   1214:                            PFKEYV2_AUTH_LOCAL);
                   1215:                        import_auth(newsa, headers[SADB_X_EXT_REMOTE_AUTH],
                   1216:                            PFKEYV2_AUTH_REMOTE);
                   1217:                        import_flow(&newsa->tdb_filter, &newsa->tdb_filtermask,
                   1218:                            headers[SADB_X_EXT_SRC_FLOW],
                   1219:                            headers[SADB_X_EXT_SRC_MASK],
                   1220:                            headers[SADB_X_EXT_DST_FLOW],
                   1221:                            headers[SADB_X_EXT_DST_MASK],
                   1222:                            headers[SADB_X_EXT_PROTOCOL],
                   1223:                            headers[SADB_X_EXT_FLOW_TYPE]);
                   1224:                        import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
                   1225: #if NPF > 0
                   1226:                        import_tag(newsa, headers[SADB_X_EXT_TAG]);
                   1227: #endif
                   1228:
                   1229:                        headers[SADB_EXT_KEY_AUTH] = NULL;
                   1230:                        headers[SADB_EXT_KEY_ENCRYPT] = NULL;
                   1231:                        headers[SADB_X_EXT_LOCAL_AUTH] = NULL;
                   1232:
                   1233:                        newsa->tdb_seq = smsg->sadb_msg_seq;
                   1234:
                   1235:                        rval = tdb_init(newsa, alg, &ii);
                   1236:                        if (rval) {
                   1237:                                rval = EINVAL;
                   1238:                                tdb_free(freeme);
                   1239:                                freeme = NULL;
                   1240:                                goto splxret;
                   1241:                        }
                   1242:                }
                   1243:
                   1244:                /* Add TDB in table */
                   1245:                puttdb((struct tdb *) freeme);
                   1246:
                   1247:                splx(s);
                   1248:
                   1249:                freeme = NULL;
                   1250:                break;
                   1251:
                   1252:        case SADB_DELETE:
                   1253:                ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
                   1254:                sunionp =
                   1255:                    (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
                   1256:                        sizeof(struct sadb_address));
                   1257:                s = spltdb();
                   1258:
                   1259:                sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
                   1260:                    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
                   1261:                if (sa2 == NULL) {
                   1262:                        rval = ESRCH;
                   1263:                        goto splxret;
                   1264:                }
                   1265:
                   1266:                tdb_delete(sa2);
                   1267:
                   1268:                splx(s);
                   1269:
                   1270:                sa2 = NULL;
                   1271:                break;
                   1272:
                   1273:        case SADB_X_ASKPOLICY:
                   1274:                /* Get the relevant policy */
                   1275:                ipa = ipsec_get_acquire(((struct sadb_x_policy *) headers[SADB_X_EXT_POLICY])->sadb_x_policy_seq);
                   1276:                if (ipa == NULL) {
                   1277:                        rval = ESRCH;
                   1278:                        goto ret;
                   1279:                }
                   1280:
                   1281:                rval = pfkeyv2_policy(ipa, headers, &freeme);
                   1282:                if (rval)
                   1283:                        mode = PFKEYV2_SENDMESSAGE_UNICAST;
                   1284:
                   1285:                break;
                   1286:
                   1287:        case SADB_GET:
                   1288:                ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
                   1289:                sunionp =
                   1290:                    (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
                   1291:                        sizeof(struct sadb_address));
                   1292:
                   1293:                s = spltdb();
                   1294:
                   1295:                sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
                   1296:                    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
                   1297:                if (sa2 == NULL) {
                   1298:                        rval = ESRCH;
                   1299:                        goto splxret;
                   1300:                }
                   1301:
                   1302:                rval = pfkeyv2_get(sa2, headers, &freeme, NULL);
                   1303:                if (rval)
                   1304:                        mode = PFKEYV2_SENDMESSAGE_UNICAST;
                   1305:
                   1306:                splx(s);
                   1307:
                   1308:                break;
                   1309:
                   1310:        case SADB_REGISTER:
                   1311:                if (!(pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) {
                   1312:                        pfkeyv2_socket->flags |= PFKEYV2_SOCKETFLAGS_REGISTERED;
                   1313:                        nregistered++;
                   1314:                }
                   1315:
                   1316:                i = sizeof(struct sadb_supported) + sizeof(ealgs);
                   1317:
                   1318:                if (!(freeme = malloc(i, M_PFKEY, M_DONTWAIT))) {
                   1319:                        rval = ENOMEM;
                   1320:                        goto ret;
                   1321:                }
                   1322:
                   1323:                bzero(freeme, i);
                   1324:
                   1325:                ssup = (struct sadb_supported *) freeme;
                   1326:                ssup->sadb_supported_len = i / sizeof(uint64_t);
                   1327:
                   1328:                {
                   1329:                        void *p = freeme + sizeof(struct sadb_supported);
                   1330:
                   1331:                        bcopy(&ealgs[0], p, sizeof(ealgs));
                   1332:                }
                   1333:
                   1334:                headers[SADB_EXT_SUPPORTED_ENCRYPT] = freeme;
                   1335:
                   1336:                i = sizeof(struct sadb_supported) + sizeof(aalgs);
                   1337:
                   1338:                if (!(freeme = malloc(i, M_PFKEY, M_DONTWAIT))) {
                   1339:                        rval = ENOMEM;
                   1340:                        goto ret;
                   1341:                }
                   1342:
                   1343:                /* Keep track what this socket has registered for */
                   1344:                pfkeyv2_socket->registration |= (1 << ((struct sadb_msg *)message)->sadb_msg_satype);
                   1345:
                   1346:                bzero(freeme, i);
                   1347:
                   1348:                ssup = (struct sadb_supported *) freeme;
                   1349:                ssup->sadb_supported_len = i / sizeof(uint64_t);
                   1350:
                   1351:                {
                   1352:                        void *p = freeme + sizeof(struct sadb_supported);
                   1353:
                   1354:                        bcopy(&aalgs[0], p, sizeof(aalgs));
                   1355:                }
                   1356:
                   1357:                headers[SADB_EXT_SUPPORTED_AUTH] = freeme;
                   1358:
                   1359:                i = sizeof(struct sadb_supported) + sizeof(calgs);
                   1360:
                   1361:                if (!(freeme = malloc(i, M_PFKEY, M_DONTWAIT))) {
                   1362:                        rval = ENOMEM;
                   1363:                        goto ret;
                   1364:                }
                   1365:
                   1366:                bzero(freeme, i);
                   1367:
                   1368:                ssup = (struct sadb_supported *) freeme;
                   1369:                ssup->sadb_supported_len = i / sizeof(uint64_t);
                   1370:
                   1371:                {
                   1372:                        void *p = freeme + sizeof(struct sadb_supported);
                   1373:
                   1374:                        bcopy(&calgs[0], p, sizeof(calgs));
                   1375:                }
                   1376:
                   1377:                headers[SADB_X_EXT_SUPPORTED_COMP] = freeme;
                   1378:
                   1379:                break;
                   1380:
                   1381:        case SADB_ACQUIRE:
                   1382:        case SADB_EXPIRE:
                   1383:                /* Nothing to handle */
                   1384:                rval = 0;
                   1385:                break;
                   1386:
                   1387:        case SADB_FLUSH:
                   1388:                rval = 0;
                   1389:
                   1390:                switch (smsg->sadb_msg_satype) {
                   1391:                case SADB_SATYPE_UNSPEC:
                   1392:                        s = spltdb();
                   1393:
                   1394:                        /*
                   1395:                         * Go through the list of policies, delete those that
                   1396:                         * are not socket-attached.
                   1397:                         */
                   1398:                        for (ipo = TAILQ_FIRST(&ipsec_policy_head);
                   1399:                            ipo != NULL; ipo = tmpipo) {
                   1400:                                tmpipo = TAILQ_NEXT(ipo, ipo_list);
                   1401:                                if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
                   1402:                                        ipsec_delete_policy(ipo);
                   1403:                        }
                   1404:                        splx(s);
                   1405:                        /* FALLTHROUGH */
                   1406:                case SADB_SATYPE_AH:
                   1407:                case SADB_SATYPE_ESP:
                   1408:                case SADB_X_SATYPE_IPIP:
                   1409:                case SADB_X_SATYPE_IPCOMP:
                   1410: #ifdef TCP_SIGNATURE
                   1411:                case SADB_X_SATYPE_TCPSIGNATURE:
                   1412: #endif /* TCP_SIGNATURE */
                   1413:                        s = spltdb();
                   1414:
                   1415:                        tdb_walk(pfkeyv2_flush_walker,
                   1416:                            (u_int8_t *) &(smsg->sadb_msg_satype));
                   1417:
                   1418:                        splx(s);
                   1419:                        break;
                   1420:
                   1421:                default:
                   1422:                        rval = EINVAL; /* Unknown/unsupported type */
                   1423:                }
                   1424:
                   1425:                break;
                   1426:
                   1427:        case SADB_DUMP:
                   1428:        {
                   1429:                struct dump_state dump_state;
                   1430:                dump_state.sadb_msg = (struct sadb_msg *) headers[0];
                   1431:                dump_state.socket = socket;
                   1432:
                   1433:                s = spltdb();
                   1434:                rval = tdb_walk(pfkeyv2_dump_walker, &dump_state);
                   1435:                splx(s);
                   1436:
                   1437:                if (!rval)
                   1438:                        goto realret;
                   1439:
                   1440:                if ((rval == ENOMEM) || (rval == ENOBUFS))
                   1441:                        rval = 0;
                   1442:        }
                   1443:        break;
                   1444:
                   1445:        case SADB_X_GRPSPIS:
                   1446:        {
                   1447:                struct tdb *tdb1, *tdb2, *tdb3;
                   1448:                struct sadb_protocol *sa_proto;
                   1449:
                   1450:                ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
                   1451:                sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
                   1452:                    sizeof(struct sadb_address));
                   1453:
                   1454:                s = spltdb();
                   1455:
                   1456:                tdb1 = gettdb(ssa->sadb_sa_spi, sunionp,
                   1457:                    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
                   1458:                if (tdb1 == NULL) {
                   1459:                        rval = ESRCH;
                   1460:                        goto splxret;
                   1461:                }
                   1462:
                   1463:                ssa = (struct sadb_sa *) headers[SADB_X_EXT_SA2];
                   1464:                sunionp = (union sockaddr_union *) (headers[SADB_X_EXT_DST2] +
                   1465:                    sizeof(struct sadb_address));
                   1466:                sa_proto = ((struct sadb_protocol *) headers[SADB_X_EXT_PROTOCOL]);
                   1467:
                   1468:                tdb2 = gettdb(ssa->sadb_sa_spi, sunionp,
                   1469:                    SADB_X_GETSPROTO(sa_proto->sadb_protocol_proto));
                   1470:                if (tdb2 == NULL) {
                   1471:                        rval = ESRCH;
                   1472:                        goto splxret;
                   1473:                }
                   1474:
                   1475:                /* Detect cycles */
                   1476:                for (tdb3 = tdb2; tdb3; tdb3 = tdb3->tdb_onext)
                   1477:                        if (tdb3 == tdb1) {
                   1478:                                rval = ESRCH;
                   1479:                                goto splxret;
                   1480:                        }
                   1481:
                   1482:                /* Maintenance */
                   1483:                if ((tdb1->tdb_onext) &&
                   1484:                    (tdb1->tdb_onext->tdb_inext == tdb1))
                   1485:                        tdb1->tdb_onext->tdb_inext = NULL;
                   1486:
                   1487:                if ((tdb2->tdb_inext) &&
                   1488:                    (tdb2->tdb_inext->tdb_onext == tdb2))
                   1489:                        tdb2->tdb_inext->tdb_onext = NULL;
                   1490:
                   1491:                /* Link them */
                   1492:                tdb1->tdb_onext = tdb2;
                   1493:                tdb2->tdb_inext = tdb1;
                   1494:
                   1495:                splx(s);
                   1496:        }
                   1497:        break;
                   1498:
                   1499:        case SADB_X_DELFLOW:
                   1500:                delflag = 1;
                   1501:                /*FALLTHROUGH*/
                   1502:        case SADB_X_ADDFLOW:
                   1503:        {
                   1504:                struct sadb_protocol *sab;
                   1505:                union sockaddr_union *ssrc;
                   1506:                struct route_enc re;
                   1507:                int exists = 0;
                   1508:
                   1509:                sab = (struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE];
                   1510:
                   1511:                if ((sab->sadb_protocol_direction != IPSP_DIRECTION_IN) &&
                   1512:                    (sab->sadb_protocol_direction != IPSP_DIRECTION_OUT)) {
                   1513:                        rval = EINVAL;
                   1514:                        goto ret;
                   1515:                }
                   1516:
                   1517:                /* If the security protocol wasn't specified, pretend it was ESP */
                   1518:                if (smsg->sadb_msg_satype == 0)
                   1519:                        smsg->sadb_msg_satype = SADB_SATYPE_ESP;
                   1520:
                   1521:                if (headers[SADB_EXT_ADDRESS_DST])
                   1522:                        sunionp = (union sockaddr_union *)
                   1523:                            (headers[SADB_EXT_ADDRESS_DST] +
                   1524:                                sizeof(struct sadb_address));
                   1525:                else
                   1526:                        sunionp = NULL;
                   1527:
                   1528:                if (headers[SADB_EXT_ADDRESS_SRC])
                   1529:                        ssrc = (union sockaddr_union *)
                   1530:                            (headers[SADB_EXT_ADDRESS_SRC] +
                   1531:                                sizeof(struct sadb_address));
                   1532:                else
                   1533:                        ssrc = NULL;
                   1534:
                   1535:                import_flow(&encapdst, &encapnetmask,
                   1536:                    headers[SADB_X_EXT_SRC_FLOW], headers[SADB_X_EXT_SRC_MASK],
                   1537:                    headers[SADB_X_EXT_DST_FLOW], headers[SADB_X_EXT_DST_MASK],
                   1538:                    headers[SADB_X_EXT_PROTOCOL], headers[SADB_X_EXT_FLOW_TYPE]);
                   1539:
                   1540:                /* Determine whether the exact same SPD entry already exists. */
                   1541:                bzero(&encapgw, sizeof(struct sockaddr_encap));
                   1542:                bzero(&re, sizeof(struct route_enc));
                   1543:                bcopy(&encapdst, &re.re_dst, sizeof(struct sockaddr_encap));
                   1544:
                   1545:                s = spltdb();
                   1546:
                   1547:                rtalloc((struct route *) &re);
                   1548:                if (re.re_rt != NULL) {
                   1549:                        ipo = ((struct sockaddr_encap *) re.re_rt->rt_gateway)->sen_ipsp;
                   1550:                        RTFREE(re.re_rt);
                   1551:
                   1552:                        /* Verify that the entry is identical */
                   1553:                        if (bcmp(&ipo->ipo_addr, &encapdst,
                   1554:                                sizeof(struct sockaddr_encap)) ||
                   1555:                            bcmp(&ipo->ipo_mask, &encapnetmask,
                   1556:                                sizeof(struct sockaddr_encap)))
                   1557:                                ipo = NULL; /* Fall through */
                   1558:                        else
                   1559:                                exists = 1;
                   1560:                } else
                   1561:                        ipo = NULL;
                   1562:
                   1563:                /*
                   1564:                 * If the existing policy is static, only delete or update
                   1565:                 * it if the new one is also static.
                   1566:                 */
                   1567:                if (exists && (ipo->ipo_flags & IPSP_POLICY_STATIC)) {
                   1568:                        if (!(sab->sadb_protocol_flags &
                   1569:                                SADB_X_POLICYFLAGS_POLICY)) {
                   1570:                                splx(s);
                   1571:                                goto ret;
                   1572:                        }
                   1573:                }
                   1574:
                   1575:                /* Delete ? */
                   1576:                if (delflag) {
                   1577:                        if (exists) {
                   1578:                                rval = ipsec_delete_policy(ipo);
                   1579:                                splx(s);
                   1580:                                goto ret;
                   1581:                        }
                   1582:
                   1583:                        /* If we were asked to delete something non-existant, error. */
                   1584:                        splx(s);
                   1585:                        rval = ESRCH;
                   1586:                        break;
                   1587:                }
                   1588:
                   1589:                if (!exists) {
                   1590:                        if (ipsec_policy_pool_initialized == 0) {
                   1591:                                ipsec_policy_pool_initialized = 1;
                   1592:                                pool_init(&ipsec_policy_pool,
                   1593:                                    sizeof(struct ipsec_policy), 0, 0, 0,
                   1594:                                    "ipsec policy", NULL);
                   1595:                        }
                   1596:
                   1597:                        /* Allocate policy entry */
                   1598:                        ipo = pool_get(&ipsec_policy_pool, 0);
                   1599:                        if (ipo == NULL) {
                   1600:                                splx(s);
                   1601:                                rval = ENOMEM;
                   1602:                                goto ret;
                   1603:                        }
                   1604:
                   1605:                        bzero(ipo, sizeof(struct ipsec_policy));
                   1606:                        ipo->ipo_ref_count = 1;
                   1607:                        TAILQ_INIT(&ipo->ipo_acquires);
                   1608:
                   1609:                        /* Finish initialization of SPD entry */
                   1610:                        encapgw.sen_len = SENT_LEN;
                   1611:                        encapgw.sen_family = PF_KEY;
                   1612:                        encapgw.sen_type = SENT_IPSP;
                   1613:                        encapgw.sen_ipsp = ipo;
                   1614:
                   1615:                        /* Initialize policy entry */
                   1616:                        bcopy(&encapdst, &ipo->ipo_addr,
                   1617:                            sizeof(struct sockaddr_encap));
                   1618:                        bcopy(&encapnetmask, &ipo->ipo_mask,
                   1619:                            sizeof(struct sockaddr_encap));
                   1620:                }
                   1621:
                   1622:                switch (((struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE])->sadb_protocol_proto) {
                   1623:                case SADB_X_FLOW_TYPE_USE:
                   1624:                        ipo->ipo_type = IPSP_IPSEC_USE;
                   1625:                        break;
                   1626:
                   1627:                case SADB_X_FLOW_TYPE_ACQUIRE:
                   1628:                        ipo->ipo_type = IPSP_IPSEC_ACQUIRE;
                   1629:                        break;
                   1630:
                   1631:                case SADB_X_FLOW_TYPE_REQUIRE:
                   1632:                        ipo->ipo_type = IPSP_IPSEC_REQUIRE;
                   1633:                        break;
                   1634:
                   1635:                case SADB_X_FLOW_TYPE_DENY:
                   1636:                        ipo->ipo_type = IPSP_DENY;
                   1637:                        break;
                   1638:
                   1639:                case SADB_X_FLOW_TYPE_BYPASS:
                   1640:                        ipo->ipo_type = IPSP_PERMIT;
                   1641:                        break;
                   1642:
                   1643:                case SADB_X_FLOW_TYPE_DONTACQ:
                   1644:                        ipo->ipo_type = IPSP_IPSEC_DONTACQ;
                   1645:                        break;
                   1646:
                   1647:                default:
                   1648:                        if (!exists)
                   1649:                                pool_put(&ipsec_policy_pool, ipo);
                   1650:                        else
                   1651:                                ipsec_delete_policy(ipo);
                   1652:
                   1653:                        splx(s);
                   1654:                        rval = EINVAL;
                   1655:                        goto ret;
                   1656:                }
                   1657:
                   1658:                if (sab->sadb_protocol_flags & SADB_X_POLICYFLAGS_POLICY)
                   1659:                        ipo->ipo_flags |= IPSP_POLICY_STATIC;
                   1660:
                   1661:                if (sunionp)
                   1662:                        bcopy(sunionp, &ipo->ipo_dst,
                   1663:                            sizeof(union sockaddr_union));
                   1664:                else
                   1665:                        bzero(&ipo->ipo_dst, sizeof(union sockaddr_union));
                   1666:
                   1667:                if (ssrc)
                   1668:                        bcopy(ssrc, &ipo->ipo_src,
                   1669:                            sizeof(union sockaddr_union));
                   1670:                else
                   1671:                        bzero(&ipo->ipo_src, sizeof(union sockaddr_union));
                   1672:
                   1673:                ipo->ipo_sproto = SADB_X_GETSPROTO(smsg->sadb_msg_satype);
                   1674:
                   1675:                if (ipo->ipo_srcid) {
                   1676:                        ipsp_reffree(ipo->ipo_srcid);
                   1677:                        ipo->ipo_srcid = NULL;
                   1678:                }
                   1679:
                   1680:                if (ipo->ipo_dstid) {
                   1681:                        ipsp_reffree(ipo->ipo_dstid);
                   1682:                        ipo->ipo_dstid = NULL;
                   1683:                }
                   1684:
                   1685:                if ((sid = headers[SADB_EXT_IDENTITY_SRC]) != NULL) {
                   1686:                        int clen =  (sid->sadb_ident_len * sizeof(u_int64_t)) -
                   1687:                            sizeof(struct sadb_ident);
                   1688:
                   1689:                        MALLOC(ipo->ipo_srcid, struct ipsec_ref *, clen +
                   1690:                            sizeof(struct ipsec_ref), M_CREDENTIALS, M_DONTWAIT);
                   1691:                        if (ipo->ipo_srcid == NULL) {
                   1692:                                if (exists)
                   1693:                                        ipsec_delete_policy(ipo);
                   1694:                                else
                   1695:                                        pool_put(&ipsec_policy_pool, ipo);
                   1696:                                splx(s);
                   1697:                                rval = ENOBUFS;
                   1698:                                goto ret;
                   1699:                        }
                   1700:                        ipo->ipo_srcid->ref_type = sid->sadb_ident_type;
                   1701:                        ipo->ipo_srcid->ref_len = clen;
                   1702:                        ipo->ipo_srcid->ref_count = 1;
                   1703:                        ipo->ipo_srcid->ref_malloctype = M_CREDENTIALS;
                   1704:                        bcopy(sid + 1, ipo->ipo_srcid + 1, ipo->ipo_srcid->ref_len);
                   1705:                }
                   1706:
                   1707:                if ((sid = headers[SADB_EXT_IDENTITY_DST]) != NULL) {
                   1708:                        int clen =  (sid->sadb_ident_len * sizeof(u_int64_t)) -
                   1709:                            sizeof(struct sadb_ident);
                   1710:
                   1711:                        MALLOC(ipo->ipo_dstid, struct ipsec_ref *,
                   1712:                            clen + sizeof(struct ipsec_ref),
                   1713:                            M_CREDENTIALS, M_DONTWAIT);
                   1714:                        if (ipo->ipo_dstid == NULL) {
                   1715:                                if (exists)
                   1716:                                        ipsec_delete_policy(ipo);
                   1717:                                else {
                   1718:                                        if (ipo->ipo_dstid)
                   1719:                                                ipsp_reffree(ipo->ipo_dstid);
                   1720:                                        pool_put(&ipsec_policy_pool, ipo);
                   1721:                                }
                   1722:
                   1723:                                splx(s);
                   1724:                                rval = ENOBUFS;
                   1725:                                goto ret;
                   1726:                        }
                   1727:                        ipo->ipo_dstid->ref_type = sid->sadb_ident_type;
                   1728:                        ipo->ipo_dstid->ref_len = clen;
                   1729:                        ipo->ipo_dstid->ref_count = 1;
                   1730:                        ipo->ipo_dstid->ref_malloctype = M_CREDENTIALS;
                   1731:                        bcopy(sid + 1, ipo->ipo_dstid + 1,
                   1732:                            ipo->ipo_dstid->ref_len);
                   1733:                }
                   1734:
                   1735:                /* Flow type */
                   1736:                if (!exists) {
                   1737:                        /* Add SPD entry */
                   1738:                        if ((rval = rtrequest(RTM_ADD,
                   1739:                                 (struct sockaddr *) &encapdst,
                   1740:                                 (struct sockaddr *) &encapgw,
                   1741:                                 (struct sockaddr *) &encapnetmask,
                   1742:                                 RTF_UP | RTF_GATEWAY | RTF_STATIC,
                   1743:                                 (struct rtentry **) 0, 0)) != 0) {
                   1744:                                /* Remove from linked list of policies on TDB */
                   1745:                                if (ipo->ipo_tdb)
                   1746:                                        TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head,
                   1747:                                            ipo, ipo_tdb_next);
                   1748:
                   1749:                                if (ipo->ipo_srcid)
                   1750:                                        ipsp_reffree(ipo->ipo_srcid);
                   1751:                                if (ipo->ipo_dstid)
                   1752:                                        ipsp_reffree(ipo->ipo_dstid);
                   1753:                                pool_put(&ipsec_policy_pool, ipo);
                   1754:
                   1755:                                splx(s);
                   1756:                                goto ret;
                   1757:                        }
                   1758:
                   1759:                        TAILQ_INSERT_HEAD(&ipsec_policy_head, ipo, ipo_list);
                   1760:                        ipsec_in_use++;
                   1761:                } else {
                   1762:                        ipo->ipo_last_searched = ipo->ipo_flags = 0;
                   1763:                }
                   1764:
                   1765:                splx(s);
                   1766:        }
                   1767:        break;
                   1768:
                   1769:        case SADB_X_PROMISC:
                   1770:                if (len >= 2 * sizeof(struct sadb_msg)) {
                   1771:                        struct mbuf *packet;
                   1772:
                   1773:                        if ((rval = pfdatatopacket(message, len, &packet)) != 0)
                   1774:                                goto ret;
                   1775:
                   1776:                        for (so = pfkeyv2_sockets; so; so = so->next)
                   1777:                                if ((so != pfkeyv2_socket) &&
                   1778:                                    (!smsg->sadb_msg_seq ||
                   1779:                                    (smsg->sadb_msg_seq == pfkeyv2_socket->pid)))
                   1780:                                        pfkey_sendup(so->socket, packet, 1);
                   1781:
                   1782:                        m_freem(packet);
                   1783:                } else {
                   1784:                        if (len != sizeof(struct sadb_msg)) {
                   1785:                                rval = EINVAL;
                   1786:                                goto ret;
                   1787:                        }
                   1788:
                   1789:                        i = (pfkeyv2_socket->flags &
                   1790:                            PFKEYV2_SOCKETFLAGS_PROMISC) ? 1 : 0;
                   1791:                        j = smsg->sadb_msg_satype ? 1 : 0;
                   1792:
                   1793:                        if (i ^ j) {
                   1794:                                if (j) {
                   1795:                                        pfkeyv2_socket->flags |=
                   1796:                                            PFKEYV2_SOCKETFLAGS_PROMISC;
                   1797:                                        npromisc++;
                   1798:                                } else {
                   1799:                                        pfkeyv2_socket->flags &=
                   1800:                                            ~PFKEYV2_SOCKETFLAGS_PROMISC;
                   1801:                                        npromisc--;
                   1802:                                }
                   1803:                        }
                   1804:                }
                   1805:
                   1806:
                   1807:                break;
                   1808:
                   1809:        default:
                   1810:                rval = EINVAL;
                   1811:                goto ret;
                   1812:        }
                   1813:
                   1814: ret:
                   1815:        if (rval) {
                   1816:                if ((rval == EINVAL) || (rval == ENOMEM) || (rval == ENOBUFS))
                   1817:                        goto realret;
                   1818:
                   1819:                for (i = 1; i <= SADB_EXT_MAX; i++)
                   1820:                        headers[i] = NULL;
                   1821:
                   1822:                smsg->sadb_msg_errno = abs(rval);
                   1823:        } else {
                   1824:                uint64_t seen = 0LL;
                   1825:
                   1826:                for (i = 1; i <= SADB_EXT_MAX; i++)
                   1827:                        if (headers[i])
                   1828:                                seen |= (1LL << i);
                   1829:
                   1830:                if ((seen & sadb_exts_allowed_out[smsg->sadb_msg_type])
                   1831:                    != seen)
                   1832:                        goto realret;
                   1833:
                   1834:                if ((seen & sadb_exts_required_out[smsg->sadb_msg_type]) !=
                   1835:                    sadb_exts_required_out[smsg->sadb_msg_type])
                   1836:                        goto realret;
                   1837:        }
                   1838:
                   1839:        rval = pfkeyv2_sendmessage(headers, mode, socket, 0, 0);
                   1840:
                   1841: realret:
                   1842:        if (freeme)
                   1843:                free(freeme, M_PFKEY);
                   1844:
                   1845:        free(message, M_PFKEY);
                   1846:
                   1847:        return (rval);
                   1848:
                   1849: splxret:
                   1850:        splx(s);
                   1851:        goto ret;
                   1852: }
                   1853:
                   1854: /*
                   1855:  * Send an ACQUIRE message to key management, to get a new SA.
                   1856:  */
                   1857: int
                   1858: pfkeyv2_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw,
                   1859:     union sockaddr_union *laddr, u_int32_t *seq, struct sockaddr_encap *ddst)
                   1860: {
                   1861:        void *p, *headers[SADB_EXT_MAX + 1], *buffer = NULL;
                   1862:        struct sadb_ident *srcid, *dstid;
                   1863:        struct sadb_x_cred *lcred, *lauth;
                   1864:        struct sadb_comb *sadb_comb;
                   1865:        struct sadb_address *sadd;
                   1866:        struct sadb_prop *sa_prop;
                   1867:        struct sadb_msg *smsg;
                   1868:        int rval = 0;
                   1869:        int i, j;
                   1870:
                   1871:        *seq = pfkeyv2_seq++;
                   1872:
                   1873:        if (!nregistered) {
                   1874:                rval = ESRCH;
                   1875:                goto ret;
                   1876:        }
                   1877:
                   1878:        /* How large a buffer do we need... XXX we only do one proposal for now */
                   1879:        i = sizeof(struct sadb_msg) +
                   1880:            (laddr == NULL ? 0 : sizeof(struct sadb_address) +
                   1881:                PADUP(SA_LEN(&ipo->ipo_src.sa))) +
                   1882:            sizeof(struct sadb_address) + PADUP(SA_LEN(&gw->sa)) +
                   1883:            sizeof(struct sadb_prop) + 1 * sizeof(struct sadb_comb);
                   1884:
                   1885:        if (ipo->ipo_srcid)
                   1886:                i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
                   1887:
                   1888:        if (ipo->ipo_dstid)
                   1889:                i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
                   1890:
                   1891:        if (ipo->ipo_local_cred)
                   1892:                i += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_cred->ref_len);
                   1893:
                   1894:        if (ipo->ipo_local_auth)
                   1895:                i += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_auth->ref_len);
                   1896:
                   1897:        /* Allocate */
                   1898:        if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
                   1899:                rval = ENOMEM;
                   1900:                goto ret;
                   1901:        }
                   1902:
                   1903:        bzero(headers, sizeof(headers));
                   1904:
                   1905:        buffer = p;
                   1906:        bzero(p, i);
                   1907:
                   1908:        headers[0] = p;
                   1909:        p += sizeof(struct sadb_msg);
                   1910:
                   1911:        smsg = (struct sadb_msg *) headers[0];
                   1912:        smsg->sadb_msg_version = PF_KEY_V2;
                   1913:        smsg->sadb_msg_type = SADB_ACQUIRE;
                   1914:        smsg->sadb_msg_len = i / sizeof(uint64_t);
                   1915:        smsg->sadb_msg_seq = *seq;
                   1916:
                   1917:        if (ipo->ipo_sproto == IPPROTO_ESP)
                   1918:                smsg->sadb_msg_satype = SADB_SATYPE_ESP;
                   1919:        else if (ipo->ipo_sproto == IPPROTO_AH)
                   1920:                smsg->sadb_msg_satype = SADB_SATYPE_AH;
                   1921:        else if (ipo->ipo_sproto == IPPROTO_IPCOMP)
                   1922:                smsg->sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
                   1923:
                   1924:        if (laddr) {
                   1925:                headers[SADB_EXT_ADDRESS_SRC] = p;
                   1926:                p += sizeof(struct sadb_address) + PADUP(SA_LEN(&laddr->sa));
                   1927:                sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_SRC];
                   1928:                sadd->sadb_address_len = (sizeof(struct sadb_address) +
                   1929:                    SA_LEN(&laddr->sa) + sizeof(uint64_t) - 1) /
                   1930:                    sizeof(uint64_t);
                   1931:                bcopy(laddr, headers[SADB_EXT_ADDRESS_SRC] +
                   1932:                    sizeof(struct sadb_address), SA_LEN(&laddr->sa));
                   1933:        }
                   1934:
                   1935:        headers[SADB_EXT_ADDRESS_DST] = p;
                   1936:        p += sizeof(struct sadb_address) + PADUP(SA_LEN(&gw->sa));
                   1937:        sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_DST];
                   1938:        sadd->sadb_address_len = (sizeof(struct sadb_address) +
                   1939:            SA_LEN(&gw->sa) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
                   1940:        bcopy(gw, headers[SADB_EXT_ADDRESS_DST] + sizeof(struct sadb_address),
                   1941:            SA_LEN(&gw->sa));
                   1942:
                   1943:        if (ipo->ipo_srcid) {
                   1944:                headers[SADB_EXT_IDENTITY_SRC] = p;
                   1945:                p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
                   1946:                srcid = (struct sadb_ident *) headers[SADB_EXT_IDENTITY_SRC];
                   1947:                srcid->sadb_ident_len = (sizeof(struct sadb_ident) +
                   1948:                    PADUP(ipo->ipo_srcid->ref_len)) / sizeof(u_int64_t);
                   1949:                srcid->sadb_ident_type = ipo->ipo_srcid->ref_type;
                   1950:                bcopy(ipo->ipo_srcid + 1, headers[SADB_EXT_IDENTITY_SRC] +
                   1951:                    sizeof(struct sadb_ident), ipo->ipo_srcid->ref_len);
                   1952:        }
                   1953:
                   1954:        if (ipo->ipo_dstid) {
                   1955:                headers[SADB_EXT_IDENTITY_DST] = p;
                   1956:                p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
                   1957:                dstid = (struct sadb_ident *) headers[SADB_EXT_IDENTITY_DST];
                   1958:                dstid->sadb_ident_len = (sizeof(struct sadb_ident) +
                   1959:                    PADUP(ipo->ipo_dstid->ref_len)) / sizeof(u_int64_t);
                   1960:                dstid->sadb_ident_type = ipo->ipo_dstid->ref_type;
                   1961:                bcopy(ipo->ipo_dstid + 1, headers[SADB_EXT_IDENTITY_DST] +
                   1962:                    sizeof(struct sadb_ident), ipo->ipo_dstid->ref_len);
                   1963:        }
                   1964:
                   1965:        if (ipo->ipo_local_cred) {
                   1966:                headers[SADB_X_EXT_LOCAL_CREDENTIALS] = p;
                   1967:                p += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_cred->ref_len);
                   1968:                lcred = (struct sadb_x_cred *) headers[SADB_X_EXT_LOCAL_CREDENTIALS];
                   1969:                lcred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
                   1970:                    PADUP(ipo->ipo_local_cred->ref_len)) / sizeof(u_int64_t);
                   1971:                switch (ipo->ipo_local_cred->ref_type) {
                   1972:                case IPSP_CRED_KEYNOTE:
                   1973:                        lcred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
                   1974:                        break;
                   1975:                case IPSP_CRED_X509:
                   1976:                        lcred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
                   1977:                        break;
                   1978:                }
                   1979:                bcopy(ipo->ipo_local_cred + 1, headers[SADB_X_EXT_LOCAL_CREDENTIALS] +
                   1980:                    sizeof(struct sadb_x_cred), ipo->ipo_local_cred->ref_len);
                   1981:        }
                   1982:
                   1983:        if (ipo->ipo_local_auth) {
                   1984:                headers[SADB_X_EXT_LOCAL_AUTH] = p;
                   1985:                p += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_auth->ref_len);
                   1986:                lauth = (struct sadb_x_cred *) headers[SADB_X_EXT_LOCAL_AUTH];
                   1987:                lauth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
                   1988:                    PADUP(ipo->ipo_local_auth->ref_len)) / sizeof(u_int64_t);
                   1989:                switch (ipo->ipo_local_auth->ref_type) {
                   1990:                case IPSP_AUTH_PASSPHRASE:
                   1991:                        lauth->sadb_x_cred_type = SADB_X_AUTHTYPE_PASSPHRASE;
                   1992:                        break;
                   1993:                case IPSP_AUTH_RSA:
                   1994:                        lauth->sadb_x_cred_type = SADB_X_AUTHTYPE_RSA;
                   1995:                        break;
                   1996:                }
                   1997:
                   1998:                bcopy(ipo->ipo_local_auth + 1, headers[SADB_X_EXT_LOCAL_AUTH] +
                   1999:                    sizeof(struct sadb_x_cred), ipo->ipo_local_auth->ref_len);
                   2000:        }
                   2001:
                   2002:        headers[SADB_EXT_PROPOSAL] = p;
                   2003:        p += sizeof(struct sadb_prop);
                   2004:        sa_prop = (struct sadb_prop *) headers[SADB_EXT_PROPOSAL];
                   2005:        sa_prop->sadb_prop_num = 1; /* XXX One proposal only */
                   2006:        sa_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
                   2007:            (sizeof(struct sadb_comb) * sa_prop->sadb_prop_num)) /
                   2008:            sizeof(uint64_t);
                   2009:
                   2010:        sadb_comb = p;
                   2011:
                   2012:        /* XXX Should actually ask the crypto layer what's supported */
                   2013:        for (j = 0; j < sa_prop->sadb_prop_num; j++) {
                   2014:                sadb_comb->sadb_comb_flags = 0;
                   2015:
                   2016:                if (ipsec_require_pfs)
                   2017:                        sadb_comb->sadb_comb_flags |= SADB_SAFLAGS_PFS;
                   2018:
                   2019:                /* Set the encryption algorithm */
                   2020:                if (ipo->ipo_sproto == IPPROTO_ESP) {
                   2021:                        if (!strncasecmp(ipsec_def_enc, "aes",
                   2022:                            sizeof("aes"))) {
                   2023:                                sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AES;
                   2024:                                sadb_comb->sadb_comb_encrypt_minbits = 128;
                   2025:                                sadb_comb->sadb_comb_encrypt_maxbits = 256;
                   2026:                        } else if (!strncasecmp(ipsec_def_enc, "aesctr",
                   2027:                            sizeof("aesctr"))) {
                   2028:                                sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AESCTR;
                   2029:                                sadb_comb->sadb_comb_encrypt_minbits = 128+32;
                   2030:                                sadb_comb->sadb_comb_encrypt_maxbits = 256+32;
                   2031:                        } else if (!strncasecmp(ipsec_def_enc, "3des",
                   2032:                            sizeof("3des"))) {
                   2033:                                sadb_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC;
                   2034:                                sadb_comb->sadb_comb_encrypt_minbits = 192;
                   2035:                                sadb_comb->sadb_comb_encrypt_maxbits = 192;
                   2036:                        } else if (!strncasecmp(ipsec_def_enc, "des",
                   2037:                            sizeof("des"))) {
                   2038:                                sadb_comb->sadb_comb_encrypt = SADB_EALG_DESCBC;
                   2039:                                sadb_comb->sadb_comb_encrypt_minbits = 64;
                   2040:                                sadb_comb->sadb_comb_encrypt_maxbits = 64;
                   2041:                        } else if (!strncasecmp(ipsec_def_enc, "blowfish",
                   2042:                            sizeof("blowfish"))) {
                   2043:                                sadb_comb->sadb_comb_encrypt = SADB_X_EALG_BLF;
                   2044:                                sadb_comb->sadb_comb_encrypt_minbits = 40;
                   2045:                                sadb_comb->sadb_comb_encrypt_maxbits = BLF_MAXKEYLEN * 8;
                   2046:                        } else if (!strncasecmp(ipsec_def_enc, "skipjack",
                   2047:                            sizeof("skipjack"))) {
                   2048:                                sadb_comb->sadb_comb_encrypt = SADB_X_EALG_SKIPJACK;
                   2049:                                sadb_comb->sadb_comb_encrypt_minbits = 80;
                   2050:                                sadb_comb->sadb_comb_encrypt_maxbits = 80;
                   2051:                        } else if (!strncasecmp(ipsec_def_enc, "cast128",
                   2052:                            sizeof("cast128"))) {
                   2053:                                sadb_comb->sadb_comb_encrypt = SADB_X_EALG_CAST;
                   2054:                                sadb_comb->sadb_comb_encrypt_minbits = 40;
                   2055:                                sadb_comb->sadb_comb_encrypt_maxbits = 128;
                   2056:                        }
                   2057:                } else if (ipo->ipo_sproto == IPPROTO_IPCOMP) {
                   2058:                        /* Set the compression algorithm */
                   2059:                        if (!strncasecmp(ipsec_def_comp, "deflate",
                   2060:                            sizeof("deflate"))) {
                   2061:                                sadb_comb->sadb_comb_encrypt = SADB_X_CALG_DEFLATE;
                   2062:                                sadb_comb->sadb_comb_encrypt_minbits = 0;
                   2063:                                sadb_comb->sadb_comb_encrypt_maxbits = 0;
                   2064:                        } else if (!strncasecmp(ipsec_def_comp, "lzs",
                   2065:                            sizeof("lzs"))) {
                   2066:                                sadb_comb->sadb_comb_encrypt = SADB_X_CALG_LZS;
                   2067:                                sadb_comb->sadb_comb_encrypt_minbits = 0;
                   2068:                                sadb_comb->sadb_comb_encrypt_maxbits = 0;
                   2069:                        }
                   2070:                }
                   2071:
                   2072:                /* Set the authentication algorithm */
                   2073:                if (!strncasecmp(ipsec_def_auth, "hmac-sha1",
                   2074:                    sizeof("hmac-sha1"))) {
                   2075:                        sadb_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC;
                   2076:                        sadb_comb->sadb_comb_auth_minbits = 160;
                   2077:                        sadb_comb->sadb_comb_auth_maxbits = 160;
                   2078:                } else if (!strncasecmp(ipsec_def_auth, "hmac-ripemd160",
                   2079:                    sizeof("hmac_ripemd160"))) {
                   2080:                        sadb_comb->sadb_comb_auth = SADB_X_AALG_RIPEMD160HMAC;
                   2081:                        sadb_comb->sadb_comb_auth_minbits = 160;
                   2082:                        sadb_comb->sadb_comb_auth_maxbits = 160;
                   2083:                } else if (!strncasecmp(ipsec_def_auth, "hmac-md5",
                   2084:                    sizeof("hmac-md5"))) {
                   2085:                        sadb_comb->sadb_comb_auth = SADB_AALG_MD5HMAC;
                   2086:                        sadb_comb->sadb_comb_auth_minbits = 128;
                   2087:                        sadb_comb->sadb_comb_auth_maxbits = 128;
                   2088:                } else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-256",
                   2089:                    sizeof("hmac-sha2-256"))) {
                   2090:                        sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256;
                   2091:                        sadb_comb->sadb_comb_auth_minbits = 256;
                   2092:                        sadb_comb->sadb_comb_auth_maxbits = 256;
                   2093:                } else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-384",
                   2094:                    sizeof("hmac-sha2-384"))) {
                   2095:                        sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_384;
                   2096:                        sadb_comb->sadb_comb_auth_minbits = 384;
                   2097:                        sadb_comb->sadb_comb_auth_maxbits = 384;
                   2098:                } else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-512",
                   2099:                    sizeof("hmac-sha2-512"))) {
                   2100:                        sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_512;
                   2101:                        sadb_comb->sadb_comb_auth_minbits = 512;
                   2102:                        sadb_comb->sadb_comb_auth_maxbits = 512;
                   2103:                }
                   2104:
                   2105:                sadb_comb->sadb_comb_soft_allocations = ipsec_soft_allocations;
                   2106:                sadb_comb->sadb_comb_hard_allocations = ipsec_exp_allocations;
                   2107:
                   2108:                sadb_comb->sadb_comb_soft_bytes = ipsec_soft_bytes;
                   2109:                sadb_comb->sadb_comb_hard_bytes = ipsec_exp_bytes;
                   2110:
                   2111:                sadb_comb->sadb_comb_soft_addtime = ipsec_soft_timeout;
                   2112:                sadb_comb->sadb_comb_hard_addtime = ipsec_exp_timeout;
                   2113:
                   2114:                sadb_comb->sadb_comb_soft_usetime = ipsec_soft_first_use;
                   2115:                sadb_comb->sadb_comb_hard_usetime = ipsec_exp_first_use;
                   2116:                sadb_comb++;
                   2117:        }
                   2118:
                   2119:        /* Send the ACQUIRE message to all compliant registered listeners. */
                   2120:        if ((rval = pfkeyv2_sendmessage(headers,
                   2121:            PFKEYV2_SENDMESSAGE_REGISTERED, NULL, smsg->sadb_msg_satype, 0))
                   2122:            != 0)
                   2123:                goto ret;
                   2124:
                   2125:        rval = 0;
                   2126: ret:
                   2127:        if (buffer != NULL) {
                   2128:                bzero(buffer, i);
                   2129:                free(buffer, M_PFKEY);
                   2130:        }
                   2131:
                   2132:        return (rval);
                   2133: }
                   2134:
                   2135: /*
                   2136:  * Notify key management that an expiration went off. The second argument
                   2137:  * specifies the type of expiration (soft or hard).
                   2138:  */
                   2139: int
                   2140: pfkeyv2_expire(struct tdb *sa, u_int16_t type)
                   2141: {
                   2142:        void *p, *headers[SADB_EXT_MAX+1], *buffer = NULL;
                   2143:        struct sadb_msg *smsg;
                   2144:        int rval = 0;
                   2145:        int i;
                   2146:
                   2147:        switch (sa->tdb_sproto) {
                   2148:        case IPPROTO_AH:
                   2149:        case IPPROTO_ESP:
                   2150:        case IPPROTO_IPIP:
                   2151:        case IPPROTO_IPCOMP:
                   2152: #ifdef TCP_SIGNATURE
                   2153:        case IPPROTO_TCP:
                   2154: #endif /* TCP_SIGNATURE */
                   2155:                break;
                   2156:
                   2157:        default:
                   2158:                rval = EOPNOTSUPP;
                   2159:                goto ret;
                   2160:        }
                   2161:
                   2162:        i = sizeof(struct sadb_msg) + sizeof(struct sadb_sa) +
                   2163:            2 * sizeof(struct sadb_lifetime) +
                   2164:            sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_src.sa)) +
                   2165:            sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_dst.sa));
                   2166:
                   2167:        if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
                   2168:                rval = ENOMEM;
                   2169:                goto ret;
                   2170:        }
                   2171:
                   2172:        bzero(headers, sizeof(headers));
                   2173:
                   2174:        buffer = p;
                   2175:        bzero(p, i);
                   2176:
                   2177:        headers[0] = p;
                   2178:        p += sizeof(struct sadb_msg);
                   2179:
                   2180:        smsg = (struct sadb_msg *) headers[0];
                   2181:        smsg->sadb_msg_version = PF_KEY_V2;
                   2182:        smsg->sadb_msg_type = SADB_EXPIRE;
                   2183:        smsg->sadb_msg_satype = sa->tdb_satype;
                   2184:        smsg->sadb_msg_len = i / sizeof(uint64_t);
                   2185:        smsg->sadb_msg_seq = pfkeyv2_seq++;
                   2186:
                   2187:        headers[SADB_EXT_SA] = p;
                   2188:        export_sa(&p, sa);
                   2189:
                   2190:        headers[SADB_EXT_LIFETIME_CURRENT] = p;
                   2191:        export_lifetime(&p, sa, 2);
                   2192:
                   2193:        headers[type] = p;
                   2194:        export_lifetime(&p, sa, type == SADB_EXT_LIFETIME_SOFT ?
                   2195:            PFKEYV2_LIFETIME_SOFT : PFKEYV2_LIFETIME_HARD);
                   2196:
                   2197:        headers[SADB_EXT_ADDRESS_SRC] = p;
                   2198:        export_address(&p, (struct sockaddr *) &sa->tdb_src);
                   2199:
                   2200:        headers[SADB_EXT_ADDRESS_DST] = p;
                   2201:        export_address(&p, (struct sockaddr *) &sa->tdb_dst);
                   2202:
                   2203:        if ((rval = pfkeyv2_sendmessage(headers, PFKEYV2_SENDMESSAGE_BROADCAST,
                   2204:            NULL, 0, 0)) != 0)
                   2205:                goto ret;
                   2206:
                   2207:        rval = 0;
                   2208:
                   2209:  ret:
                   2210:        if (buffer != NULL) {
                   2211:                bzero(buffer, i);
                   2212:                free(buffer, M_PFKEY);
                   2213:        }
                   2214:
                   2215:        return (rval);
                   2216: }
                   2217:
                   2218: struct pfkeyv2_sysctl_walk {
                   2219:        void            *w_where;
                   2220:        size_t           w_len;
                   2221:        int              w_op;
                   2222:        u_int8_t         w_satype;
                   2223: };
                   2224:
                   2225: int
                   2226: pfkeyv2_sysctl_walker(struct tdb *sa, void *arg, int last)
                   2227: {
                   2228:        struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
                   2229:        void *buffer = NULL;
                   2230:        int error = 0;
                   2231:        int buflen, i;
                   2232:
                   2233:        if (w->w_satype != SADB_SATYPE_UNSPEC &&
                   2234:            w->w_satype != sa->tdb_satype)
                   2235:                return (0);
                   2236:
                   2237:        if (w->w_where) {
                   2238:                void *headers[SADB_EXT_MAX+1];
                   2239:                struct sadb_msg msg;
                   2240:
                   2241:                bzero(headers, sizeof(headers));
                   2242:                if ((error = pfkeyv2_get(sa, headers, &buffer, &buflen)) != 0)
                   2243:                        goto done;
                   2244:                if (w->w_len < sizeof(msg) + buflen) {
                   2245:                        error = ENOMEM;
                   2246:                        goto done;
                   2247:                }
                   2248:                /* prepend header */
                   2249:                bzero(&msg, sizeof(msg));
                   2250:                msg.sadb_msg_version = PF_KEY_V2;
                   2251:                msg.sadb_msg_satype = sa->tdb_satype;
                   2252:                msg.sadb_msg_type = SADB_DUMP;
                   2253:                msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t);
                   2254:                if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0)
                   2255:                        goto done;
                   2256:                w->w_where += sizeof(msg);
                   2257:                w->w_len -= sizeof(msg);
                   2258:                /* set extension type */
                   2259:                for (i = 1; i <= SADB_EXT_MAX; i++)
                   2260:                        if (headers[i])
                   2261:                                ((struct sadb_ext *)
                   2262:                                    headers[i])->sadb_ext_type = i;
                   2263:                if ((error = copyout(buffer, w->w_where, buflen)) != 0)
                   2264:                        goto done;
                   2265:                w->w_where += buflen;
                   2266:                w->w_len -= buflen;
                   2267:        } else {
                   2268:                if ((error = pfkeyv2_get(sa, NULL, NULL, &buflen)) != 0)
                   2269:                        return (error);
                   2270:                w->w_len += buflen;
                   2271:                w->w_len += sizeof(struct sadb_msg);
                   2272:        }
                   2273:
                   2274: done:
                   2275:        if (buffer)
                   2276:                free(buffer, M_PFKEY);
                   2277:        return (error);
                   2278: }
                   2279:
                   2280: int
                   2281: pfkeyv2_dump_policy(struct ipsec_policy *ipo, void **headers, void **buffer,
                   2282:     int *lenp)
                   2283: {
                   2284:        struct sadb_ident *ident;
                   2285:        int i, rval, perm;
                   2286:        void *p;
                   2287:
                   2288:        /* Find how much space we need. */
                   2289:        i = 2 * sizeof(struct sadb_protocol);
                   2290:
                   2291:        /* We'll need four of them: src, src mask, dst, dst mask. */
                   2292:        switch (ipo->ipo_addr.sen_type) {
                   2293: #ifdef INET
                   2294:        case SENT_IP4:
                   2295:                i += 4 * PADUP(sizeof(struct sockaddr_in));
                   2296:                i += 4 * sizeof(struct sadb_address);
                   2297:                break;
                   2298: #endif /* INET */
                   2299: #ifdef INET6
                   2300:        case SENT_IP6:
                   2301:                i += 4 * PADUP(sizeof(struct sockaddr_in6));
                   2302:                i += 4 * sizeof(struct sadb_address);
                   2303:                break;
                   2304: #endif /* INET6 */
                   2305:        default:
                   2306:                return (EINVAL);
                   2307:        }
                   2308:
                   2309:        /* Local address, might be zeroed. */
                   2310:        switch (ipo->ipo_src.sa.sa_family) {
                   2311:        case 0:
                   2312:                break;
                   2313: #ifdef INET
                   2314:        case AF_INET:
                   2315:                i += PADUP(sizeof(struct sockaddr_in));
                   2316:                i += sizeof(struct sadb_address);
                   2317:                break;
                   2318: #endif /* INET */
                   2319: #ifdef INET6
                   2320:        case AF_INET6:
                   2321:                i += PADUP(sizeof(struct sockaddr_in6));
                   2322:                i += sizeof(struct sadb_address);
                   2323:                break;
                   2324: #endif /* INET6 */
                   2325:        default:
                   2326:                return (EINVAL);
                   2327:        }
                   2328:
                   2329:        /* Remote address, might be zeroed. XXX ??? */
                   2330:        switch (ipo->ipo_dst.sa.sa_family) {
                   2331:        case 0:
                   2332:                break;
                   2333: #ifdef INET
                   2334:        case AF_INET:
                   2335:                i += PADUP(sizeof(struct sockaddr_in));
                   2336:                i += sizeof(struct sadb_address);
                   2337:                break;
                   2338: #endif /* INET */
                   2339: #ifdef INET6
                   2340:        case AF_INET6:
                   2341:                i += PADUP(sizeof(struct sockaddr_in6));
                   2342:                i += sizeof(struct sadb_address);
                   2343:                break;
                   2344: #endif /* INET6 */
                   2345:        default:
                   2346:                return (EINVAL);
                   2347:        }
                   2348:
                   2349:        if (ipo->ipo_srcid)
                   2350:                i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
                   2351:        if (ipo->ipo_dstid)
                   2352:                i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
                   2353:
                   2354:        if (lenp)
                   2355:                *lenp = i;
                   2356:
                   2357:        if (buffer == NULL) {
                   2358:                rval = 0;
                   2359:                goto ret;
                   2360:        }
                   2361:
                   2362:        if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
                   2363:                rval = ENOMEM;
                   2364:                goto ret;
                   2365:        } else {
                   2366:                *buffer = p;
                   2367:                bzero(p, i);
                   2368:        }
                   2369:
                   2370:        /* Local address. */
                   2371:        if (ipo->ipo_src.sa.sa_family) {
                   2372:                headers[SADB_EXT_ADDRESS_SRC] = p;
                   2373:                export_address(&p, (struct sockaddr *)&ipo->ipo_src);
                   2374:        }
                   2375:
                   2376:        /* Remote address. */
                   2377:        if (ipo->ipo_dst.sa.sa_family) {
                   2378:                headers[SADB_EXT_ADDRESS_DST] = p;
                   2379:                export_address(&p, (struct sockaddr *)&ipo->ipo_dst);
                   2380:        }
                   2381:
                   2382:        /* Get actual flow. */
                   2383:        export_flow(&p, ipo->ipo_type, &ipo->ipo_addr, &ipo->ipo_mask,
                   2384:            headers);
                   2385:
                   2386:        /* Add ids only when we are root. */
                   2387:        perm = suser(curproc, 0);
                   2388:        if (perm == 0 && ipo->ipo_srcid) {
                   2389:                headers[SADB_EXT_IDENTITY_SRC] = p;
                   2390:                p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
                   2391:                ident = (struct sadb_ident *)headers[SADB_EXT_IDENTITY_SRC];
                   2392:                ident->sadb_ident_len = (sizeof(struct sadb_ident) +
                   2393:                    PADUP(ipo->ipo_srcid->ref_len)) / sizeof(uint64_t);
                   2394:                ident->sadb_ident_type = ipo->ipo_srcid->ref_type;
                   2395:                bcopy(ipo->ipo_srcid + 1, headers[SADB_EXT_IDENTITY_SRC] +
                   2396:                    sizeof(struct sadb_ident), ipo->ipo_srcid->ref_len);
                   2397:        }
                   2398:        if (perm == 0 && ipo->ipo_dstid) {
                   2399:                headers[SADB_EXT_IDENTITY_DST] = p;
                   2400:                p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
                   2401:                ident = (struct sadb_ident *)headers[SADB_EXT_IDENTITY_DST];
                   2402:                ident->sadb_ident_len = (sizeof(struct sadb_ident) +
                   2403:                    PADUP(ipo->ipo_dstid->ref_len)) / sizeof(uint64_t);
                   2404:                ident->sadb_ident_type = ipo->ipo_dstid->ref_type;
                   2405:                bcopy(ipo->ipo_dstid + 1, headers[SADB_EXT_IDENTITY_DST] +
                   2406:                    sizeof(struct sadb_ident), ipo->ipo_dstid->ref_len);
                   2407:        }
                   2408:
                   2409:        rval = 0;
                   2410: ret:
                   2411:        return (rval);
                   2412: }
                   2413:
                   2414: /*
                   2415:  * Caller is responsible for setting at least spltdb().
                   2416:  */
                   2417: int
                   2418: pfkeyv2_ipo_walk(int (*walker)(struct ipsec_policy *, void *), void *arg)
                   2419: {
                   2420:        int rval = 0;
                   2421:        struct ipsec_policy *ipo;
                   2422:
                   2423:        TAILQ_FOREACH(ipo, &ipsec_policy_head, ipo_list)
                   2424:                rval = walker(ipo, (void *)arg);
                   2425:        return (rval);
                   2426: }
                   2427:
                   2428: int
                   2429: pfkeyv2_sysctl_policydumper(struct ipsec_policy *ipo, void *arg)
                   2430: {
                   2431:        struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
                   2432:        void *buffer = 0;
                   2433:        int i, buflen, error = 0;
                   2434:
                   2435:        /* Do not dump policies attached to a socket. */
                   2436:        if (ipo->ipo_flags & IPSP_POLICY_SOCKET)
                   2437:                return (0);
                   2438:
                   2439:        if (w->w_where) {
                   2440:                void *headers[SADB_EXT_MAX + 1];
                   2441:                struct sadb_msg msg;
                   2442:
                   2443:                bzero(headers, sizeof(headers));
                   2444:                if ((error = pfkeyv2_dump_policy(ipo, headers, &buffer,
                   2445:                    &buflen)) != 0)
                   2446:                        goto done;
                   2447:                if (w->w_len < buflen) {
                   2448:                        error = ENOMEM;
                   2449:                        goto done;
                   2450:                }
                   2451:                /* prepend header */
                   2452:                bzero(&msg, sizeof(msg));
                   2453:                msg.sadb_msg_version = PF_KEY_V2;
                   2454:                if (ipo->ipo_sproto == IPPROTO_ESP)
                   2455:                        msg.sadb_msg_satype = SADB_SATYPE_ESP;
                   2456:                else if (ipo->ipo_sproto == IPPROTO_AH)
                   2457:                        msg.sadb_msg_satype = SADB_SATYPE_AH;
                   2458:                else if (ipo->ipo_sproto == IPPROTO_IPCOMP)
                   2459:                        msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
                   2460:                else if (ipo->ipo_sproto == IPPROTO_IPIP)
                   2461:                        msg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
                   2462:                msg.sadb_msg_type = SADB_X_SPDDUMP;
                   2463:                msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t);
                   2464:                if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0)
                   2465:                        goto done;
                   2466:                w->w_where += sizeof(msg);
                   2467:                w->w_len -= sizeof(msg);
                   2468:                /* set extension type */
                   2469:                for (i = 1; i < SADB_EXT_MAX; i++)
                   2470:                        if (headers[i])
                   2471:                                ((struct sadb_ext *)
                   2472:                                    headers[i])->sadb_ext_type = i;
                   2473:                if ((error = copyout(buffer, w->w_where, buflen)) != 0)
                   2474:                        goto done;
                   2475:                w->w_where += buflen;
                   2476:                w->w_len -= buflen;
                   2477:        } else {
                   2478:                if ((error = pfkeyv2_dump_policy(ipo, NULL, NULL,
                   2479:                    &buflen)) != 0)
                   2480:                        goto done;
                   2481:                w->w_len += buflen;
                   2482:                w->w_len += sizeof(struct sadb_msg);
                   2483:        }
                   2484:
                   2485: done:
                   2486:        if (buffer)
                   2487:                free(buffer, M_PFKEY);
                   2488:        return (error);
                   2489: }
                   2490:
                   2491: int
                   2492: pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
                   2493:     void *new, size_t newlen)
                   2494: {
                   2495:        struct pfkeyv2_sysctl_walk w;
                   2496:        int s, error = EINVAL;
                   2497:
                   2498:        if (new)
                   2499:                return (EPERM);
                   2500:        if (namelen < 1)
                   2501:                return (EINVAL);
                   2502:        w.w_op = name[0];
                   2503:        w.w_satype = name[1];
                   2504:        w.w_where = oldp;
                   2505:        w.w_len = oldp ? *oldlenp : 0;
                   2506:
                   2507:        switch(w.w_op) {
                   2508:        case NET_KEY_SADB_DUMP:
                   2509:                if ((error = suser(curproc, 0)) != 0)
                   2510:                        return (error);
                   2511:                s = spltdb();
                   2512:                error = tdb_walk(pfkeyv2_sysctl_walker, &w);
                   2513:                splx(s);
                   2514:                if (oldp)
                   2515:                        *oldlenp = w.w_where - oldp;
                   2516:                else
                   2517:                        *oldlenp = w.w_len;
                   2518:                break;
                   2519:
                   2520:        case NET_KEY_SPD_DUMP:
                   2521:                s = spltdb();
                   2522:                error = pfkeyv2_ipo_walk(pfkeyv2_sysctl_policydumper, &w);
                   2523:                splx(s);
                   2524:                if (oldp)
                   2525:                        *oldlenp = w.w_where - oldp;
                   2526:                else
                   2527:                        *oldlenp = w.w_len;
                   2528:                break;
                   2529:        }
                   2530:
                   2531:        return (error);
                   2532: }
                   2533:
                   2534: int
                   2535: pfkeyv2_init(void)
                   2536: {
                   2537:        int rval;
                   2538:
                   2539:        bzero(&pfkeyv2_version, sizeof(struct pfkey_version));
                   2540:        pfkeyv2_version.protocol = PFKEYV2_PROTOCOL;
                   2541:        pfkeyv2_version.create = &pfkeyv2_create;
                   2542:        pfkeyv2_version.release = &pfkeyv2_release;
                   2543:        pfkeyv2_version.send = &pfkeyv2_send;
                   2544:        pfkeyv2_version.sysctl = &pfkeyv2_sysctl;
                   2545:
                   2546:        rval = pfkey_register(&pfkeyv2_version);
                   2547:        return (rval);
                   2548: }
                   2549:
                   2550: int
                   2551: pfkeyv2_cleanup(void)
                   2552: {
                   2553:        pfkey_unregister(&pfkeyv2_version);
                   2554:        return (0);
                   2555: }

CVSweb