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