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

Annotation of sys/net/pfkeyv2_convert.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: pfkeyv2_convert.c,v 1.29 2006/11/24 13:52:14 reyk Exp $       */
        !             2: /*
        !             3:  * The author of this code is Angelos D. Keromytis (angelos@keromytis.org)
        !             4:  *
        !             5:  * Part of this code is based on code written by Craig Metz (cmetz@inner.net)
        !             6:  * for NRL. Those licenses follow this one.
        !             7:  *
        !             8:  * Copyright (c) 2001 Angelos D. Keromytis.
        !             9:  *
        !            10:  * Permission to use, copy, and modify this software with or without fee
        !            11:  * is hereby granted, provided that this entire notice is included in
        !            12:  * all copies of any software which is or includes a copy or
        !            13:  * modification of this software.
        !            14:  * You may use this code under the GNU public license if you so wish. Please
        !            15:  * contribute changes back to the authors under this freer than GPL license
        !            16:  * so that we may further the use of strong encryption without limitations to
        !            17:  * all.
        !            18:  *
        !            19:  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
        !            20:  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
        !            21:  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
        !            22:  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
        !            23:  * PURPOSE.
        !            24:  */
        !            25:
        !            26: /*
        !            27:  *     @(#)COPYRIGHT   1.1 (NRL) 17 January 1995
        !            28:  *
        !            29:  * NRL grants permission for redistribution and use in source and binary
        !            30:  * forms, with or without modification, of the software and documentation
        !            31:  * created at NRL provided that the following conditions are met:
        !            32:  *
        !            33:  * 1. Redistributions of source code must retain the above copyright
        !            34:  *    notice, this list of conditions and the following disclaimer.
        !            35:  * 2. Redistributions in binary form must reproduce the above copyright
        !            36:  *    notice, this list of conditions and the following disclaimer in the
        !            37:  *    documentation and/or other materials provided with the distribution.
        !            38:  * 3. All advertising materials mentioning features or use of this software
        !            39:  *    must display the following acknowledgements:
        !            40:  *     This product includes software developed by the University of
        !            41:  *     California, Berkeley and its contributors.
        !            42:  *     This product includes software developed at the Information
        !            43:  *     Technology Division, US Naval Research Laboratory.
        !            44:  * 4. Neither the name of the NRL nor the names of its contributors
        !            45:  *    may be used to endorse or promote products derived from this software
        !            46:  *    without specific prior written permission.
        !            47:  *
        !            48:  * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
        !            49:  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            50:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
        !            51:  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
        !            52:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
        !            53:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
        !            54:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
        !            55:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
        !            56:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
        !            57:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
        !            58:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            59:  *
        !            60:  * The views and conclusions contained in the software and documentation
        !            61:  * are those of the authors and should not be interpreted as representing
        !            62:  * official policies, either expressed or implied, of the US Naval
        !            63:  * Research Laboratory (NRL).
        !            64:  */
        !            65:
        !            66: /*
        !            67:  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved.
        !            68:  *
        !            69:  * Redistribution and use in source and binary forms, with or without
        !            70:  * modification, are permitted provided that the following conditions
        !            71:  * are met:
        !            72:  * 1. Redistributions of source code must retain the above copyright
        !            73:  *    notice, this list of conditions and the following disclaimer.
        !            74:  * 2. Redistributions in binary form must reproduce the above copyright
        !            75:  *    notice, this list of conditions and the following disclaimer in the
        !            76:  *    documentation and/or other materials provided with the distribution.
        !            77:  * 3. Neither the name of the author nor the names of any contributors
        !            78:  *    may be used to endorse or promote products derived from this software
        !            79:  *    without specific prior written permission.
        !            80:  *
        !            81:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            82:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            83:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            84:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            85:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            86:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            87:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            88:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            89:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            90:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            91:  * SUCH DAMAGE.
        !            92:  */
        !            93:
        !            94: #include "pf.h"
        !            95:
        !            96: #include <sys/types.h>
        !            97: #include <sys/param.h>
        !            98: #include <sys/systm.h>
        !            99: #include <sys/mbuf.h>
        !           100: #include <sys/kernel.h>
        !           101: #include <sys/socket.h>
        !           102: #include <net/route.h>
        !           103: #include <net/if.h>
        !           104:
        !           105: #if NPF > 0
        !           106: #include <net/pfvar.h>
        !           107: #endif
        !           108:
        !           109: #include <netinet/ip_ipsp.h>
        !           110: #ifdef INET6
        !           111: #include <netinet6/in6_var.h>
        !           112: #endif
        !           113: #include <net/pfkeyv2.h>
        !           114: #include <crypto/cryptodev.h>
        !           115: #include <crypto/xform.h>
        !           116:
        !           117: /*
        !           118:  * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts
        !           119:  * of the TDB will be initialized by other import routines, and tdb_init().
        !           120:  */
        !           121: void
        !           122: import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii)
        !           123: {
        !           124:        if (!sadb_sa)
        !           125:                return;
        !           126:
        !           127:        if (ii) {
        !           128:                ii->ii_encalg = sadb_sa->sadb_sa_encrypt;
        !           129:                ii->ii_authalg = sadb_sa->sadb_sa_auth;
        !           130:                ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */
        !           131:
        !           132:                tdb->tdb_spi = sadb_sa->sadb_sa_spi;
        !           133:                tdb->tdb_wnd = sadb_sa->sadb_sa_replay;
        !           134:
        !           135:                if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS)
        !           136:                        tdb->tdb_flags |= TDBF_PFS;
        !           137:
        !           138:                if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_HALFIV)
        !           139:                        tdb->tdb_flags |= TDBF_HALFIV;
        !           140:
        !           141:                if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
        !           142:                        tdb->tdb_flags |= TDBF_TUNNELING;
        !           143:
        !           144:                if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_RANDOMPADDING)
        !           145:                        tdb->tdb_flags |= TDBF_RANDOMPADDING;
        !           146:
        !           147:                if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_NOREPLAY)
        !           148:                        tdb->tdb_flags |= TDBF_NOREPLAY;
        !           149:
        !           150:                if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP)
        !           151:                        tdb->tdb_flags |= TDBF_UDPENCAP;
        !           152:        }
        !           153:
        !           154:        if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE)
        !           155:                tdb->tdb_flags |= TDBF_INVALID;
        !           156: }
        !           157:
        !           158: /*
        !           159:  * Export some of the information on a TDB.
        !           160:  */
        !           161: void
        !           162: export_sa(void **p, struct tdb *tdb)
        !           163: {
        !           164:        struct sadb_sa *sadb_sa = (struct sadb_sa *) *p;
        !           165:
        !           166:        sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t);
        !           167:
        !           168:        sadb_sa->sadb_sa_spi = tdb->tdb_spi;
        !           169:        sadb_sa->sadb_sa_replay = tdb->tdb_wnd;
        !           170:
        !           171:        if (tdb->tdb_flags & TDBF_INVALID)
        !           172:                sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL;
        !           173:        else
        !           174:                sadb_sa->sadb_sa_state = SADB_SASTATE_MATURE;
        !           175:
        !           176:        if (tdb->tdb_sproto == IPPROTO_IPCOMP &&
        !           177:            tdb->tdb_compalgxform != NULL) {
        !           178:                switch (tdb->tdb_compalgxform->type) {
        !           179:                case CRYPTO_DEFLATE_COMP:
        !           180:                        sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
        !           181:                        break;
        !           182:                case CRYPTO_LZS_COMP:
        !           183:                        sadb_sa->sadb_sa_encrypt = SADB_X_CALG_LZS;
        !           184:                        break;
        !           185:                }
        !           186:        }
        !           187:
        !           188:        if (tdb->tdb_authalgxform) {
        !           189:                switch (tdb->tdb_authalgxform->type) {
        !           190:                case CRYPTO_MD5_HMAC:
        !           191:                        sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC;
        !           192:                        break;
        !           193:
        !           194:                case CRYPTO_SHA1_HMAC:
        !           195:                        sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC;
        !           196:                        break;
        !           197:
        !           198:                case CRYPTO_RIPEMD160_HMAC:
        !           199:                        sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
        !           200:                        break;
        !           201:
        !           202:                case CRYPTO_SHA2_256_HMAC:
        !           203:                        sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_256;
        !           204:                        break;
        !           205:
        !           206:                case CRYPTO_SHA2_384_HMAC:
        !           207:                        sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_384;
        !           208:                        break;
        !           209:
        !           210:                case CRYPTO_SHA2_512_HMAC:
        !           211:                        sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_512;
        !           212:                        break;
        !           213:
        !           214:                case CRYPTO_MD5_KPDK:
        !           215:                        sadb_sa->sadb_sa_auth = SADB_X_AALG_MD5;
        !           216:                        break;
        !           217:
        !           218:                case CRYPTO_SHA1_KPDK:
        !           219:                        sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA1;
        !           220:                        break;
        !           221:                }
        !           222:        }
        !           223:
        !           224:        if (tdb->tdb_encalgxform) {
        !           225:                switch (tdb->tdb_encalgxform->type) {
        !           226:                case CRYPTO_NULL:
        !           227:                        sadb_sa->sadb_sa_encrypt = SADB_EALG_NULL;
        !           228:                        break;
        !           229:
        !           230:                case CRYPTO_DES_CBC:
        !           231:                        sadb_sa->sadb_sa_encrypt = SADB_EALG_DESCBC;
        !           232:                        break;
        !           233:
        !           234:                case CRYPTO_3DES_CBC:
        !           235:                        sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC;
        !           236:                        break;
        !           237:
        !           238:                case CRYPTO_AES_CBC:
        !           239:                        sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES;
        !           240:                        break;
        !           241:
        !           242:                case CRYPTO_AES_CTR:
        !           243:                        sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR;
        !           244:                        break;
        !           245:
        !           246:                case CRYPTO_CAST_CBC:
        !           247:                        sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST;
        !           248:                        break;
        !           249:
        !           250:                case CRYPTO_BLF_CBC:
        !           251:                        sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF;
        !           252:                        break;
        !           253:
        !           254:                case CRYPTO_SKIPJACK_CBC:
        !           255:                        sadb_sa->sadb_sa_encrypt = SADB_X_EALG_SKIPJACK;
        !           256:                        break;
        !           257:                }
        !           258:        }
        !           259:
        !           260:        if (tdb->tdb_flags & TDBF_PFS)
        !           261:                sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS;
        !           262:
        !           263:        /* Only relevant for the "old" IPsec transforms. */
        !           264:        if (tdb->tdb_flags & TDBF_HALFIV)
        !           265:                sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV;
        !           266:
        !           267:        if (tdb->tdb_flags & TDBF_TUNNELING)
        !           268:                sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
        !           269:
        !           270:        if (tdb->tdb_flags & TDBF_RANDOMPADDING)
        !           271:                sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_RANDOMPADDING;
        !           272:
        !           273:        if (tdb->tdb_flags & TDBF_NOREPLAY)
        !           274:                sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY;
        !           275:
        !           276:        *p += sizeof(struct sadb_sa);
        !           277: }
        !           278:
        !           279: /*
        !           280:  * Initialize expirations and counters based on lifetime payload.
        !           281:  */
        !           282: void
        !           283: import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type)
        !           284: {
        !           285:        struct timeval tv;
        !           286:
        !           287:        if (!sadb_lifetime)
        !           288:                return;
        !           289:
        !           290:        getmicrotime(&tv);
        !           291:
        !           292:        switch (type) {
        !           293:        case PFKEYV2_LIFETIME_HARD:
        !           294:                if ((tdb->tdb_exp_allocations =
        !           295:                    sadb_lifetime->sadb_lifetime_allocations) != 0)
        !           296:                        tdb->tdb_flags |= TDBF_ALLOCATIONS;
        !           297:                else
        !           298:                        tdb->tdb_flags &= ~TDBF_ALLOCATIONS;
        !           299:
        !           300:                if ((tdb->tdb_exp_bytes =
        !           301:                    sadb_lifetime->sadb_lifetime_bytes) != 0)
        !           302:                        tdb->tdb_flags |= TDBF_BYTES;
        !           303:                else
        !           304:                        tdb->tdb_flags &= ~TDBF_BYTES;
        !           305:
        !           306:                if ((tdb->tdb_exp_timeout =
        !           307:                    sadb_lifetime->sadb_lifetime_addtime) != 0) {
        !           308:                        tdb->tdb_flags |= TDBF_TIMER;
        !           309:                        if (tv.tv_sec + tdb->tdb_exp_timeout < tv.tv_sec)
        !           310:                                tv.tv_sec = ((unsigned long) -1) / 2; /* XXX */
        !           311:                        else
        !           312:                                tv.tv_sec += tdb->tdb_exp_timeout;
        !           313:                        timeout_add(&tdb->tdb_timer_tmo, hzto(&tv));
        !           314:                } else
        !           315:                        tdb->tdb_flags &= ~TDBF_TIMER;
        !           316:
        !           317:                if ((tdb->tdb_exp_first_use =
        !           318:                    sadb_lifetime->sadb_lifetime_usetime) != 0)
        !           319:                        tdb->tdb_flags |= TDBF_FIRSTUSE;
        !           320:                else
        !           321:                        tdb->tdb_flags &= ~TDBF_FIRSTUSE;
        !           322:                break;
        !           323:
        !           324:        case PFKEYV2_LIFETIME_SOFT:
        !           325:                if ((tdb->tdb_soft_allocations =
        !           326:                    sadb_lifetime->sadb_lifetime_allocations) != 0)
        !           327:                        tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS;
        !           328:                else
        !           329:                        tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS;
        !           330:
        !           331:                if ((tdb->tdb_soft_bytes =
        !           332:                    sadb_lifetime->sadb_lifetime_bytes) != 0)
        !           333:                        tdb->tdb_flags |= TDBF_SOFT_BYTES;
        !           334:                else
        !           335:                        tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
        !           336:
        !           337:                if ((tdb->tdb_soft_timeout =
        !           338:                    sadb_lifetime->sadb_lifetime_addtime) != 0) {
        !           339:                        tdb->tdb_flags |= TDBF_SOFT_TIMER;
        !           340:                        if (tv.tv_sec + tdb->tdb_soft_timeout < tv.tv_sec)
        !           341:                                tv.tv_sec = ((unsigned long) -1) / 2; /* XXX */
        !           342:                        else
        !           343:                                tv.tv_sec += tdb->tdb_soft_timeout;
        !           344:                        timeout_add(&tdb->tdb_stimer_tmo, hzto(&tv));
        !           345:                } else
        !           346:                        tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
        !           347:
        !           348:                if ((tdb->tdb_soft_first_use =
        !           349:                    sadb_lifetime->sadb_lifetime_usetime) != 0)
        !           350:                        tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE;
        !           351:                else
        !           352:                        tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
        !           353:                break;
        !           354:
        !           355:        case PFKEYV2_LIFETIME_CURRENT:  /* Nothing fancy here. */
        !           356:                tdb->tdb_cur_allocations =
        !           357:                    sadb_lifetime->sadb_lifetime_allocations;
        !           358:                tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes;
        !           359:                tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime;
        !           360:                tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime;
        !           361:        }
        !           362: }
        !           363:
        !           364: /*
        !           365:  * Export TDB expiration information.
        !           366:  */
        !           367: void
        !           368: export_lifetime(void **p, struct tdb *tdb, int type)
        !           369: {
        !           370:        struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p;
        !           371:
        !           372:        sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) /
        !           373:            sizeof(uint64_t);
        !           374:
        !           375:        switch (type) {
        !           376:        case PFKEYV2_LIFETIME_HARD:
        !           377:                if (tdb->tdb_flags & TDBF_ALLOCATIONS)
        !           378:                        sadb_lifetime->sadb_lifetime_allocations =
        !           379:                            tdb->tdb_exp_allocations;
        !           380:
        !           381:                if (tdb->tdb_flags & TDBF_BYTES)
        !           382:                        sadb_lifetime->sadb_lifetime_bytes =
        !           383:                            tdb->tdb_exp_bytes;
        !           384:
        !           385:                if (tdb->tdb_flags & TDBF_TIMER)
        !           386:                        sadb_lifetime->sadb_lifetime_addtime =
        !           387:                            tdb->tdb_exp_timeout;
        !           388:
        !           389:                if (tdb->tdb_flags & TDBF_FIRSTUSE)
        !           390:                        sadb_lifetime->sadb_lifetime_usetime =
        !           391:                            tdb->tdb_exp_first_use;
        !           392:                break;
        !           393:
        !           394:        case PFKEYV2_LIFETIME_SOFT:
        !           395:                if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
        !           396:                        sadb_lifetime->sadb_lifetime_allocations =
        !           397:                            tdb->tdb_soft_allocations;
        !           398:
        !           399:                if (tdb->tdb_flags & TDBF_SOFT_BYTES)
        !           400:                        sadb_lifetime->sadb_lifetime_bytes =
        !           401:                            tdb->tdb_soft_bytes;
        !           402:
        !           403:                if (tdb->tdb_flags & TDBF_SOFT_TIMER)
        !           404:                        sadb_lifetime->sadb_lifetime_addtime =
        !           405:                            tdb->tdb_soft_timeout;
        !           406:
        !           407:                if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
        !           408:                        sadb_lifetime->sadb_lifetime_usetime =
        !           409:                            tdb->tdb_soft_first_use;
        !           410:                break;
        !           411:
        !           412:        case PFKEYV2_LIFETIME_CURRENT:
        !           413:                sadb_lifetime->sadb_lifetime_allocations =
        !           414:                    tdb->tdb_cur_allocations;
        !           415:                sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes;
        !           416:                sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established;
        !           417:                sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use;
        !           418:                break;
        !           419:
        !           420:        case PFKEYV2_LIFETIME_LASTUSE:
        !           421:                sadb_lifetime->sadb_lifetime_allocations = 0;
        !           422:                sadb_lifetime->sadb_lifetime_bytes = 0;
        !           423:                sadb_lifetime->sadb_lifetime_addtime = 0;
        !           424:                sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used;
        !           425:                break;
        !           426:        }
        !           427:
        !           428:        *p += sizeof(struct sadb_lifetime);
        !           429: }
        !           430:
        !           431: /*
        !           432:  * Import flow information to two struct sockaddr_encap's. Either
        !           433:  * all or none of the address arguments are NULL.
        !           434:  */
        !           435: void
        !           436: import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask,
        !           437:     struct sadb_address *ssrc, struct sadb_address *ssrcmask,
        !           438:     struct sadb_address *ddst, struct sadb_address *ddstmask,
        !           439:     struct sadb_protocol *sab, struct sadb_protocol *ftype)
        !           440: {
        !           441:        u_int8_t transproto = 0;
        !           442:        union sockaddr_union *src = (union sockaddr_union *)(ssrc + 1);
        !           443:        union sockaddr_union *dst = (union sockaddr_union *)(ddst + 1);
        !           444:        union sockaddr_union *srcmask = (union sockaddr_union *)(ssrcmask + 1);
        !           445:        union sockaddr_union *dstmask = (union sockaddr_union *)(ddstmask + 1);
        !           446:
        !           447:        if (ssrc == NULL)
        !           448:                return; /* There wasn't any information to begin with. */
        !           449:
        !           450:        bzero(flow, sizeof(*flow));
        !           451:        bzero(flowmask, sizeof(*flowmask));
        !           452:
        !           453:        if (sab != NULL)
        !           454:                transproto = sab->sadb_protocol_proto;
        !           455:
        !           456:        /*
        !           457:         * Check that all the address families match. We know they are
        !           458:         * valid and supported because pfkeyv2_parsemessage() checked that.
        !           459:         */
        !           460:        if ((src->sa.sa_family != dst->sa.sa_family) ||
        !           461:            (src->sa.sa_family != srcmask->sa.sa_family) ||
        !           462:            (src->sa.sa_family != dstmask->sa.sa_family))
        !           463:                return;
        !           464:
        !           465:        /*
        !           466:         * We set these as an indication that tdb_filter/tdb_filtermask are
        !           467:         * in fact initialized.
        !           468:         */
        !           469:        flow->sen_family = flowmask->sen_family = PF_KEY;
        !           470:        flow->sen_len = flowmask->sen_len = SENT_LEN;
        !           471:
        !           472:        switch (src->sa.sa_family)
        !           473:        {
        !           474: #ifdef INET
        !           475:        case AF_INET:
        !           476:                /* netmask handling */
        !           477:                rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
        !           478:                rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
        !           479:
        !           480:                flow->sen_type = SENT_IP4;
        !           481:                flow->sen_direction = ftype->sadb_protocol_direction;
        !           482:                flow->sen_ip_src = src->sin.sin_addr;
        !           483:                flow->sen_ip_dst = dst->sin.sin_addr;
        !           484:                flow->sen_proto = transproto;
        !           485:                flow->sen_sport = src->sin.sin_port;
        !           486:                flow->sen_dport = dst->sin.sin_port;
        !           487:
        !           488:                flowmask->sen_type = SENT_IP4;
        !           489:                flowmask->sen_direction = 0xff;
        !           490:                flowmask->sen_ip_src = srcmask->sin.sin_addr;
        !           491:                flowmask->sen_ip_dst = dstmask->sin.sin_addr;
        !           492:                flowmask->sen_sport = srcmask->sin.sin_port;
        !           493:                flowmask->sen_dport = dstmask->sin.sin_port;
        !           494:                if (transproto)
        !           495:                        flowmask->sen_proto = 0xff;
        !           496:                break;
        !           497: #endif /* INET */
        !           498:
        !           499: #ifdef INET6
        !           500:        case AF_INET6:
        !           501:                in6_embedscope(&src->sin6.sin6_addr, &src->sin6,
        !           502:                    NULL, NULL);
        !           503:                in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6,
        !           504:                    NULL, NULL);
        !           505:
        !           506:                /* netmask handling */
        !           507:                rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
        !           508:                rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
        !           509:
        !           510:                flow->sen_type = SENT_IP6;
        !           511:                flow->sen_ip6_direction = ftype->sadb_protocol_direction;
        !           512:                flow->sen_ip6_src = src->sin6.sin6_addr;
        !           513:                flow->sen_ip6_dst = dst->sin6.sin6_addr;
        !           514:                flow->sen_ip6_proto = transproto;
        !           515:                flow->sen_ip6_sport = src->sin6.sin6_port;
        !           516:                flow->sen_ip6_dport = dst->sin6.sin6_port;
        !           517:
        !           518:                flowmask->sen_type = SENT_IP6;
        !           519:                flowmask->sen_ip6_direction = 0xff;
        !           520:                flowmask->sen_ip6_src = srcmask->sin6.sin6_addr;
        !           521:                flowmask->sen_ip6_dst = dstmask->sin6.sin6_addr;
        !           522:                flowmask->sen_ip6_sport = srcmask->sin6.sin6_port;
        !           523:                flowmask->sen_ip6_dport = dstmask->sin6.sin6_port;
        !           524:                if (transproto)
        !           525:                        flowmask->sen_ip6_proto = 0xff;
        !           526:                break;
        !           527: #endif /* INET6 */
        !           528:        }
        !           529: }
        !           530:
        !           531: /*
        !           532:  * Helper to export addresses from an struct sockaddr_encap.
        !           533:  */
        !           534: static void
        !           535: export_encap(void **p, struct sockaddr_encap *encap, int type)
        !           536: {
        !           537:        struct sadb_address *saddr = (struct sadb_address *)*p;
        !           538:        union sockaddr_union *sunion;
        !           539:
        !           540:        *p += sizeof(struct sadb_address);
        !           541:        sunion = (union sockaddr_union *)*p;
        !           542:
        !           543:        switch (encap->sen_type) {
        !           544:        case SENT_IP4:
        !           545:                saddr->sadb_address_len = (sizeof(struct sadb_address) +
        !           546:                    PADUP(sizeof(struct sockaddr_in))) / sizeof(uint64_t);
        !           547:                sunion->sa.sa_len = sizeof(struct sockaddr_in);
        !           548:                sunion->sa.sa_family = AF_INET;
        !           549:                if (type == SADB_X_EXT_SRC_FLOW ||
        !           550:                    type == SADB_X_EXT_SRC_MASK) {
        !           551:                        sunion->sin.sin_addr = encap->sen_ip_src;
        !           552:                        sunion->sin.sin_port = encap->sen_sport;
        !           553:                } else {
        !           554:                        sunion->sin.sin_addr = encap->sen_ip_dst;
        !           555:                        sunion->sin.sin_port = encap->sen_dport;
        !           556:                }
        !           557:                *p += PADUP(sizeof(struct sockaddr_in));
        !           558:                break;
        !           559:         case SENT_IP6:
        !           560:                saddr->sadb_address_len = (sizeof(struct sadb_address)
        !           561:                    + PADUP(sizeof(struct sockaddr_in6))) / sizeof(uint64_t);
        !           562:                sunion->sa.sa_len = sizeof(struct sockaddr_in6);
        !           563:                sunion->sa.sa_family = AF_INET6;
        !           564:                if (type == SADB_X_EXT_SRC_FLOW ||
        !           565:                    type == SADB_X_EXT_SRC_MASK) {
        !           566:                        sunion->sin6.sin6_addr = encap->sen_ip6_src;
        !           567:                        sunion->sin6.sin6_port = encap->sen_ip6_sport;
        !           568:                } else {
        !           569:                        sunion->sin6.sin6_addr = encap->sen_ip6_dst;
        !           570:                        sunion->sin6.sin6_port = encap->sen_ip6_dport;
        !           571:                }
        !           572:                *p += PADUP(sizeof(struct sockaddr_in6));
        !           573:                break;
        !           574:        }
        !           575: }
        !           576:
        !           577: /*
        !           578:  * Export flow information from two struct sockaddr_encap's.
        !           579:  */
        !           580: void
        !           581: export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow,
        !           582:     struct sockaddr_encap *flowmask, void **headers)
        !           583: {
        !           584:        struct sadb_protocol *sab;
        !           585:
        !           586:        headers[SADB_X_EXT_FLOW_TYPE] = *p;
        !           587:        sab = (struct sadb_protocol *)*p;
        !           588:        sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
        !           589:            sizeof(uint64_t);
        !           590:
        !           591:        switch (ftype) {
        !           592:        case IPSP_IPSEC_USE:
        !           593:                sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
        !           594:                break;
        !           595:        case IPSP_IPSEC_ACQUIRE:
        !           596:                sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE;
        !           597:                break;
        !           598:        case IPSP_IPSEC_REQUIRE:
        !           599:                sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE;
        !           600:                break;
        !           601:        case IPSP_DENY:
        !           602:                sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY;
        !           603:                break;
        !           604:        case IPSP_PERMIT:
        !           605:                sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS;
        !           606:                break;
        !           607:        case IPSP_IPSEC_DONTACQ:
        !           608:                sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ;
        !           609:                break;
        !           610:        default:
        !           611:                sab->sadb_protocol_proto = 0;
        !           612:                break;
        !           613:        }
        !           614:
        !           615:        switch (flow->sen_type) {
        !           616: #ifdef INET
        !           617:        case SENT_IP4:
        !           618:                sab->sadb_protocol_direction = flow->sen_direction;
        !           619:                break;
        !           620: #endif /* INET */
        !           621: #ifdef INET6
        !           622:        case SENT_IP6:
        !           623:                sab->sadb_protocol_direction = flow->sen_ip6_direction;
        !           624:                break;
        !           625: #endif /* INET6 */
        !           626:        }
        !           627:        *p += sizeof(struct sadb_protocol);
        !           628:
        !           629:        headers[SADB_X_EXT_PROTOCOL] = *p;
        !           630:        sab = (struct sadb_protocol *)*p;
        !           631:        sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
        !           632:            sizeof(uint64_t);
        !           633:        switch (flow->sen_type) {
        !           634: #ifdef INET
        !           635:        case SENT_IP4:
        !           636:                sab->sadb_protocol_proto = flow->sen_proto;
        !           637:                break;
        !           638: #endif /* INET */
        !           639: #ifdef INET6
        !           640:        case SENT_IP6:
        !           641:                sab->sadb_protocol_proto = flow->sen_ip6_proto;
        !           642:                break;
        !           643: #endif /* INET6 */
        !           644:        }
        !           645:        *p += sizeof(struct sadb_protocol);
        !           646:
        !           647:        headers[SADB_X_EXT_SRC_FLOW] = *p;
        !           648:        export_encap(p, flow, SADB_X_EXT_SRC_FLOW);
        !           649:
        !           650:        headers[SADB_X_EXT_SRC_MASK] = *p;
        !           651:        export_encap(p, flowmask, SADB_X_EXT_SRC_MASK);
        !           652:
        !           653:        headers[SADB_X_EXT_DST_FLOW] = *p;
        !           654:        export_encap(p, flow, SADB_X_EXT_DST_FLOW);
        !           655:
        !           656:        headers[SADB_X_EXT_DST_MASK] = *p;
        !           657:        export_encap(p, flowmask, SADB_X_EXT_DST_MASK);
        !           658: }
        !           659:
        !           660: /*
        !           661:  * Copy an SADB_ADDRESS payload to a struct sockaddr.
        !           662:  */
        !           663: void
        !           664: import_address(struct sockaddr *sa, struct sadb_address *sadb_address)
        !           665: {
        !           666:        int salen;
        !           667:        struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address +
        !           668:            sizeof(struct sadb_address));
        !           669:
        !           670:        if (!sadb_address)
        !           671:                return;
        !           672:
        !           673:        if (ssa->sa_len)
        !           674:                salen = ssa->sa_len;
        !           675:        else
        !           676:                switch (ssa->sa_family) {
        !           677: #ifdef INET
        !           678:                case AF_INET:
        !           679:                        salen = sizeof(struct sockaddr_in);
        !           680:                        break;
        !           681: #endif /* INET */
        !           682:
        !           683: #if INET6
        !           684:                case AF_INET6:
        !           685:                        salen = sizeof(struct sockaddr_in6);
        !           686:                        break;
        !           687: #endif /* INET6 */
        !           688:
        !           689:                default:
        !           690:                        return;
        !           691:                }
        !           692:
        !           693:        bcopy(ssa, sa, salen);
        !           694:        sa->sa_len = salen;
        !           695: }
        !           696:
        !           697: /*
        !           698:  * Export a struct sockaddr as an SADB_ADDRESS payload.
        !           699:  */
        !           700: void
        !           701: export_address(void **p, struct sockaddr *sa)
        !           702: {
        !           703:        struct sadb_address *sadb_address = (struct sadb_address *) *p;
        !           704:
        !           705:        sadb_address->sadb_address_len = (sizeof(struct sadb_address) +
        !           706:            PADUP(SA_LEN(sa))) / sizeof(uint64_t);
        !           707:
        !           708:        *p += sizeof(struct sadb_address);
        !           709:        bcopy(sa, *p, SA_LEN(sa));
        !           710:        ((struct sockaddr *) *p)->sa_family = sa->sa_family;
        !           711:        *p += PADUP(SA_LEN(sa));
        !           712: }
        !           713:
        !           714: /*
        !           715:  * Import authentication information into the TDB.
        !           716:  */
        !           717: void
        !           718: import_auth(struct tdb *tdb, struct sadb_x_cred *sadb_auth, int dstauth)
        !           719: {
        !           720:        struct ipsec_ref **ipr;
        !           721:
        !           722:        if (!sadb_auth)
        !           723:                return;
        !           724:
        !           725:        if (dstauth == PFKEYV2_AUTH_REMOTE)
        !           726:                ipr = &tdb->tdb_remote_auth;
        !           727:        else
        !           728:                ipr = &tdb->tdb_local_auth;
        !           729:
        !           730:        MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_auth) -
        !           731:            sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
        !           732:            M_CREDENTIALS, M_WAITOK);
        !           733:        (*ipr)->ref_len = EXTLEN(sadb_auth) - sizeof(struct sadb_x_cred);
        !           734:
        !           735:        switch (sadb_auth->sadb_x_cred_type) {
        !           736:        case SADB_X_AUTHTYPE_PASSPHRASE:
        !           737:                (*ipr)->ref_type = IPSP_AUTH_PASSPHRASE;
        !           738:                break;
        !           739:        case SADB_X_AUTHTYPE_RSA:
        !           740:                (*ipr)->ref_type = IPSP_AUTH_RSA;
        !           741:                break;
        !           742:        default:
        !           743:                FREE(*ipr, M_CREDENTIALS);
        !           744:                *ipr = NULL;
        !           745:                return;
        !           746:        }
        !           747:        (*ipr)->ref_count = 1;
        !           748:        (*ipr)->ref_malloctype = M_CREDENTIALS;
        !           749:        bcopy((void *) sadb_auth + sizeof(struct sadb_x_cred),
        !           750:            (*ipr) + 1, (*ipr)->ref_len);
        !           751: }
        !           752:
        !           753: /*
        !           754:  * Import a set of credentials into the TDB.
        !           755:  */
        !           756: void
        !           757: import_credentials(struct tdb *tdb, struct sadb_x_cred *sadb_cred, int dstcred)
        !           758: {
        !           759:        struct ipsec_ref **ipr;
        !           760:
        !           761:        if (!sadb_cred)
        !           762:                return;
        !           763:
        !           764:        if (dstcred == PFKEYV2_CRED_REMOTE)
        !           765:                ipr = &tdb->tdb_remote_cred;
        !           766:        else
        !           767:                ipr = &tdb->tdb_local_cred;
        !           768:
        !           769:        MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_cred) -
        !           770:            sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
        !           771:            M_CREDENTIALS, M_WAITOK);
        !           772:        (*ipr)->ref_len = EXTLEN(sadb_cred) - sizeof(struct sadb_x_cred);
        !           773:
        !           774:        switch (sadb_cred->sadb_x_cred_type) {
        !           775:        case SADB_X_CREDTYPE_X509:
        !           776:                (*ipr)->ref_type = IPSP_CRED_X509;
        !           777:                break;
        !           778:        case SADB_X_CREDTYPE_KEYNOTE:
        !           779:                (*ipr)->ref_type = IPSP_CRED_KEYNOTE;
        !           780:                break;
        !           781:        default:
        !           782:                FREE(*ipr, M_CREDENTIALS);
        !           783:                *ipr = NULL;
        !           784:                return;
        !           785:        }
        !           786:        (*ipr)->ref_count = 1;
        !           787:        (*ipr)->ref_malloctype = M_CREDENTIALS;
        !           788:        bcopy((void *) sadb_cred + sizeof(struct sadb_x_cred),
        !           789:            (*ipr) + 1, (*ipr)->ref_len);
        !           790: }
        !           791:
        !           792: /*
        !           793:  * Import an identity payload into the TDB.
        !           794:  */
        !           795: void
        !           796: import_identity(struct tdb *tdb, struct sadb_ident *sadb_ident, int type)
        !           797: {
        !           798:        struct ipsec_ref **ipr;
        !           799:
        !           800:        if (!sadb_ident)
        !           801:                return;
        !           802:
        !           803:        if (type == PFKEYV2_IDENTITY_SRC)
        !           804:                ipr = &tdb->tdb_srcid;
        !           805:        else
        !           806:                ipr = &tdb->tdb_dstid;
        !           807:
        !           808:        MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_ident) -
        !           809:            sizeof(struct sadb_ident) + sizeof(struct ipsec_ref),
        !           810:            M_CREDENTIALS, M_WAITOK);
        !           811:        (*ipr)->ref_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident);
        !           812:
        !           813:        switch (sadb_ident->sadb_ident_type) {
        !           814:        case SADB_IDENTTYPE_PREFIX:
        !           815:                (*ipr)->ref_type = IPSP_IDENTITY_PREFIX;
        !           816:                break;
        !           817:        case SADB_IDENTTYPE_FQDN:
        !           818:                (*ipr)->ref_type = IPSP_IDENTITY_FQDN;
        !           819:                break;
        !           820:        case SADB_IDENTTYPE_USERFQDN:
        !           821:                (*ipr)->ref_type = IPSP_IDENTITY_USERFQDN;
        !           822:                break;
        !           823:        case SADB_X_IDENTTYPE_CONNECTION:
        !           824:                (*ipr)->ref_type = IPSP_IDENTITY_CONNECTION;
        !           825:                break;
        !           826:        default:
        !           827:                FREE(*ipr, M_CREDENTIALS);
        !           828:                *ipr = NULL;
        !           829:                return;
        !           830:        }
        !           831:        (*ipr)->ref_count = 1;
        !           832:        (*ipr)->ref_malloctype = M_CREDENTIALS;
        !           833:        bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*ipr) + 1,
        !           834:            (*ipr)->ref_len);
        !           835: }
        !           836:
        !           837: void
        !           838: export_credentials(void **p, struct tdb *tdb, int dstcred)
        !           839: {
        !           840:        struct ipsec_ref **ipr;
        !           841:        struct sadb_x_cred *sadb_cred = (struct sadb_x_cred *) *p;
        !           842:
        !           843:        if (dstcred == PFKEYV2_CRED_REMOTE)
        !           844:                ipr = &tdb->tdb_remote_cred;
        !           845:        else
        !           846:                ipr = &tdb->tdb_local_cred;
        !           847:
        !           848:        sadb_cred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
        !           849:            PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
        !           850:
        !           851:        switch ((*ipr)->ref_type) {
        !           852:        case IPSP_CRED_KEYNOTE:
        !           853:                sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
        !           854:                break;
        !           855:        case IPSP_CRED_X509:
        !           856:                sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
        !           857:                break;
        !           858:        }
        !           859:        *p += sizeof(struct sadb_x_cred);
        !           860:        bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
        !           861:        *p += PADUP((*ipr)->ref_len);
        !           862: }
        !           863:
        !           864: void
        !           865: export_auth(void **p, struct tdb *tdb, int dstauth)
        !           866: {
        !           867:        struct ipsec_ref **ipr;
        !           868:        struct sadb_x_cred *sadb_auth = (struct sadb_x_cred *) *p;
        !           869:
        !           870:        if (dstauth == PFKEYV2_AUTH_REMOTE)
        !           871:                ipr = &tdb->tdb_remote_auth;
        !           872:        else
        !           873:                ipr = &tdb->tdb_local_auth;
        !           874:
        !           875:        sadb_auth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
        !           876:            PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
        !           877:
        !           878:        switch ((*ipr)->ref_type) {
        !           879:        case IPSP_AUTH_PASSPHRASE:
        !           880:                sadb_auth->sadb_x_cred_type = SADB_X_AUTHTYPE_PASSPHRASE;
        !           881:                break;
        !           882:        case IPSP_AUTH_RSA:
        !           883:                sadb_auth->sadb_x_cred_type = SADB_X_AUTHTYPE_RSA;
        !           884:                break;
        !           885:        }
        !           886:        *p += sizeof(struct sadb_x_cred);
        !           887:        bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
        !           888:        *p += PADUP((*ipr)->ref_len);
        !           889: }
        !           890:
        !           891: void
        !           892: export_identity(void **p, struct tdb *tdb, int type)
        !           893: {
        !           894:        struct ipsec_ref **ipr;
        !           895:        struct sadb_ident *sadb_ident = (struct sadb_ident *) *p;
        !           896:
        !           897:        if (type == PFKEYV2_IDENTITY_SRC)
        !           898:                ipr = &tdb->tdb_srcid;
        !           899:        else
        !           900:                ipr = &tdb->tdb_dstid;
        !           901:
        !           902:        sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) +
        !           903:            PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
        !           904:
        !           905:        switch ((*ipr)->ref_type) {
        !           906:        case IPSP_IDENTITY_PREFIX:
        !           907:                sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX;
        !           908:                break;
        !           909:        case IPSP_IDENTITY_FQDN:
        !           910:                sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN;
        !           911:                break;
        !           912:        case IPSP_IDENTITY_USERFQDN:
        !           913:                sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
        !           914:                break;
        !           915:        case IPSP_IDENTITY_CONNECTION:
        !           916:                sadb_ident->sadb_ident_type = SADB_X_IDENTTYPE_CONNECTION;
        !           917:                break;
        !           918:        }
        !           919:        *p += sizeof(struct sadb_ident);
        !           920:        bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
        !           921:        *p += PADUP((*ipr)->ref_len);
        !           922: }
        !           923:
        !           924: /* ... */
        !           925: void
        !           926: import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type)
        !           927: {
        !           928:        if (!sadb_key)
        !           929:                return;
        !           930:
        !           931:        if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */
        !           932:                ii->ii_enckeylen = sadb_key->sadb_key_bits / 8;
        !           933:                ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key);
        !           934:        } else {
        !           935:                ii->ii_authkeylen = sadb_key->sadb_key_bits / 8;
        !           936:                ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key);
        !           937:        }
        !           938: }
        !           939:
        !           940: void
        !           941: export_key(void **p, struct tdb *tdb, int type)
        !           942: {
        !           943:        struct sadb_key *sadb_key = (struct sadb_key *) *p;
        !           944:
        !           945:        if (type == PFKEYV2_ENCRYPTION_KEY) {
        !           946:                sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
        !           947:                    PADUP(tdb->tdb_emxkeylen)) /
        !           948:                    sizeof(uint64_t);
        !           949:                sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8;
        !           950:                *p += sizeof(struct sadb_key);
        !           951:                bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen);
        !           952:                *p += PADUP(tdb->tdb_emxkeylen);
        !           953:        } else {
        !           954:                sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
        !           955:                    PADUP(tdb->tdb_amxkeylen)) /
        !           956:                    sizeof(uint64_t);
        !           957:                sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8;
        !           958:                *p += sizeof(struct sadb_key);
        !           959:                bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen);
        !           960:                *p += PADUP(tdb->tdb_amxkeylen);
        !           961:        }
        !           962: }
        !           963:
        !           964: /* Import/Export remote port for UDP Encapsulation */
        !           965: void
        !           966: import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap)
        !           967: {
        !           968:        if (sadb_udpencap)
        !           969:                tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port;
        !           970: }
        !           971:
        !           972: void
        !           973: export_udpencap(void **p, struct tdb *tdb)
        !           974: {
        !           975:        struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p;
        !           976:
        !           977:        sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port;
        !           978:        sadb_udpencap->sadb_x_udpencap_reserved = 0;
        !           979:        sadb_udpencap->sadb_x_udpencap_len =
        !           980:            sizeof(struct sadb_x_udpencap) / sizeof(uint64_t);
        !           981:        *p += sizeof(struct sadb_x_udpencap);
        !           982: }
        !           983:
        !           984: #if NPF > 0
        !           985: /* Import PF tag information for SA */
        !           986: void
        !           987: import_tag(struct tdb *tdb, struct sadb_x_tag *stag)
        !           988: {
        !           989:        char *s;
        !           990:
        !           991:        if (stag) {
        !           992:                s = (char *)(stag + 1);
        !           993:                tdb->tdb_tag = pf_tagname2tag(s);
        !           994:        }
        !           995: }
        !           996:
        !           997: /* Export PF tag information for SA */
        !           998: void
        !           999: export_tag(void **p, struct tdb *tdb)
        !          1000: {
        !          1001:        struct sadb_x_tag *stag = (struct sadb_x_tag *)*p;
        !          1002:        char *s = (char *)(stag + 1);
        !          1003:
        !          1004:        pf_tag2tagname(tdb->tdb_tag, s);
        !          1005:        stag->sadb_x_tag_taglen = strlen(s) + 1;
        !          1006:        stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) +
        !          1007:            PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t);
        !          1008:        *p += PADUP(stag->sadb_x_tag_taglen) + sizeof(struct sadb_x_tag);
        !          1009: }
        !          1010: #endif

CVSweb