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(so, satype, mode, src, dst, min, max, reqid, seq) 378 int so; 379 u_int satype, mode; 380 struct sockaddr *src, *dst; 381 u_int32_t min, max, reqid, seq; 382{ 383 struct sadb_msg *newmsg; 384 caddr_t ep; 385 int len; 386 int need_spirange = 0; 387 caddr_t p; 388 int plen; 389 390 /* validity check */ 391 if (src == NULL || dst == NULL) { 392 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 393 return -1; 394 } 395 if (src->sa_family != dst->sa_family) { 396 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 397 return -1; 398 } 399 if (min > max || (min > 0 && min <= 255)) { 400 __ipsec_errcode = EIPSEC_INVAL_SPI; 401 return -1; 402 } 403 switch (src->sa_family) { 404 case AF_INET: 405 plen = sizeof(struct in_addr) << 3; 406 break; 407 case AF_INET6: 408 plen = sizeof(struct in6_addr) << 3; 409 break; 410 default: 411 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 412 return -1; 413 } 414 415 /* create new sadb_msg to send. */ 416 len = sizeof(struct sadb_msg) 417 + sizeof(struct sadb_x_sa2) 418 + sizeof(struct sadb_address) 419 + PFKEY_ALIGN8(sysdep_sa_len(src)) 420 + sizeof(struct sadb_address) 421 + PFKEY_ALIGN8(sysdep_sa_len(dst)); 422 423 if (min > 255 && max < (u_int)~0) { 424 need_spirange++; 425 len += sizeof(struct sadb_spirange); 426 } 427 428 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 429 __ipsec_set_strerror(strerror(errno)); 430 return -1; 431 } 432 ep = ((caddr_t)(void *)newmsg) + len; 433 434 p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_GETSPI, 435 (u_int)len, satype, seq, getpid()); 436 if (!p) { 437 free(newmsg); 438 return -1; 439 } 440 441 p = pfkey_setsadbxsa2(p, ep, mode, reqid); 442 if (!p) { 443 free(newmsg); 444 return -1; 445 } 446 447 /* set sadb_address for source */ 448 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, 449 IPSEC_ULPROTO_ANY); 450 if (!p) { 451 free(newmsg); 452 return -1; 453 } 454 455 /* set sadb_address for destination */ 456 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, 457 IPSEC_ULPROTO_ANY); 458 if (!p) { 459 free(newmsg); 460 return -1; 461 } 462 463 /* proccessing spi range */ 464 if (need_spirange) { 465 struct sadb_spirange spirange; 466 467 if (p + sizeof(spirange) > ep) { 468 free(newmsg); 469 return -1; 470 } 471 472 memset(&spirange, 0, sizeof(spirange)); 473 spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange)); 474 spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE; 475 spirange.sadb_spirange_min = min; 476 spirange.sadb_spirange_max = max; 477 478 memcpy(p, &spirange, sizeof(spirange)); 479 480 p += sizeof(spirange); 481 } 482 if (p != ep) { 483 free(newmsg); 484 return -1; 485 } 486 487 /* send message */ 488 len = pfkey_send(so, newmsg, len); 489 free(newmsg); 490 491 if (len < 0) 492 return -1; 493 494 __ipsec_errcode = EIPSEC_NO_ERROR; 495 return len; 496} 497 498/* 499 * sending SADB_UPDATE message to the kernel. 500 * The length of key material is a_keylen + e_keylen. 501 * OUT: 502 * positive: success and return length sent. 503 * -1 : error occured, and set errno. 504 */ 505int 506pfkey_send_update2(sa_parms) 507 struct pfkey_send_sa_args *sa_parms; 508{ 509 int len; 510 511 512 sa_parms->type = SADB_UPDATE; 513 if ((len = pfkey_send_x1(sa_parms)) < 0) 514 return -1; 515 516 return len; 517} 518 519/* 520 * sending SADB_ADD message to the kernel. 521 * The length of key material is a_keylen + e_keylen. 522 * OUT: 523 * positive: success and return length sent. 524 * -1 : error occured, and set errno. 525 */ 526int 527pfkey_send_add2(sa_parms) 528 struct pfkey_send_sa_args *sa_parms; 529{ 530 int len; 531 532 sa_parms->type = SADB_ADD; 533 if ((len = pfkey_send_x1(sa_parms)) < 0) 534 return -1; 535 536 return len; 537} 538 539/* 540 * sending SADB_DELETE message to the kernel. 541 * OUT: 542 * positive: success and return length sent. 543 * -1 : error occured, and set errno. 544 */ 545int 546pfkey_send_delete(so, satype, mode, src, dst, spi) 547 int so; 548 u_int satype, mode; 549 struct sockaddr *src, *dst; 550 u_int32_t spi; 551{ 552 int len; 553 if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0) 554 return -1; 555 556 return len; 557} 558 559/* 560 * sending SADB_DELETE without spi to the kernel. This is 561 * the "delete all" request (an extension also present in 562 * Solaris). 563 * 564 * OUT: 565 * positive: success and return length sent 566 * -1 : error occured, and set errno 567 */ 568/*ARGSUSED*/ 569int 570pfkey_send_delete_all(so, satype, mode, src, dst) 571 int so; 572 u_int satype, mode; 573 struct sockaddr *src, *dst; 574{ 575 struct sadb_msg *newmsg; 576 int len; 577 caddr_t p; 578 int plen; 579 caddr_t ep; 580 581 /* validity check */ 582 if (src == NULL || dst == NULL) { 583 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 584 return -1; 585 } 586 if (src->sa_family != dst->sa_family) { 587 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 588 return -1; 589 } 590 switch (src->sa_family) { 591 case AF_INET: 592 plen = sizeof(struct in_addr) << 3; 593 break; 594 case AF_INET6: 595 plen = sizeof(struct in6_addr) << 3; 596 break; 597 default: 598 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 599 return -1; 600 } 601 602 /* create new sadb_msg to reply. */ 603 len = sizeof(struct sadb_msg) 604 + sizeof(struct sadb_address) 605 + PFKEY_ALIGN8(sysdep_sa_len(src)) 606 + sizeof(struct sadb_address) 607 + PFKEY_ALIGN8(sysdep_sa_len(dst)); 608 609 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 610 __ipsec_set_strerror(strerror(errno)); 611 return -1; 612 } 613 ep = ((caddr_t)(void *)newmsg) + len; 614 615 p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_DELETE, (u_int)len, 616 satype, 0, getpid()); 617 if (!p) { 618 free(newmsg); 619 return -1; 620 } 621 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, 622 IPSEC_ULPROTO_ANY); 623 if (!p) { 624 free(newmsg); 625 return -1; 626 } 627 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, 628 IPSEC_ULPROTO_ANY); 629 if (!p || p != ep) { 630 free(newmsg); 631 return -1; 632 } 633 634 /* send message */ 635 len = pfkey_send(so, newmsg, len); 636 free(newmsg); 637 638 if (len < 0) 639 return -1; 640 641 __ipsec_errcode = EIPSEC_NO_ERROR; 642 return len; 643} 644 645/* 646 * sending SADB_GET message to the kernel. 647 * OUT: 648 * positive: success and return length sent. 649 * -1 : error occured, and set errno. 650 */ 651int 652pfkey_send_get(so, satype, mode, src, dst, spi) 653 int so; 654 u_int satype, mode; 655 struct sockaddr *src, *dst; 656 u_int32_t spi; 657{ 658 int len; 659 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) 660 return -1; 661 662 return len; 663} 664 665/* 666 * sending SADB_REGISTER message to the kernel. 667 * OUT: 668 * positive: success and return length sent. 669 * -1 : error occured, and set errno. 670 */ 671int 672pfkey_send_register(so, satype) 673 int so; 674 u_int satype; 675{ 676 int len, algno; 677 678 if (satype == PF_UNSPEC) { 679 for (algno = 0; 680 algno < sizeof(supported_map)/sizeof(supported_map[0]); 681 algno++) { 682 if (ipsec_supported[algno]) { 683 free(ipsec_supported[algno]); 684 ipsec_supported[algno] = NULL; 685 } 686 } 687 } else { 688 algno = findsupportedmap((int)satype); 689 if (algno == -1) { 690 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 691 return -1; 692 } 693 694 if (ipsec_supported[algno]) { 695 free(ipsec_supported[algno]); 696 ipsec_supported[algno] = NULL; 697 } 698 } 699 700 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0) 701 return -1; 702 703 return len; 704} 705 706/* 707 * receiving SADB_REGISTER message from the kernel, and copy buffer for 708 * sadb_supported returned into ipsec_supported. 709 * OUT: 710 * 0: success and return length sent. 711 * -1: error occured, and set errno. 712 */ 713int 714pfkey_recv_register(so) 715 int so; 716{ 717 pid_t pid = getpid(); 718 struct sadb_msg *newmsg; 719 int error = -1; 720 721 /* receive message */ 722 for (;;) { 723 if ((newmsg = pfkey_recv(so)) == NULL) 724 return -1; 725 if (newmsg->sadb_msg_type == SADB_REGISTER && 726 newmsg->sadb_msg_pid == pid) 727 break; 728 free(newmsg); 729 } 730 731 /* check and fix */ 732 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); 733 734 error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len); 735 free(newmsg); 736 737 if (error == 0) 738 __ipsec_errcode = EIPSEC_NO_ERROR; 739 740 return error; 741} 742 743/* 744 * receiving SADB_REGISTER message from the kernel, and copy buffer for 745 * sadb_supported returned into ipsec_supported. 746 * NOTE: sadb_msg_len must be host order. 747 * IN: 748 * tlen: msg length, it's to makeing sure. 749 * OUT: 750 * 0: success and return length sent. 751 * -1: error occured, and set errno. 752 */ 753int 754pfkey_set_supported(msg, tlen) 755 struct sadb_msg *msg; 756 int tlen; 757{ 758 struct sadb_supported *sup; 759 caddr_t p; 760 caddr_t ep; 761 762 /* validity */ 763 if (msg->sadb_msg_len != tlen) { 764 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 765 return -1; 766 } 767 768 p = (void *)msg; 769 ep = p + tlen; 770 771 p += sizeof(struct sadb_msg); 772 773 while (p < ep) { 774 sup = (void *)p; 775 if (ep < p + sizeof(*sup) || 776 PFKEY_EXTLEN(sup) < sizeof(*sup) || 777 ep < p + sup->sadb_supported_len) { 778 /* invalid format */ 779 break; 780 } 781 782 switch (sup->sadb_supported_exttype) { 783 case SADB_EXT_SUPPORTED_AUTH: 784 case SADB_EXT_SUPPORTED_ENCRYPT: 785 break; 786 default: 787 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 788 return -1; 789 } 790 791 /* fixed length */ 792 sup->sadb_supported_len = PFKEY_EXTLEN(sup); 793 794 /* set supported map */ 795 if (setsupportedmap(sup) != 0) 796 return -1; 797 798 p += sup->sadb_supported_len; 799 } 800 801 if (p != ep) { 802 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 803 return -1; 804 } 805 806 __ipsec_errcode = EIPSEC_NO_ERROR; 807 808 return 0; 809} 810 811/* 812 * sending SADB_FLUSH message to the kernel. 813 * OUT: 814 * positive: success and return length sent. 815 * -1 : error occured, and set errno. 816 */ 817int 818pfkey_send_flush(so, satype) 819 int so; 820 u_int satype; 821{ 822 int len; 823 824 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0) 825 return -1; 826 827 return len; 828} 829 830/* 831 * sending SADB_DUMP message to the kernel. 832 * OUT: 833 * positive: success and return length sent. 834 * -1 : error occured, and set errno. 835 */ 836int 837pfkey_send_dump(so, satype) 838 int so; 839 u_int satype; 840{ 841 int len; 842 843 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0) 844 return -1; 845 846 return len; 847} 848 849/* 850 * sending SADB_X_PROMISC message to the kernel. 851 * NOTE that this function handles promisc mode toggle only. 852 * IN: 853 * flag: set promisc off if zero, set promisc on if non-zero. 854 * OUT: 855 * positive: success and return length sent. 856 * -1 : error occured, and set errno. 857 * 0 : error occured, and set errno. 858 * others: a pointer to new allocated buffer in which supported 859 * algorithms is. 860 */ 861int 862pfkey_send_promisc_toggle(so, flag) 863 int so; 864 int flag; 865{ 866 int len; 867 868 if ((len = pfkey_send_x3(so, SADB_X_PROMISC, 869 (u_int)(flag ? 1 : 0))) < 0) 870 return -1; 871 872 return len; 873} 874 875/* 876 * sending SADB_X_SPDADD message to the kernel. 877 * OUT: 878 * positive: success and return length sent. 879 * -1 : error occured, and set errno. 880 */ 881int 882pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 883 int so; 884 struct sockaddr *src, *dst; 885 u_int prefs, prefd, proto; 886 caddr_t policy; 887 int policylen; 888 u_int32_t seq; 889{ 890 int len; 891 892 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 893 src, prefs, dst, prefd, proto, 894 (u_int64_t)0, (u_int64_t)0, 895 policy, policylen, seq)) < 0) 896 return -1; 897 898 return len; 899} 900 901/* 902 * sending SADB_X_SPDADD message to the kernel. 903 * OUT: 904 * positive: success and return length sent. 905 * -1 : error occured, and set errno. 906 */ 907int 908pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime, 909 policy, policylen, seq) 910 int so; 911 struct sockaddr *src, *dst; 912 u_int prefs, prefd, proto; 913 u_int64_t ltime, vtime; 914 caddr_t policy; 915 int policylen; 916 u_int32_t seq; 917{ 918 int len; 919 920 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 921 src, prefs, dst, prefd, proto, 922 ltime, vtime, 923 policy, policylen, seq)) < 0) 924 return -1; 925 926 return len; 927} 928 929/* 930 * sending SADB_X_SPDUPDATE message to the kernel. 931 * OUT: 932 * positive: success and return length sent. 933 * -1 : error occured, and set errno. 934 */ 935int 936pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 937 int so; 938 struct sockaddr *src, *dst; 939 u_int prefs, prefd, proto; 940 caddr_t policy; 941 int policylen; 942 u_int32_t seq; 943{ 944 int len; 945 946 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 947 src, prefs, dst, prefd, proto, 948 (u_int64_t)0, (u_int64_t)0, 949 policy, policylen, seq)) < 0) 950 return -1; 951 952 return len; 953} 954 955/* 956 * sending SADB_X_SPDUPDATE message to the kernel. 957 * OUT: 958 * positive: success and return length sent. 959 * -1 : error occured, and set errno. 960 */ 961int 962pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime, 963 policy, policylen, seq) 964 int so; 965 struct sockaddr *src, *dst; 966 u_int prefs, prefd, proto; 967 u_int64_t ltime, vtime; 968 caddr_t policy; 969 int policylen; 970 u_int32_t seq; 971{ 972 int len; 973 974 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 975 src, prefs, dst, prefd, proto, 976 ltime, vtime, 977 policy, policylen, seq)) < 0) 978 return -1; 979 980 return len; 981} 982 983/* 984 * sending SADB_X_SPDDELETE message to the kernel. 985 * OUT: 986 * positive: success and return length sent. 987 * -1 : error occured, and set errno. 988 */ 989int 990pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 991 int so; 992 struct sockaddr *src, *dst; 993 u_int prefs, prefd, proto; 994 caddr_t policy; 995 int policylen; 996 u_int32_t seq; 997{ 998 int len; 999 1000 if (policylen != sizeof(struct sadb_x_policy)) { 1001 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1002 return -1; 1003 } 1004 1005 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, 1006 src, prefs, dst, prefd, proto, 1007 (u_int64_t)0, (u_int64_t)0, 1008 policy, policylen, seq)) < 0) 1009 return -1; 1010 1011 return len; 1012} 1013 1014/* 1015 * sending SADB_X_SPDDELETE message to the kernel. 1016 * OUT: 1017 * positive: success and return length sent. 1018 * -1 : error occured, and set errno. 1019 */ 1020int 1021pfkey_send_spddelete2(so, spid) 1022 int so; 1023 u_int32_t spid; 1024{ 1025 int len; 1026 1027 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0) 1028 return -1; 1029 1030 return len; 1031} 1032 1033/* 1034 * sending SADB_X_SPDGET message to the kernel. 1035 * OUT: 1036 * positive: success and return length sent. 1037 * -1 : error occured, and set errno. 1038 */ 1039int 1040pfkey_send_spdget(so, spid) 1041 int so; 1042 u_int32_t spid; 1043{ 1044 int len; 1045 1046 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0) 1047 return -1; 1048 1049 return len; 1050} 1051 1052/* 1053 * sending SADB_X_SPDSETIDX message to the kernel. 1054 * OUT: 1055 * positive: success and return length sent. 1056 * -1 : error occured, and set errno. 1057 */ 1058int 1059pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 1060 int so; 1061 struct sockaddr *src, *dst; 1062 u_int prefs, prefd, proto; 1063 caddr_t policy; 1064 int policylen; 1065 u_int32_t seq; 1066{ 1067 int len; 1068 1069 if (policylen != sizeof(struct sadb_x_policy)) { 1070 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1071 return -1; 1072 } 1073 1074 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, 1075 src, prefs, dst, prefd, proto, 1076 (u_int64_t)0, (u_int64_t)0, 1077 policy, policylen, seq)) < 0) 1078 return -1; 1079 1080 return len; 1081} 1082 1083/* 1084 * sending SADB_SPDFLUSH message to the kernel. 1085 * OUT: 1086 * positive: success and return length sent. 1087 * -1 : error occured, and set errno. 1088 */ 1089int 1090pfkey_send_spdflush(so) 1091 int so; 1092{ 1093 int len; 1094 1095 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0) 1096 return -1; 1097 1098 return len; 1099} 1100 1101/* 1102 * sending SADB_SPDDUMP message to the kernel. 1103 * OUT: 1104 * positive: success and return length sent. 1105 * -1 : error occured, and set errno. 1106 */ 1107int 1108pfkey_send_spddump(so) 1109 int so; 1110{ 1111 int len; 1112 1113 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0) 1114 return -1; 1115 1116 return len; 1117} 1118 1119 1120#ifdef SADB_X_MIGRATE 1121/* 1122 * sending SADB_X_MIGRATE message to the kernel. 1123 * OUT: 1124 * positive: success and return length sent. 1125 * -1 : error occured, and set errno. 1126 */ 1127int 1128pfkey_send_migrate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 1129 int so; 1130 struct sockaddr *src, *dst; 1131 u_int prefs, prefd, proto; 1132 caddr_t policy; 1133 int policylen; 1134 u_int32_t seq; 1135{ 1136 struct sadb_msg *newmsg; 1137 int len; 1138 caddr_t p; 1139 int plen; 1140 caddr_t ep; 1141 1142 /* validity check */ 1143 if (src == NULL || dst == NULL) { 1144 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1145 return -1; 1146 } 1147 if (src->sa_family != dst->sa_family) { 1148 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1149 return -1; 1150 } 1151 1152 switch (src->sa_family) { 1153 case AF_INET: 1154 plen = sizeof(struct in_addr) << 3; 1155 break; 1156 case AF_INET6: 1157 plen = sizeof(struct in6_addr) << 3; 1158 break; 1159 default: 1160 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1161 return -1; 1162 } 1163 if (prefs > plen || prefd > plen) { 1164 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; 1165 return -1; 1166 } 1167 1168 /* create new sadb_msg to reply. */ 1169 len = sizeof(struct sadb_msg) 1170 + sizeof(struct sadb_address) 1171 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1172 + sizeof(struct sadb_address) 1173 + PFKEY_ALIGN8(sysdep_sa_len(dst)) 1174 + policylen; 1175 1176 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1177 __ipsec_set_strerror(strerror(errno)); 1178 return -1; 1179 } 1180 ep = ((caddr_t)newmsg) + len; 1181 1182 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_X_MIGRATE, (u_int)len, 1183 SADB_SATYPE_UNSPEC, seq, getpid()); 1184 if (!p) { 1185 free(newmsg); 1186 return -1; 1187 } 1188 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); 1189 if (!p) { 1190 free(newmsg); 1191 return -1; 1192 } 1193 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); 1194 if (!p || p + policylen != ep) { 1195 free(newmsg); 1196 return -1; 1197 } 1198 memcpy(p, policy, policylen); 1199 1200 /* send message */ 1201 len = pfkey_send(so, newmsg, len); 1202 free(newmsg); 1203 1204 if (len < 0) 1205 return -1; 1206 1207 __ipsec_errcode = EIPSEC_NO_ERROR; 1208 return len; 1209} 1210#endif 1211 1212 1213/* sending SADB_ADD or SADB_UPDATE message to the kernel */ 1214static int 1215pfkey_send_x1(sa_parms) 1216 struct pfkey_send_sa_args *sa_parms; 1217{ 1218 struct sadb_msg *newmsg; 1219 int len; 1220 caddr_t p; 1221 int plen; 1222 caddr_t ep; 1223 1224 /* validity check */ 1225 if (sa_parms->src == NULL || sa_parms->dst == NULL) { 1226 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1227 return -1; 1228 } 1229 if (sa_parms->src->sa_family != sa_parms->dst->sa_family) { 1230 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1231 return -1; 1232 } 1233 switch (sa_parms->src->sa_family) { 1234 case AF_INET: 1235 plen = sizeof(struct in_addr) << 3; 1236 break; 1237 case AF_INET6: 1238 plen = sizeof(struct in6_addr) << 3; 1239 break; 1240 default: 1241 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1242 return -1; 1243 } 1244 1245 switch (sa_parms->satype) { 1246 case SADB_SATYPE_ESP: 1247 if (sa_parms->e_type == SADB_EALG_NONE) { 1248 __ipsec_errcode = EIPSEC_NO_ALGS; 1249 return -1; 1250 } 1251 break; 1252 case SADB_SATYPE_AH: 1253 if (sa_parms->e_type != SADB_EALG_NONE) { 1254 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1255 return -1; 1256 } 1257 if (sa_parms->a_type == SADB_AALG_NONE) { 1258 __ipsec_errcode = EIPSEC_NO_ALGS; 1259 return -1; 1260 } 1261 break; 1262 case SADB_X_SATYPE_IPCOMP: 1263 if (sa_parms->e_type == SADB_X_CALG_NONE) { 1264 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1265 return -1; 1266 } 1267 if (sa_parms->a_type != SADB_AALG_NONE) { 1268 __ipsec_errcode = EIPSEC_NO_ALGS; 1269 return -1; 1270 } 1271 break; 1272#ifdef SADB_X_AALG_TCP_MD5 1273 case SADB_X_SATYPE_TCPSIGNATURE: 1274 if (sa_parms->e_type != SADB_EALG_NONE) { 1275 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1276 return -1; 1277 } 1278 if (sa_parms->a_type != SADB_X_AALG_TCP_MD5) { 1279 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1280 return -1; 1281 } 1282 break; 1283#endif 1284 default: 1285 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1286 return -1; 1287 } 1288 1289 /* create new sadb_msg to reply. */ 1290 len = sizeof(struct sadb_msg) 1291 + sizeof(struct sadb_sa) 1292 + sizeof(struct sadb_x_sa2) 1293 + sizeof(struct sadb_address) 1294 + PFKEY_ALIGN8(sysdep_sa_len(sa_parms->src)) 1295 + sizeof(struct sadb_address) 1296 + PFKEY_ALIGN8(sysdep_sa_len(sa_parms->dst)) 1297 + sizeof(struct sadb_lifetime) 1298 + sizeof(struct sadb_lifetime); 1299 1300 if (sa_parms->e_type != SADB_EALG_NONE && 1301 sa_parms->satype != SADB_X_SATYPE_IPCOMP) 1302 len += (sizeof(struct sadb_key) + 1303 PFKEY_ALIGN8(sa_parms->e_keylen)); 1304 if (sa_parms->a_type != SADB_AALG_NONE) 1305 len += (sizeof(struct sadb_key) + 1306 PFKEY_ALIGN8(sa_parms->a_keylen)); 1307 1308#ifdef SADB_X_EXT_SEC_CTX 1309 if (sa_parms->ctxstr != NULL) 1310 len += (sizeof(struct sadb_x_sec_ctx) 1311 + PFKEY_ALIGN8(sa_parms->ctxstrlen)); 1312#endif 1313 1314#ifdef SADB_X_EXT_NAT_T_TYPE 1315 /* add nat-t packets */ 1316 if (sa_parms->l_natt_type) { 1317 switch(sa_parms->satype) { 1318 case SADB_SATYPE_ESP: 1319 case SADB_X_SATYPE_IPCOMP: 1320 break; 1321 default: 1322 __ipsec_errcode = EIPSEC_NO_ALGS; 1323 return -1; 1324 } 1325 1326 len += sizeof(struct sadb_x_nat_t_type); 1327 len += sizeof(struct sadb_x_nat_t_port); 1328 len += sizeof(struct sadb_x_nat_t_port); 1329 if (sa_parms->l_natt_oa) 1330 len += sizeof(struct sadb_address) + 1331 PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oa)); 1332#ifdef SADB_X_EXT_NAT_T_FRAG 1333 if (sa_parms->l_natt_frag) 1334 len += sizeof(struct sadb_x_nat_t_frag); 1335#endif 1336 } 1337#endif 1338 1339 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1340 __ipsec_set_strerror(strerror(errno)); 1341 return -1; 1342 } 1343 ep = ((caddr_t)(void *)newmsg) + len; 1344 1345 p = pfkey_setsadbmsg((void *)newmsg, ep, sa_parms->type, (u_int)len, 1346 sa_parms->satype, sa_parms->seq, getpid()); 1347 if (!p) { 1348 free(newmsg); 1349 return -1; 1350 } 1351 p = pfkey_setsadbsa(p, ep, sa_parms->spi, sa_parms->wsize, 1352 sa_parms->a_type, sa_parms->e_type, 1353 sa_parms->flags); 1354 if (!p) { 1355 free(newmsg); 1356 return -1; 1357 } 1358 p = pfkey_setsadbxsa2(p, ep, sa_parms->mode, sa_parms->reqid); 1359 if (!p) { 1360 free(newmsg); 1361 return -1; 1362 } 1363 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, sa_parms->src, 1364 (u_int)plen, IPSEC_ULPROTO_ANY); 1365 if (!p) { 1366 free(newmsg); 1367 return -1; 1368 } 1369 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, sa_parms->dst, 1370 (u_int)plen, IPSEC_ULPROTO_ANY); 1371 if (!p) { 1372 free(newmsg); 1373 return -1; 1374 } 1375 1376 if (sa_parms->e_type != SADB_EALG_NONE && 1377 sa_parms->satype != SADB_X_SATYPE_IPCOMP) { 1378 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT, 1379 sa_parms->keymat, sa_parms->e_keylen); 1380 if (!p) { 1381 free(newmsg); 1382 return -1; 1383 } 1384 } 1385 if (sa_parms->a_type != SADB_AALG_NONE) { 1386 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH, 1387 sa_parms->keymat + sa_parms->e_keylen, 1388 sa_parms->a_keylen); 1389 if (!p) { 1390 free(newmsg); 1391 return -1; 1392 } 1393 } 1394 1395 /* set sadb_lifetime for destination */ 1396 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 1397 sa_parms->l_alloc, sa_parms->l_bytes, 1398 sa_parms->l_addtime, sa_parms->l_usetime); 1399 if (!p) { 1400 free(newmsg); 1401 return -1; 1402 } 1403 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT, 1404 sa_parms->l_alloc, sa_parms->l_bytes, 1405 sa_parms->l_addtime, sa_parms->l_usetime); 1406 if (!p) { 1407 free(newmsg); 1408 return -1; 1409 } 1410#ifdef SADB_X_EXT_SEC_CTX 1411 if (sa_parms->ctxstr != NULL) { 1412 p = pfkey_setsecctx(p, ep, SADB_X_EXT_SEC_CTX, sa_parms->ctxdoi, 1413 sa_parms->ctxalg, sa_parms->ctxstr, 1414 sa_parms->ctxstrlen); 1415 if (!p) { 1416 free(newmsg); 1417 return -1; 1418 } 1419 } 1420#endif 1421 1422#ifdef SADB_X_EXT_NAT_T_TYPE 1423 /* Add nat-t messages */ 1424 if (sa_parms->l_natt_type) { 1425 p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, 1426 sa_parms->l_natt_type); 1427 if (!p) { 1428 free(newmsg); 1429 return -1; 1430 } 1431 1432 p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT, 1433 sa_parms->l_natt_sport); 1434 if (!p) { 1435 free(newmsg); 1436 return -1; 1437 } 1438 1439 p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT, 1440 sa_parms->l_natt_dport); 1441 if (!p) { 1442 free(newmsg); 1443 return -1; 1444 } 1445 1446 if (sa_parms->l_natt_oa) { 1447 p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_NAT_T_OA, 1448 sa_parms->l_natt_oa, 1449 (u_int)PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oa)), 1450 IPSEC_ULPROTO_ANY); 1451 if (!p) { 1452 free(newmsg); 1453 return -1; 1454 } 1455 } 1456 1457#ifdef SADB_X_EXT_NAT_T_FRAG 1458 if (sa_parms->l_natt_frag) { 1459 p = pfkey_set_natt_frag(p, ep, SADB_X_EXT_NAT_T_FRAG, 1460 sa_parms->l_natt_frag); 1461 if (!p) { 1462 free(newmsg); 1463 return -1; 1464 } 1465 } 1466#endif 1467 } 1468#endif 1469 1470 if (p != ep) { 1471 free(newmsg); 1472 return -1; 1473 } 1474 1475 /* send message */ 1476 len = pfkey_send(sa_parms->so, newmsg, len); 1477 free(newmsg); 1478 1479 if (len < 0) 1480 return -1; 1481 1482 __ipsec_errcode = EIPSEC_NO_ERROR; 1483 return len; 1484} 1485 1486/* sending SADB_DELETE or SADB_GET message to the kernel */ 1487/*ARGSUSED*/ 1488static int 1489pfkey_send_x2(so, type, satype, mode, src, dst, spi) 1490 int so; 1491 u_int type, satype, mode; 1492 struct sockaddr *src, *dst; 1493 u_int32_t spi; 1494{ 1495 struct sadb_msg *newmsg; 1496 int len; 1497 caddr_t p; 1498 int plen; 1499 caddr_t ep; 1500 1501 /* validity check */ 1502 if (src == NULL || dst == NULL) { 1503 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1504 return -1; 1505 } 1506 if (src->sa_family != dst->sa_family) { 1507 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1508 return -1; 1509 } 1510 switch (src->sa_family) { 1511 case AF_INET: 1512 plen = sizeof(struct in_addr) << 3; 1513 break; 1514 case AF_INET6: 1515 plen = sizeof(struct in6_addr) << 3; 1516 break; 1517 default: 1518 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1519 return -1; 1520 } 1521 1522 /* create new sadb_msg to reply. */ 1523 len = sizeof(struct sadb_msg) 1524 + sizeof(struct sadb_sa) 1525 + sizeof(struct sadb_address) 1526 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1527 + sizeof(struct sadb_address) 1528 + PFKEY_ALIGN8(sysdep_sa_len(dst)); 1529 1530 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1531 __ipsec_set_strerror(strerror(errno)); 1532 return -1; 1533 } 1534 ep = ((caddr_t)(void *)newmsg) + len; 1535 1536 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0, 1537 getpid()); 1538 if (!p) { 1539 free(newmsg); 1540 return -1; 1541 } 1542 p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0); 1543 if (!p) { 1544 free(newmsg); 1545 return -1; 1546 } 1547 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, 1548 IPSEC_ULPROTO_ANY); 1549 if (!p) { 1550 free(newmsg); 1551 return -1; 1552 } 1553 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, 1554 IPSEC_ULPROTO_ANY); 1555 if (!p || p != ep) { 1556 free(newmsg); 1557 return -1; 1558 } 1559 1560 /* send message */ 1561 len = pfkey_send(so, newmsg, len); 1562 free(newmsg); 1563 1564 if (len < 0) 1565 return -1; 1566 1567 __ipsec_errcode = EIPSEC_NO_ERROR; 1568 return len; 1569} 1570 1571/* 1572 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message 1573 * to the kernel 1574 */ 1575static int 1576pfkey_send_x3(so, type, satype) 1577 int so; 1578 u_int type, satype; 1579{ 1580 struct sadb_msg *newmsg; 1581 int len; 1582 caddr_t p; 1583 caddr_t ep; 1584 1585 /* validity check */ 1586 switch (type) { 1587 case SADB_X_PROMISC: 1588 if (satype != 0 && satype != 1) { 1589 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1590 return -1; 1591 } 1592 break; 1593 default: 1594 switch (satype) { 1595 case SADB_SATYPE_UNSPEC: 1596 case SADB_SATYPE_AH: 1597 case SADB_SATYPE_ESP: 1598 case SADB_X_SATYPE_IPCOMP: 1599#ifdef SADB_X_SATYPE_TCPSIGNATURE 1600 case SADB_X_SATYPE_TCPSIGNATURE: 1601#endif 1602 break; 1603 default: 1604 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1605 return -1; 1606 } 1607 } 1608 1609 /* create new sadb_msg to send. */ 1610 len = sizeof(struct sadb_msg); 1611 1612 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1613 __ipsec_set_strerror(strerror(errno)); 1614 return -1; 1615 } 1616 ep = ((caddr_t)(void *)newmsg) + len; 1617 1618 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0, 1619 getpid()); 1620 if (!p || p != ep) { 1621 free(newmsg); 1622 return -1; 1623 } 1624 1625 /* send message */ 1626 len = pfkey_send(so, newmsg, len); 1627 free(newmsg); 1628 1629 if (len < 0) 1630 return -1; 1631 1632 __ipsec_errcode = EIPSEC_NO_ERROR; 1633 return len; 1634} 1635 1636/* sending SADB_X_SPDADD message to the kernel */ 1637static int 1638pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, 1639 ltime, vtime, policy, policylen, seq) 1640 int so; 1641 struct sockaddr *src, *dst; 1642 u_int type, prefs, prefd, proto; 1643 u_int64_t ltime, vtime; 1644 char *policy; 1645 int policylen; 1646 u_int32_t seq; 1647{ 1648 struct sadb_msg *newmsg; 1649 int len; 1650 caddr_t p; 1651 int plen; 1652 caddr_t ep; 1653 1654 /* validity check */ 1655 if (src == NULL || dst == NULL) { 1656 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1657 return -1; 1658 } 1659 if (src->sa_family != dst->sa_family) { 1660 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1661 return -1; 1662 } 1663 1664 switch (src->sa_family) { 1665 case AF_INET: 1666 plen = sizeof(struct in_addr) << 3; 1667 break; 1668 case AF_INET6: 1669 plen = sizeof(struct in6_addr) << 3; 1670 break; 1671 default: 1672 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1673 return -1; 1674 } 1675 if (prefs > plen || prefd > plen) { 1676 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; 1677 return -1; 1678 } 1679 1680 /* create new sadb_msg to reply. */ 1681 len = sizeof(struct sadb_msg) 1682 + sizeof(struct sadb_address) 1683 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1684 + sizeof(struct sadb_address) 1685 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1686 + sizeof(struct sadb_lifetime) 1687 + policylen; 1688 1689 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1690 __ipsec_set_strerror(strerror(errno)); 1691 return -1; 1692 } 1693 ep = ((caddr_t)(void *)newmsg) + len; 1694 1695 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, 1696 SADB_SATYPE_UNSPEC, seq, getpid()); 1697 if (!p) { 1698 free(newmsg); 1699 return -1; 1700 } 1701 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); 1702 if (!p) { 1703 free(newmsg); 1704 return -1; 1705 } 1706 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); 1707 if (!p) { 1708 free(newmsg); 1709 return -1; 1710 } 1711 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 1712 0, 0, (u_int)ltime, (u_int)vtime); 1713 if (!p || p + policylen != ep) { 1714 free(newmsg); 1715 return -1; 1716 } 1717 memcpy(p, policy, (size_t)policylen); 1718 1719 /* send message */ 1720 len = pfkey_send(so, newmsg, len); 1721 free(newmsg); 1722 1723 if (len < 0) 1724 return -1; 1725 1726 __ipsec_errcode = EIPSEC_NO_ERROR; 1727 return len; 1728} 1729 1730/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ 1731static int 1732pfkey_send_x5(so, type, spid) 1733 int so; 1734 u_int type; 1735 u_int32_t spid; 1736{ 1737 struct sadb_msg *newmsg; 1738 struct sadb_x_policy xpl; 1739 int len; 1740 caddr_t p; 1741 caddr_t ep; 1742 1743 /* create new sadb_msg to reply. */ 1744 len = sizeof(struct sadb_msg) 1745 + sizeof(xpl); 1746 1747 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1748 __ipsec_set_strerror(strerror(errno)); 1749 return -1; 1750 } 1751 ep = ((caddr_t)(void *)newmsg) + len; 1752 1753 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, 1754 SADB_SATYPE_UNSPEC, 0, getpid()); 1755 if (!p) { 1756 free(newmsg); 1757 return -1; 1758 } 1759 1760 if (p + sizeof(xpl) != ep) { 1761 free(newmsg); 1762 return -1; 1763 } 1764 memset(&xpl, 0, sizeof(xpl)); 1765 xpl.sadb_x_policy_len = PFKEY_UNIT64(sizeof(xpl)); 1766 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; 1767 xpl.sadb_x_policy_id = spid; 1768 memcpy(p, &xpl, sizeof(xpl)); 1769 1770 /* send message */ 1771 len = pfkey_send(so, newmsg, len); 1772 free(newmsg); 1773 1774 if (len < 0) 1775 return -1; 1776 1777 __ipsec_errcode = EIPSEC_NO_ERROR; 1778 return len; 1779} 1780 1781/* 1782 * open a socket. 1783 * OUT: 1784 * -1: fail. 1785 * others : success and return value of socket. 1786 */ 1787int 1788pfkey_open() 1789{ 1790 int so; 1791 int bufsiz = 128 * 1024; /*is 128K enough?*/ 1792 1793 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { 1794 __ipsec_set_strerror(strerror(errno)); 1795 return -1; 1796 } 1797 1798 /* 1799 * This is a temporary workaround for KAME PR 154. 1800 * Don't really care even if it fails. 1801 */ 1802 (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)); 1803 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1804 bufsiz = 256 * 1024; 1805 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1806 bufsiz = 512 * 1024; 1807 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1808 bufsiz = 1024 * 1024; 1809 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1810 __ipsec_errcode = EIPSEC_NO_ERROR; 1811 return so; 1812} 1813 1814/* 1815 * close a socket. 1816 * OUT: 1817 * 0: success. 1818 * -1: fail. 1819 */ 1820void 1821pfkey_close(so) 1822 int so; 1823{ 1824 (void)close(so); 1825 1826 __ipsec_errcode = EIPSEC_NO_ERROR; 1827 return; 1828} 1829 1830/* 1831 * receive sadb_msg data, and return pointer to new buffer allocated. 1832 * Must free this buffer later. 1833 * OUT: 1834 * NULL : error occured. 1835 * others : a pointer to sadb_msg structure. 1836 * 1837 * XXX should be rewritten to pass length explicitly 1838 */ 1839struct sadb_msg * 1840pfkey_recv(so) 1841 int so; 1842{ 1843 struct sadb_msg buf, *newmsg; 1844 int len, reallen; 1845 1846 while ((len = recv(so, (void *)&buf, sizeof(buf), MSG_PEEK)) < 0) { 1847 if (errno == EINTR) 1848 continue; 1849 __ipsec_set_strerror(strerror(errno)); 1850 return NULL; 1851 } 1852 1853 if (len < sizeof(buf)) { 1854 recv(so, (void *)&buf, sizeof(buf), 0); 1855 __ipsec_errcode = EIPSEC_MAX; 1856 return NULL; 1857 } 1858 1859 /* read real message */ 1860 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); 1861 if ((newmsg = CALLOC((size_t)reallen, struct sadb_msg *)) == 0) { 1862 __ipsec_set_strerror(strerror(errno)); 1863 return NULL; 1864 } 1865 1866 while ((len = recv(so, (void *)newmsg, (socklen_t)reallen, 0)) < 0) { 1867 if (errno == EINTR) 1868 continue; 1869 __ipsec_set_strerror(strerror(errno)); 1870 free(newmsg); 1871 return NULL; 1872 } 1873 1874 if (len != reallen) { 1875 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1876 free(newmsg); 1877 return NULL; 1878 } 1879 1880 /* don't trust what the kernel says, validate! */ 1881 if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) { 1882 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1883 free(newmsg); 1884 return NULL; 1885 } 1886 1887 __ipsec_errcode = EIPSEC_NO_ERROR; 1888 return newmsg; 1889} 1890 1891/* 1892 * send message to a socket. 1893 * OUT: 1894 * others: success and return length sent. 1895 * -1 : fail. 1896 */ 1897int 1898pfkey_send(so, msg, len) 1899 int so; 1900 struct sadb_msg *msg; 1901 int len; 1902{ 1903 if ((len = send(so, (void *)msg, (socklen_t)len, 0)) < 0) { 1904 __ipsec_set_strerror(strerror(errno)); 1905 return -1; 1906 } 1907 1908 __ipsec_errcode = EIPSEC_NO_ERROR; 1909 return len; 1910} 1911 1912/* 1913 * %%% Utilities 1914 * NOTE: These functions are derived from netkey/key.c in KAME. 1915 */ 1916/* 1917 * set the pointer to each header in this message buffer. 1918 * IN: msg: pointer to message buffer. 1919 * mhp: pointer to the buffer initialized like below: 1920 * caddr_t mhp[SADB_EXT_MAX + 1]; 1921 * OUT: -1: invalid. 1922 * 0: valid. 1923 * 1924 * XXX should be rewritten to obtain length explicitly 1925 */ 1926int 1927pfkey_align(msg, mhp) 1928 struct sadb_msg *msg; 1929 caddr_t *mhp; 1930{ 1931 struct sadb_ext *ext; 1932 int i; 1933 caddr_t p; 1934 caddr_t ep; /* XXX should be passed from upper layer */ 1935 1936 /* validity check */ 1937 if (msg == NULL || mhp == NULL) { 1938 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1939 return -1; 1940 } 1941 1942 /* initialize */ 1943 for (i = 0; i < SADB_EXT_MAX + 1; i++) 1944 mhp[i] = NULL; 1945 1946 mhp[0] = (void *)msg; 1947 1948 /* initialize */ 1949 p = (void *) msg; 1950 ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len); 1951 1952 /* skip base header */ 1953 p += sizeof(struct sadb_msg); 1954 1955 while (p < ep) { 1956 ext = (void *)p; 1957 if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) || 1958 ep < p + PFKEY_EXTLEN(ext)) { 1959 /* invalid format */ 1960 break; 1961 } 1962 1963 /* duplicate check */ 1964 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/ 1965 if (mhp[ext->sadb_ext_type] != NULL) { 1966 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1967 return -1; 1968 } 1969 1970 /* set pointer */ 1971 switch (ext->sadb_ext_type) { 1972 case SADB_EXT_SA: 1973 case SADB_EXT_LIFETIME_CURRENT: 1974 case SADB_EXT_LIFETIME_HARD: 1975 case SADB_EXT_LIFETIME_SOFT: 1976 case SADB_EXT_ADDRESS_SRC: 1977 case SADB_EXT_ADDRESS_DST: 1978 case SADB_EXT_ADDRESS_PROXY: 1979 case SADB_EXT_KEY_AUTH: 1980 /* XXX should to be check weak keys. */ 1981 case SADB_EXT_KEY_ENCRYPT: 1982 /* XXX should to be check weak keys. */ 1983 case SADB_EXT_IDENTITY_SRC: 1984 case SADB_EXT_IDENTITY_DST: 1985 case SADB_EXT_SENSITIVITY: 1986 case SADB_EXT_PROPOSAL: 1987 case SADB_EXT_SUPPORTED_AUTH: 1988 case SADB_EXT_SUPPORTED_ENCRYPT: 1989 case SADB_EXT_SPIRANGE: 1990 case SADB_X_EXT_POLICY: 1991 case SADB_X_EXT_SA2: 1992#ifdef SADB_X_EXT_NAT_T_TYPE 1993 case SADB_X_EXT_NAT_T_TYPE: 1994 case SADB_X_EXT_NAT_T_SPORT: 1995 case SADB_X_EXT_NAT_T_DPORT: 1996 case SADB_X_EXT_NAT_T_OA: 1997#endif 1998#ifdef SADB_X_EXT_TAG 1999 case SADB_X_EXT_TAG: 2000#endif 2001#ifdef SADB_X_EXT_PACKET 2002 case SADB_X_EXT_PACKET: 2003#endif 2004#ifdef SADB_X_EXT_SEC_CTX 2005 case SADB_X_EXT_SEC_CTX: 2006#endif 2007 mhp[ext->sadb_ext_type] = (void *)ext; 2008 break; 2009 default: 2010 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 2011 return -1; 2012 } 2013 2014 p += PFKEY_EXTLEN(ext); 2015 } 2016 2017 if (p != ep) { 2018 __ipsec_errcode = EIPSEC_INVAL_SADBMSG; 2019 return -1; 2020 } 2021 2022 __ipsec_errcode = EIPSEC_NO_ERROR; 2023 return 0; 2024} 2025 2026/* 2027 * check basic usage for sadb_msg, 2028 * NOTE: This routine is derived from netkey/key.c in KAME. 2029 * IN: msg: pointer to message buffer. 2030 * mhp: pointer to the buffer initialized like below: 2031 * 2032 * caddr_t mhp[SADB_EXT_MAX + 1]; 2033 * 2034 * OUT: -1: invalid. 2035 * 0: valid. 2036 */ 2037int 2038pfkey_check(mhp) 2039 caddr_t *mhp; 2040{ 2041 struct sadb_msg *msg; 2042 2043 /* validity check */ 2044 if (mhp == NULL || mhp[0] == NULL) { 2045 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 2046 return -1; 2047 } 2048 2049 msg = (void *)mhp[0]; 2050 2051 /* check version */ 2052 if (msg->sadb_msg_version != PF_KEY_V2) { 2053 __ipsec_errcode = EIPSEC_INVAL_VERSION; 2054 return -1; 2055 } 2056 2057 /* check type */ 2058 if (msg->sadb_msg_type > SADB_MAX) { 2059 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE; 2060 return -1; 2061 } 2062 2063 /* check SA type */ 2064 switch (msg->sadb_msg_satype) { 2065 case SADB_SATYPE_UNSPEC: 2066 switch (msg->sadb_msg_type) { 2067 case SADB_GETSPI: 2068 case SADB_UPDATE: 2069 case SADB_ADD: 2070 case SADB_DELETE: 2071 case SADB_GET: 2072 case SADB_ACQUIRE: 2073 case SADB_EXPIRE: 2074#ifdef SADB_X_NAT_T_NEW_MAPPING 2075 case SADB_X_NAT_T_NEW_MAPPING: 2076#endif 2077 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2078 return -1; 2079 } 2080 break; 2081 case SADB_SATYPE_ESP: 2082 case SADB_SATYPE_AH: 2083 case SADB_X_SATYPE_IPCOMP: 2084#ifdef SADB_X_SATYPE_TCPSIGNATURE 2085 case SADB_X_SATYPE_TCPSIGNATURE: 2086#endif 2087 switch (msg->sadb_msg_type) { 2088 case SADB_X_SPDADD: 2089 case SADB_X_SPDDELETE: 2090 case SADB_X_SPDGET: 2091 case SADB_X_SPDDUMP: 2092 case SADB_X_SPDFLUSH: 2093 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2094 return -1; 2095 } 2096#ifdef SADB_X_NAT_T_NEW_MAPPING 2097 if (msg->sadb_msg_type == SADB_X_NAT_T_NEW_MAPPING && 2098 msg->sadb_msg_satype != SADB_SATYPE_ESP) { 2099 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2100 return -1; 2101 } 2102#endif 2103 break; 2104 case SADB_SATYPE_RSVP: 2105 case SADB_SATYPE_OSPFV2: 2106 case SADB_SATYPE_RIPV2: 2107 case SADB_SATYPE_MIP: 2108 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 2109 return -1; 2110 case 1: /* XXX: What does it do ? */ 2111 if (msg->sadb_msg_type == SADB_X_PROMISC) 2112 break; 2113 /*FALLTHROUGH*/ 2114 default: 2115 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2116 return -1; 2117 } 2118 2119 /* check field of upper layer protocol and address family */ 2120 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL 2121 && mhp[SADB_EXT_ADDRESS_DST] != NULL) { 2122 struct sadb_address *src0, *dst0; 2123 2124 src0 = (void *)(mhp[SADB_EXT_ADDRESS_SRC]); 2125 dst0 = (void *)(mhp[SADB_EXT_ADDRESS_DST]); 2126 2127 if (src0->sadb_address_proto != dst0->sadb_address_proto) { 2128 __ipsec_errcode = EIPSEC_PROTO_MISMATCH; 2129 return -1; 2130 } 2131 2132 if (PFKEY_ADDR_SADDR(src0)->sa_family 2133 != PFKEY_ADDR_SADDR(dst0)->sa_family) { 2134 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 2135 return -1; 2136 } 2137 2138 switch (PFKEY_ADDR_SADDR(src0)->sa_family) { 2139 case AF_INET: 2140 case AF_INET6: 2141 break; 2142 default: 2143 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 2144 return -1; 2145 } 2146 2147 /* 2148 * prefixlen == 0 is valid because there must be the case 2149 * all addresses are matched. 2150 */ 2151 } 2152 2153 __ipsec_errcode = EIPSEC_NO_ERROR; 2154 return 0; 2155} 2156 2157/* 2158 * set data into sadb_msg. 2159 * `buf' must has been allocated sufficiently. 2160 */ 2161static caddr_t 2162pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid) 2163 caddr_t buf; 2164 caddr_t lim; 2165 u_int type, satype; 2166 u_int tlen; 2167 u_int32_t seq; 2168 pid_t pid; 2169{ 2170 struct sadb_msg *p; 2171 u_int len; 2172 2173 p = (void *)buf; 2174 len = sizeof(struct sadb_msg); 2175 2176 if (buf + len > lim) 2177 return NULL; 2178 2179 memset(p, 0, len); 2180 p->sadb_msg_version = PF_KEY_V2; 2181 p->sadb_msg_type = type; 2182 p->sadb_msg_errno = 0; 2183 p->sadb_msg_satype = satype; 2184 p->sadb_msg_len = PFKEY_UNIT64(tlen); 2185 p->sadb_msg_reserved = 0; 2186 p->sadb_msg_seq = seq; 2187 p->sadb_msg_pid = (u_int32_t)pid; 2188 2189 return(buf + len); 2190} 2191 2192/* 2193 * copy secasvar data into sadb_address. 2194 * `buf' must has been allocated sufficiently. 2195 */ 2196static caddr_t 2197pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags) 2198 caddr_t buf; 2199 caddr_t lim; 2200 u_int32_t spi, flags; 2201 u_int wsize, auth, enc; 2202{ 2203 struct sadb_sa *p; 2204 u_int len; 2205 2206 p = (void *)buf; 2207 len = sizeof(struct sadb_sa); 2208 2209 if (buf + len > lim) 2210 return NULL; 2211 2212 memset(p, 0, len); 2213 p->sadb_sa_len = PFKEY_UNIT64(len); 2214 p->sadb_sa_exttype = SADB_EXT_SA; 2215 p->sadb_sa_spi = spi; 2216 p->sadb_sa_replay = wsize; 2217 p->sadb_sa_state = SADB_SASTATE_LARVAL; 2218 p->sadb_sa_auth = auth; 2219 p->sadb_sa_encrypt = enc; 2220 p->sadb_sa_flags = flags; 2221 2222 return(buf + len); 2223} 2224 2225/* 2226 * set data into sadb_address. 2227 * `buf' must has been allocated sufficiently. 2228 * prefixlen is in bits. 2229 */ 2230static caddr_t 2231pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto) 2232 caddr_t buf; 2233 caddr_t lim; 2234 u_int exttype; 2235 struct sockaddr *saddr; 2236 u_int prefixlen; 2237 u_int ul_proto; 2238{ 2239 struct sadb_address *p; 2240 u_int len; 2241 2242 p = (void *)buf; 2243 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len(saddr)); 2244 2245 if (buf + len > lim) 2246 return NULL; 2247 2248 memset(p, 0, len); 2249 p->sadb_address_len = PFKEY_UNIT64(len); 2250 p->sadb_address_exttype = exttype & 0xffff; 2251 p->sadb_address_proto = ul_proto & 0xff; 2252 p->sadb_address_prefixlen = prefixlen; 2253 p->sadb_address_reserved = 0; 2254 2255 memcpy(p + 1, saddr, (size_t)sysdep_sa_len(saddr)); 2256 2257 return(buf + len); 2258} 2259 2260/* 2261 * set sadb_key structure after clearing buffer with zero. 2262 * OUT: the pointer of buf + len. 2263 */ 2264static caddr_t 2265pfkey_setsadbkey(buf, lim, type, key, keylen) 2266 caddr_t buf; 2267 caddr_t lim; 2268 caddr_t key; 2269 u_int type, keylen; 2270{ 2271 struct sadb_key *p; 2272 u_int len; 2273 2274 p = (void *)buf; 2275 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); 2276 2277 if (buf + len > lim) 2278 return NULL; 2279 2280 memset(p, 0, len); 2281 p->sadb_key_len = PFKEY_UNIT64(len); 2282 p->sadb_key_exttype = type; 2283 p->sadb_key_bits = keylen << 3; 2284 p->sadb_key_reserved = 0; 2285 2286 memcpy(p + 1, key, keylen); 2287 2288 return buf + len; 2289} 2290 2291/* 2292 * set sadb_lifetime structure after clearing buffer with zero. 2293 * OUT: the pointer of buf + len. 2294 */ 2295static caddr_t 2296pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime) 2297 caddr_t buf; 2298 caddr_t lim; 2299 u_int type; 2300 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime; 2301{ 2302 struct sadb_lifetime *p; 2303 u_int len; 2304 2305 p = (void *)buf; 2306 len = sizeof(struct sadb_lifetime); 2307 2308 if (buf + len > lim) 2309 return NULL; 2310 2311 memset(p, 0, len); 2312 p->sadb_lifetime_len = PFKEY_UNIT64(len); 2313 p->sadb_lifetime_exttype = type; 2314 2315 switch (type) { 2316 case SADB_EXT_LIFETIME_SOFT: 2317 p->sadb_lifetime_allocations 2318 = (l_alloc * soft_lifetime_allocations_rate) /100; 2319 p->sadb_lifetime_bytes 2320 = (l_bytes * soft_lifetime_bytes_rate) /100; 2321 p->sadb_lifetime_addtime 2322 = (l_addtime * soft_lifetime_addtime_rate) /100; 2323 p->sadb_lifetime_usetime 2324 = (l_usetime * soft_lifetime_usetime_rate) /100; 2325 break; 2326 case SADB_EXT_LIFETIME_HARD: 2327 p->sadb_lifetime_allocations = l_alloc; 2328 p->sadb_lifetime_bytes = l_bytes; 2329 p->sadb_lifetime_addtime = l_addtime; 2330 p->sadb_lifetime_usetime = l_usetime; 2331 break; 2332 } 2333 2334 return buf + len; 2335} 2336 2337/* 2338 * copy secasvar data into sadb_address. 2339 * `buf' must has been allocated sufficiently. 2340 */ 2341static caddr_t 2342pfkey_setsadbxsa2(buf, lim, mode0, reqid) 2343 caddr_t buf; 2344 caddr_t lim; 2345 u_int32_t mode0; 2346 u_int32_t reqid; 2347{ 2348 struct sadb_x_sa2 *p; 2349 u_int8_t mode = mode0 & 0xff; 2350 u_int len; 2351 2352 p = (void *)buf; 2353 len = sizeof(struct sadb_x_sa2); 2354 2355 if (buf + len > lim) 2356 return NULL; 2357 2358 memset(p, 0, len); 2359 p->sadb_x_sa2_len = PFKEY_UNIT64(len); 2360 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; 2361 p->sadb_x_sa2_mode = mode; 2362 p->sadb_x_sa2_reqid = reqid; 2363 2364 return(buf + len); 2365} 2366 2367#ifdef SADB_X_EXT_NAT_T_TYPE 2368static caddr_t 2369pfkey_set_natt_type(buf, lim, type, l_natt_type) 2370 caddr_t buf; 2371 caddr_t lim; 2372 u_int type; 2373 u_int8_t l_natt_type; 2374{ 2375 struct sadb_x_nat_t_type *p; 2376 u_int len; 2377 2378 p = (void *)buf; 2379 len = sizeof(struct sadb_x_nat_t_type); 2380 2381 if (buf + len > lim) 2382 return NULL; 2383 2384 memset(p, 0, len); 2385 p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len); 2386 p->sadb_x_nat_t_type_exttype = type; 2387 p->sadb_x_nat_t_type_type = l_natt_type; 2388 2389 return(buf + len); 2390} 2391 2392static caddr_t 2393pfkey_set_natt_port(buf, lim, type, l_natt_port) 2394 caddr_t buf; 2395 caddr_t lim; 2396 u_int type; 2397 u_int16_t l_natt_port; 2398{ 2399 struct sadb_x_nat_t_port *p; 2400 u_int len; 2401 2402 p = (void *)buf; 2403 len = sizeof(struct sadb_x_nat_t_port); 2404 2405 if (buf + len > lim) 2406 return NULL; 2407 2408 memset(p, 0, len); 2409 p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len); 2410 p->sadb_x_nat_t_port_exttype = type; 2411 p->sadb_x_nat_t_port_port = htons(l_natt_port); 2412 2413 return(buf + len); 2414} 2415#endif 2416 2417#ifdef SADB_X_EXT_NAT_T_FRAG 2418static caddr_t 2419pfkey_set_natt_frag(buf, lim, type, l_natt_frag) 2420 caddr_t buf; 2421 caddr_t lim; 2422 u_int type; 2423 u_int16_t l_natt_frag; 2424{ 2425 struct sadb_x_nat_t_frag *p; 2426 u_int len; 2427 2428 p = (void *)buf; 2429 len = sizeof(struct sadb_x_nat_t_frag); 2430 2431 if (buf + len > lim) 2432 return NULL; 2433 2434 memset(p, 0, len); 2435 p->sadb_x_nat_t_frag_len = PFKEY_UNIT64(len); 2436 p->sadb_x_nat_t_frag_exttype = type; 2437 p->sadb_x_nat_t_frag_fraglen = l_natt_frag; 2438 2439 return(buf + len); 2440} 2441#endif 2442 2443#ifdef SADB_X_EXT_SEC_CTX 2444static caddr_t 2445pfkey_setsecctx(buf, lim, type, ctx_doi, ctx_alg, sec_ctx, sec_ctxlen) 2446 caddr_t buf; 2447 caddr_t lim; 2448 u_int type; 2449 u_int8_t ctx_doi, ctx_alg; 2450 caddr_t sec_ctx; 2451 u_int16_t sec_ctxlen; 2452{ 2453 struct sadb_x_sec_ctx *p; 2454 u_int len; 2455 2456 p = (struct sadb_x_sec_ctx *)buf; 2457 len = sizeof(struct sadb_x_sec_ctx) + PFKEY_ALIGN8(sec_ctxlen); 2458 2459 if (buf + len > lim) 2460 return NULL; 2461 2462 memset(p, 0, len); 2463 p->sadb_x_sec_len = PFKEY_UNIT64(len); 2464 p->sadb_x_sec_exttype = type; 2465 p->sadb_x_ctx_len = sec_ctxlen; 2466 p->sadb_x_ctx_doi = ctx_doi; 2467 p->sadb_x_ctx_alg = ctx_alg; 2468 2469 memcpy(p + 1, sec_ctx, sec_ctxlen); 2470 2471 return buf + len; 2472} 2473#endif 2474 2475/* 2476 * Deprecated, available for backward compatibility with third party 2477 * libipsec users. Please use pfkey_send_update2 and pfkey_send_add2 instead 2478 */ 2479int 2480pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize, 2481 keymat, e_type, e_keylen, a_type, a_keylen, flags, 2482 l_alloc, l_bytes, l_addtime, l_usetime, seq) 2483 int so; 2484 u_int satype, mode, wsize; 2485 struct sockaddr *src, *dst; 2486 u_int32_t spi, reqid; 2487 caddr_t keymat; 2488 u_int e_type, e_keylen, a_type, a_keylen, flags; 2489 u_int32_t l_alloc; 2490 u_int64_t l_bytes, l_addtime, l_usetime; 2491 u_int32_t seq; 2492{ 2493 struct pfkey_send_sa_args psaa; 2494 2495 memset(&psaa, 0, sizeof(psaa)); 2496 psaa.so = so; 2497 psaa.type = SADB_UPDATE; 2498 psaa.satype = satype; 2499 psaa.mode = mode; 2500 psaa.wsize = wsize; 2501 psaa.src = src; 2502 psaa.dst = dst; 2503 psaa.spi = spi; 2504 psaa.reqid = reqid; 2505 psaa.keymat = keymat; 2506 psaa.e_type = e_type; 2507 psaa.e_keylen = e_keylen; 2508 psaa.a_type = a_type; 2509 psaa.a_keylen = a_keylen; 2510 psaa.flags = flags; 2511 psaa.l_alloc = l_alloc; 2512 psaa.l_bytes = l_bytes; 2513 psaa.l_addtime = l_addtime; 2514 psaa.l_usetime = l_usetime; 2515 psaa.seq = seq; 2516 2517 return pfkey_send_update2(&psaa); 2518} 2519 2520int 2521pfkey_send_update_nat(so, satype, mode, src, dst, spi, reqid, wsize, 2522 keymat, e_type, e_keylen, a_type, a_keylen, flags, 2523 l_alloc, l_bytes, l_addtime, l_usetime, seq, 2524 l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa, 2525 l_natt_frag) 2526 int so; 2527 u_int satype, mode, wsize; 2528 struct sockaddr *src, *dst; 2529 u_int32_t spi, reqid; 2530 caddr_t keymat; 2531 u_int e_type, e_keylen, a_type, a_keylen, flags; 2532 u_int32_t l_alloc; 2533 u_int64_t l_bytes, l_addtime, l_usetime; 2534 u_int32_t seq; 2535 u_int8_t l_natt_type; 2536 u_int16_t l_natt_sport, l_natt_dport; 2537 struct sockaddr *l_natt_oa; 2538 u_int16_t l_natt_frag; 2539{ 2540 struct pfkey_send_sa_args psaa; 2541 2542 memset(&psaa, 0, sizeof(psaa)); 2543 psaa.so = so; 2544 psaa.type = SADB_UPDATE; 2545 psaa.satype = satype; 2546 psaa.mode = mode; 2547 psaa.wsize = wsize; 2548 psaa.src = src; 2549 psaa.dst = dst; 2550 psaa.spi = spi; 2551 psaa.reqid = reqid; 2552 psaa.keymat = keymat; 2553 psaa.e_type = e_type; 2554 psaa.e_keylen = e_keylen; 2555 psaa.a_type = a_type; 2556 psaa.a_keylen = a_keylen; 2557 psaa.flags = flags; 2558 psaa.l_alloc = l_alloc; 2559 psaa.l_bytes = l_bytes; 2560 psaa.l_addtime = l_addtime; 2561 psaa.l_usetime = l_usetime; 2562 psaa.seq = seq; 2563 psaa.l_natt_type = l_natt_type; 2564 psaa.l_natt_sport = l_natt_sport; 2565 psaa.l_natt_dport = l_natt_dport; 2566 psaa.l_natt_oa = l_natt_oa; 2567 psaa.l_natt_frag = l_natt_frag; 2568 2569 return pfkey_send_update2(&psaa); 2570} 2571 2572int 2573pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize, 2574 keymat, e_type, e_keylen, a_type, a_keylen, flags, 2575 l_alloc, l_bytes, l_addtime, l_usetime, seq) 2576 int so; 2577 u_int satype, mode, wsize; 2578 struct sockaddr *src, *dst; 2579 u_int32_t spi, reqid; 2580 caddr_t keymat; 2581 u_int e_type, e_keylen, a_type, a_keylen, flags; 2582 u_int32_t l_alloc; 2583 u_int64_t l_bytes, l_addtime, l_usetime; 2584 u_int32_t seq; 2585{ 2586 struct pfkey_send_sa_args psaa; 2587 2588 memset(&psaa, 0, sizeof(psaa)); 2589 psaa.so = so; 2590 psaa.type = SADB_ADD; 2591 psaa.satype = satype; 2592 psaa.mode = mode; 2593 psaa.wsize = wsize; 2594 psaa.src = src; 2595 psaa.dst = dst; 2596 psaa.spi = spi; 2597 psaa.reqid = reqid; 2598 psaa.keymat = keymat; 2599 psaa.e_type = e_type; 2600 psaa.e_keylen = e_keylen; 2601 psaa.a_type = a_type; 2602 psaa.a_keylen = a_keylen; 2603 psaa.flags = flags; 2604 psaa.l_alloc = l_alloc; 2605 psaa.l_bytes = l_bytes; 2606 psaa.l_addtime = l_addtime; 2607 psaa.l_usetime = l_usetime; 2608 psaa.seq = seq; 2609 2610 return pfkey_send_add2(&psaa); 2611} 2612 2613int 2614pfkey_send_add_nat(so, satype, mode, src, dst, spi, reqid, wsize, 2615 keymat, e_type, e_keylen, a_type, a_keylen, flags, 2616 l_alloc, l_bytes, l_addtime, l_usetime, seq, 2617 l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa, 2618 l_natt_frag) 2619 int so; 2620 u_int satype, mode, wsize; 2621 struct sockaddr *src, *dst; 2622 u_int32_t spi, reqid; 2623 caddr_t keymat; 2624 u_int e_type, e_keylen, a_type, a_keylen, flags; 2625 u_int32_t l_alloc; 2626 u_int64_t l_bytes, l_addtime, l_usetime; 2627 u_int32_t seq; 2628 u_int8_t l_natt_type; 2629 u_int16_t l_natt_sport, l_natt_dport; 2630 struct sockaddr *l_natt_oa; 2631 u_int16_t l_natt_frag; 2632{ 2633 struct pfkey_send_sa_args psaa; 2634 2635 memset(&psaa, 0, sizeof(psaa)); 2636 psaa.so = so; 2637 psaa.type = SADB_ADD; 2638 psaa.satype = satype; 2639 psaa.mode = mode; 2640 psaa.wsize = wsize; 2641 psaa.src = src; 2642 psaa.dst = dst; 2643 psaa.spi = spi; 2644 psaa.reqid = reqid; 2645 psaa.keymat = keymat; 2646 psaa.e_type = e_type; 2647 psaa.e_keylen = e_keylen; 2648 psaa.a_type = a_type; 2649 psaa.a_keylen = a_keylen; 2650 psaa.flags = flags; 2651 psaa.l_alloc = l_alloc; 2652 psaa.l_bytes = l_bytes; 2653 psaa.l_addtime = l_addtime; 2654 psaa.l_usetime = l_usetime; 2655 psaa.seq = seq; 2656 psaa.l_natt_type = l_natt_type; 2657 psaa.l_natt_sport = l_natt_sport; 2658 psaa.l_natt_dport = l_natt_dport; 2659 psaa.l_natt_oa = l_natt_oa; 2660 psaa.l_natt_frag = l_natt_frag; 2661 2662 return pfkey_send_add2(&psaa); 2663} 2664