1 /* $FreeBSD$ */ 2 /* $KAME: pfkey.c,v 1.31 2000/06/10 14:17:43 sakane Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/types.h> 34 #include <sys/param.h> 35 #include <sys/socket.h> 36 #include <net/pfkeyv2.h> 37 #include <netkey/key_var.h> 38 #include <netinet/in.h> 39 #include <netinet6/ipsec.h> 40 41 #include <stdlib.h> 42 #include <unistd.h> 43 #include <string.h> 44 #include <errno.h> 45 46 #include "ipsec_strerror.h" 47 #include "libpfkey.h" 48 49 #define CALLOC(size, cast) (cast)calloc(1, (size)) 50 51 static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *, 52 struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t, 53 u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t, 54 u_int32_t, u_int32_t, u_int32_t)); 55 static int pfkey_send_x2 __P((int, u_int, u_int, u_int, 56 struct sockaddr *, struct sockaddr *, u_int32_t)); 57 static int pfkey_send_x3 __P((int, u_int, u_int)); 58 static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int, 59 struct sockaddr *, u_int, u_int, char *, int, u_int32_t)); 60 static int pfkey_send_x5 __P((int, u_int, u_int32_t)); 61 62 static caddr_t pfkey_setsadbmsg __P((caddr_t, u_int, u_int, 63 u_int, u_int32_t, pid_t)); 64 static caddr_t pfkey_setsadbsa __P((caddr_t, u_int32_t, u_int, 65 u_int, u_int, u_int32_t)); 66 static caddr_t pfkey_setsadbaddr __P((caddr_t, u_int, 67 struct sockaddr *, u_int, u_int)); 68 static caddr_t pfkey_setsadbkey __P((caddr_t, u_int, caddr_t, u_int)); 69 static caddr_t pfkey_setsadblifetime __P((caddr_t, u_int, u_int32_t, u_int32_t, 70 u_int32_t, u_int32_t)); 71 static caddr_t pfkey_setsadbxsa2 __P((caddr_t, u_int32_t, u_int32_t)); 72 73 /* 74 * check key length against algorithm specified. 75 * supported is either SADB_EXT_SUPPORTED_ENCRYPT or SADB_EXT_SUPPORTED_AUTH. 76 * Refer to keyv2.h to get more info. 77 * keylen is the unit of bit. 78 * OUT: 79 * -1: invalid. 80 * 0: valid. 81 */ 82 struct sadb_msg *ipsec_supported = NULL; 83 84 int 85 ipsec_check_keylen(supported, alg_id, keylen) 86 u_int supported; 87 u_int alg_id; 88 u_int keylen; 89 { 90 u_int tlen; 91 caddr_t p; 92 struct sadb_supported *sup; 93 struct sadb_alg *alg; 94 95 /* validity check */ 96 if (ipsec_supported == NULL) { 97 __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST; 98 return -1; 99 } 100 switch (supported) { 101 case SADB_EXT_SUPPORTED_AUTH: 102 case SADB_EXT_SUPPORTED_ENCRYPT: 103 break; 104 default: 105 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 106 return -1; 107 } 108 109 tlen = ipsec_supported->sadb_msg_len - sizeof(struct sadb_msg); 110 p = (caddr_t)ipsec_supported + sizeof(struct sadb_msg); 111 112 for (; 113 tlen > 0; 114 tlen -= sup->sadb_supported_len, p += sup->sadb_supported_len) { 115 116 sup = (struct sadb_supported *)p; 117 118 if (sup->sadb_supported_exttype != supported) 119 continue; 120 121 { 122 u_int ttlen = sup->sadb_supported_len; 123 caddr_t pp = p + sizeof(*sup); 124 125 for (; 126 ttlen > 0; 127 ttlen -= sizeof(*alg), pp += sizeof(*alg)) { 128 alg = (struct sadb_alg *)pp; 129 130 if (alg->sadb_alg_id == alg_id) 131 goto found; 132 } 133 } 134 } 135 136 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 137 return -1; 138 /* NOTREACHED */ 139 140 found: 141 if (keylen < alg->sadb_alg_minbits 142 || keylen > alg->sadb_alg_maxbits) { 143 __ipsec_errcode = EIPSEC_INVAL_KEYLEN; 144 return -1; 145 } 146 147 __ipsec_errcode = EIPSEC_NO_ERROR; 148 return 0; 149 } 150 151 /* 152 * set the rate for SOFT lifetime against HARD one. 153 * If rate is more than 100 or equal to zero, then set to 100. 154 */ 155 static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE; 156 static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE; 157 static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE; 158 static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE; 159 160 u_int 161 pfkey_set_softrate(type, rate) 162 u_int type, rate; 163 { 164 __ipsec_errcode = EIPSEC_NO_ERROR; 165 166 if (rate > 100 || rate == 0) 167 rate = 100; 168 169 switch (type) { 170 case SADB_X_LIFETIME_ALLOCATIONS: 171 soft_lifetime_allocations_rate = rate; 172 return 0; 173 case SADB_X_LIFETIME_BYTES: 174 soft_lifetime_bytes_rate = rate; 175 return 0; 176 case SADB_X_LIFETIME_ADDTIME: 177 soft_lifetime_addtime_rate = rate; 178 return 0; 179 case SADB_X_LIFETIME_USETIME: 180 soft_lifetime_usetime_rate = rate; 181 return 0; 182 } 183 184 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 185 return 1; 186 } 187 188 /* 189 * get current rate for SOFT lifetime against HARD one. 190 * ATTENTION: ~0 is returned if invalid type was passed. 191 */ 192 u_int 193 pfkey_get_softrate(type) 194 u_int type; 195 { 196 switch (type) { 197 case SADB_X_LIFETIME_ALLOCATIONS: 198 return soft_lifetime_allocations_rate; 199 case SADB_X_LIFETIME_BYTES: 200 return soft_lifetime_bytes_rate; 201 case SADB_X_LIFETIME_ADDTIME: 202 return soft_lifetime_addtime_rate; 203 case SADB_X_LIFETIME_USETIME: 204 return soft_lifetime_usetime_rate; 205 } 206 207 return ~0; 208 } 209 210 /* 211 * sending SADB_GETSPI message to the kernel. 212 * OUT: 213 * positive: success and return length sent. 214 * -1 : error occured, and set errno. 215 */ 216 int 217 pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) 218 int so; 219 u_int satype, mode; 220 struct sockaddr *src, *dst; 221 u_int32_t min, max, reqid, seq; 222 { 223 struct sadb_msg *newmsg; 224 int len; 225 int need_spirange = 0; 226 caddr_t p; 227 int plen; 228 229 /* validity check */ 230 if (src == NULL || dst == NULL) { 231 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 232 return -1; 233 } 234 if (src->sa_family != dst->sa_family) { 235 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 236 return -1; 237 } 238 if (min > max || (min > 0 && min <= 255)) { 239 __ipsec_errcode = EIPSEC_INVAL_SPI; 240 return -1; 241 } 242 switch (src->sa_family) { 243 case AF_INET: 244 plen = sizeof(struct in_addr) << 3; 245 break; 246 case AF_INET6: 247 plen = sizeof(struct in6_addr) << 3; 248 break; 249 default: 250 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 251 return -1; 252 } 253 254 /* create new sadb_msg to send. */ 255 len = sizeof(struct sadb_msg) 256 + sizeof(struct sadb_x_sa2) 257 + sizeof(struct sadb_address) 258 + PFKEY_ALIGN8(src->sa_len) 259 + sizeof(struct sadb_address) 260 + PFKEY_ALIGN8(dst->sa_len); 261 262 if (min > 255 && max < ~0) { 263 need_spirange++; 264 len += sizeof(struct sadb_spirange); 265 } 266 267 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 268 __ipsec_set_strerror(strerror(errno)); 269 return -1; 270 } 271 272 p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_GETSPI, 273 len, satype, seq, getpid()); 274 275 p = pfkey_setsadbxsa2(p, mode, reqid); 276 277 /* set sadb_address for source */ 278 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen, 279 IPSEC_ULPROTO_ANY); 280 281 /* set sadb_address for destination */ 282 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen, 283 IPSEC_ULPROTO_ANY); 284 285 /* proccessing spi range */ 286 if (need_spirange) { 287 int _len = sizeof(struct sadb_spirange); 288 289 #define _SADB_SPIRANGE(p) ((struct sadb_spirange *)(p)) 290 _SADB_SPIRANGE(p)->sadb_spirange_len = PFKEY_UNIT64(_len); 291 _SADB_SPIRANGE(p)->sadb_spirange_exttype = SADB_EXT_SPIRANGE; 292 _SADB_SPIRANGE(p)->sadb_spirange_min = min; 293 _SADB_SPIRANGE(p)->sadb_spirange_max = max; 294 #undef _SADB_SPIRANGE(p) 295 p += _len; 296 } 297 298 /* send message */ 299 len = pfkey_send(so, newmsg, len); 300 free(newmsg); 301 302 if (len < 0) 303 return -1; 304 305 __ipsec_errcode = EIPSEC_NO_ERROR; 306 return len; 307 } 308 309 /* 310 * sending SADB_UPDATE message to the kernel. 311 * The length of key material is a_keylen + e_keylen. 312 * OUT: 313 * positive: success and return length sent. 314 * -1 : error occured, and set errno. 315 */ 316 int 317 pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize, 318 keymat, e_type, e_keylen, a_type, a_keylen, flags, 319 l_alloc, l_bytes, l_addtime, l_usetime, seq) 320 int so; 321 u_int satype, mode, wsize; 322 struct sockaddr *src, *dst; 323 u_int32_t spi, reqid; 324 caddr_t keymat; 325 u_int e_type, e_keylen, a_type, a_keylen, flags; 326 u_int32_t l_alloc; 327 u_int64_t l_bytes, l_addtime, l_usetime; 328 u_int32_t seq; 329 { 330 int len; 331 if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi, 332 reqid, wsize, 333 keymat, e_type, e_keylen, a_type, a_keylen, flags, 334 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) 335 return -1; 336 337 return len; 338 } 339 340 /* 341 * sending SADB_ADD message to the kernel. 342 * The length of key material is a_keylen + e_keylen. 343 * OUT: 344 * positive: success and return length sent. 345 * -1 : error occured, and set errno. 346 */ 347 int 348 pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize, 349 keymat, e_type, e_keylen, a_type, a_keylen, flags, 350 l_alloc, l_bytes, l_addtime, l_usetime, seq) 351 int so; 352 u_int satype, mode, wsize; 353 struct sockaddr *src, *dst; 354 u_int32_t spi, reqid; 355 caddr_t keymat; 356 u_int e_type, e_keylen, a_type, a_keylen, flags; 357 u_int32_t l_alloc; 358 u_int64_t l_bytes, l_addtime, l_usetime; 359 u_int32_t seq; 360 { 361 int len; 362 if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi, 363 reqid, wsize, 364 keymat, e_type, e_keylen, a_type, a_keylen, flags, 365 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) 366 return -1; 367 368 return len; 369 } 370 371 /* 372 * sending SADB_DELETE message to the kernel. 373 * OUT: 374 * positive: success and return length sent. 375 * -1 : error occured, and set errno. 376 */ 377 int 378 pfkey_send_delete(so, satype, mode, src, dst, spi) 379 int so; 380 u_int satype, mode; 381 struct sockaddr *src, *dst; 382 u_int32_t spi; 383 { 384 int len; 385 if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0) 386 return -1; 387 388 return len; 389 } 390 391 /* 392 * sending SADB_GET message to the kernel. 393 * OUT: 394 * positive: success and return length sent. 395 * -1 : error occured, and set errno. 396 */ 397 int 398 pfkey_send_get(so, satype, mode, src, dst, spi) 399 int so; 400 u_int satype, mode; 401 struct sockaddr *src, *dst; 402 u_int32_t spi; 403 { 404 int len; 405 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) 406 return -1; 407 408 return len; 409 } 410 411 /* 412 * sending SADB_REGISTER message to the kernel. 413 * OUT: 414 * positive: success and return length sent. 415 * -1 : error occured, and set errno. 416 */ 417 int 418 pfkey_send_register(so, satype) 419 int so; 420 u_int satype; 421 { 422 int len; 423 424 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0) 425 return -1; 426 427 return len; 428 } 429 430 /* 431 * receiving SADB_REGISTER message from the kernel, and copy buffer for 432 * sadb_supported returned into ipsec_supported. 433 * OUT: 434 * 0: success and return length sent. 435 * -1: error occured, and set errno. 436 */ 437 int 438 pfkey_recv_register(so) 439 int so; 440 { 441 pid_t pid = getpid(); 442 struct sadb_msg *newmsg; 443 struct sadb_supported *sup; 444 caddr_t p; 445 int tlen; 446 447 /* receive message */ 448 do { 449 if ((newmsg = pfkey_recv(so)) == NULL) 450 return -1; 451 452 } while (newmsg->sadb_msg_type != SADB_REGISTER 453 || newmsg->sadb_msg_pid != pid); 454 455 /* check and fix */ 456 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); 457 458 tlen = newmsg->sadb_msg_len - sizeof(struct sadb_msg); 459 p = (caddr_t)newmsg + sizeof(struct sadb_msg); 460 while (tlen > 0) { 461 sup = (struct sadb_supported *)p; 462 switch (sup->sadb_supported_exttype) { 463 case SADB_EXT_SUPPORTED_AUTH: 464 case SADB_EXT_SUPPORTED_ENCRYPT: 465 sup->sadb_supported_len = PFKEY_EXTLEN(sup); 466 break; 467 default: 468 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 469 free(newmsg); 470 return -1; 471 } 472 473 tlen -= sup->sadb_supported_len; 474 p += sup->sadb_supported_len; 475 } 476 477 if (tlen < 0) { 478 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 479 return -1; 480 } 481 482 if (ipsec_supported != NULL) 483 free(ipsec_supported); 484 485 ipsec_supported = newmsg; 486 487 __ipsec_errcode = EIPSEC_NO_ERROR; 488 return 0; 489 } 490 491 /* 492 * sending SADB_FLUSH message to the kernel. 493 * OUT: 494 * positive: success and return length sent. 495 * -1 : error occured, and set errno. 496 */ 497 int 498 pfkey_send_flush(so, satype) 499 int so; 500 u_int satype; 501 { 502 int len; 503 504 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0) 505 return -1; 506 507 return len; 508 } 509 510 /* 511 * sending SADB_DUMP message to the kernel. 512 * OUT: 513 * positive: success and return length sent. 514 * -1 : error occured, and set errno. 515 */ 516 int 517 pfkey_send_dump(so, satype) 518 int so; 519 u_int satype; 520 { 521 int len; 522 523 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0) 524 return -1; 525 526 return len; 527 } 528 529 /* 530 * sending SADB_X_PROMISC message to the kernel. 531 * NOTE that this function handles promisc mode toggle only. 532 * IN: 533 * flag: set promisc off if zero, set promisc on if non-zero. 534 * OUT: 535 * positive: success and return length sent. 536 * -1 : error occured, and set errno. 537 * 0 : error occured, and set errno. 538 * others: a pointer to new allocated buffer in which supported 539 * algorithms is. 540 */ 541 int 542 pfkey_send_promisc_toggle(so, flag) 543 int so; 544 int flag; 545 { 546 int len; 547 548 if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0) 549 return -1; 550 551 return len; 552 } 553 554 /* 555 * sending SADB_X_SPDADD message to the kernel. 556 * OUT: 557 * positive: success and return length sent. 558 * -1 : error occured, and set errno. 559 */ 560 int 561 pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 562 int so; 563 struct sockaddr *src, *dst; 564 u_int prefs, prefd, proto; 565 caddr_t policy; 566 int policylen; 567 u_int32_t seq; 568 { 569 int len; 570 571 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 572 src, prefs, dst, prefd, proto, 573 policy, policylen, seq)) < 0) 574 return -1; 575 576 return len; 577 } 578 579 /* 580 * sending SADB_X_SPDUPDATE message to the kernel. 581 * OUT: 582 * positive: success and return length sent. 583 * -1 : error occured, and set errno. 584 */ 585 int 586 pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 587 int so; 588 struct sockaddr *src, *dst; 589 u_int prefs, prefd, proto; 590 caddr_t policy; 591 int policylen; 592 u_int32_t seq; 593 { 594 int len; 595 596 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 597 src, prefs, dst, prefd, proto, 598 policy, policylen, seq)) < 0) 599 return -1; 600 601 return len; 602 } 603 604 /* 605 * sending SADB_X_SPDDELETE message to the kernel. 606 * OUT: 607 * positive: success and return length sent. 608 * -1 : error occured, and set errno. 609 */ 610 int 611 pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 612 int so; 613 struct sockaddr *src, *dst; 614 u_int prefs, prefd, proto; 615 caddr_t policy; 616 int policylen; 617 u_int32_t seq; 618 { 619 int len; 620 621 if (policylen != sizeof(struct sadb_x_policy)) { 622 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 623 return -1; 624 } 625 626 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, 627 src, prefs, dst, prefd, proto, 628 policy, policylen, seq)) < 0) 629 return -1; 630 631 return len; 632 } 633 634 /* 635 * sending SADB_X_SPDDELETE message to the kernel. 636 * OUT: 637 * positive: success and return length sent. 638 * -1 : error occured, and set errno. 639 */ 640 int 641 pfkey_send_spddelete2(so, spid) 642 int so; 643 u_int32_t spid; 644 { 645 int len; 646 647 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0) 648 return -1; 649 650 return len; 651 } 652 653 /* 654 * sending SADB_X_SPDGET message to the kernel. 655 * OUT: 656 * positive: success and return length sent. 657 * -1 : error occured, and set errno. 658 */ 659 int 660 pfkey_send_spdget(so, spid) 661 int so; 662 u_int32_t spid; 663 { 664 int len; 665 666 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0) 667 return -1; 668 669 return len; 670 } 671 672 /* 673 * sending SADB_X_SPDSETIDX message to the kernel. 674 * OUT: 675 * positive: success and return length sent. 676 * -1 : error occured, and set errno. 677 */ 678 int 679 pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 680 int so; 681 struct sockaddr *src, *dst; 682 u_int prefs, prefd, proto; 683 caddr_t policy; 684 int policylen; 685 u_int32_t seq; 686 { 687 int len; 688 689 if (policylen != sizeof(struct sadb_x_policy)) { 690 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 691 return -1; 692 } 693 694 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, 695 src, prefs, dst, prefd, proto, 696 policy, policylen, seq)) < 0) 697 return -1; 698 699 return len; 700 } 701 702 /* 703 * sending SADB_SPDFLUSH message to the kernel. 704 * OUT: 705 * positive: success and return length sent. 706 * -1 : error occured, and set errno. 707 */ 708 int 709 pfkey_send_spdflush(so) 710 int so; 711 { 712 int len; 713 714 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0) 715 return -1; 716 717 return len; 718 } 719 720 /* 721 * sending SADB_SPDDUMP message to the kernel. 722 * OUT: 723 * positive: success and return length sent. 724 * -1 : error occured, and set errno. 725 */ 726 int 727 pfkey_send_spddump(so) 728 int so; 729 { 730 int len; 731 732 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0) 733 return -1; 734 735 return len; 736 } 737 738 /* sending SADB_ADD or SADB_UPDATE message to the kernel */ 739 static int 740 pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, 741 keymat, e_type, e_keylen, a_type, a_keylen, flags, 742 l_alloc, l_bytes, l_addtime, l_usetime, seq) 743 int so; 744 u_int type, satype, mode; 745 struct sockaddr *src, *dst; 746 u_int32_t spi, reqid; 747 u_int wsize; 748 caddr_t keymat; 749 u_int e_type, e_keylen, a_type, a_keylen, flags; 750 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq; 751 { 752 struct sadb_msg *newmsg; 753 int len; 754 caddr_t p; 755 int plen; 756 757 /* validity check */ 758 if (src == NULL || dst == NULL) { 759 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 760 return -1; 761 } 762 if (src->sa_family != dst->sa_family) { 763 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 764 return -1; 765 } 766 switch (src->sa_family) { 767 case AF_INET: 768 plen = sizeof(struct in_addr) << 3; 769 break; 770 case AF_INET6: 771 plen = sizeof(struct in6_addr) << 3; 772 break; 773 default: 774 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 775 return -1; 776 } 777 778 switch (satype) { 779 case SADB_SATYPE_ESP: 780 if (e_type == SADB_EALG_NONE) { 781 __ipsec_errcode = EIPSEC_NO_ALGS; 782 return -1; 783 } 784 break; 785 case SADB_SATYPE_AH: 786 if (e_type != SADB_EALG_NONE) { 787 __ipsec_errcode = EIPSEC_INVAL_ALGS; 788 return -1; 789 } 790 if (a_type == SADB_AALG_NONE) { 791 __ipsec_errcode = EIPSEC_NO_ALGS; 792 return -1; 793 } 794 break; 795 case SADB_X_SATYPE_IPCOMP: 796 break; 797 default: 798 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 799 return -1; 800 } 801 802 /* create new sadb_msg to reply. */ 803 len = sizeof(struct sadb_msg) 804 + sizeof(struct sadb_sa) 805 + sizeof(struct sadb_x_sa2) 806 + sizeof(struct sadb_address) 807 + PFKEY_ALIGN8(src->sa_len) 808 + sizeof(struct sadb_address) 809 + PFKEY_ALIGN8(dst->sa_len) 810 + sizeof(struct sadb_lifetime) 811 + sizeof(struct sadb_lifetime); 812 813 if (e_type != SADB_EALG_NONE) 814 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); 815 if (a_type != SADB_AALG_NONE) 816 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen)); 817 818 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 819 __ipsec_set_strerror(strerror(errno)); 820 return -1; 821 } 822 823 p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, 824 satype, seq, getpid()); 825 p = pfkey_setsadbsa(p, spi, wsize, a_type, e_type, flags); 826 p = pfkey_setsadbxsa2(p, mode, reqid); 827 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen, 828 IPSEC_ULPROTO_ANY); 829 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen, 830 IPSEC_ULPROTO_ANY); 831 832 if (e_type != SADB_EALG_NONE) 833 p = pfkey_setsadbkey(p, SADB_EXT_KEY_ENCRYPT, 834 keymat, e_keylen); 835 if (a_type != SADB_AALG_NONE) 836 p = pfkey_setsadbkey(p, SADB_EXT_KEY_AUTH, 837 keymat + e_keylen, a_keylen); 838 839 /* set sadb_lifetime for destination */ 840 p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_HARD, 841 l_alloc, l_bytes, l_addtime, l_usetime); 842 p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_SOFT, 843 l_alloc, l_bytes, l_addtime, l_usetime); 844 845 /* send message */ 846 len = pfkey_send(so, newmsg, len); 847 free(newmsg); 848 849 if (len < 0) 850 return -1; 851 852 __ipsec_errcode = EIPSEC_NO_ERROR; 853 return len; 854 } 855 856 /* sending SADB_DELETE or SADB_GET message to the kernel */ 857 static int 858 pfkey_send_x2(so, type, satype, mode, src, dst, spi) 859 int so; 860 u_int type, satype, mode; 861 struct sockaddr *src, *dst; 862 u_int32_t spi; 863 { 864 struct sadb_msg *newmsg; 865 int len; 866 caddr_t p; 867 int plen; 868 869 /* validity check */ 870 if (src == NULL || dst == NULL) { 871 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 872 return -1; 873 } 874 if (src->sa_family != dst->sa_family) { 875 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 876 return -1; 877 } 878 switch (src->sa_family) { 879 case AF_INET: 880 plen = sizeof(struct in_addr) << 3; 881 break; 882 case AF_INET6: 883 plen = sizeof(struct in6_addr) << 3; 884 break; 885 default: 886 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 887 return -1; 888 } 889 890 /* create new sadb_msg to reply. */ 891 len = sizeof(struct sadb_msg) 892 + sizeof(struct sadb_sa) 893 + sizeof(struct sadb_address) 894 + PFKEY_ALIGN8(src->sa_len) 895 + sizeof(struct sadb_address) 896 + PFKEY_ALIGN8(dst->sa_len); 897 898 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 899 __ipsec_set_strerror(strerror(errno)); 900 return -1; 901 } 902 903 p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid()); 904 p = pfkey_setsadbsa(p, spi, 0, 0, 0, 0); 905 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen, 906 IPSEC_ULPROTO_ANY); 907 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen, 908 IPSEC_ULPROTO_ANY); 909 910 /* send message */ 911 len = pfkey_send(so, newmsg, len); 912 free(newmsg); 913 914 if (len < 0) 915 return -1; 916 917 __ipsec_errcode = EIPSEC_NO_ERROR; 918 return len; 919 } 920 921 /* 922 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message 923 * to the kernel 924 */ 925 static int 926 pfkey_send_x3(so, type, satype) 927 int so; 928 u_int type, satype; 929 { 930 struct sadb_msg *newmsg; 931 int len; 932 933 /* validity check */ 934 switch (type) { 935 case SADB_X_PROMISC: 936 if (satype != 0 && satype != 1) { 937 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 938 return -1; 939 } 940 break; 941 default: 942 switch (satype) { 943 case SADB_SATYPE_UNSPEC: 944 case SADB_SATYPE_AH: 945 case SADB_SATYPE_ESP: 946 case SADB_X_SATYPE_IPCOMP: 947 break; 948 default: 949 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 950 return -1; 951 } 952 } 953 954 /* create new sadb_msg to send. */ 955 len = sizeof(struct sadb_msg); 956 957 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 958 __ipsec_set_strerror(strerror(errno)); 959 return -1; 960 } 961 962 (void)pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid()); 963 964 /* send message */ 965 len = pfkey_send(so, newmsg, len); 966 free(newmsg); 967 968 if (len < 0) 969 return -1; 970 971 __ipsec_errcode = EIPSEC_NO_ERROR; 972 return len; 973 } 974 975 /* sending SADB_X_SPDADD message to the kernel */ 976 static int 977 pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, policy, policylen, seq) 978 int so; 979 struct sockaddr *src, *dst; 980 u_int type, prefs, prefd, proto; 981 char *policy; 982 int policylen; 983 u_int32_t seq; 984 { 985 struct sadb_msg *newmsg; 986 int len; 987 caddr_t p; 988 int plen; 989 990 /* validity check */ 991 if (src == NULL || dst == NULL) { 992 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 993 return -1; 994 } 995 if (src->sa_family != dst->sa_family) { 996 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 997 return -1; 998 } 999 1000 switch (src->sa_family) { 1001 case AF_INET: 1002 plen = sizeof(struct in_addr) << 3; 1003 break; 1004 case AF_INET6: 1005 plen = sizeof(struct in6_addr) << 3; 1006 break; 1007 default: 1008 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1009 return -1; 1010 } 1011 if (prefs > plen || prefd > plen) { 1012 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; 1013 return -1; 1014 } 1015 1016 /* create new sadb_msg to reply. */ 1017 len = sizeof(struct sadb_msg) 1018 + sizeof(struct sadb_address) 1019 + PFKEY_ALIGN8(src->sa_len) 1020 + sizeof(struct sadb_address) 1021 + PFKEY_ALIGN8(src->sa_len) 1022 + policylen; 1023 1024 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1025 __ipsec_set_strerror(strerror(errno)); 1026 return -1; 1027 } 1028 1029 p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, 1030 SADB_SATYPE_UNSPEC, seq, getpid()); 1031 p = pfkey_setsadbaddr(p, 1032 SADB_EXT_ADDRESS_SRC, 1033 src, 1034 prefs, 1035 proto); 1036 p = pfkey_setsadbaddr(p, 1037 SADB_EXT_ADDRESS_DST, 1038 dst, 1039 prefd, 1040 proto); 1041 memcpy(p, policy, policylen); 1042 1043 /* send message */ 1044 len = pfkey_send(so, newmsg, len); 1045 free(newmsg); 1046 1047 if (len < 0) 1048 return -1; 1049 1050 __ipsec_errcode = EIPSEC_NO_ERROR; 1051 return len; 1052 } 1053 1054 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ 1055 static int 1056 pfkey_send_x5(so, type, spid) 1057 int so; 1058 u_int type; 1059 u_int32_t spid; 1060 { 1061 struct sadb_msg *newmsg; 1062 struct sadb_x_policy xpl; 1063 int len; 1064 caddr_t p; 1065 1066 /* create new sadb_msg to reply. */ 1067 len = sizeof(struct sadb_msg) 1068 + sizeof(xpl); 1069 1070 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1071 __ipsec_set_strerror(strerror(errno)); 1072 return -1; 1073 } 1074 1075 p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, 1076 SADB_SATYPE_UNSPEC, 0, getpid()); 1077 1078 memset(&xpl, 0, sizeof(xpl)); 1079 xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl)); 1080 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; 1081 xpl.sadb_x_policy_id = spid; 1082 1083 memcpy(p, &xpl, sizeof(xpl)); 1084 1085 /* send message */ 1086 len = pfkey_send(so, newmsg, len); 1087 free(newmsg); 1088 1089 if (len < 0) 1090 return -1; 1091 1092 __ipsec_errcode = EIPSEC_NO_ERROR; 1093 return len; 1094 } 1095 1096 /* 1097 * open a socket. 1098 * OUT: 1099 * -1: fail. 1100 * others : success and return value of socket. 1101 */ 1102 int 1103 pfkey_open() 1104 { 1105 int so; 1106 const int bufsiz = 128 * 1024; /*is 128K enough?*/ 1107 1108 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { 1109 __ipsec_set_strerror(strerror(errno)); 1110 return -1; 1111 } 1112 1113 /* 1114 * This is a temporary workaround for KAME PR 154. 1115 * Don't really care even if it fails. 1116 */ 1117 (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)); 1118 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1119 1120 __ipsec_errcode = EIPSEC_NO_ERROR; 1121 return so; 1122 } 1123 1124 /* 1125 * close a socket. 1126 * OUT: 1127 * 0: success. 1128 * -1: fail. 1129 */ 1130 void 1131 pfkey_close(so) 1132 int so; 1133 { 1134 (void)close(so); 1135 1136 __ipsec_errcode = EIPSEC_NO_ERROR; 1137 return; 1138 } 1139 1140 /* 1141 * receive sadb_msg data, and return pointer to new buffer allocated. 1142 * Must free this buffer later. 1143 * OUT: 1144 * NULL : error occured. 1145 * others : a pointer to sadb_msg structure. 1146 */ 1147 struct sadb_msg * 1148 pfkey_recv(so) 1149 int so; 1150 { 1151 struct sadb_msg buf, *newmsg; 1152 int len, reallen; 1153 1154 while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) { 1155 if (errno == EINTR) continue; 1156 __ipsec_set_strerror(strerror(errno)); 1157 return NULL; 1158 } 1159 1160 if (len < sizeof(buf)) { 1161 recv(so, (caddr_t)&buf, sizeof(buf), 0); 1162 __ipsec_errcode = EIPSEC_MAX; 1163 return NULL; 1164 } 1165 1166 /* read real message */ 1167 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); 1168 if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) { 1169 __ipsec_set_strerror(strerror(errno)); 1170 return NULL; 1171 } 1172 1173 while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) { 1174 if (errno == EINTR) continue; 1175 __ipsec_set_strerror(strerror(errno)); 1176 free(newmsg); 1177 return NULL; 1178 } 1179 1180 if (len != reallen) { 1181 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1182 free(newmsg); 1183 return NULL; 1184 } 1185 1186 __ipsec_errcode = EIPSEC_NO_ERROR; 1187 return newmsg; 1188 } 1189 1190 /* 1191 * send message to a socket. 1192 * OUT: 1193 * others: success and return length sent. 1194 * -1 : fail. 1195 */ 1196 int 1197 pfkey_send(so, msg, len) 1198 int so; 1199 struct sadb_msg *msg; 1200 int len; 1201 { 1202 if ((len = send(so, (caddr_t)msg, len, 0)) < 0) { 1203 __ipsec_set_strerror(strerror(errno)); 1204 return -1; 1205 } 1206 1207 __ipsec_errcode = EIPSEC_NO_ERROR; 1208 return len; 1209 } 1210 1211 /* 1212 * %%% Utilities 1213 * NOTE: These functions are derived from netkey/key.c in KAME. 1214 */ 1215 /* 1216 * set the pointer to each header in this message buffer. 1217 * IN: msg: pointer to message buffer. 1218 * mhp: pointer to the buffer initialized like below: 1219 * caddr_t mhp[SADB_EXT_MAX + 1]; 1220 * OUT: -1: invalid. 1221 * 0: valid. 1222 */ 1223 int 1224 pfkey_align(msg, mhp) 1225 struct sadb_msg *msg; 1226 caddr_t *mhp; 1227 { 1228 struct sadb_ext *ext; 1229 int tlen, extlen; 1230 int i; 1231 1232 /* validity check */ 1233 if (msg == NULL || mhp == NULL) { 1234 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1235 return -1; 1236 } 1237 1238 /* initialize */ 1239 for (i = 0; i < SADB_EXT_MAX + 1; i++) 1240 mhp[i] = NULL; 1241 1242 mhp[0] = (caddr_t)msg; 1243 1244 tlen = PFKEY_UNUNIT64(msg->sadb_msg_len) - sizeof(struct sadb_msg); 1245 ext = (struct sadb_ext *)((caddr_t)msg + sizeof(struct sadb_msg)); 1246 1247 while (tlen > 0) { 1248 /* duplicate check */ 1249 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/ 1250 if (mhp[ext->sadb_ext_type] != NULL) { 1251 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1252 return -1; 1253 } 1254 1255 /* set pointer */ 1256 switch (ext->sadb_ext_type) { 1257 case SADB_EXT_SA: 1258 case SADB_EXT_LIFETIME_CURRENT: 1259 case SADB_EXT_LIFETIME_HARD: 1260 case SADB_EXT_LIFETIME_SOFT: 1261 case SADB_EXT_ADDRESS_SRC: 1262 case SADB_EXT_ADDRESS_DST: 1263 case SADB_EXT_ADDRESS_PROXY: 1264 case SADB_EXT_KEY_AUTH: 1265 /* XXX should to be check weak keys. */ 1266 case SADB_EXT_KEY_ENCRYPT: 1267 /* XXX should to be check weak keys. */ 1268 case SADB_EXT_IDENTITY_SRC: 1269 case SADB_EXT_IDENTITY_DST: 1270 case SADB_EXT_SENSITIVITY: 1271 case SADB_EXT_PROPOSAL: 1272 case SADB_EXT_SUPPORTED_AUTH: 1273 case SADB_EXT_SUPPORTED_ENCRYPT: 1274 case SADB_EXT_SPIRANGE: 1275 case SADB_X_EXT_POLICY: 1276 case SADB_X_EXT_SA2: 1277 mhp[ext->sadb_ext_type] = (caddr_t)ext; 1278 break; 1279 default: 1280 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1281 return -1; 1282 } 1283 1284 extlen = PFKEY_EXTLEN(ext); 1285 tlen -= extlen; 1286 ext = (struct sadb_ext *)((caddr_t)ext + extlen); 1287 } 1288 1289 __ipsec_errcode = EIPSEC_NO_ERROR; 1290 return 0; 1291 } 1292 1293 /* 1294 * check basic usage for sadb_msg, 1295 * NOTE: This routine is derived from netkey/key.c in KAME. 1296 * IN: msg: pointer to message buffer. 1297 * mhp: pointer to the buffer initialized like below: 1298 * 1299 * caddr_t mhp[SADB_EXT_MAX + 1]; 1300 * 1301 * OUT: -1: invalid. 1302 * 0: valid. 1303 */ 1304 int 1305 pfkey_check(mhp) 1306 caddr_t *mhp; 1307 { 1308 struct sadb_msg *msg; 1309 1310 /* validity check */ 1311 if (mhp == NULL || mhp[0] == NULL) { 1312 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1313 return -1; 1314 } 1315 1316 msg = (struct sadb_msg *)mhp[0]; 1317 1318 /* check version */ 1319 if (msg->sadb_msg_version != PF_KEY_V2) { 1320 __ipsec_errcode = EIPSEC_INVAL_VERSION; 1321 return -1; 1322 } 1323 1324 /* check type */ 1325 if (msg->sadb_msg_type > SADB_MAX) { 1326 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE; 1327 return -1; 1328 } 1329 1330 /* check SA type */ 1331 switch (msg->sadb_msg_satype) { 1332 case SADB_SATYPE_UNSPEC: 1333 switch (msg->sadb_msg_type) { 1334 case SADB_GETSPI: 1335 case SADB_UPDATE: 1336 case SADB_ADD: 1337 case SADB_DELETE: 1338 case SADB_GET: 1339 case SADB_ACQUIRE: 1340 case SADB_EXPIRE: 1341 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1342 return -1; 1343 } 1344 break; 1345 case SADB_SATYPE_ESP: 1346 case SADB_SATYPE_AH: 1347 case SADB_X_SATYPE_IPCOMP: 1348 switch (msg->sadb_msg_type) { 1349 case SADB_X_SPDADD: 1350 case SADB_X_SPDDELETE: 1351 case SADB_X_SPDGET: 1352 case SADB_X_SPDDUMP: 1353 case SADB_X_SPDFLUSH: 1354 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1355 return -1; 1356 } 1357 break; 1358 case SADB_SATYPE_RSVP: 1359 case SADB_SATYPE_OSPFV2: 1360 case SADB_SATYPE_RIPV2: 1361 case SADB_SATYPE_MIP: 1362 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 1363 return -1; 1364 case 1: /* XXX: What does it do ? */ 1365 if (msg->sadb_msg_type == SADB_X_PROMISC) 1366 break; 1367 /*FALLTHROUGH*/ 1368 default: 1369 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1370 return -1; 1371 } 1372 1373 /* check field of upper layer protocol and address family */ 1374 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL 1375 && mhp[SADB_EXT_ADDRESS_DST] != NULL) { 1376 struct sadb_address *src0, *dst0; 1377 1378 src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); 1379 dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); 1380 1381 if (src0->sadb_address_proto != dst0->sadb_address_proto) { 1382 __ipsec_errcode = EIPSEC_PROTO_MISMATCH; 1383 return -1; 1384 } 1385 1386 if (PFKEY_ADDR_SADDR(src0)->sa_family 1387 != PFKEY_ADDR_SADDR(dst0)->sa_family) { 1388 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1389 return -1; 1390 } 1391 1392 switch (PFKEY_ADDR_SADDR(src0)->sa_family) { 1393 case AF_INET: 1394 case AF_INET6: 1395 break; 1396 default: 1397 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1398 return -1; 1399 } 1400 1401 /* 1402 * prefixlen == 0 is valid because there must be the case 1403 * all addresses are matched. 1404 */ 1405 } 1406 1407 __ipsec_errcode = EIPSEC_NO_ERROR; 1408 return 0; 1409 } 1410 1411 /* 1412 * set data into sadb_msg. 1413 * `buf' must has been allocated sufficiently. 1414 */ 1415 static caddr_t 1416 pfkey_setsadbmsg(buf, type, tlen, satype, seq, pid) 1417 caddr_t buf; 1418 u_int type, satype; 1419 u_int tlen; 1420 u_int32_t seq; 1421 pid_t pid; 1422 { 1423 struct sadb_msg *p; 1424 u_int len; 1425 1426 p = (struct sadb_msg *)buf; 1427 len = sizeof(struct sadb_msg); 1428 1429 memset(p, 0, len); 1430 p->sadb_msg_version = PF_KEY_V2; 1431 p->sadb_msg_type = type; 1432 p->sadb_msg_errno = 0; 1433 p->sadb_msg_satype = satype; 1434 p->sadb_msg_len = PFKEY_UNIT64(tlen); 1435 p->sadb_msg_reserved = 0; 1436 p->sadb_msg_seq = seq; 1437 p->sadb_msg_pid = (u_int32_t)pid; 1438 1439 return(buf + len); 1440 } 1441 1442 /* 1443 * copy secasvar data into sadb_address. 1444 * `buf' must has been allocated sufficiently. 1445 */ 1446 static caddr_t 1447 pfkey_setsadbsa(buf, spi, wsize, auth, enc, flags) 1448 caddr_t buf; 1449 u_int32_t spi, flags; 1450 u_int wsize, auth, enc; 1451 { 1452 struct sadb_sa *p; 1453 u_int len; 1454 1455 p = (struct sadb_sa *)buf; 1456 len = sizeof(struct sadb_sa); 1457 1458 memset(p, 0, len); 1459 p->sadb_sa_len = PFKEY_UNIT64(len); 1460 p->sadb_sa_exttype = SADB_EXT_SA; 1461 p->sadb_sa_spi = spi; 1462 p->sadb_sa_replay = wsize; 1463 p->sadb_sa_state = SADB_SASTATE_LARVAL; 1464 p->sadb_sa_auth = auth; 1465 p->sadb_sa_encrypt = enc; 1466 p->sadb_sa_flags = flags; 1467 1468 return(buf + len); 1469 } 1470 1471 /* 1472 * set data into sadb_address. 1473 * `buf' must has been allocated sufficiently. 1474 * prefixlen is in bits. 1475 */ 1476 static caddr_t 1477 pfkey_setsadbaddr(buf, exttype, saddr, prefixlen, ul_proto) 1478 caddr_t buf; 1479 u_int exttype; 1480 struct sockaddr *saddr; 1481 u_int prefixlen; 1482 u_int ul_proto; 1483 { 1484 struct sadb_address *p; 1485 u_int len; 1486 1487 p = (struct sadb_address *)buf; 1488 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len); 1489 1490 memset(p, 0, len); 1491 p->sadb_address_len = PFKEY_UNIT64(len); 1492 p->sadb_address_exttype = exttype & 0xffff; 1493 p->sadb_address_proto = ul_proto & 0xff; 1494 p->sadb_address_prefixlen = prefixlen; 1495 p->sadb_address_reserved = 0; 1496 1497 memcpy(p + 1, saddr, saddr->sa_len); 1498 1499 return(buf + len); 1500 } 1501 1502 /* 1503 * set sadb_key structure after clearing buffer with zero. 1504 * OUT: the pointer of buf + len. 1505 */ 1506 static caddr_t 1507 pfkey_setsadbkey(buf, type, key, keylen) 1508 caddr_t buf, key; 1509 u_int type, keylen; 1510 { 1511 struct sadb_key *p; 1512 u_int len; 1513 1514 p = (struct sadb_key *)buf; 1515 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); 1516 1517 memset(p, 0, len); 1518 p->sadb_key_len = PFKEY_UNIT64(len); 1519 p->sadb_key_exttype = type; 1520 p->sadb_key_bits = keylen << 3; 1521 p->sadb_key_reserved = 0; 1522 1523 memcpy(p + 1, key, keylen); 1524 1525 return buf + len; 1526 } 1527 1528 /* 1529 * set sadb_lifetime structure after clearing buffer with zero. 1530 * OUT: the pointer of buf + len. 1531 */ 1532 static caddr_t 1533 pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime) 1534 caddr_t buf; 1535 u_int type; 1536 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime; 1537 { 1538 struct sadb_lifetime *p; 1539 u_int len; 1540 1541 p = (struct sadb_lifetime *)buf; 1542 len = sizeof(struct sadb_lifetime); 1543 1544 memset(p, 0, len); 1545 p->sadb_lifetime_len = PFKEY_UNIT64(len); 1546 p->sadb_lifetime_exttype = type; 1547 1548 switch (type) { 1549 case SADB_EXT_LIFETIME_SOFT: 1550 p->sadb_lifetime_allocations 1551 = (l_alloc * soft_lifetime_allocations_rate) /100; 1552 p->sadb_lifetime_bytes 1553 = (l_bytes * soft_lifetime_bytes_rate) /100; 1554 p->sadb_lifetime_addtime 1555 = (l_addtime * soft_lifetime_addtime_rate) /100; 1556 p->sadb_lifetime_usetime 1557 = (l_usetime * soft_lifetime_usetime_rate) /100; 1558 break; 1559 case SADB_EXT_LIFETIME_HARD: 1560 p->sadb_lifetime_allocations = l_alloc; 1561 p->sadb_lifetime_bytes = l_bytes; 1562 p->sadb_lifetime_addtime = l_addtime; 1563 p->sadb_lifetime_usetime = l_usetime; 1564 break; 1565 } 1566 1567 return buf + len; 1568 } 1569 1570 /* 1571 * copy secasvar data into sadb_address. 1572 * `buf' must has been allocated sufficiently. 1573 */ 1574 static caddr_t 1575 pfkey_setsadbxsa2(buf, mode0, reqid) 1576 caddr_t buf; 1577 u_int32_t mode0; 1578 u_int32_t reqid; 1579 { 1580 struct sadb_x_sa2 *p; 1581 u_int8_t mode = mode0 & 0xff; 1582 u_int len; 1583 1584 p = (struct sadb_x_sa2 *)buf; 1585 len = sizeof(struct sadb_x_sa2); 1586 1587 memset(p, 0, len); 1588 p->sadb_x_sa2_len = PFKEY_UNIT64(len); 1589 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1590 p->sadb_x_sa2_mode = mode; 1591 p->sadb_x_sa2_reqid = reqid; 1592 1593 return(buf + len); 1594 } 1595 1596