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