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