1 /* $OpenBSD: pfkeyv2_convert.c,v 1.57 2015/12/09 21:41:50 naddy 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 <sys/timeout.h> 103 #include <net/route.h> 104 #include <net/if.h> 105 106 #include <netinet/in.h> 107 #include <netinet/ip_ipsp.h> 108 #include <net/pfkeyv2.h> 109 #include <crypto/cryptodev.h> 110 #include <crypto/xform.h> 111 112 #if NPF > 0 113 #include <net/pfvar.h> 114 #endif 115 116 /* 117 * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts 118 * of the TDB will be initialized by other import routines, and tdb_init(). 119 */ 120 void 121 import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii) 122 { 123 if (!sadb_sa) 124 return; 125 126 if (ii) { 127 ii->ii_encalg = sadb_sa->sadb_sa_encrypt; 128 ii->ii_authalg = sadb_sa->sadb_sa_auth; 129 ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */ 130 131 tdb->tdb_spi = sadb_sa->sadb_sa_spi; 132 tdb->tdb_wnd = sadb_sa->sadb_sa_replay; 133 134 if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS) 135 tdb->tdb_flags |= TDBF_PFS; 136 137 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL) 138 tdb->tdb_flags |= TDBF_TUNNELING; 139 140 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP) 141 tdb->tdb_flags |= TDBF_UDPENCAP; 142 143 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_ESN) 144 tdb->tdb_flags |= TDBF_ESN; 145 } 146 147 if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE) 148 tdb->tdb_flags |= TDBF_INVALID; 149 } 150 151 /* 152 * Export some of the information on a TDB. 153 */ 154 void 155 export_sa(void **p, struct tdb *tdb) 156 { 157 struct sadb_sa *sadb_sa = (struct sadb_sa *) *p; 158 159 sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t); 160 161 sadb_sa->sadb_sa_spi = tdb->tdb_spi; 162 sadb_sa->sadb_sa_replay = tdb->tdb_wnd; 163 164 if (tdb->tdb_flags & TDBF_INVALID) 165 sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL; 166 else 167 sadb_sa->sadb_sa_state = SADB_SASTATE_MATURE; 168 169 if (tdb->tdb_sproto == IPPROTO_IPCOMP && 170 tdb->tdb_compalgxform != NULL) { 171 switch (tdb->tdb_compalgxform->type) { 172 case CRYPTO_DEFLATE_COMP: 173 sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE; 174 break; 175 case CRYPTO_LZS_COMP: 176 sadb_sa->sadb_sa_encrypt = SADB_X_CALG_LZS; 177 break; 178 } 179 } 180 181 if (tdb->tdb_authalgxform) { 182 switch (tdb->tdb_authalgxform->type) { 183 case CRYPTO_MD5_HMAC: 184 sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC; 185 break; 186 187 case CRYPTO_SHA1_HMAC: 188 sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC; 189 break; 190 191 case CRYPTO_RIPEMD160_HMAC: 192 sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC; 193 break; 194 195 case CRYPTO_SHA2_256_HMAC: 196 sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_256; 197 break; 198 199 case CRYPTO_SHA2_384_HMAC: 200 sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_384; 201 break; 202 203 case CRYPTO_SHA2_512_HMAC: 204 sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_512; 205 break; 206 207 case CRYPTO_AES_128_GMAC: 208 sadb_sa->sadb_sa_auth = SADB_X_AALG_AES128GMAC; 209 break; 210 211 case CRYPTO_AES_192_GMAC: 212 sadb_sa->sadb_sa_auth = SADB_X_AALG_AES192GMAC; 213 break; 214 215 case CRYPTO_AES_256_GMAC: 216 sadb_sa->sadb_sa_auth = SADB_X_AALG_AES256GMAC; 217 break; 218 219 case CRYPTO_CHACHA20_POLY1305_MAC: 220 sadb_sa->sadb_sa_auth = SADB_X_AALG_CHACHA20POLY1305; 221 break; 222 } 223 } 224 225 if (tdb->tdb_encalgxform) { 226 switch (tdb->tdb_encalgxform->type) { 227 case CRYPTO_NULL: 228 sadb_sa->sadb_sa_encrypt = SADB_EALG_NULL; 229 break; 230 231 case CRYPTO_3DES_CBC: 232 sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC; 233 break; 234 235 case CRYPTO_AES_CBC: 236 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES; 237 break; 238 239 case CRYPTO_AES_CTR: 240 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR; 241 break; 242 243 case CRYPTO_AES_GCM_16: 244 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGCM16; 245 break; 246 247 case CRYPTO_AES_GMAC: 248 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGMAC; 249 break; 250 251 case CRYPTO_CAST_CBC: 252 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST; 253 break; 254 255 case CRYPTO_BLF_CBC: 256 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF; 257 break; 258 259 case CRYPTO_CHACHA20_POLY1305: 260 sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CHACHA20POLY1305; 261 break; 262 } 263 } 264 265 if (tdb->tdb_flags & TDBF_PFS) 266 sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS; 267 268 if (tdb->tdb_flags & TDBF_TUNNELING) 269 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL; 270 271 if (tdb->tdb_flags & TDBF_UDPENCAP) 272 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP; 273 274 if (tdb->tdb_flags & TDBF_ESN) 275 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_ESN; 276 277 *p += sizeof(struct sadb_sa); 278 } 279 280 /* 281 * Initialize expirations and counters based on lifetime payload. 282 */ 283 void 284 import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type) 285 { 286 if (!sadb_lifetime) 287 return; 288 289 switch (type) { 290 case PFKEYV2_LIFETIME_HARD: 291 if ((tdb->tdb_exp_allocations = 292 sadb_lifetime->sadb_lifetime_allocations) != 0) 293 tdb->tdb_flags |= TDBF_ALLOCATIONS; 294 else 295 tdb->tdb_flags &= ~TDBF_ALLOCATIONS; 296 297 if ((tdb->tdb_exp_bytes = 298 sadb_lifetime->sadb_lifetime_bytes) != 0) 299 tdb->tdb_flags |= TDBF_BYTES; 300 else 301 tdb->tdb_flags &= ~TDBF_BYTES; 302 303 if ((tdb->tdb_exp_timeout = 304 sadb_lifetime->sadb_lifetime_addtime) != 0) { 305 tdb->tdb_flags |= TDBF_TIMER; 306 timeout_add_sec(&tdb->tdb_timer_tmo, 307 tdb->tdb_exp_timeout); 308 } else 309 tdb->tdb_flags &= ~TDBF_TIMER; 310 311 if ((tdb->tdb_exp_first_use = 312 sadb_lifetime->sadb_lifetime_usetime) != 0) 313 tdb->tdb_flags |= TDBF_FIRSTUSE; 314 else 315 tdb->tdb_flags &= ~TDBF_FIRSTUSE; 316 break; 317 318 case PFKEYV2_LIFETIME_SOFT: 319 if ((tdb->tdb_soft_allocations = 320 sadb_lifetime->sadb_lifetime_allocations) != 0) 321 tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS; 322 else 323 tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS; 324 325 if ((tdb->tdb_soft_bytes = 326 sadb_lifetime->sadb_lifetime_bytes) != 0) 327 tdb->tdb_flags |= TDBF_SOFT_BYTES; 328 else 329 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; 330 331 if ((tdb->tdb_soft_timeout = 332 sadb_lifetime->sadb_lifetime_addtime) != 0) { 333 tdb->tdb_flags |= TDBF_SOFT_TIMER; 334 timeout_add_sec(&tdb->tdb_stimer_tmo, 335 tdb->tdb_soft_timeout); 336 } else 337 tdb->tdb_flags &= ~TDBF_SOFT_TIMER; 338 339 if ((tdb->tdb_soft_first_use = 340 sadb_lifetime->sadb_lifetime_usetime) != 0) 341 tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE; 342 else 343 tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE; 344 break; 345 346 case PFKEYV2_LIFETIME_CURRENT: /* Nothing fancy here. */ 347 tdb->tdb_cur_allocations = 348 sadb_lifetime->sadb_lifetime_allocations; 349 tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes; 350 tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime; 351 tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime; 352 } 353 } 354 355 /* 356 * Export TDB expiration information. 357 */ 358 void 359 export_lifetime(void **p, struct tdb *tdb, int type) 360 { 361 struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p; 362 363 sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / 364 sizeof(uint64_t); 365 366 switch (type) { 367 case PFKEYV2_LIFETIME_HARD: 368 if (tdb->tdb_flags & TDBF_ALLOCATIONS) 369 sadb_lifetime->sadb_lifetime_allocations = 370 tdb->tdb_exp_allocations; 371 372 if (tdb->tdb_flags & TDBF_BYTES) 373 sadb_lifetime->sadb_lifetime_bytes = 374 tdb->tdb_exp_bytes; 375 376 if (tdb->tdb_flags & TDBF_TIMER) 377 sadb_lifetime->sadb_lifetime_addtime = 378 tdb->tdb_exp_timeout; 379 380 if (tdb->tdb_flags & TDBF_FIRSTUSE) 381 sadb_lifetime->sadb_lifetime_usetime = 382 tdb->tdb_exp_first_use; 383 break; 384 385 case PFKEYV2_LIFETIME_SOFT: 386 if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS) 387 sadb_lifetime->sadb_lifetime_allocations = 388 tdb->tdb_soft_allocations; 389 390 if (tdb->tdb_flags & TDBF_SOFT_BYTES) 391 sadb_lifetime->sadb_lifetime_bytes = 392 tdb->tdb_soft_bytes; 393 394 if (tdb->tdb_flags & TDBF_SOFT_TIMER) 395 sadb_lifetime->sadb_lifetime_addtime = 396 tdb->tdb_soft_timeout; 397 398 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) 399 sadb_lifetime->sadb_lifetime_usetime = 400 tdb->tdb_soft_first_use; 401 break; 402 403 case PFKEYV2_LIFETIME_CURRENT: 404 sadb_lifetime->sadb_lifetime_allocations = 405 tdb->tdb_cur_allocations; 406 sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes; 407 sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established; 408 sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use; 409 break; 410 411 case PFKEYV2_LIFETIME_LASTUSE: 412 sadb_lifetime->sadb_lifetime_allocations = 0; 413 sadb_lifetime->sadb_lifetime_bytes = 0; 414 sadb_lifetime->sadb_lifetime_addtime = 0; 415 sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used; 416 break; 417 } 418 419 *p += sizeof(struct sadb_lifetime); 420 } 421 422 /* 423 * Import flow information to two struct sockaddr_encap's. Either 424 * all or none of the address arguments are NULL. 425 */ 426 void 427 import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask, 428 struct sadb_address *ssrc, struct sadb_address *ssrcmask, 429 struct sadb_address *ddst, struct sadb_address *ddstmask, 430 struct sadb_protocol *sab, struct sadb_protocol *ftype) 431 { 432 u_int8_t transproto = 0; 433 union sockaddr_union *src = (union sockaddr_union *)(ssrc + 1); 434 union sockaddr_union *dst = (union sockaddr_union *)(ddst + 1); 435 union sockaddr_union *srcmask = (union sockaddr_union *)(ssrcmask + 1); 436 union sockaddr_union *dstmask = (union sockaddr_union *)(ddstmask + 1); 437 438 if (ssrc == NULL) 439 return; /* There wasn't any information to begin with. */ 440 441 bzero(flow, sizeof(*flow)); 442 bzero(flowmask, sizeof(*flowmask)); 443 444 if (sab != NULL) 445 transproto = sab->sadb_protocol_proto; 446 447 /* 448 * Check that all the address families match. We know they are 449 * valid and supported because pfkeyv2_parsemessage() checked that. 450 */ 451 if ((src->sa.sa_family != dst->sa.sa_family) || 452 (src->sa.sa_family != srcmask->sa.sa_family) || 453 (src->sa.sa_family != dstmask->sa.sa_family)) 454 return; 455 456 /* 457 * We set these as an indication that tdb_filter/tdb_filtermask are 458 * in fact initialized. 459 */ 460 flow->sen_family = flowmask->sen_family = PF_KEY; 461 flow->sen_len = flowmask->sen_len = SENT_LEN; 462 463 switch (src->sa.sa_family) { 464 case AF_INET: 465 /* netmask handling */ 466 rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa); 467 rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa); 468 469 flow->sen_type = SENT_IP4; 470 flow->sen_direction = ftype->sadb_protocol_direction; 471 flow->sen_ip_src = src->sin.sin_addr; 472 flow->sen_ip_dst = dst->sin.sin_addr; 473 flow->sen_proto = transproto; 474 flow->sen_sport = src->sin.sin_port; 475 flow->sen_dport = dst->sin.sin_port; 476 477 flowmask->sen_type = SENT_IP4; 478 flowmask->sen_direction = 0xff; 479 flowmask->sen_ip_src = srcmask->sin.sin_addr; 480 flowmask->sen_ip_dst = dstmask->sin.sin_addr; 481 flowmask->sen_sport = srcmask->sin.sin_port; 482 flowmask->sen_dport = dstmask->sin.sin_port; 483 if (transproto) 484 flowmask->sen_proto = 0xff; 485 break; 486 487 #ifdef INET6 488 case AF_INET6: 489 in6_embedscope(&src->sin6.sin6_addr, &src->sin6, 490 NULL); 491 in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6, 492 NULL); 493 494 /* netmask handling */ 495 rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa); 496 rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa); 497 498 flow->sen_type = SENT_IP6; 499 flow->sen_ip6_direction = ftype->sadb_protocol_direction; 500 flow->sen_ip6_src = src->sin6.sin6_addr; 501 flow->sen_ip6_dst = dst->sin6.sin6_addr; 502 flow->sen_ip6_proto = transproto; 503 flow->sen_ip6_sport = src->sin6.sin6_port; 504 flow->sen_ip6_dport = dst->sin6.sin6_port; 505 506 flowmask->sen_type = SENT_IP6; 507 flowmask->sen_ip6_direction = 0xff; 508 flowmask->sen_ip6_src = srcmask->sin6.sin6_addr; 509 flowmask->sen_ip6_dst = dstmask->sin6.sin6_addr; 510 flowmask->sen_ip6_sport = srcmask->sin6.sin6_port; 511 flowmask->sen_ip6_dport = dstmask->sin6.sin6_port; 512 if (transproto) 513 flowmask->sen_ip6_proto = 0xff; 514 break; 515 #endif /* INET6 */ 516 } 517 } 518 519 /* 520 * Helper to export addresses from an struct sockaddr_encap. 521 */ 522 static void 523 export_encap(void **p, struct sockaddr_encap *encap, int type) 524 { 525 struct sadb_address *saddr = (struct sadb_address *)*p; 526 union sockaddr_union *sunion; 527 528 *p += sizeof(struct sadb_address); 529 sunion = (union sockaddr_union *)*p; 530 531 switch (encap->sen_type) { 532 case SENT_IP4: 533 saddr->sadb_address_len = (sizeof(struct sadb_address) + 534 PADUP(sizeof(struct sockaddr_in))) / sizeof(uint64_t); 535 sunion->sa.sa_len = sizeof(struct sockaddr_in); 536 sunion->sa.sa_family = AF_INET; 537 if (type == SADB_X_EXT_SRC_FLOW || 538 type == SADB_X_EXT_SRC_MASK) { 539 sunion->sin.sin_addr = encap->sen_ip_src; 540 sunion->sin.sin_port = encap->sen_sport; 541 } else { 542 sunion->sin.sin_addr = encap->sen_ip_dst; 543 sunion->sin.sin_port = encap->sen_dport; 544 } 545 *p += PADUP(sizeof(struct sockaddr_in)); 546 break; 547 case SENT_IP6: 548 saddr->sadb_address_len = (sizeof(struct sadb_address) 549 + PADUP(sizeof(struct sockaddr_in6))) / sizeof(uint64_t); 550 sunion->sa.sa_len = sizeof(struct sockaddr_in6); 551 sunion->sa.sa_family = AF_INET6; 552 if (type == SADB_X_EXT_SRC_FLOW || 553 type == SADB_X_EXT_SRC_MASK) { 554 sunion->sin6.sin6_addr = encap->sen_ip6_src; 555 sunion->sin6.sin6_port = encap->sen_ip6_sport; 556 } else { 557 sunion->sin6.sin6_addr = encap->sen_ip6_dst; 558 sunion->sin6.sin6_port = encap->sen_ip6_dport; 559 } 560 *p += PADUP(sizeof(struct sockaddr_in6)); 561 break; 562 } 563 } 564 565 /* 566 * Export flow information from two struct sockaddr_encap's. 567 */ 568 void 569 export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow, 570 struct sockaddr_encap *flowmask, void **headers) 571 { 572 struct sadb_protocol *sab; 573 574 headers[SADB_X_EXT_FLOW_TYPE] = *p; 575 sab = (struct sadb_protocol *)*p; 576 sab->sadb_protocol_len = sizeof(struct sadb_protocol) / 577 sizeof(uint64_t); 578 579 switch (ftype) { 580 case IPSP_IPSEC_USE: 581 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE; 582 break; 583 case IPSP_IPSEC_ACQUIRE: 584 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE; 585 break; 586 case IPSP_IPSEC_REQUIRE: 587 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE; 588 break; 589 case IPSP_DENY: 590 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY; 591 break; 592 case IPSP_PERMIT: 593 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS; 594 break; 595 case IPSP_IPSEC_DONTACQ: 596 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ; 597 break; 598 default: 599 sab->sadb_protocol_proto = 0; 600 break; 601 } 602 603 switch (flow->sen_type) { 604 case SENT_IP4: 605 sab->sadb_protocol_direction = flow->sen_direction; 606 break; 607 #ifdef INET6 608 case SENT_IP6: 609 sab->sadb_protocol_direction = flow->sen_ip6_direction; 610 break; 611 #endif /* INET6 */ 612 } 613 *p += sizeof(struct sadb_protocol); 614 615 headers[SADB_X_EXT_PROTOCOL] = *p; 616 sab = (struct sadb_protocol *)*p; 617 sab->sadb_protocol_len = sizeof(struct sadb_protocol) / 618 sizeof(uint64_t); 619 switch (flow->sen_type) { 620 case SENT_IP4: 621 sab->sadb_protocol_proto = flow->sen_proto; 622 break; 623 #ifdef INET6 624 case SENT_IP6: 625 sab->sadb_protocol_proto = flow->sen_ip6_proto; 626 break; 627 #endif /* INET6 */ 628 } 629 *p += sizeof(struct sadb_protocol); 630 631 headers[SADB_X_EXT_SRC_FLOW] = *p; 632 export_encap(p, flow, SADB_X_EXT_SRC_FLOW); 633 634 headers[SADB_X_EXT_SRC_MASK] = *p; 635 export_encap(p, flowmask, SADB_X_EXT_SRC_MASK); 636 637 headers[SADB_X_EXT_DST_FLOW] = *p; 638 export_encap(p, flow, SADB_X_EXT_DST_FLOW); 639 640 headers[SADB_X_EXT_DST_MASK] = *p; 641 export_encap(p, flowmask, SADB_X_EXT_DST_MASK); 642 } 643 644 /* 645 * Copy an SADB_ADDRESS payload to a struct sockaddr. 646 */ 647 void 648 import_address(struct sockaddr *sa, struct sadb_address *sadb_address) 649 { 650 int salen; 651 struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address + 652 sizeof(struct sadb_address)); 653 654 if (!sadb_address) 655 return; 656 657 if (ssa->sa_len) 658 salen = ssa->sa_len; 659 else 660 switch (ssa->sa_family) { 661 case AF_INET: 662 salen = sizeof(struct sockaddr_in); 663 break; 664 665 #ifdef INET6 666 case AF_INET6: 667 salen = sizeof(struct sockaddr_in6); 668 break; 669 #endif /* INET6 */ 670 671 default: 672 return; 673 } 674 675 bcopy(ssa, sa, salen); 676 sa->sa_len = salen; 677 } 678 679 /* 680 * Export a struct sockaddr as an SADB_ADDRESS payload. 681 */ 682 void 683 export_address(void **p, struct sockaddr *sa) 684 { 685 struct sadb_address *sadb_address = (struct sadb_address *) *p; 686 687 sadb_address->sadb_address_len = (sizeof(struct sadb_address) + 688 PADUP(SA_LEN(sa))) / sizeof(uint64_t); 689 690 *p += sizeof(struct sadb_address); 691 bcopy(sa, *p, SA_LEN(sa)); 692 ((struct sockaddr *) *p)->sa_family = sa->sa_family; 693 *p += PADUP(SA_LEN(sa)); 694 } 695 696 /* 697 * Import an identity payload into the TDB. 698 */ 699 static void 700 import_identity(struct ipsec_id **id, struct sadb_ident *sadb_ident) 701 { 702 if (!sadb_ident) { 703 *id = NULL; 704 return; 705 } 706 707 *id = malloc(EXTLEN(sadb_ident) - sizeof(struct sadb_ident) + 708 sizeof(struct ipsec_id), M_CREDENTIALS, M_WAITOK); 709 (*id)->len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident); 710 711 switch (sadb_ident->sadb_ident_type) { 712 case SADB_IDENTTYPE_PREFIX: 713 (*id)->type = IPSP_IDENTITY_PREFIX; 714 break; 715 case SADB_IDENTTYPE_FQDN: 716 (*id)->type = IPSP_IDENTITY_FQDN; 717 break; 718 case SADB_IDENTTYPE_USERFQDN: 719 (*id)->type = IPSP_IDENTITY_USERFQDN; 720 break; 721 default: 722 free(*id, M_CREDENTIALS, 0); 723 *id = NULL; 724 return; 725 } 726 bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*id) + 1, 727 (*id)->len); 728 } 729 730 void 731 import_identities(struct ipsec_ids **ids, int swapped, 732 struct sadb_ident *srcid, struct sadb_ident *dstid) 733 { 734 struct ipsec_ids *tmp; 735 736 *ids = NULL; 737 tmp = malloc(sizeof(struct ipsec_ids), M_CREDENTIALS, M_WAITOK); 738 import_identity(&tmp->id_local, swapped ? dstid: srcid); 739 import_identity(&tmp->id_remote, swapped ? srcid: dstid); 740 if (tmp->id_local != NULL && tmp->id_remote != NULL) { 741 *ids = ipsp_ids_insert(tmp); 742 if (*ids == tmp) 743 return; 744 } 745 free(tmp->id_local, M_CREDENTIALS, 0); 746 free(tmp->id_remote, M_CREDENTIALS, 0); 747 free(tmp, M_CREDENTIALS, 0); 748 } 749 750 static void 751 export_identity(void **p, struct ipsec_id *id) 752 { 753 struct sadb_ident *sadb_ident = (struct sadb_ident *) *p; 754 755 sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) + 756 PADUP(id->len)) / sizeof(uint64_t); 757 758 switch (id->type) { 759 case IPSP_IDENTITY_PREFIX: 760 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX; 761 break; 762 case IPSP_IDENTITY_FQDN: 763 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN; 764 break; 765 case IPSP_IDENTITY_USERFQDN: 766 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN; 767 break; 768 } 769 *p += sizeof(struct sadb_ident); 770 bcopy(id + 1, *p, id->len); 771 *p += PADUP(id->len); 772 } 773 774 void 775 export_identities(void **p, struct ipsec_ids *ids, int swapped, 776 void **headers) 777 { 778 headers[SADB_EXT_IDENTITY_SRC] = *p; 779 export_identity(p, swapped ? ids->id_remote : ids->id_local); 780 headers[SADB_EXT_IDENTITY_DST] = *p; 781 export_identity(p, swapped ? ids->id_local : ids->id_remote); 782 } 783 784 /* ... */ 785 void 786 import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type) 787 { 788 if (!sadb_key) 789 return; 790 791 if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */ 792 ii->ii_enckeylen = sadb_key->sadb_key_bits / 8; 793 ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key); 794 } else { 795 ii->ii_authkeylen = sadb_key->sadb_key_bits / 8; 796 ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key); 797 } 798 } 799 800 void 801 export_key(void **p, struct tdb *tdb, int type) 802 { 803 struct sadb_key *sadb_key = (struct sadb_key *) *p; 804 805 if (type == PFKEYV2_ENCRYPTION_KEY) { 806 sadb_key->sadb_key_len = (sizeof(struct sadb_key) + 807 PADUP(tdb->tdb_emxkeylen)) / 808 sizeof(uint64_t); 809 sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8; 810 *p += sizeof(struct sadb_key); 811 bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen); 812 *p += PADUP(tdb->tdb_emxkeylen); 813 } else { 814 sadb_key->sadb_key_len = (sizeof(struct sadb_key) + 815 PADUP(tdb->tdb_amxkeylen)) / 816 sizeof(uint64_t); 817 sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8; 818 *p += sizeof(struct sadb_key); 819 bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen); 820 *p += PADUP(tdb->tdb_amxkeylen); 821 } 822 } 823 824 /* Import/Export remote port for UDP Encapsulation */ 825 void 826 import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap) 827 { 828 if (sadb_udpencap) 829 tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port; 830 } 831 832 void 833 export_udpencap(void **p, struct tdb *tdb) 834 { 835 struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p; 836 837 sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port; 838 sadb_udpencap->sadb_x_udpencap_reserved = 0; 839 sadb_udpencap->sadb_x_udpencap_len = 840 sizeof(struct sadb_x_udpencap) / sizeof(uint64_t); 841 *p += sizeof(struct sadb_x_udpencap); 842 } 843 844 #if NPF > 0 845 /* Import PF tag information for SA */ 846 void 847 import_tag(struct tdb *tdb, struct sadb_x_tag *stag) 848 { 849 char *s; 850 851 if (stag) { 852 s = (char *)(stag + 1); 853 tdb->tdb_tag = pf_tagname2tag(s, 1); 854 } 855 } 856 857 /* Export PF tag information for SA */ 858 void 859 export_tag(void **p, struct tdb *tdb) 860 { 861 struct sadb_x_tag *stag = (struct sadb_x_tag *)*p; 862 char *s = (char *)(stag + 1); 863 864 pf_tag2tagname(tdb->tdb_tag, s); 865 866 stag->sadb_x_tag_taglen = strlen(s) + 1; 867 stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) + 868 PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t); 869 *p += sizeof(struct sadb_x_tag) + PADUP(stag->sadb_x_tag_taglen); 870 } 871 872 /* Import enc(4) tap device information for SA */ 873 void 874 import_tap(struct tdb *tdb, struct sadb_x_tap *stap) 875 { 876 if (stap) 877 tdb->tdb_tap = stap->sadb_x_tap_unit; 878 } 879 880 /* Export enc(4) tap device information for SA */ 881 void 882 export_tap(void **p, struct tdb *tdb) 883 { 884 struct sadb_x_tap *stag = (struct sadb_x_tap *)*p; 885 886 stag->sadb_x_tap_unit = tdb->tdb_tap; 887 stag->sadb_x_tap_len = sizeof(struct sadb_x_tap) / sizeof(uint64_t); 888 *p += sizeof(struct sadb_x_tap); 889 } 890 #endif 891