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