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