1/* $NetBSD: pfkey.c,v 1.13.4.2 2007/10/15 16:05:22 vanhu Exp $ */ 2 3/* $KAME: pfkey.c,v 1.47 2003/10/02 19:52:12 itojun Exp $ */ 4 5/* 6 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifdef HAVE_CONFIG_H 35#include "config.h" 36#endif 37 38#include <sys/types.h> 39#include <sys/param.h> 40#include <sys/socket.h> 41#include <net/pfkeyv2.h> 42#include <netinet/in.h> 43#include PATH_IPSEC_H 44 45#include <stdlib.h> 46#include <unistd.h> 47#include <string.h> 48#include <errno.h> 49#include <stdio.h> 50 51#include "ipsec_strerror.h" 52#include "libpfkey.h" 53 54#define CALLOC(size, cast) (cast)calloc(1, (size)) 55 56static int findsupportedmap __P((int)); 57static int setsupportedmap __P((struct sadb_supported *)); 58static struct sadb_alg *findsupportedalg __P((u_int, u_int)); 59static int pfkey_send_x1 __P((struct pfkey_send_sa_args *)); 60static int pfkey_send_x2 __P((int, u_int, u_int, u_int, 61 struct sockaddr *, struct sockaddr *, u_int32_t)); 62static int pfkey_send_x3 __P((int, u_int, u_int)); 63static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int, 64 struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t, 65 char *, int, u_int32_t)); 66static int pfkey_send_x5 __P((int, u_int, u_int32_t)); 67 68static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int, 69 u_int, u_int32_t, pid_t)); 70static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int, 71 u_int, u_int, u_int32_t)); 72static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int, 73 struct sockaddr *, u_int, u_int)); 74static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int)); 75static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t, 76 u_int32_t, u_int32_t, u_int32_t)); 77static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t)); 78 79#ifdef SADB_X_EXT_NAT_T_TYPE 80static caddr_t pfkey_set_natt_type __P((caddr_t, caddr_t, u_int, u_int8_t)); 81static caddr_t pfkey_set_natt_port __P((caddr_t, caddr_t, u_int, u_int16_t)); 82#endif 83#ifdef SADB_X_EXT_NAT_T_FRAG 84static caddr_t pfkey_set_natt_frag __P((caddr_t, caddr_t, u_int, u_int16_t)); 85#endif 86 87#ifdef SADB_X_EXT_SEC_CTX 88static caddr_t pfkey_setsecctx __P((caddr_t, caddr_t, u_int, u_int8_t, u_int8_t, 89 caddr_t, u_int16_t)); 90#endif 91 92int libipsec_opt = 0 93#ifdef SADB_X_EXT_NAT_T_TYPE 94 | LIBIPSEC_OPT_NATT 95#endif 96#ifdef SADB_X_EXT_NAT_T_FRAG 97 | LIBIPSEC_OPT_FRAG 98#endif 99#ifdef SADB_X_EXT_NAT_T_SEC_CTX 100 | LIBIPSEC_OPT_SEC_CTX 101#endif 102 ; 103 104/* 105 * make and search supported algorithm structure. 106 */ 107static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, 108#ifdef SADB_X_SATYPE_TCPSIGNATURE 109 NULL, 110#endif 111}; 112 113static int supported_map[] = { 114 SADB_SATYPE_AH, 115 SADB_SATYPE_ESP, 116 SADB_X_SATYPE_IPCOMP, 117#ifdef SADB_X_SATYPE_TCPSIGNATURE 118 SADB_X_SATYPE_TCPSIGNATURE, 119#endif 120}; 121 122static int 123findsupportedmap(satype) 124 int satype; 125{ 126 int i; 127 128 for (i = 0; i < sizeof(supported_map)/sizeof(supported_map[0]); i++) 129 if (supported_map[i] == satype) 130 return i; 131 return -1; 132} 133 134static struct sadb_alg * 135findsupportedalg(satype, alg_id) 136 u_int satype, alg_id; 137{ 138 int algno; 139 int tlen; 140 caddr_t p; 141 142 /* validity check */ 143 algno = findsupportedmap((int)satype); 144 if (algno == -1) { 145 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 146 return NULL; 147 } 148 if (ipsec_supported[algno] == NULL) { 149 __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST; 150 return NULL; 151 } 152 153 tlen = ipsec_supported[algno]->sadb_supported_len 154 - sizeof(struct sadb_supported); 155 p = (void *)(ipsec_supported[algno] + 1); 156 while (tlen > 0) { 157 if (tlen < sizeof(struct sadb_alg)) { 158 /* invalid format */ 159 break; 160 } 161 if (((struct sadb_alg *)(void *)p)->sadb_alg_id == alg_id) 162 return (void *)p; 163 164 tlen -= sizeof(struct sadb_alg); 165 p += sizeof(struct sadb_alg); 166 } 167 168 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 169 return NULL; 170} 171 172static int 173setsupportedmap(sup) 174 struct sadb_supported *sup; 175{ 176 struct sadb_supported **ipsup; 177 178 switch (sup->sadb_supported_exttype) { 179 case SADB_EXT_SUPPORTED_AUTH: 180 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_AH)]; 181 break; 182 case SADB_EXT_SUPPORTED_ENCRYPT: 183 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_ESP)]; 184 break; 185 default: 186 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 187 return -1; 188 } 189 190 if (*ipsup) 191 free(*ipsup); 192 193 *ipsup = malloc((size_t)sup->sadb_supported_len); 194 if (!*ipsup) { 195 __ipsec_set_strerror(strerror(errno)); 196 return -1; 197 } 198 memcpy(*ipsup, sup, (size_t)sup->sadb_supported_len); 199 200 return 0; 201} 202 203/* 204 * check key length against algorithm specified. 205 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the 206 * augument, and only calls to ipsec_check_keylen2(); 207 * keylen is the unit of bit. 208 * OUT: 209 * -1: invalid. 210 * 0: valid. 211 */ 212int 213ipsec_check_keylen(supported, alg_id, keylen) 214 u_int supported; 215 u_int alg_id; 216 u_int keylen; 217{ 218 u_int satype; 219 220 /* validity check */ 221 switch (supported) { 222 case SADB_EXT_SUPPORTED_AUTH: 223 satype = SADB_SATYPE_AH; 224 break; 225 case SADB_EXT_SUPPORTED_ENCRYPT: 226 satype = SADB_SATYPE_ESP; 227 break; 228 default: 229 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 230 return -1; 231 } 232 233 return ipsec_check_keylen2(satype, alg_id, keylen); 234} 235 236/* 237 * check key length against algorithm specified. 238 * satype is one of satype defined at pfkeyv2.h. 239 * keylen is the unit of bit. 240 * OUT: 241 * -1: invalid. 242 * 0: valid. 243 */ 244int 245ipsec_check_keylen2(satype, alg_id, keylen) 246 u_int satype; 247 u_int alg_id; 248 u_int keylen; 249{ 250 struct sadb_alg *alg; 251 252 alg = findsupportedalg(satype, alg_id); 253 if (!alg) 254 return -1; 255 256 if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) { 257 fprintf(stderr, "%d %d %d\n", keylen, alg->sadb_alg_minbits, 258 alg->sadb_alg_maxbits); 259 __ipsec_errcode = EIPSEC_INVAL_KEYLEN; 260 return -1; 261 } 262 263 __ipsec_errcode = EIPSEC_NO_ERROR; 264 return 0; 265} 266 267/* 268 * get max/min key length against algorithm specified. 269 * satype is one of satype defined at pfkeyv2.h. 270 * keylen is the unit of bit. 271 * OUT: 272 * -1: invalid. 273 * 0: valid. 274 */ 275int 276ipsec_get_keylen(supported, alg_id, alg0) 277 u_int supported, alg_id; 278 struct sadb_alg *alg0; 279{ 280 struct sadb_alg *alg; 281 u_int satype; 282 283 /* validity check */ 284 if (!alg0) { 285 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 286 return -1; 287 } 288 289 switch (supported) { 290 case SADB_EXT_SUPPORTED_AUTH: 291 satype = SADB_SATYPE_AH; 292 break; 293 case SADB_EXT_SUPPORTED_ENCRYPT: 294 satype = SADB_SATYPE_ESP; 295 break; 296 default: 297 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 298 return -1; 299 } 300 301 alg = findsupportedalg(satype, alg_id); 302 if (!alg) 303 return -1; 304 305 memcpy(alg0, alg, sizeof(*alg0)); 306 307 __ipsec_errcode = EIPSEC_NO_ERROR; 308 return 0; 309} 310 311/* 312 * set the rate for SOFT lifetime against HARD one. 313 * If rate is more than 100 or equal to zero, then set to 100. 314 */ 315static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE; 316static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE; 317static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE; 318static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE; 319 320u_int 321pfkey_set_softrate(type, rate) 322 u_int type, rate; 323{ 324 __ipsec_errcode = EIPSEC_NO_ERROR; 325 326 if (rate > 100 || rate == 0) 327 rate = 100; 328 329 switch (type) { 330 case SADB_X_LIFETIME_ALLOCATIONS: 331 soft_lifetime_allocations_rate = rate; 332 return 0; 333 case SADB_X_LIFETIME_BYTES: 334 soft_lifetime_bytes_rate = rate; 335 return 0; 336 case SADB_X_LIFETIME_ADDTIME: 337 soft_lifetime_addtime_rate = rate; 338 return 0; 339 case SADB_X_LIFETIME_USETIME: 340 soft_lifetime_usetime_rate = rate; 341 return 0; 342 } 343 344 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 345 return 1; 346} 347 348/* 349 * get current rate for SOFT lifetime against HARD one. 350 * ATTENTION: ~0 is returned if invalid type was passed. 351 */ 352u_int 353pfkey_get_softrate(type) 354 u_int type; 355{ 356 switch (type) { 357 case SADB_X_LIFETIME_ALLOCATIONS: 358 return soft_lifetime_allocations_rate; 359 case SADB_X_LIFETIME_BYTES: 360 return soft_lifetime_bytes_rate; 361 case SADB_X_LIFETIME_ADDTIME: 362 return soft_lifetime_addtime_rate; 363 case SADB_X_LIFETIME_USETIME: 364 return soft_lifetime_usetime_rate; 365 } 366 367 return (u_int)~0; 368} 369 370/* 371 * sending SADB_GETSPI message to the kernel. 372 * OUT: 373 * positive: success and return length sent. 374 * -1 : error occured, and set errno. 375 */ 376int 377pfkey_send_getspi(int so, u_int satype, u_int mode, struct sockaddr *src, 378 struct sockaddr *dst, u_int32_t min, u_int32_t max, u_int32_t reqid, 379 u_int32_t seq) 380{ 381 struct sadb_msg *newmsg; 382 caddr_t ep; 383 int len; 384 int need_spirange = 0; 385 caddr_t p; 386 int plen; 387 388 /* validity check */ 389 if (src == NULL || dst == NULL) { 390 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 391 return -1; 392 } 393 if (src->sa_family != dst->sa_family) { 394 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 395 return -1; 396 } 397 if (min > max || (min > 0 && min <= 255)) { 398 __ipsec_errcode = EIPSEC_INVAL_SPI; 399 return -1; 400 } 401 switch (src->sa_family) { 402 case AF_INET: 403 plen = sizeof(struct in_addr) << 3; 404 break; 405 case AF_INET6: 406 plen = sizeof(struct in6_addr) << 3; 407 break; 408 default: 409 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 410 return -1; 411 } 412 413 /* create new sadb_msg to send. */ 414 len = sizeof(struct sadb_msg) 415 + sizeof(struct sadb_x_sa2) 416 + sizeof(struct sadb_address) 417 + PFKEY_ALIGN8(sysdep_sa_len(src)) 418 + sizeof(struct sadb_address) 419 + PFKEY_ALIGN8(sysdep_sa_len(dst)); 420 421 if (min > 255 && max < (u_int)~0) { 422 need_spirange++; 423 len += sizeof(struct sadb_spirange); 424 } 425 426 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 427 __ipsec_set_strerror(strerror(errno)); 428 return -1; 429 } 430 ep = ((caddr_t)(void *)newmsg) + len; 431 432 p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_GETSPI, 433 (u_int)len, satype, seq, getpid()); 434 if (!p) { 435 free(newmsg); 436 return -1; 437 } 438 439 p = pfkey_setsadbxsa2(p, ep, mode, reqid); 440 if (!p) { 441 free(newmsg); 442 return -1; 443 } 444 445 /* set sadb_address for source */ 446 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, 447 IPSEC_ULPROTO_ANY); 448 if (!p) { 449 free(newmsg); 450 return -1; 451 } 452 453 /* set sadb_address for destination */ 454 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, 455 IPSEC_ULPROTO_ANY); 456 if (!p) { 457 free(newmsg); 458 return -1; 459 } 460 461 /* proccessing spi range */ 462 if (need_spirange) { 463 struct sadb_spirange spirange; 464 465 if (p + sizeof(spirange) > ep) { 466 free(newmsg); 467 return -1; 468 } 469 470 memset(&spirange, 0, sizeof(spirange)); 471 spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange)); 472 spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE; 473 spirange.sadb_spirange_min = min; 474 spirange.sadb_spirange_max = max; 475 476 memcpy(p, &spirange, sizeof(spirange)); 477 478 p += sizeof(spirange); 479 } 480 if (p != ep) { 481 free(newmsg); 482 return -1; 483 } 484 485 /* send message */ 486 len = pfkey_send(so, newmsg, len); 487 free(newmsg); 488 489 if (len < 0) 490 return -1; 491 492 __ipsec_errcode = EIPSEC_NO_ERROR; 493 return len; 494} 495 496/* 497 * sending SADB_UPDATE message to the kernel. 498 * The length of key material is a_keylen + e_keylen. 499 * OUT: 500 * positive: success and return length sent. 501 * -1 : error occured, and set errno. 502 */ 503int 504pfkey_send_update2(struct pfkey_send_sa_args *sa_parms) 505{ 506 int len; 507 508 509 sa_parms->type = SADB_UPDATE; 510 if ((len = pfkey_send_x1(sa_parms)) < 0) 511 return -1; 512 513 return len; 514} 515 516/* 517 * sending SADB_ADD message to the kernel. 518 * The length of key material is a_keylen + e_keylen. 519 * OUT: 520 * positive: success and return length sent. 521 * -1 : error occured, and set errno. 522 */ 523int 524pfkey_send_add2(struct pfkey_send_sa_args *sa_parms) 525{ 526 int len; 527 528 sa_parms->type = SADB_ADD; 529 if ((len = pfkey_send_x1(sa_parms)) < 0) 530 return -1; 531 532 return len; 533} 534 535/* 536 * sending SADB_DELETE message to the kernel. 537 * OUT: 538 * positive: success and return length sent. 539 * -1 : error occured, and set errno. 540 */ 541int 542pfkey_send_delete(int so, u_int satype, u_int mode, struct sockaddr *src, 543 struct sockaddr *dst, u_int32_t spi) 544{ 545 int len; 546 if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0) 547 return -1; 548 549 return len; 550} 551 552/* 553 * sending SADB_DELETE without spi to the kernel. This is 554 * the "delete all" request (an extension also present in 555 * Solaris). 556 * 557 * OUT: 558 * positive: success and return length sent 559 * -1 : error occured, and set errno 560 */ 561/*ARGSUSED*/ 562int 563pfkey_send_delete_all(int so, u_int satype, u_int mode, struct sockaddr *src, 564 struct sockaddr *dst) 565{ 566 struct sadb_msg *newmsg; 567 int len; 568 caddr_t p; 569 int plen; 570 caddr_t ep; 571 572 /* validity check */ 573 if (src == NULL || dst == NULL) { 574 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 575 return -1; 576 } 577 if (src->sa_family != dst->sa_family) { 578 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 579 return -1; 580 } 581 switch (src->sa_family) { 582 case AF_INET: 583 plen = sizeof(struct in_addr) << 3; 584 break; 585 case AF_INET6: 586 plen = sizeof(struct in6_addr) << 3; 587 break; 588 default: 589 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 590 return -1; 591 } 592 593 /* create new sadb_msg to reply. */ 594 len = sizeof(struct sadb_msg) 595 + sizeof(struct sadb_address) 596 + PFKEY_ALIGN8(sysdep_sa_len(src)) 597 + sizeof(struct sadb_address) 598 + PFKEY_ALIGN8(sysdep_sa_len(dst)); 599 600 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 601 __ipsec_set_strerror(strerror(errno)); 602 return -1; 603 } 604 ep = ((caddr_t)(void *)newmsg) + len; 605 606 p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_DELETE, (u_int)len, 607 satype, 0, getpid()); 608 if (!p) { 609 free(newmsg); 610 return -1; 611 } 612 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, 613 IPSEC_ULPROTO_ANY); 614 if (!p) { 615 free(newmsg); 616 return -1; 617 } 618 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, 619 IPSEC_ULPROTO_ANY); 620 if (!p || p != ep) { 621 free(newmsg); 622 return -1; 623 } 624 625 /* send message */ 626 len = pfkey_send(so, newmsg, len); 627 free(newmsg); 628 629 if (len < 0) 630 return -1; 631 632 __ipsec_errcode = EIPSEC_NO_ERROR; 633 return len; 634} 635 636/* 637 * sending SADB_GET message to the kernel. 638 * OUT: 639 * positive: success and return length sent. 640 * -1 : error occured, and set errno. 641 */ 642int 643pfkey_send_get(int so, u_int satype, u_int mode, struct sockaddr *src, 644 struct sockaddr *dst, u_int32_t spi) 645{ 646 int len; 647 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) 648 return -1; 649 650 return len; 651} 652 653/* 654 * sending SADB_REGISTER message to the kernel. 655 * OUT: 656 * positive: success and return length sent. 657 * -1 : error occured, and set errno. 658 */ 659int 660pfkey_send_register(int so, u_int satype) 661{ 662 int len, algno; 663 664 if (satype == PF_UNSPEC) { 665 for (algno = 0; 666 algno < sizeof(supported_map)/sizeof(supported_map[0]); 667 algno++) { 668 if (ipsec_supported[algno]) { 669 free(ipsec_supported[algno]); 670 ipsec_supported[algno] = NULL; 671 } 672 } 673 } else { 674 algno = findsupportedmap((int)satype); 675 if (algno == -1) { 676 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 677 return -1; 678 } 679 680 if (ipsec_supported[algno]) { 681 free(ipsec_supported[algno]); 682 ipsec_supported[algno] = NULL; 683 } 684 } 685 686 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0) 687 return -1; 688 689 return len; 690} 691 692/* 693 * receiving SADB_REGISTER message from the kernel, and copy buffer for 694 * sadb_supported returned into ipsec_supported. 695 * OUT: 696 * 0: success and return length sent. 697 * -1: error occured, and set errno. 698 */ 699int 700pfkey_recv_register(int so) 701{ 702 pid_t pid = getpid(); 703 struct sadb_msg *newmsg; 704 int error = -1; 705 706 /* receive message */ 707 for (;;) { 708 if ((newmsg = pfkey_recv(so)) == NULL) 709 return -1; 710 if (newmsg->sadb_msg_type == SADB_REGISTER && 711 newmsg->sadb_msg_pid == pid) 712 break; 713 free(newmsg); 714 } 715 716 /* check and fix */ 717 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); 718 719 error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len); 720 free(newmsg); 721 722 if (error == 0) 723 __ipsec_errcode = EIPSEC_NO_ERROR; 724 725 return error; 726} 727 728/* 729 * receiving SADB_REGISTER message from the kernel, and copy buffer for 730 * sadb_supported returned into ipsec_supported. 731 * NOTE: sadb_msg_len must be host order. 732 * IN: 733 * tlen: msg length, it's to makeing sure. 734 * OUT: 735 * 0: success and return length sent. 736 * -1: error occured, and set errno. 737 */ 738int 739pfkey_set_supported(struct sadb_msg *msg, int tlen) 740{ 741 struct sadb_supported *sup; 742 caddr_t p; 743 caddr_t ep; 744 745 /* validity */ 746 if (msg->sadb_msg_len != tlen) { 747 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 748 return -1; 749 } 750 751 p = (void *)msg; 752 ep = p + tlen; 753 754 p += sizeof(struct sadb_msg); 755 756 while (p < ep) { 757 sup = (void *)p; 758 if (ep < p + sizeof(*sup) || 759 PFKEY_EXTLEN(sup) < sizeof(*sup) || 760 ep < p + sup->sadb_supported_len) { 761 /* invalid format */ 762 break; 763 } 764 765 switch (sup->sadb_supported_exttype) { 766 case SADB_EXT_SUPPORTED_AUTH: 767 case SADB_EXT_SUPPORTED_ENCRYPT: 768 break; 769 default: 770 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 771 return -1; 772 } 773 774 /* fixed length */ 775 sup->sadb_supported_len = PFKEY_EXTLEN(sup); 776 777 /* set supported map */ 778 if (setsupportedmap(sup) != 0) 779 return -1; 780 781 p += sup->sadb_supported_len; 782 } 783 784 if (p != ep) { 785 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 786 return -1; 787 } 788 789 __ipsec_errcode = EIPSEC_NO_ERROR; 790 791 return 0; 792} 793 794/* 795 * sending SADB_FLUSH message to the kernel. 796 * OUT: 797 * positive: success and return length sent. 798 * -1 : error occured, and set errno. 799 */ 800int 801pfkey_send_flush(int so, u_int satype) 802{ 803 int len; 804 805 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0) 806 return -1; 807 808 return len; 809} 810 811/* 812 * sending SADB_DUMP message to the kernel. 813 * OUT: 814 * positive: success and return length sent. 815 * -1 : error occured, and set errno. 816 */ 817int 818pfkey_send_dump(int so, u_int satype) 819{ 820 int len; 821 822 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0) 823 return -1; 824 825 return len; 826} 827 828/* 829 * sending SADB_X_PROMISC message to the kernel. 830 * NOTE that this function handles promisc mode toggle only. 831 * IN: 832 * flag: set promisc off if zero, set promisc on if non-zero. 833 * OUT: 834 * positive: success and return length sent. 835 * -1 : error occured, and set errno. 836 * 0 : error occured, and set errno. 837 * others: a pointer to new allocated buffer in which supported 838 * algorithms is. 839 */ 840int 841pfkey_send_promisc_toggle(int so, int flag) 842{ 843 int len; 844 845 if ((len = pfkey_send_x3(so, SADB_X_PROMISC, 846 (u_int)(flag ? 1 : 0))) < 0) 847 return -1; 848 849 return len; 850} 851 852/* 853 * sending SADB_X_SPDADD message to the kernel. 854 * OUT: 855 * positive: success and return length sent. 856 * -1 : error occured, and set errno. 857 */ 858int 859pfkey_send_spdadd(int so, struct sockaddr *src, u_int prefs, 860 struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy, 861 int policylen, u_int32_t seq) 862{ 863 int len; 864 865 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 866 src, prefs, dst, prefd, proto, 867 (u_int64_t)0, (u_int64_t)0, 868 policy, policylen, seq)) < 0) 869 return -1; 870 871 return len; 872} 873 874/* 875 * sending SADB_X_SPDADD message to the kernel. 876 * OUT: 877 * positive: success and return length sent. 878 * -1 : error occured, and set errno. 879 */ 880int 881pfkey_send_spdadd2(int so, struct sockaddr *src, u_int prefs, 882 struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime, 883 u_int64_t vtime, caddr_t policy, int policylen, u_int32_t seq) 884{ 885 int len; 886 887 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 888 src, prefs, dst, prefd, proto, 889 ltime, vtime, 890 policy, policylen, seq)) < 0) 891 return -1; 892 893 return len; 894} 895 896/* 897 * sending SADB_X_SPDUPDATE message to the kernel. 898 * OUT: 899 * positive: success and return length sent. 900 * -1 : error occured, and set errno. 901 */ 902int 903pfkey_send_spdupdate(int so, struct sockaddr *src, u_int prefs, 904 struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy, 905 int policylen, u_int32_t seq) 906{ 907 int len; 908 909 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 910 src, prefs, dst, prefd, proto, 911 (u_int64_t)0, (u_int64_t)0, 912 policy, policylen, seq)) < 0) 913 return -1; 914 915 return len; 916} 917 918/* 919 * sending SADB_X_SPDUPDATE message to the kernel. 920 * OUT: 921 * positive: success and return length sent. 922 * -1 : error occured, and set errno. 923 */ 924int 925pfkey_send_spdupdate2(int so, struct sockaddr *src, u_int prefs, 926 struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime, 927 u_int64_t vtime, caddr_t policy, int policylen, u_int32_t seq) 928{ 929 int len; 930 931 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 932 src, prefs, dst, prefd, proto, 933 ltime, vtime, 934 policy, policylen, seq)) < 0) 935 return -1; 936 937 return len; 938} 939 940/* 941 * sending SADB_X_SPDDELETE message to the kernel. 942 * OUT: 943 * positive: success and return length sent. 944 * -1 : error occured, and set errno. 945 */ 946int 947pfkey_send_spddelete(int so, struct sockaddr *src, u_int prefs, 948 struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy, 949 int policylen, u_int32_t seq) 950{ 951 int len; 952 953 if (policylen != sizeof(struct sadb_x_policy)) { 954 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 955 return -1; 956 } 957 958 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, 959 src, prefs, dst, prefd, proto, 960 (u_int64_t)0, (u_int64_t)0, 961 policy, policylen, seq)) < 0) 962 return -1; 963 964 return len; 965} 966 967/* 968 * sending SADB_X_SPDDELETE message to the kernel. 969 * OUT: 970 * positive: success and return length sent. 971 * -1 : error occured, and set errno. 972 */ 973int 974pfkey_send_spddelete2(int so, u_int32_t spid) 975{ 976 int len; 977 978 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0) 979 return -1; 980 981 return len; 982} 983 984/* 985 * sending SADB_X_SPDGET message to the kernel. 986 * OUT: 987 * positive: success and return length sent. 988 * -1 : error occured, and set errno. 989 */ 990int 991pfkey_send_spdget(int so, u_int32_t spid) 992{ 993 int len; 994 995 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0) 996 return -1; 997 998 return len; 999} 1000 1001/* 1002 * sending SADB_X_SPDSETIDX message to the kernel. 1003 * OUT: 1004 * positive: success and return length sent. 1005 * -1 : error occured, and set errno. 1006 */ 1007int 1008pfkey_send_spdsetidx(int so, struct sockaddr *src, u_int prefs, 1009 struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy, 1010 int policylen, u_int32_t seq) 1011{ 1012 int len; 1013 1014 if (policylen != sizeof(struct sadb_x_policy)) { 1015 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1016 return -1; 1017 } 1018 1019 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, 1020 src, prefs, dst, prefd, proto, 1021 (u_int64_t)0, (u_int64_t)0, 1022 policy, policylen, seq)) < 0) 1023 return -1; 1024 1025 return len; 1026} 1027 1028/* 1029 * sending SADB_SPDFLUSH message to the kernel. 1030 * OUT: 1031 * positive: success and return length sent. 1032 * -1 : error occured, and set errno. 1033 */ 1034int 1035pfkey_send_spdflush(int so) 1036{ 1037 int len; 1038 1039 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0) 1040 return -1; 1041 1042 return len; 1043} 1044 1045/* 1046 * sending SADB_SPDDUMP message to the kernel. 1047 * OUT: 1048 * positive: success and return length sent. 1049 * -1 : error occured, and set errno. 1050 */ 1051int 1052pfkey_send_spddump(int so) 1053{ 1054 int len; 1055 1056 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0) 1057 return -1; 1058 1059 return len; 1060} 1061 1062 1063#ifdef SADB_X_MIGRATE 1064/* 1065 * sending SADB_X_MIGRATE message to the kernel. 1066 * OUT: 1067 * positive: success and return length sent. 1068 * -1 : error occured, and set errno. 1069 */ 1070int 1071pfkey_send_migrate(int so, struct sockaddr *src, u_int prefs, 1072 struct sockaddr *dst, u_int prefd, 1073 u_int proto, caddr_t policy, int policylen, u_int32_t seq) 1074{ 1075 struct sadb_msg *newmsg; 1076 int len; 1077 caddr_t p; 1078 int plen; 1079 caddr_t ep; 1080 1081 /* validity check */ 1082 if (src == NULL || dst == NULL) { 1083 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1084 return -1; 1085 } 1086 if (src->sa_family != dst->sa_family) { 1087 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1088 return -1; 1089 } 1090 1091 switch (src->sa_family) { 1092 case AF_INET: 1093 plen = sizeof(struct in_addr) << 3; 1094 break; 1095 case AF_INET6: 1096 plen = sizeof(struct in6_addr) << 3; 1097 break; 1098 default: 1099 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1100 return -1; 1101 } 1102 if (prefs > plen || prefd > plen) { 1103 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; 1104 return -1; 1105 } 1106 1107 /* create new sadb_msg to reply. */ 1108 len = sizeof(struct sadb_msg) 1109 + sizeof(struct sadb_address) 1110 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1111 + sizeof(struct sadb_address) 1112 + PFKEY_ALIGN8(sysdep_sa_len(dst)) 1113 + policylen; 1114 1115 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1116 __ipsec_set_strerror(strerror(errno)); 1117 return -1; 1118 } 1119 ep = ((caddr_t)newmsg) + len; 1120 1121 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_X_MIGRATE, (u_int)len, 1122 SADB_SATYPE_UNSPEC, seq, getpid()); 1123 if (!p) { 1124 free(newmsg); 1125 return -1; 1126 } 1127 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); 1128 if (!p) { 1129 free(newmsg); 1130 return -1; 1131 } 1132 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); 1133 if (!p || p + policylen != ep) { 1134 free(newmsg); 1135 return -1; 1136 } 1137 memcpy(p, policy, policylen); 1138 1139 /* send message */ 1140 len = pfkey_send(so, newmsg, len); 1141 free(newmsg); 1142 1143 if (len < 0) 1144 return -1; 1145 1146 __ipsec_errcode = EIPSEC_NO_ERROR; 1147 return len; 1148} 1149#endif 1150 1151 1152/* sending SADB_ADD or SADB_UPDATE message to the kernel */ 1153static int 1154pfkey_send_x1(struct pfkey_send_sa_args *sa_parms) 1155{ 1156 struct sadb_msg *newmsg; 1157 int len; 1158 caddr_t p; 1159 int plen; 1160 caddr_t ep; 1161 1162 /* validity check */ 1163 if (sa_parms->src == NULL || sa_parms->dst == NULL) { 1164 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1165 return -1; 1166 } 1167 if (sa_parms->src->sa_family != sa_parms->dst->sa_family) { 1168 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1169 return -1; 1170 } 1171 switch (sa_parms->src->sa_family) { 1172 case AF_INET: 1173 plen = sizeof(struct in_addr) << 3; 1174 break; 1175 case AF_INET6: 1176 plen = sizeof(struct in6_addr) << 3; 1177 break; 1178 default: 1179 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1180 return -1; 1181 } 1182 1183 switch (sa_parms->satype) { 1184 case SADB_SATYPE_ESP: 1185 if (sa_parms->e_type == SADB_EALG_NONE) { 1186 __ipsec_errcode = EIPSEC_NO_ALGS; 1187 return -1; 1188 } 1189 break; 1190 case SADB_SATYPE_AH: 1191 if (sa_parms->e_type != SADB_EALG_NONE) { 1192 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1193 return -1; 1194 } 1195 if (sa_parms->a_type == SADB_AALG_NONE) { 1196 __ipsec_errcode = EIPSEC_NO_ALGS; 1197 return -1; 1198 } 1199 break; 1200 case SADB_X_SATYPE_IPCOMP: 1201 if (sa_parms->e_type == SADB_X_CALG_NONE) { 1202 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1203 return -1; 1204 } 1205 if (sa_parms->a_type != SADB_AALG_NONE) { 1206 __ipsec_errcode = EIPSEC_NO_ALGS; 1207 return -1; 1208 } 1209 break; 1210#ifdef SADB_X_AALG_TCP_MD5 1211 case SADB_X_SATYPE_TCPSIGNATURE: 1212 if (sa_parms->e_type != SADB_EALG_NONE) { 1213 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1214 return -1; 1215 } 1216 if (sa_parms->a_type != SADB_X_AALG_TCP_MD5) { 1217 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1218 return -1; 1219 } 1220 break; 1221#endif 1222 default: 1223 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1224 return -1; 1225 } 1226 1227 /* create new sadb_msg to reply. */ 1228 len = sizeof(struct sadb_msg) 1229 + sizeof(struct sadb_sa) 1230 + sizeof(struct sadb_x_sa2) 1231 + sizeof(struct sadb_address) 1232 + PFKEY_ALIGN8(sysdep_sa_len(sa_parms->src)) 1233 + sizeof(struct sadb_address) 1234 + PFKEY_ALIGN8(sysdep_sa_len(sa_parms->dst)) 1235 + sizeof(struct sadb_lifetime) 1236 + sizeof(struct sadb_lifetime); 1237 1238 if (sa_parms->e_type != SADB_EALG_NONE && 1239 sa_parms->satype != SADB_X_SATYPE_IPCOMP) 1240 len += (sizeof(struct sadb_key) + 1241 PFKEY_ALIGN8(sa_parms->e_keylen)); 1242 if (sa_parms->a_type != SADB_AALG_NONE) 1243 len += (sizeof(struct sadb_key) + 1244 PFKEY_ALIGN8(sa_parms->a_keylen)); 1245 1246#ifdef SADB_X_EXT_SEC_CTX 1247 if (sa_parms->ctxstr != NULL) 1248 len += (sizeof(struct sadb_x_sec_ctx) 1249 + PFKEY_ALIGN8(sa_parms->ctxstrlen)); 1250#endif 1251 1252#ifdef SADB_X_EXT_NAT_T_TYPE 1253 /* add nat-t packets */ 1254 if (sa_parms->l_natt_type) { 1255 switch(sa_parms->satype) { 1256 case SADB_SATYPE_ESP: 1257 case SADB_X_SATYPE_IPCOMP: 1258 break; 1259 default: 1260 __ipsec_errcode = EIPSEC_NO_ALGS; 1261 return -1; 1262 } 1263 1264 len += sizeof(struct sadb_x_nat_t_type); 1265 len += sizeof(struct sadb_x_nat_t_port); 1266 len += sizeof(struct sadb_x_nat_t_port); 1267 if (sa_parms->l_natt_oa) 1268 len += sizeof(struct sadb_address) + 1269 PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oa)); 1270#ifdef SADB_X_EXT_NAT_T_FRAG 1271 if (sa_parms->l_natt_frag) 1272 len += sizeof(struct sadb_x_nat_t_frag); 1273#endif 1274 } 1275#endif 1276 1277 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1278 __ipsec_set_strerror(strerror(errno)); 1279 return -1; 1280 } 1281 ep = ((caddr_t)(void *)newmsg) + len; 1282 1283 p = pfkey_setsadbmsg((void *)newmsg, ep, sa_parms->type, (u_int)len, 1284 sa_parms->satype, sa_parms->seq, getpid()); 1285 if (!p) { 1286 free(newmsg); 1287 return -1; 1288 } 1289 p = pfkey_setsadbsa(p, ep, sa_parms->spi, sa_parms->wsize, 1290 sa_parms->a_type, sa_parms->e_type, 1291 sa_parms->flags); 1292 if (!p) { 1293 free(newmsg); 1294 return -1; 1295 } 1296 p = pfkey_setsadbxsa2(p, ep, sa_parms->mode, sa_parms->reqid); 1297 if (!p) { 1298 free(newmsg); 1299 return -1; 1300 } 1301 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, sa_parms->src, 1302 (u_int)plen, IPSEC_ULPROTO_ANY); 1303 if (!p) { 1304 free(newmsg); 1305 return -1; 1306 } 1307 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, sa_parms->dst, 1308 (u_int)plen, IPSEC_ULPROTO_ANY); 1309 if (!p) { 1310 free(newmsg); 1311 return -1; 1312 } 1313 1314 if (sa_parms->e_type != SADB_EALG_NONE && 1315 sa_parms->satype != SADB_X_SATYPE_IPCOMP) { 1316 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT, 1317 sa_parms->keymat, sa_parms->e_keylen); 1318 if (!p) { 1319 free(newmsg); 1320 return -1; 1321 } 1322 } 1323 if (sa_parms->a_type != SADB_AALG_NONE) { 1324 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH, 1325 sa_parms->keymat + sa_parms->e_keylen, 1326 sa_parms->a_keylen); 1327 if (!p) { 1328 free(newmsg); 1329 return -1; 1330 } 1331 } 1332 1333 /* set sadb_lifetime for destination */ 1334 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 1335 sa_parms->l_alloc, sa_parms->l_bytes, 1336 sa_parms->l_addtime, sa_parms->l_usetime); 1337 if (!p) { 1338 free(newmsg); 1339 return -1; 1340 } 1341 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT, 1342 sa_parms->l_alloc, sa_parms->l_bytes, 1343 sa_parms->l_addtime, sa_parms->l_usetime); 1344 if (!p) { 1345 free(newmsg); 1346 return -1; 1347 } 1348#ifdef SADB_X_EXT_SEC_CTX 1349 if (sa_parms->ctxstr != NULL) { 1350 p = pfkey_setsecctx(p, ep, SADB_X_EXT_SEC_CTX, sa_parms->ctxdoi, 1351 sa_parms->ctxalg, sa_parms->ctxstr, 1352 sa_parms->ctxstrlen); 1353 if (!p) { 1354 free(newmsg); 1355 return -1; 1356 } 1357 } 1358#endif 1359 1360#ifdef SADB_X_EXT_NAT_T_TYPE 1361 /* Add nat-t messages */ 1362 if (sa_parms->l_natt_type) { 1363 p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, 1364 sa_parms->l_natt_type); 1365 if (!p) { 1366 free(newmsg); 1367 return -1; 1368 } 1369 1370 p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT, 1371 sa_parms->l_natt_sport); 1372 if (!p) { 1373 free(newmsg); 1374 return -1; 1375 } 1376 1377 p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT, 1378 sa_parms->l_natt_dport); 1379 if (!p) { 1380 free(newmsg); 1381 return -1; 1382 } 1383 1384 if (sa_parms->l_natt_oa) { 1385 p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_NAT_T_OA, 1386 sa_parms->l_natt_oa, 1387 (u_int)PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oa)), 1388 IPSEC_ULPROTO_ANY); 1389 if (!p) { 1390 free(newmsg); 1391 return -1; 1392 } 1393 } 1394 1395#ifdef SADB_X_EXT_NAT_T_FRAG 1396 if (sa_parms->l_natt_frag) { 1397 p = pfkey_set_natt_frag(p, ep, SADB_X_EXT_NAT_T_FRAG, 1398 sa_parms->l_natt_frag); 1399 if (!p) { 1400 free(newmsg); 1401 return -1; 1402 } 1403 } 1404#endif 1405 } 1406#endif 1407 1408 if (p != ep) { 1409 free(newmsg); 1410 return -1; 1411 } 1412 1413 /* send message */ 1414 len = pfkey_send(sa_parms->so, newmsg, len); 1415 free(newmsg); 1416 1417 if (len < 0) 1418 return -1; 1419 1420 __ipsec_errcode = EIPSEC_NO_ERROR; 1421 return len; 1422} 1423 1424/* sending SADB_DELETE or SADB_GET message to the kernel */ 1425/*ARGSUSED*/ 1426static int 1427pfkey_send_x2(int so, u_int type, u_int satype, u_int mode, 1428 struct sockaddr *src, struct sockaddr *dst, u_int32_t spi) 1429{ 1430 struct sadb_msg *newmsg; 1431 int len; 1432 caddr_t p; 1433 int plen; 1434 caddr_t ep; 1435 1436 /* validity check */ 1437 if (src == NULL || dst == NULL) { 1438 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1439 return -1; 1440 } 1441 if (src->sa_family != dst->sa_family) { 1442 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1443 return -1; 1444 } 1445 switch (src->sa_family) { 1446 case AF_INET: 1447 plen = sizeof(struct in_addr) << 3; 1448 break; 1449 case AF_INET6: 1450 plen = sizeof(struct in6_addr) << 3; 1451 break; 1452 default: 1453 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1454 return -1; 1455 } 1456 1457 /* create new sadb_msg to reply. */ 1458 len = sizeof(struct sadb_msg) 1459 + sizeof(struct sadb_sa) 1460 + sizeof(struct sadb_address) 1461 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1462 + sizeof(struct sadb_address) 1463 + PFKEY_ALIGN8(sysdep_sa_len(dst)); 1464 1465 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1466 __ipsec_set_strerror(strerror(errno)); 1467 return -1; 1468 } 1469 ep = ((caddr_t)(void *)newmsg) + len; 1470 1471 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0, 1472 getpid()); 1473 if (!p) { 1474 free(newmsg); 1475 return -1; 1476 } 1477 p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0); 1478 if (!p) { 1479 free(newmsg); 1480 return -1; 1481 } 1482 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, 1483 IPSEC_ULPROTO_ANY); 1484 if (!p) { 1485 free(newmsg); 1486 return -1; 1487 } 1488 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, 1489 IPSEC_ULPROTO_ANY); 1490 if (!p || p != ep) { 1491 free(newmsg); 1492 return -1; 1493 } 1494 1495 /* send message */ 1496 len = pfkey_send(so, newmsg, len); 1497 free(newmsg); 1498 1499 if (len < 0) 1500 return -1; 1501 1502 __ipsec_errcode = EIPSEC_NO_ERROR; 1503 return len; 1504} 1505 1506/* 1507 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message 1508 * to the kernel 1509 */ 1510static int 1511pfkey_send_x3(int so, u_int type, u_int satype) 1512{ 1513 struct sadb_msg *newmsg; 1514 int len; 1515 caddr_t p; 1516 caddr_t ep; 1517 1518 /* validity check */ 1519 switch (type) { 1520 case SADB_X_PROMISC: 1521 if (satype != 0 && satype != 1) { 1522 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1523 return -1; 1524 } 1525 break; 1526 default: 1527 switch (satype) { 1528 case SADB_SATYPE_UNSPEC: 1529 case SADB_SATYPE_AH: 1530 case SADB_SATYPE_ESP: 1531 case SADB_X_SATYPE_IPCOMP: 1532#ifdef SADB_X_SATYPE_TCPSIGNATURE 1533 case SADB_X_SATYPE_TCPSIGNATURE: 1534#endif 1535 break; 1536 default: 1537 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1538 return -1; 1539 } 1540 } 1541 1542 /* create new sadb_msg to send. */ 1543 len = sizeof(struct sadb_msg); 1544 1545 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1546 __ipsec_set_strerror(strerror(errno)); 1547 return -1; 1548 } 1549 ep = ((caddr_t)(void *)newmsg) + len; 1550 1551 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0, 1552 getpid()); 1553 if (!p || p != ep) { 1554 free(newmsg); 1555 return -1; 1556 } 1557 1558 /* send message */ 1559 len = pfkey_send(so, newmsg, len); 1560 free(newmsg); 1561 1562 if (len < 0) 1563 return -1; 1564 1565 __ipsec_errcode = EIPSEC_NO_ERROR; 1566 return len; 1567} 1568 1569/* sending SADB_X_SPDADD message to the kernel */ 1570static int 1571pfkey_send_x4(int so, u_int type, struct sockaddr *src, u_int prefs, 1572 struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime, 1573 u_int64_t vtime, char *policy, int policylen, u_int32_t seq) 1574{ 1575 struct sadb_msg *newmsg; 1576 int len; 1577 caddr_t p; 1578 int plen; 1579 caddr_t ep; 1580 1581 /* validity check */ 1582 if (src == NULL || dst == NULL) { 1583 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1584 return -1; 1585 } 1586 if (src->sa_family != dst->sa_family) { 1587 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1588 return -1; 1589 } 1590 1591 switch (src->sa_family) { 1592 case AF_INET: 1593 plen = sizeof(struct in_addr) << 3; 1594 break; 1595 case AF_INET6: 1596 plen = sizeof(struct in6_addr) << 3; 1597 break; 1598 default: 1599 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1600 return -1; 1601 } 1602 if (prefs > plen || prefd > plen) { 1603 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; 1604 return -1; 1605 } 1606 1607 /* create new sadb_msg to reply. */ 1608 len = sizeof(struct sadb_msg) 1609 + sizeof(struct sadb_address) 1610 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1611 + sizeof(struct sadb_address) 1612 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1613 + sizeof(struct sadb_lifetime) 1614 + policylen; 1615 1616 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1617 __ipsec_set_strerror(strerror(errno)); 1618 return -1; 1619 } 1620 ep = ((caddr_t)(void *)newmsg) + len; 1621 1622 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, 1623 SADB_SATYPE_UNSPEC, seq, getpid()); 1624 if (!p) { 1625 free(newmsg); 1626 return -1; 1627 } 1628 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); 1629 if (!p) { 1630 free(newmsg); 1631 return -1; 1632 } 1633 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); 1634 if (!p) { 1635 free(newmsg); 1636 return -1; 1637 } 1638 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 1639 0, 0, (u_int)ltime, (u_int)vtime); 1640 if (!p || p + policylen != ep) { 1641 free(newmsg); 1642 return -1; 1643 } 1644 memcpy(p, policy, (size_t)policylen); 1645 1646 /* send message */ 1647 len = pfkey_send(so, newmsg, len); 1648 free(newmsg); 1649 1650 if (len < 0) 1651 return -1; 1652 1653 __ipsec_errcode = EIPSEC_NO_ERROR; 1654 return len; 1655} 1656 1657/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ 1658static int 1659pfkey_send_x5(int so, u_int type, u_int32_t spid) 1660{ 1661 struct sadb_msg *newmsg; 1662 struct sadb_x_policy xpl; 1663 int len; 1664 caddr_t p; 1665 caddr_t ep; 1666 1667 /* create new sadb_msg to reply. */ 1668 len = sizeof(struct sadb_msg) 1669 + sizeof(xpl); 1670 1671 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1672 __ipsec_set_strerror(strerror(errno)); 1673 return -1; 1674 } 1675 ep = ((caddr_t)(void *)newmsg) + len; 1676 1677 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, 1678 SADB_SATYPE_UNSPEC, 0, getpid()); 1679 if (!p) { 1680 free(newmsg); 1681 return -1; 1682 } 1683 1684 if (p + sizeof(xpl) != ep) { 1685 free(newmsg); 1686 return -1; 1687 } 1688 memset(&xpl, 0, sizeof(xpl)); 1689 xpl.sadb_x_policy_len = PFKEY_UNIT64(sizeof(xpl)); 1690 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; 1691 xpl.sadb_x_policy_id = spid; 1692 memcpy(p, &xpl, sizeof(xpl)); 1693 1694 /* send message */ 1695 len = pfkey_send(so, newmsg, len); 1696 free(newmsg); 1697 1698 if (len < 0) 1699 return -1; 1700 1701 __ipsec_errcode = EIPSEC_NO_ERROR; 1702 return len; 1703} 1704 1705/* 1706 * open a socket. 1707 * OUT: 1708 * -1: fail. 1709 * others : success and return value of socket. 1710 */ 1711int 1712pfkey_open(void) 1713{ 1714 int so; 1715 int bufsiz = 128 * 1024; /*is 128K enough?*/ 1716 1717 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { 1718 __ipsec_set_strerror(strerror(errno)); 1719 return -1; 1720 } 1721 1722 /* 1723 * This is a temporary workaround for KAME PR 154. 1724 * Don't really care even if it fails. 1725 */ 1726 (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)); 1727 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1728 bufsiz = 256 * 1024; 1729 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1730 bufsiz = 512 * 1024; 1731 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1732 bufsiz = 1024 * 1024; 1733 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1734 __ipsec_errcode = EIPSEC_NO_ERROR; 1735 return so; 1736} 1737 1738/* 1739 * close a socket. 1740 * OUT: 1741 * 0: success. 1742 * -1: fail. 1743 */ 1744void 1745pfkey_close(int so) 1746{ 1747 (void)close(so); 1748 1749 __ipsec_errcode = EIPSEC_NO_ERROR; 1750 return; 1751} 1752 1753/* 1754 * receive sadb_msg data, and return pointer to new buffer allocated. 1755 * Must free this buffer later. 1756 * OUT: 1757 * NULL : error occured. 1758 * others : a pointer to sadb_msg structure. 1759 * 1760 * XXX should be rewritten to pass length explicitly 1761 */ 1762struct sadb_msg * 1763pfkey_recv(int so) 1764{ 1765 struct sadb_msg buf, *newmsg; 1766 int len, reallen; 1767 1768 while ((len = recv(so, (void *)&buf, sizeof(buf), MSG_PEEK)) < 0) { 1769 if (errno == EINTR) 1770 continue; 1771 __ipsec_set_strerror(strerror(errno)); 1772 return NULL; 1773 } 1774 1775 if (len < sizeof(buf)) { 1776 recv(so, (void *)&buf, sizeof(buf), 0); 1777 __ipsec_errcode = EIPSEC_MAX; 1778 return NULL; 1779 } 1780 1781 /* read real message */ 1782 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); 1783 if ((newmsg = CALLOC((size_t)reallen, struct sadb_msg *)) == 0) { 1784 __ipsec_set_strerror(strerror(errno)); 1785 return NULL; 1786 } 1787 1788 while ((len = recv(so, (void *)newmsg, (socklen_t)reallen, 0)) < 0) { 1789 if (errno == EINTR) 1790 continue; 1791 __ipsec_set_strerror(strerror(errno)); 1792 free(newmsg); 1793 return NULL; 1794 } 1795 1796 if (len != reallen) { 1797 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1798 free(newmsg); 1799 return NULL; 1800 } 1801 1802 /* don't trust what the kernel says, validate! */ 1803 if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) { 1804 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1805 free(newmsg); 1806 return NULL; 1807 } 1808 1809 __ipsec_errcode = EIPSEC_NO_ERROR; 1810 return newmsg; 1811} 1812 1813/* 1814 * send message to a socket. 1815 * OUT: 1816 * others: success and return length sent. 1817 * -1 : fail. 1818 */ 1819int 1820pfkey_send(int so, struct sadb_msg *msg, int len) 1821{ 1822 if ((len = send(so, (void *)msg, (socklen_t)len, 0)) < 0) { 1823 __ipsec_set_strerror(strerror(errno)); 1824 return -1; 1825 } 1826 1827 __ipsec_errcode = EIPSEC_NO_ERROR; 1828 return len; 1829} 1830 1831/* 1832 * %%% Utilities 1833 * NOTE: These functions are derived from netkey/key.c in KAME. 1834 */ 1835/* 1836 * set the pointer to each header in this message buffer. 1837 * IN: msg: pointer to message buffer. 1838 * mhp: pointer to the buffer initialized like below: 1839 * caddr_t mhp[SADB_EXT_MAX + 1]; 1840 * OUT: -1: invalid. 1841 * 0: valid. 1842 * 1843 * XXX should be rewritten to obtain length explicitly 1844 */ 1845int 1846pfkey_align(struct sadb_msg *msg, caddr_t *mhp) 1847{ 1848 struct sadb_ext *ext; 1849 int i; 1850 caddr_t p; 1851 caddr_t ep; /* XXX should be passed from upper layer */ 1852 1853 /* validity check */ 1854 if (msg == NULL || mhp == NULL) { 1855 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1856 return -1; 1857 } 1858 1859 /* initialize */ 1860 for (i = 0; i < SADB_EXT_MAX + 1; i++) 1861 mhp[i] = NULL; 1862 1863 mhp[0] = (void *)msg; 1864 1865 /* initialize */ 1866 p = (void *) msg; 1867 ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len); 1868 1869 /* skip base header */ 1870 p += sizeof(struct sadb_msg); 1871 1872 while (p < ep) { 1873 ext = (void *)p; 1874 if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) || 1875 ep < p + PFKEY_EXTLEN(ext)) { 1876 /* invalid format */ 1877 break; 1878 } 1879 1880 /* duplicate check */ 1881 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/ 1882 if (mhp[ext->sadb_ext_type] != NULL) { 1883 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1884 return -1; 1885 } 1886 1887 /* set pointer */ 1888 switch (ext->sadb_ext_type) { 1889 case SADB_EXT_SA: 1890 case SADB_EXT_LIFETIME_CURRENT: 1891 case SADB_EXT_LIFETIME_HARD: 1892 case SADB_EXT_LIFETIME_SOFT: 1893 case SADB_EXT_ADDRESS_SRC: 1894 case SADB_EXT_ADDRESS_DST: 1895 case SADB_EXT_ADDRESS_PROXY: 1896 case SADB_EXT_KEY_AUTH: 1897 /* XXX should to be check weak keys. */ 1898 case SADB_EXT_KEY_ENCRYPT: 1899 /* XXX should to be check weak keys. */ 1900 case SADB_EXT_IDENTITY_SRC: 1901 case SADB_EXT_IDENTITY_DST: 1902 case SADB_EXT_SENSITIVITY: 1903 case SADB_EXT_PROPOSAL: 1904 case SADB_EXT_SUPPORTED_AUTH: 1905 case SADB_EXT_SUPPORTED_ENCRYPT: 1906 case SADB_EXT_SPIRANGE: 1907 case SADB_X_EXT_POLICY: 1908 case SADB_X_EXT_SA2: 1909#ifdef SADB_X_EXT_NAT_T_TYPE 1910 case SADB_X_EXT_NAT_T_TYPE: 1911 case SADB_X_EXT_NAT_T_SPORT: 1912 case SADB_X_EXT_NAT_T_DPORT: 1913 case SADB_X_EXT_NAT_T_OA: 1914#endif 1915#ifdef SADB_X_EXT_TAG 1916 case SADB_X_EXT_TAG: 1917#endif 1918#ifdef SADB_X_EXT_PACKET 1919 case SADB_X_EXT_PACKET: 1920#endif 1921#ifdef SADB_X_EXT_SEC_CTX 1922 case SADB_X_EXT_SEC_CTX: 1923#endif 1924 mhp[ext->sadb_ext_type] = (void *)ext; 1925 break; 1926 default: 1927 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1928 return -1; 1929 } 1930 1931 p += PFKEY_EXTLEN(ext); 1932 } 1933 1934 if (p != ep) { 1935 __ipsec_errcode = EIPSEC_INVAL_SADBMSG; 1936 return -1; 1937 } 1938 1939 __ipsec_errcode = EIPSEC_NO_ERROR; 1940 return 0; 1941} 1942 1943/* 1944 * check basic usage for sadb_msg, 1945 * NOTE: This routine is derived from netkey/key.c in KAME. 1946 * IN: msg: pointer to message buffer. 1947 * mhp: pointer to the buffer initialized like below: 1948 * 1949 * caddr_t mhp[SADB_EXT_MAX + 1]; 1950 * 1951 * OUT: -1: invalid. 1952 * 0: valid. 1953 */ 1954int 1955pfkey_check(caddr_t *mhp) 1956{ 1957 struct sadb_msg *msg; 1958 1959 /* validity check */ 1960 if (mhp == NULL || mhp[0] == NULL) { 1961 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1962 return -1; 1963 } 1964 1965 msg = (void *)mhp[0]; 1966 1967 /* check version */ 1968 if (msg->sadb_msg_version != PF_KEY_V2) { 1969 __ipsec_errcode = EIPSEC_INVAL_VERSION; 1970 return -1; 1971 } 1972 1973 /* check type */ 1974 if (msg->sadb_msg_type > SADB_MAX) { 1975 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE; 1976 return -1; 1977 } 1978 1979 /* check SA type */ 1980 switch (msg->sadb_msg_satype) { 1981 case SADB_SATYPE_UNSPEC: 1982 switch (msg->sadb_msg_type) { 1983 case SADB_GETSPI: 1984 case SADB_UPDATE: 1985 case SADB_ADD: 1986 case SADB_DELETE: 1987 case SADB_GET: 1988 case SADB_ACQUIRE: 1989 case SADB_EXPIRE: 1990#ifdef SADB_X_NAT_T_NEW_MAPPING 1991 case SADB_X_NAT_T_NEW_MAPPING: 1992#endif 1993 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1994 return -1; 1995 } 1996 break; 1997 case SADB_SATYPE_ESP: 1998 case SADB_SATYPE_AH: 1999 case SADB_X_SATYPE_IPCOMP: 2000#ifdef SADB_X_SATYPE_TCPSIGNATURE 2001 case SADB_X_SATYPE_TCPSIGNATURE: 2002#endif 2003 switch (msg->sadb_msg_type) { 2004 case SADB_X_SPDADD: 2005 case SADB_X_SPDDELETE: 2006 case SADB_X_SPDGET: 2007 case SADB_X_SPDDUMP: 2008 case SADB_X_SPDFLUSH: 2009 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2010 return -1; 2011 } 2012#ifdef SADB_X_NAT_T_NEW_MAPPING 2013 if (msg->sadb_msg_type == SADB_X_NAT_T_NEW_MAPPING && 2014 msg->sadb_msg_satype != SADB_SATYPE_ESP) { 2015 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2016 return -1; 2017 } 2018#endif 2019 break; 2020 case SADB_SATYPE_RSVP: 2021 case SADB_SATYPE_OSPFV2: 2022 case SADB_SATYPE_RIPV2: 2023 case SADB_SATYPE_MIP: 2024 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 2025 return -1; 2026 case 1: /* XXX: What does it do ? */ 2027 if (msg->sadb_msg_type == SADB_X_PROMISC) 2028 break; 2029 /*FALLTHROUGH*/ 2030 default: 2031 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2032 return -1; 2033 } 2034 2035 /* check field of upper layer protocol and address family */ 2036 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL 2037 && mhp[SADB_EXT_ADDRESS_DST] != NULL) { 2038 struct sadb_address *src0, *dst0; 2039 2040 src0 = (void *)(mhp[SADB_EXT_ADDRESS_SRC]); 2041 dst0 = (void *)(mhp[SADB_EXT_ADDRESS_DST]); 2042 2043 if (src0->sadb_address_proto != dst0->sadb_address_proto) { 2044 __ipsec_errcode = EIPSEC_PROTO_MISMATCH; 2045 return -1; 2046 } 2047 2048 if (PFKEY_ADDR_SADDR(src0)->sa_family 2049 != PFKEY_ADDR_SADDR(dst0)->sa_family) { 2050 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 2051 return -1; 2052 } 2053 2054 switch (PFKEY_ADDR_SADDR(src0)->sa_family) { 2055 case AF_INET: 2056 case AF_INET6: 2057 break; 2058 default: 2059 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 2060 return -1; 2061 } 2062 2063 /* 2064 * prefixlen == 0 is valid because there must be the case 2065 * all addresses are matched. 2066 */ 2067 } 2068 2069 __ipsec_errcode = EIPSEC_NO_ERROR; 2070 return 0; 2071} 2072 2073/* 2074 * set data into sadb_msg. 2075 * `buf' must has been allocated sufficiently. 2076 */ 2077static caddr_t 2078pfkey_setsadbmsg(caddr_t buf, caddr_t lim, u_int type, u_int tlen, 2079 u_int satype, u_int32_t seq, pid_t pid) 2080{ 2081 struct sadb_msg *p; 2082 u_int len; 2083 2084 p = (void *)buf; 2085 len = sizeof(struct sadb_msg); 2086 2087 if (buf + len > lim) 2088 return NULL; 2089 2090 memset(p, 0, len); 2091 p->sadb_msg_version = PF_KEY_V2; 2092 p->sadb_msg_type = type; 2093 p->sadb_msg_errno = 0; 2094 p->sadb_msg_satype = satype; 2095 p->sadb_msg_len = PFKEY_UNIT64(tlen); 2096 p->sadb_msg_reserved = 0; 2097 p->sadb_msg_seq = seq; 2098 p->sadb_msg_pid = (u_int32_t)pid; 2099 2100 return(buf + len); 2101} 2102 2103/* 2104 * copy secasvar data into sadb_address. 2105 * `buf' must has been allocated sufficiently. 2106 */ 2107static caddr_t 2108pfkey_setsadbsa(caddr_t buf, caddr_t lim, u_int32_t spi, u_int wsize, 2109 u_int auth, u_int enc, u_int32_t flags) 2110{ 2111 struct sadb_sa *p; 2112 u_int len; 2113 2114 p = (void *)buf; 2115 len = sizeof(struct sadb_sa); 2116 2117 if (buf + len > lim) 2118 return NULL; 2119 2120 memset(p, 0, len); 2121 p->sadb_sa_len = PFKEY_UNIT64(len); 2122 p->sadb_sa_exttype = SADB_EXT_SA; 2123 p->sadb_sa_spi = spi; 2124 p->sadb_sa_replay = wsize; 2125 p->sadb_sa_state = SADB_SASTATE_LARVAL; 2126 p->sadb_sa_auth = auth; 2127 p->sadb_sa_encrypt = enc; 2128 p->sadb_sa_flags = flags; 2129 2130 return(buf + len); 2131} 2132 2133/* 2134 * set data into sadb_address. 2135 * `buf' must has been allocated sufficiently. 2136 * prefixlen is in bits. 2137 */ 2138static caddr_t 2139pfkey_setsadbaddr(caddr_t buf, caddr_t lim, u_int exttype, 2140 struct sockaddr *saddr, u_int prefixlen, u_int ul_proto) 2141{ 2142 struct sadb_address *p; 2143 u_int len; 2144 2145 p = (void *)buf; 2146 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len(saddr)); 2147 2148 if (buf + len > lim) 2149 return NULL; 2150 2151 memset(p, 0, len); 2152 p->sadb_address_len = PFKEY_UNIT64(len); 2153 p->sadb_address_exttype = exttype & 0xffff; 2154 p->sadb_address_proto = ul_proto & 0xff; 2155 p->sadb_address_prefixlen = prefixlen; 2156 p->sadb_address_reserved = 0; 2157 2158 memcpy(p + 1, saddr, (size_t)sysdep_sa_len(saddr)); 2159 2160 return(buf + len); 2161} 2162 2163/* 2164 * set sadb_key structure after clearing buffer with zero. 2165 * OUT: the pointer of buf + len. 2166 */ 2167static caddr_t 2168pfkey_setsadbkey(caddr_t buf, caddr_t lim, u_int type, caddr_t key, 2169 u_int keylen) 2170{ 2171 struct sadb_key *p; 2172 u_int len; 2173 2174 p = (void *)buf; 2175 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); 2176 2177 if (buf + len > lim) 2178 return NULL; 2179 2180 memset(p, 0, len); 2181 p->sadb_key_len = PFKEY_UNIT64(len); 2182 p->sadb_key_exttype = type; 2183 p->sadb_key_bits = keylen << 3; 2184 p->sadb_key_reserved = 0; 2185 2186 memcpy(p + 1, key, keylen); 2187 2188 return buf + len; 2189} 2190 2191/* 2192 * set sadb_lifetime structure after clearing buffer with zero. 2193 * OUT: the pointer of buf + len. 2194 */ 2195static caddr_t 2196pfkey_setsadblifetime(caddr_t buf, caddr_t lim, u_int type, u_int32_t l_alloc, 2197 u_int32_t l_bytes, u_int32_t l_addtime, u_int32_t l_usetime) 2198{ 2199 struct sadb_lifetime *p; 2200 u_int len; 2201 2202 p = (void *)buf; 2203 len = sizeof(struct sadb_lifetime); 2204 2205 if (buf + len > lim) 2206 return NULL; 2207 2208 memset(p, 0, len); 2209 p->sadb_lifetime_len = PFKEY_UNIT64(len); 2210 p->sadb_lifetime_exttype = type; 2211 2212 switch (type) { 2213 case SADB_EXT_LIFETIME_SOFT: 2214 p->sadb_lifetime_allocations 2215 = (l_alloc * soft_lifetime_allocations_rate) /100; 2216 p->sadb_lifetime_bytes 2217 = (l_bytes * soft_lifetime_bytes_rate) /100; 2218 p->sadb_lifetime_addtime 2219 = (l_addtime * soft_lifetime_addtime_rate) /100; 2220 p->sadb_lifetime_usetime 2221 = (l_usetime * soft_lifetime_usetime_rate) /100; 2222 break; 2223 case SADB_EXT_LIFETIME_HARD: 2224 p->sadb_lifetime_allocations = l_alloc; 2225 p->sadb_lifetime_bytes = l_bytes; 2226 p->sadb_lifetime_addtime = l_addtime; 2227 p->sadb_lifetime_usetime = l_usetime; 2228 break; 2229 } 2230 2231 return buf + len; 2232} 2233 2234/* 2235 * copy secasvar data into sadb_address. 2236 * `buf' must has been allocated sufficiently. 2237 */ 2238static caddr_t 2239pfkey_setsadbxsa2(caddr_t buf, caddr_t lim, u_int32_t mode0, u_int32_t reqid) 2240{ 2241 struct sadb_x_sa2 *p; 2242 u_int8_t mode = mode0 & 0xff; 2243 u_int len; 2244 2245 p = (void *)buf; 2246 len = sizeof(struct sadb_x_sa2); 2247 2248 if (buf + len > lim) 2249 return NULL; 2250 2251 memset(p, 0, len); 2252 p->sadb_x_sa2_len = PFKEY_UNIT64(len); 2253 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; 2254 p->sadb_x_sa2_mode = mode; 2255 p->sadb_x_sa2_reqid = reqid; 2256 2257 return(buf + len); 2258} 2259 2260#ifdef SADB_X_EXT_NAT_T_TYPE 2261static caddr_t 2262pfkey_set_natt_type(caddr_t buf, caddr_t lim, u_int type, u_int8_t l_natt_type) 2263{ 2264 struct sadb_x_nat_t_type *p; 2265 u_int len; 2266 2267 p = (void *)buf; 2268 len = sizeof(struct sadb_x_nat_t_type); 2269 2270 if (buf + len > lim) 2271 return NULL; 2272 2273 memset(p, 0, len); 2274 p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len); 2275 p->sadb_x_nat_t_type_exttype = type; 2276 p->sadb_x_nat_t_type_type = l_natt_type; 2277 2278 return(buf + len); 2279} 2280 2281static caddr_t 2282pfkey_set_natt_port(caddr_t buf, caddr_t lim, u_int type, u_int16_t l_natt_port) 2283{ 2284 struct sadb_x_nat_t_port *p; 2285 u_int len; 2286 2287 p = (void *)buf; 2288 len = sizeof(struct sadb_x_nat_t_port); 2289 2290 if (buf + len > lim) 2291 return NULL; 2292 2293 memset(p, 0, len); 2294 p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len); 2295 p->sadb_x_nat_t_port_exttype = type; 2296 p->sadb_x_nat_t_port_port = htons(l_natt_port); 2297 2298 return(buf + len); 2299} 2300#endif 2301 2302#ifdef SADB_X_EXT_NAT_T_FRAG 2303static caddr_t 2304pfkey_set_natt_frag(caddr_t buf, caddr_t lim, u_int type, 2305 u_int16_t l_natt_frag) 2306{ 2307 struct sadb_x_nat_t_frag *p; 2308 u_int len; 2309 2310 p = (void *)buf; 2311 len = sizeof(struct sadb_x_nat_t_frag); 2312 2313 if (buf + len > lim) 2314 return NULL; 2315 2316 memset(p, 0, len); 2317 p->sadb_x_nat_t_frag_len = PFKEY_UNIT64(len); 2318 p->sadb_x_nat_t_frag_exttype = type; 2319 p->sadb_x_nat_t_frag_fraglen = l_natt_frag; 2320 2321 return(buf + len); 2322} 2323#endif 2324 2325#ifdef SADB_X_EXT_SEC_CTX 2326static caddr_t 2327pfkey_setsecctx(caddr_t buf, caddr_t lim, u_int type, u_int8_t ctx_doi, 2328 u_int8_t ctx_alg, caddr_t sec_ctx, u_int16_t sec_ctxlen) 2329{ 2330 struct sadb_x_sec_ctx *p; 2331 u_int len; 2332 2333 p = (struct sadb_x_sec_ctx *)buf; 2334 len = sizeof(struct sadb_x_sec_ctx) + PFKEY_ALIGN8(sec_ctxlen); 2335 2336 if (buf + len > lim) 2337 return NULL; 2338 2339 memset(p, 0, len); 2340 p->sadb_x_sec_len = PFKEY_UNIT64(len); 2341 p->sadb_x_sec_exttype = type; 2342 p->sadb_x_ctx_len = sec_ctxlen; 2343 p->sadb_x_ctx_doi = ctx_doi; 2344 p->sadb_x_ctx_alg = ctx_alg; 2345 2346 memcpy(p + 1, sec_ctx, sec_ctxlen); 2347 2348 return buf + len; 2349} 2350#endif 2351 2352/* 2353 * Deprecated, available for backward compatibility with third party 2354 * libipsec users. Please use pfkey_send_update2 and pfkey_send_add2 instead 2355 */ 2356int 2357pfkey_send_update(int so, u_int satype, u_int mode, struct sockaddr *src, 2358 struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize, 2359 caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type, 2360 u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, 2361 u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq) 2362{ 2363 struct pfkey_send_sa_args psaa; 2364 2365 memset(&psaa, 0, sizeof(psaa)); 2366 psaa.so = so; 2367 psaa.type = SADB_UPDATE; 2368 psaa.satype = satype; 2369 psaa.mode = mode; 2370 psaa.wsize = wsize; 2371 psaa.src = src; 2372 psaa.dst = dst; 2373 psaa.spi = spi; 2374 psaa.reqid = reqid; 2375 psaa.keymat = keymat; 2376 psaa.e_type = e_type; 2377 psaa.e_keylen = e_keylen; 2378 psaa.a_type = a_type; 2379 psaa.a_keylen = a_keylen; 2380 psaa.flags = flags; 2381 psaa.l_alloc = l_alloc; 2382 psaa.l_bytes = l_bytes; 2383 psaa.l_addtime = l_addtime; 2384 psaa.l_usetime = l_usetime; 2385 psaa.seq = seq; 2386 2387 return pfkey_send_update2(&psaa); 2388} 2389 2390int 2391pfkey_send_update_nat(int so, u_int satype, u_int mode, struct sockaddr *src, 2392 struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize, 2393 caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type, 2394 u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, 2395 u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq, 2396 u_int8_t l_natt_type, u_int16_t l_natt_sport, u_int16_t l_natt_dport, 2397 struct sockaddr *l_natt_oa, u_int16_t l_natt_frag) 2398{ 2399 struct pfkey_send_sa_args psaa; 2400 2401 memset(&psaa, 0, sizeof(psaa)); 2402 psaa.so = so; 2403 psaa.type = SADB_UPDATE; 2404 psaa.satype = satype; 2405 psaa.mode = mode; 2406 psaa.wsize = wsize; 2407 psaa.src = src; 2408 psaa.dst = dst; 2409 psaa.spi = spi; 2410 psaa.reqid = reqid; 2411 psaa.keymat = keymat; 2412 psaa.e_type = e_type; 2413 psaa.e_keylen = e_keylen; 2414 psaa.a_type = a_type; 2415 psaa.a_keylen = a_keylen; 2416 psaa.flags = flags; 2417 psaa.l_alloc = l_alloc; 2418 psaa.l_bytes = l_bytes; 2419 psaa.l_addtime = l_addtime; 2420 psaa.l_usetime = l_usetime; 2421 psaa.seq = seq; 2422 psaa.l_natt_type = l_natt_type; 2423 psaa.l_natt_sport = l_natt_sport; 2424 psaa.l_natt_dport = l_natt_dport; 2425 psaa.l_natt_oa = l_natt_oa; 2426 psaa.l_natt_frag = l_natt_frag; 2427 2428 return pfkey_send_update2(&psaa); 2429} 2430 2431int 2432pfkey_send_add(int so, u_int satype, u_int mode, struct sockaddr *src, 2433 struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize, 2434 caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type, 2435 u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, 2436 u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq) 2437{ 2438 struct pfkey_send_sa_args psaa; 2439 2440 memset(&psaa, 0, sizeof(psaa)); 2441 psaa.so = so; 2442 psaa.type = SADB_ADD; 2443 psaa.satype = satype; 2444 psaa.mode = mode; 2445 psaa.wsize = wsize; 2446 psaa.src = src; 2447 psaa.dst = dst; 2448 psaa.spi = spi; 2449 psaa.reqid = reqid; 2450 psaa.keymat = keymat; 2451 psaa.e_type = e_type; 2452 psaa.e_keylen = e_keylen; 2453 psaa.a_type = a_type; 2454 psaa.a_keylen = a_keylen; 2455 psaa.flags = flags; 2456 psaa.l_alloc = l_alloc; 2457 psaa.l_bytes = l_bytes; 2458 psaa.l_addtime = l_addtime; 2459 psaa.l_usetime = l_usetime; 2460 psaa.seq = seq; 2461 2462 return pfkey_send_add2(&psaa); 2463} 2464 2465int 2466pfkey_send_add_nat(int so, u_int satype, u_int mode, struct sockaddr *src, 2467 struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize, 2468 caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type, 2469 u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, 2470 u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq, 2471 u_int8_t l_natt_type, u_int16_t l_natt_sport, u_int16_t l_natt_dport, 2472 struct sockaddr *l_natt_oa, u_int16_t l_natt_frag) 2473{ 2474 struct pfkey_send_sa_args psaa; 2475 2476 memset(&psaa, 0, sizeof(psaa)); 2477 psaa.so = so; 2478 psaa.type = SADB_ADD; 2479 psaa.satype = satype; 2480 psaa.mode = mode; 2481 psaa.wsize = wsize; 2482 psaa.src = src; 2483 psaa.dst = dst; 2484 psaa.spi = spi; 2485 psaa.reqid = reqid; 2486 psaa.keymat = keymat; 2487 psaa.e_type = e_type; 2488 psaa.e_keylen = e_keylen; 2489 psaa.a_type = a_type; 2490 psaa.a_keylen = a_keylen; 2491 psaa.flags = flags; 2492 psaa.l_alloc = l_alloc; 2493 psaa.l_bytes = l_bytes; 2494 psaa.l_addtime = l_addtime; 2495 psaa.l_usetime = l_usetime; 2496 psaa.seq = seq; 2497 psaa.l_natt_type = l_natt_type; 2498 psaa.l_natt_sport = l_natt_sport; 2499 psaa.l_natt_dport = l_natt_dport; 2500 psaa.l_natt_oa = l_natt_oa; 2501 psaa.l_natt_frag = l_natt_frag; 2502 2503 return pfkey_send_add2(&psaa); 2504} 2505