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