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