pfkey.c revision 1.1.1.2.2.3
1/* $NetBSD: pfkey.c,v 1.1.1.2.2.3 2005/10/21 17:08:17 riz 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((int)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 = (void *)(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 *)(void *)p)->sadb_alg_id == alg_id) 153 return (void *)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((size_t)sup->sadb_supported_len); 185 if (!*ipsup) { 186 __ipsec_set_strerror(strerror(errno)); 187 return -1; 188 } 189 memcpy(*ipsup, sup, (size_t)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 u_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 (u_int)~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 < (u_int)~0) { 415 need_spirange++; 416 len += sizeof(struct sadb_spirange); 417 } 418 419 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 420 __ipsec_set_strerror(strerror(errno)); 421 return -1; 422 } 423 ep = ((caddr_t)(void *)newmsg) + len; 424 425 p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_GETSPI, 426 (u_int)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, (u_int)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, (u_int)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, (u_int)l_bytes, (u_int)l_addtime, 515 (u_int)l_usetime, seq, 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, (u_int)l_bytes, (u_int)l_addtime, 547 (u_int)l_usetime, seq, l_natt_type, l_natt_sport, 548 l_natt_dport, l_natt_oa, 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, (u_int)l_bytes, (u_int)l_addtime, 581 (u_int)l_usetime, seq, 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, (u_int)l_bytes, (u_int)l_addtime, 613 (u_int)l_usetime, seq, l_natt_type, l_natt_sport, 614 l_natt_dport, l_natt_oa, 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 */ 650/*ARGSUSED*/ 651int 652pfkey_send_delete_all(so, satype, mode, src, dst) 653 int so; 654 u_int satype, mode; 655 struct sockaddr *src, *dst; 656{ 657 struct sadb_msg *newmsg; 658 int len; 659 caddr_t p; 660 int plen; 661 caddr_t ep; 662 663 /* validity check */ 664 if (src == NULL || dst == NULL) { 665 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 666 return -1; 667 } 668 if (src->sa_family != dst->sa_family) { 669 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 670 return -1; 671 } 672 switch (src->sa_family) { 673 case AF_INET: 674 plen = sizeof(struct in_addr) << 3; 675 break; 676 case AF_INET6: 677 plen = sizeof(struct in6_addr) << 3; 678 break; 679 default: 680 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 681 return -1; 682 } 683 684 /* create new sadb_msg to reply. */ 685 len = sizeof(struct sadb_msg) 686 + sizeof(struct sadb_address) 687 + PFKEY_ALIGN8(sysdep_sa_len(src)) 688 + sizeof(struct sadb_address) 689 + PFKEY_ALIGN8(sysdep_sa_len(dst)); 690 691 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 692 __ipsec_set_strerror(strerror(errno)); 693 return -1; 694 } 695 ep = ((caddr_t)(void *)newmsg) + len; 696 697 p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_DELETE, (u_int)len, 698 satype, 0, getpid()); 699 if (!p) { 700 free(newmsg); 701 return -1; 702 } 703 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, 704 IPSEC_ULPROTO_ANY); 705 if (!p) { 706 free(newmsg); 707 return -1; 708 } 709 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, 710 IPSEC_ULPROTO_ANY); 711 if (!p || p != ep) { 712 free(newmsg); 713 return -1; 714 } 715 716 /* send message */ 717 len = pfkey_send(so, newmsg, len); 718 free(newmsg); 719 720 if (len < 0) 721 return -1; 722 723 __ipsec_errcode = EIPSEC_NO_ERROR; 724 return len; 725} 726 727/* 728 * sending SADB_GET message to the kernel. 729 * OUT: 730 * positive: success and return length sent. 731 * -1 : error occured, and set errno. 732 */ 733int 734pfkey_send_get(so, satype, mode, src, dst, spi) 735 int so; 736 u_int satype, mode; 737 struct sockaddr *src, *dst; 738 u_int32_t spi; 739{ 740 int len; 741 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) 742 return -1; 743 744 return len; 745} 746 747/* 748 * sending SADB_REGISTER message to the kernel. 749 * OUT: 750 * positive: success and return length sent. 751 * -1 : error occured, and set errno. 752 */ 753int 754pfkey_send_register(so, satype) 755 int so; 756 u_int satype; 757{ 758 int len, algno; 759 760 if (satype == PF_UNSPEC) { 761 for (algno = 0; 762 algno < sizeof(supported_map)/sizeof(supported_map[0]); 763 algno++) { 764 if (ipsec_supported[algno]) { 765 free(ipsec_supported[algno]); 766 ipsec_supported[algno] = NULL; 767 } 768 } 769 } else { 770 algno = findsupportedmap((int)satype); 771 if (algno == -1) { 772 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 773 return -1; 774 } 775 776 if (ipsec_supported[algno]) { 777 free(ipsec_supported[algno]); 778 ipsec_supported[algno] = NULL; 779 } 780 } 781 782 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0) 783 return -1; 784 785 return len; 786} 787 788/* 789 * receiving SADB_REGISTER message from the kernel, and copy buffer for 790 * sadb_supported returned into ipsec_supported. 791 * OUT: 792 * 0: success and return length sent. 793 * -1: error occured, and set errno. 794 */ 795int 796pfkey_recv_register(so) 797 int so; 798{ 799 pid_t pid = getpid(); 800 struct sadb_msg *newmsg; 801 int error = -1; 802 803 /* receive message */ 804 for (;;) { 805 if ((newmsg = pfkey_recv(so)) == NULL) 806 return -1; 807 if (newmsg->sadb_msg_type == SADB_REGISTER && 808 newmsg->sadb_msg_pid == pid) 809 break; 810 free(newmsg); 811 } 812 813 /* check and fix */ 814 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); 815 816 error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len); 817 free(newmsg); 818 819 if (error == 0) 820 __ipsec_errcode = EIPSEC_NO_ERROR; 821 822 return error; 823} 824 825/* 826 * receiving SADB_REGISTER message from the kernel, and copy buffer for 827 * sadb_supported returned into ipsec_supported. 828 * NOTE: sadb_msg_len must be host order. 829 * IN: 830 * tlen: msg length, it's to makeing sure. 831 * OUT: 832 * 0: success and return length sent. 833 * -1: error occured, and set errno. 834 */ 835int 836pfkey_set_supported(msg, tlen) 837 struct sadb_msg *msg; 838 int tlen; 839{ 840 struct sadb_supported *sup; 841 caddr_t p; 842 caddr_t ep; 843 844 /* validity */ 845 if (msg->sadb_msg_len != tlen) { 846 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 847 return -1; 848 } 849 850 p = (void *)msg; 851 ep = p + tlen; 852 853 p += sizeof(struct sadb_msg); 854 855 while (p < ep) { 856 sup = (void *)p; 857 if (ep < p + sizeof(*sup) || 858 PFKEY_EXTLEN(sup) < sizeof(*sup) || 859 ep < p + sup->sadb_supported_len) { 860 /* invalid format */ 861 break; 862 } 863 864 switch (sup->sadb_supported_exttype) { 865 case SADB_EXT_SUPPORTED_AUTH: 866 case SADB_EXT_SUPPORTED_ENCRYPT: 867 break; 868 default: 869 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 870 return -1; 871 } 872 873 /* fixed length */ 874 sup->sadb_supported_len = PFKEY_EXTLEN(sup); 875 876 /* set supported map */ 877 if (setsupportedmap(sup) != 0) 878 return -1; 879 880 p += sup->sadb_supported_len; 881 } 882 883 if (p != ep) { 884 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 885 return -1; 886 } 887 888 __ipsec_errcode = EIPSEC_NO_ERROR; 889 890 return 0; 891} 892 893/* 894 * sending SADB_FLUSH message to the kernel. 895 * OUT: 896 * positive: success and return length sent. 897 * -1 : error occured, and set errno. 898 */ 899int 900pfkey_send_flush(so, satype) 901 int so; 902 u_int satype; 903{ 904 int len; 905 906 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0) 907 return -1; 908 909 return len; 910} 911 912/* 913 * sending SADB_DUMP message to the kernel. 914 * OUT: 915 * positive: success and return length sent. 916 * -1 : error occured, and set errno. 917 */ 918int 919pfkey_send_dump(so, satype) 920 int so; 921 u_int satype; 922{ 923 int len; 924 925 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0) 926 return -1; 927 928 return len; 929} 930 931/* 932 * sending SADB_X_PROMISC message to the kernel. 933 * NOTE that this function handles promisc mode toggle only. 934 * IN: 935 * flag: set promisc off if zero, set promisc on if non-zero. 936 * OUT: 937 * positive: success and return length sent. 938 * -1 : error occured, and set errno. 939 * 0 : error occured, and set errno. 940 * others: a pointer to new allocated buffer in which supported 941 * algorithms is. 942 */ 943int 944pfkey_send_promisc_toggle(so, flag) 945 int so; 946 int flag; 947{ 948 int len; 949 950 if ((len = pfkey_send_x3(so, SADB_X_PROMISC, 951 (u_int)(flag ? 1 : 0))) < 0) 952 return -1; 953 954 return len; 955} 956 957/* 958 * sending SADB_X_SPDADD message to the kernel. 959 * OUT: 960 * positive: success and return length sent. 961 * -1 : error occured, and set errno. 962 */ 963int 964pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 965 int so; 966 struct sockaddr *src, *dst; 967 u_int prefs, prefd, proto; 968 caddr_t policy; 969 int policylen; 970 u_int32_t seq; 971{ 972 int len; 973 974 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 975 src, prefs, dst, prefd, proto, 976 (u_int64_t)0, (u_int64_t)0, 977 policy, policylen, seq)) < 0) 978 return -1; 979 980 return len; 981} 982 983/* 984 * sending SADB_X_SPDADD message to the kernel. 985 * OUT: 986 * positive: success and return length sent. 987 * -1 : error occured, and set errno. 988 */ 989int 990pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime, 991 policy, policylen, seq) 992 int so; 993 struct sockaddr *src, *dst; 994 u_int prefs, prefd, proto; 995 u_int64_t ltime, vtime; 996 caddr_t policy; 997 int policylen; 998 u_int32_t seq; 999{ 1000 int len; 1001 1002 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 1003 src, prefs, dst, prefd, proto, 1004 ltime, vtime, 1005 policy, policylen, seq)) < 0) 1006 return -1; 1007 1008 return len; 1009} 1010 1011/* 1012 * sending SADB_X_SPDUPDATE message to the kernel. 1013 * OUT: 1014 * positive: success and return length sent. 1015 * -1 : error occured, and set errno. 1016 */ 1017int 1018pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 1019 int so; 1020 struct sockaddr *src, *dst; 1021 u_int prefs, prefd, proto; 1022 caddr_t policy; 1023 int policylen; 1024 u_int32_t seq; 1025{ 1026 int len; 1027 1028 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 1029 src, prefs, dst, prefd, proto, 1030 (u_int64_t)0, (u_int64_t)0, 1031 policy, policylen, seq)) < 0) 1032 return -1; 1033 1034 return len; 1035} 1036 1037/* 1038 * sending SADB_X_SPDUPDATE message to the kernel. 1039 * OUT: 1040 * positive: success and return length sent. 1041 * -1 : error occured, and set errno. 1042 */ 1043int 1044pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime, 1045 policy, policylen, seq) 1046 int so; 1047 struct sockaddr *src, *dst; 1048 u_int prefs, prefd, proto; 1049 u_int64_t ltime, vtime; 1050 caddr_t policy; 1051 int policylen; 1052 u_int32_t seq; 1053{ 1054 int len; 1055 1056 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 1057 src, prefs, dst, prefd, proto, 1058 ltime, vtime, 1059 policy, policylen, seq)) < 0) 1060 return -1; 1061 1062 return len; 1063} 1064 1065/* 1066 * sending SADB_X_SPDDELETE message to the kernel. 1067 * OUT: 1068 * positive: success and return length sent. 1069 * -1 : error occured, and set errno. 1070 */ 1071int 1072pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 1073 int so; 1074 struct sockaddr *src, *dst; 1075 u_int prefs, prefd, proto; 1076 caddr_t policy; 1077 int policylen; 1078 u_int32_t seq; 1079{ 1080 int len; 1081 1082 if (policylen != sizeof(struct sadb_x_policy)) { 1083 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1084 return -1; 1085 } 1086 1087 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, 1088 src, prefs, dst, prefd, proto, 1089 (u_int64_t)0, (u_int64_t)0, 1090 policy, policylen, seq)) < 0) 1091 return -1; 1092 1093 return len; 1094} 1095 1096/* 1097 * sending SADB_X_SPDDELETE message to the kernel. 1098 * OUT: 1099 * positive: success and return length sent. 1100 * -1 : error occured, and set errno. 1101 */ 1102int 1103pfkey_send_spddelete2(so, spid) 1104 int so; 1105 u_int32_t spid; 1106{ 1107 int len; 1108 1109 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0) 1110 return -1; 1111 1112 return len; 1113} 1114 1115/* 1116 * sending SADB_X_SPDGET message to the kernel. 1117 * OUT: 1118 * positive: success and return length sent. 1119 * -1 : error occured, and set errno. 1120 */ 1121int 1122pfkey_send_spdget(so, spid) 1123 int so; 1124 u_int32_t spid; 1125{ 1126 int len; 1127 1128 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0) 1129 return -1; 1130 1131 return len; 1132} 1133 1134/* 1135 * sending SADB_X_SPDSETIDX message to the kernel. 1136 * OUT: 1137 * positive: success and return length sent. 1138 * -1 : error occured, and set errno. 1139 */ 1140int 1141pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 1142 int so; 1143 struct sockaddr *src, *dst; 1144 u_int prefs, prefd, proto; 1145 caddr_t policy; 1146 int policylen; 1147 u_int32_t seq; 1148{ 1149 int len; 1150 1151 if (policylen != sizeof(struct sadb_x_policy)) { 1152 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1153 return -1; 1154 } 1155 1156 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, 1157 src, prefs, dst, prefd, proto, 1158 (u_int64_t)0, (u_int64_t)0, 1159 policy, policylen, seq)) < 0) 1160 return -1; 1161 1162 return len; 1163} 1164 1165/* 1166 * sending SADB_SPDFLUSH message to the kernel. 1167 * OUT: 1168 * positive: success and return length sent. 1169 * -1 : error occured, and set errno. 1170 */ 1171int 1172pfkey_send_spdflush(so) 1173 int so; 1174{ 1175 int len; 1176 1177 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0) 1178 return -1; 1179 1180 return len; 1181} 1182 1183/* 1184 * sending SADB_SPDDUMP message to the kernel. 1185 * OUT: 1186 * positive: success and return length sent. 1187 * -1 : error occured, and set errno. 1188 */ 1189int 1190pfkey_send_spddump(so) 1191 int so; 1192{ 1193 int len; 1194 1195 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0) 1196 return -1; 1197 1198 return len; 1199} 1200 1201/* sending SADB_ADD or SADB_UPDATE message to the kernel */ 1202static int 1203pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, 1204 keymat, e_type, e_keylen, a_type, a_keylen, flags, 1205 l_alloc, l_bytes, l_addtime, l_usetime, seq, 1206 l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa, 1207 l_natt_frag) 1208 int so; 1209 u_int type, satype, mode; 1210 struct sockaddr *src, *dst, *l_natt_oa; 1211 u_int32_t spi, reqid; 1212 u_int wsize; 1213 caddr_t keymat; 1214 u_int e_type, e_keylen, a_type, a_keylen, flags; 1215 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq; 1216 u_int16_t l_natt_sport, l_natt_dport; 1217 u_int8_t l_natt_type; 1218 u_int16_t l_natt_frag; 1219{ 1220 struct sadb_msg *newmsg; 1221 int len; 1222 caddr_t p; 1223 int plen; 1224 caddr_t ep; 1225 1226 /* validity check */ 1227 if (src == NULL || dst == NULL) { 1228 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1229 return -1; 1230 } 1231 if (src->sa_family != dst->sa_family) { 1232 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1233 return -1; 1234 } 1235 switch (src->sa_family) { 1236 case AF_INET: 1237 plen = sizeof(struct in_addr) << 3; 1238 break; 1239 case AF_INET6: 1240 plen = sizeof(struct in6_addr) << 3; 1241 break; 1242 default: 1243 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1244 return -1; 1245 } 1246 1247 switch (satype) { 1248 case SADB_SATYPE_ESP: 1249 if (e_type == SADB_EALG_NONE) { 1250 __ipsec_errcode = EIPSEC_NO_ALGS; 1251 return -1; 1252 } 1253 break; 1254 case SADB_SATYPE_AH: 1255 if (e_type != SADB_EALG_NONE) { 1256 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1257 return -1; 1258 } 1259 if (a_type == SADB_AALG_NONE) { 1260 __ipsec_errcode = EIPSEC_NO_ALGS; 1261 return -1; 1262 } 1263 break; 1264 case SADB_X_SATYPE_IPCOMP: 1265 if (e_type == SADB_X_CALG_NONE) { 1266 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1267 return -1; 1268 } 1269 if (a_type != SADB_AALG_NONE) { 1270 __ipsec_errcode = EIPSEC_NO_ALGS; 1271 return -1; 1272 } 1273 break; 1274#ifdef SADB_X_AALG_TCP_MD5 1275 case SADB_X_SATYPE_TCPSIGNATURE: 1276 if (e_type != SADB_EALG_NONE) { 1277 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1278 return -1; 1279 } 1280 if (a_type != SADB_X_AALG_TCP_MD5) { 1281 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1282 return -1; 1283 } 1284 break; 1285#endif 1286 default: 1287 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1288 return -1; 1289 } 1290 1291 /* create new sadb_msg to reply. */ 1292 len = sizeof(struct sadb_msg) 1293 + sizeof(struct sadb_sa) 1294 + sizeof(struct sadb_x_sa2) 1295 + sizeof(struct sadb_address) 1296 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1297 + sizeof(struct sadb_address) 1298 + PFKEY_ALIGN8(sysdep_sa_len(dst)) 1299 + sizeof(struct sadb_lifetime) 1300 + sizeof(struct sadb_lifetime); 1301 1302 if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP) 1303 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); 1304 if (a_type != SADB_AALG_NONE) 1305 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen)); 1306 1307#ifdef SADB_X_EXT_NAT_T_TYPE 1308 /* add nat-t packets */ 1309 if (l_natt_type) { 1310 switch(satype) { 1311 case SADB_SATYPE_ESP: 1312 case SADB_X_SATYPE_IPCOMP: 1313 break; 1314 default: 1315 __ipsec_errcode = EIPSEC_NO_ALGS; 1316 return -1; 1317 } 1318 1319 len += sizeof(struct sadb_x_nat_t_type); 1320 len += sizeof(struct sadb_x_nat_t_port); 1321 len += sizeof(struct sadb_x_nat_t_port); 1322 if (l_natt_oa) 1323 len += sizeof(struct sadb_address) + 1324 PFKEY_ALIGN8(sysdep_sa_len(l_natt_oa)); 1325#ifdef SADB_X_EXT_NAT_T_FRAG 1326 if (l_natt_frag) 1327 len += sizeof(struct sadb_x_nat_t_frag); 1328#endif 1329 } 1330#endif 1331 1332 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1333 __ipsec_set_strerror(strerror(errno)); 1334 return -1; 1335 } 1336 ep = ((caddr_t)(void *)newmsg) + len; 1337 1338 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, 1339 satype, seq, getpid()); 1340 if (!p) { 1341 free(newmsg); 1342 return -1; 1343 } 1344 p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags); 1345 if (!p) { 1346 free(newmsg); 1347 return -1; 1348 } 1349 p = pfkey_setsadbxsa2(p, ep, mode, reqid); 1350 if (!p) { 1351 free(newmsg); 1352 return -1; 1353 } 1354 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, 1355 IPSEC_ULPROTO_ANY); 1356 if (!p) { 1357 free(newmsg); 1358 return -1; 1359 } 1360 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, 1361 IPSEC_ULPROTO_ANY); 1362 if (!p) { 1363 free(newmsg); 1364 return -1; 1365 } 1366 1367 if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP) { 1368 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT, 1369 keymat, e_keylen); 1370 if (!p) { 1371 free(newmsg); 1372 return -1; 1373 } 1374 } 1375 if (a_type != SADB_AALG_NONE) { 1376 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH, 1377 keymat + e_keylen, a_keylen); 1378 if (!p) { 1379 free(newmsg); 1380 return -1; 1381 } 1382 } 1383 1384 /* set sadb_lifetime for destination */ 1385 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 1386 l_alloc, l_bytes, l_addtime, l_usetime); 1387 if (!p) { 1388 free(newmsg); 1389 return -1; 1390 } 1391 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT, 1392 l_alloc, l_bytes, l_addtime, l_usetime); 1393 if (!p) { 1394 free(newmsg); 1395 return -1; 1396 } 1397 1398#ifdef SADB_X_EXT_NAT_T_TYPE 1399 /* Add nat-t messages */ 1400 if (l_natt_type) { 1401 p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, l_natt_type); 1402 if (!p) { 1403 free(newmsg); 1404 return -1; 1405 } 1406 1407 p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT, 1408 l_natt_sport); 1409 if (!p) { 1410 free(newmsg); 1411 return -1; 1412 } 1413 1414 p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT, 1415 l_natt_dport); 1416 if (!p) { 1417 free(newmsg); 1418 return -1; 1419 } 1420 1421 if (l_natt_oa) { 1422 p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_NAT_T_OA, 1423 l_natt_oa, 1424 (u_int)PFKEY_ALIGN8(sysdep_sa_len(l_natt_oa)), 1425 IPSEC_ULPROTO_ANY); 1426 if (!p) { 1427 free(newmsg); 1428 return -1; 1429 } 1430 } 1431 1432 if (l_natt_frag) { 1433#ifdef SADB_X_EXT_NAT_T_FRAG 1434 p = pfkey_set_natt_frag(p, ep, SADB_X_EXT_NAT_T_FRAG, 1435 l_natt_frag); 1436 if (!p) { 1437 free(newmsg); 1438 return -1; 1439 } 1440#endif 1441 } 1442 } 1443#endif 1444 1445 if (p != ep) { 1446 free(newmsg); 1447 return -1; 1448 } 1449 1450 /* send message */ 1451 len = pfkey_send(so, newmsg, len); 1452 free(newmsg); 1453 1454 if (len < 0) 1455 return -1; 1456 1457 __ipsec_errcode = EIPSEC_NO_ERROR; 1458 return len; 1459} 1460 1461/* sending SADB_DELETE or SADB_GET message to the kernel */ 1462/*ARGSUSED*/ 1463static int 1464pfkey_send_x2(so, type, satype, mode, src, dst, spi) 1465 int so; 1466 u_int type, satype, mode; 1467 struct sockaddr *src, *dst; 1468 u_int32_t spi; 1469{ 1470 struct sadb_msg *newmsg; 1471 int len; 1472 caddr_t p; 1473 int plen; 1474 caddr_t ep; 1475 1476 /* validity check */ 1477 if (src == NULL || dst == NULL) { 1478 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1479 return -1; 1480 } 1481 if (src->sa_family != dst->sa_family) { 1482 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1483 return -1; 1484 } 1485 switch (src->sa_family) { 1486 case AF_INET: 1487 plen = sizeof(struct in_addr) << 3; 1488 break; 1489 case AF_INET6: 1490 plen = sizeof(struct in6_addr) << 3; 1491 break; 1492 default: 1493 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1494 return -1; 1495 } 1496 1497 /* create new sadb_msg to reply. */ 1498 len = sizeof(struct sadb_msg) 1499 + sizeof(struct sadb_sa) 1500 + sizeof(struct sadb_address) 1501 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1502 + sizeof(struct sadb_address) 1503 + PFKEY_ALIGN8(sysdep_sa_len(dst)); 1504 1505 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1506 __ipsec_set_strerror(strerror(errno)); 1507 return -1; 1508 } 1509 ep = ((caddr_t)(void *)newmsg) + len; 1510 1511 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0, 1512 getpid()); 1513 if (!p) { 1514 free(newmsg); 1515 return -1; 1516 } 1517 p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0); 1518 if (!p) { 1519 free(newmsg); 1520 return -1; 1521 } 1522 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, 1523 IPSEC_ULPROTO_ANY); 1524 if (!p) { 1525 free(newmsg); 1526 return -1; 1527 } 1528 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, 1529 IPSEC_ULPROTO_ANY); 1530 if (!p || p != ep) { 1531 free(newmsg); 1532 return -1; 1533 } 1534 1535 /* send message */ 1536 len = pfkey_send(so, newmsg, len); 1537 free(newmsg); 1538 1539 if (len < 0) 1540 return -1; 1541 1542 __ipsec_errcode = EIPSEC_NO_ERROR; 1543 return len; 1544} 1545 1546/* 1547 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message 1548 * to the kernel 1549 */ 1550static int 1551pfkey_send_x3(so, type, satype) 1552 int so; 1553 u_int type, satype; 1554{ 1555 struct sadb_msg *newmsg; 1556 int len; 1557 caddr_t p; 1558 caddr_t ep; 1559 1560 /* validity check */ 1561 switch (type) { 1562 case SADB_X_PROMISC: 1563 if (satype != 0 && satype != 1) { 1564 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1565 return -1; 1566 } 1567 break; 1568 default: 1569 switch (satype) { 1570 case SADB_SATYPE_UNSPEC: 1571 case SADB_SATYPE_AH: 1572 case SADB_SATYPE_ESP: 1573 case SADB_X_SATYPE_IPCOMP: 1574#ifdef SADB_X_SATYPE_TCPSIGNATURE 1575 case SADB_X_SATYPE_TCPSIGNATURE: 1576#endif 1577 break; 1578 default: 1579 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1580 return -1; 1581 } 1582 } 1583 1584 /* create new sadb_msg to send. */ 1585 len = sizeof(struct sadb_msg); 1586 1587 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1588 __ipsec_set_strerror(strerror(errno)); 1589 return -1; 1590 } 1591 ep = ((caddr_t)(void *)newmsg) + len; 1592 1593 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0, 1594 getpid()); 1595 if (!p || p != ep) { 1596 free(newmsg); 1597 return -1; 1598 } 1599 1600 /* send message */ 1601 len = pfkey_send(so, newmsg, len); 1602 free(newmsg); 1603 1604 if (len < 0) 1605 return -1; 1606 1607 __ipsec_errcode = EIPSEC_NO_ERROR; 1608 return len; 1609} 1610 1611/* sending SADB_X_SPDADD message to the kernel */ 1612static int 1613pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, 1614 ltime, vtime, policy, policylen, seq) 1615 int so; 1616 struct sockaddr *src, *dst; 1617 u_int type, prefs, prefd, proto; 1618 u_int64_t ltime, vtime; 1619 char *policy; 1620 int policylen; 1621 u_int32_t seq; 1622{ 1623 struct sadb_msg *newmsg; 1624 int len; 1625 caddr_t p; 1626 int plen; 1627 caddr_t ep; 1628 1629 /* validity check */ 1630 if (src == NULL || dst == NULL) { 1631 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1632 return -1; 1633 } 1634 if (src->sa_family != dst->sa_family) { 1635 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1636 return -1; 1637 } 1638 1639 switch (src->sa_family) { 1640 case AF_INET: 1641 plen = sizeof(struct in_addr) << 3; 1642 break; 1643 case AF_INET6: 1644 plen = sizeof(struct in6_addr) << 3; 1645 break; 1646 default: 1647 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1648 return -1; 1649 } 1650 if (prefs > plen || prefd > plen) { 1651 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; 1652 return -1; 1653 } 1654 1655 /* create new sadb_msg to reply. */ 1656 len = sizeof(struct sadb_msg) 1657 + sizeof(struct sadb_address) 1658 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1659 + sizeof(struct sadb_address) 1660 + PFKEY_ALIGN8(sysdep_sa_len(src)) 1661 + sizeof(struct sadb_lifetime) 1662 + policylen; 1663 1664 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1665 __ipsec_set_strerror(strerror(errno)); 1666 return -1; 1667 } 1668 ep = ((caddr_t)(void *)newmsg) + len; 1669 1670 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, 1671 SADB_SATYPE_UNSPEC, seq, getpid()); 1672 if (!p) { 1673 free(newmsg); 1674 return -1; 1675 } 1676 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); 1677 if (!p) { 1678 free(newmsg); 1679 return -1; 1680 } 1681 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); 1682 if (!p) { 1683 free(newmsg); 1684 return -1; 1685 } 1686 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 1687 0, 0, (u_int)ltime, (u_int)vtime); 1688 if (!p || p + policylen != ep) { 1689 free(newmsg); 1690 return -1; 1691 } 1692 memcpy(p, policy, (size_t)policylen); 1693 1694 /* send message */ 1695 len = pfkey_send(so, newmsg, len); 1696 free(newmsg); 1697 1698 if (len < 0) 1699 return -1; 1700 1701 __ipsec_errcode = EIPSEC_NO_ERROR; 1702 return len; 1703} 1704 1705/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ 1706static int 1707pfkey_send_x5(so, type, spid) 1708 int so; 1709 u_int type; 1710 u_int32_t spid; 1711{ 1712 struct sadb_msg *newmsg; 1713 struct sadb_x_policy xpl; 1714 int len; 1715 caddr_t p; 1716 caddr_t ep; 1717 1718 /* create new sadb_msg to reply. */ 1719 len = sizeof(struct sadb_msg) 1720 + sizeof(xpl); 1721 1722 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { 1723 __ipsec_set_strerror(strerror(errno)); 1724 return -1; 1725 } 1726 ep = ((caddr_t)(void *)newmsg) + len; 1727 1728 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, 1729 SADB_SATYPE_UNSPEC, 0, getpid()); 1730 if (!p) { 1731 free(newmsg); 1732 return -1; 1733 } 1734 1735 if (p + sizeof(xpl) != ep) { 1736 free(newmsg); 1737 return -1; 1738 } 1739 memset(&xpl, 0, sizeof(xpl)); 1740 xpl.sadb_x_policy_len = PFKEY_UNIT64(sizeof(xpl)); 1741 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; 1742 xpl.sadb_x_policy_id = spid; 1743 memcpy(p, &xpl, sizeof(xpl)); 1744 1745 /* send message */ 1746 len = pfkey_send(so, newmsg, len); 1747 free(newmsg); 1748 1749 if (len < 0) 1750 return -1; 1751 1752 __ipsec_errcode = EIPSEC_NO_ERROR; 1753 return len; 1754} 1755 1756/* 1757 * open a socket. 1758 * OUT: 1759 * -1: fail. 1760 * others : success and return value of socket. 1761 */ 1762int 1763pfkey_open() 1764{ 1765 int so; 1766 const int bufsiz = 128 * 1024; /*is 128K enough?*/ 1767 1768 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { 1769 __ipsec_set_strerror(strerror(errno)); 1770 return -1; 1771 } 1772 1773 /* 1774 * This is a temporary workaround for KAME PR 154. 1775 * Don't really care even if it fails. 1776 */ 1777 (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)); 1778 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1779 1780 __ipsec_errcode = EIPSEC_NO_ERROR; 1781 return so; 1782} 1783 1784/* 1785 * close a socket. 1786 * OUT: 1787 * 0: success. 1788 * -1: fail. 1789 */ 1790void 1791pfkey_close(so) 1792 int so; 1793{ 1794 (void)close(so); 1795 1796 __ipsec_errcode = EIPSEC_NO_ERROR; 1797 return; 1798} 1799 1800/* 1801 * receive sadb_msg data, and return pointer to new buffer allocated. 1802 * Must free this buffer later. 1803 * OUT: 1804 * NULL : error occured. 1805 * others : a pointer to sadb_msg structure. 1806 * 1807 * XXX should be rewritten to pass length explicitly 1808 */ 1809struct sadb_msg * 1810pfkey_recv(so) 1811 int so; 1812{ 1813 struct sadb_msg buf, *newmsg; 1814 int len, reallen; 1815 1816 while ((len = recv(so, (void *)&buf, sizeof(buf), MSG_PEEK)) < 0) { 1817 if (errno == EINTR) 1818 continue; 1819 __ipsec_set_strerror(strerror(errno)); 1820 return NULL; 1821 } 1822 1823 if (len < sizeof(buf)) { 1824 recv(so, (void *)&buf, sizeof(buf), 0); 1825 __ipsec_errcode = EIPSEC_MAX; 1826 return NULL; 1827 } 1828 1829 /* read real message */ 1830 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); 1831 if ((newmsg = CALLOC((size_t)reallen, struct sadb_msg *)) == 0) { 1832 __ipsec_set_strerror(strerror(errno)); 1833 return NULL; 1834 } 1835 1836 while ((len = recv(so, (void *)newmsg, (socklen_t)reallen, 0)) < 0) { 1837 if (errno == EINTR) 1838 continue; 1839 __ipsec_set_strerror(strerror(errno)); 1840 free(newmsg); 1841 return NULL; 1842 } 1843 1844 if (len != reallen) { 1845 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1846 free(newmsg); 1847 return NULL; 1848 } 1849 1850 /* don't trust what the kernel says, validate! */ 1851 if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) { 1852 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1853 free(newmsg); 1854 return NULL; 1855 } 1856 1857 __ipsec_errcode = EIPSEC_NO_ERROR; 1858 return newmsg; 1859} 1860 1861/* 1862 * send message to a socket. 1863 * OUT: 1864 * others: success and return length sent. 1865 * -1 : fail. 1866 */ 1867int 1868pfkey_send(so, msg, len) 1869 int so; 1870 struct sadb_msg *msg; 1871 int len; 1872{ 1873 if ((len = send(so, (void *)msg, (socklen_t)len, 0)) < 0) { 1874 __ipsec_set_strerror(strerror(errno)); 1875 return -1; 1876 } 1877 1878 __ipsec_errcode = EIPSEC_NO_ERROR; 1879 return len; 1880} 1881 1882/* 1883 * %%% Utilities 1884 * NOTE: These functions are derived from netkey/key.c in KAME. 1885 */ 1886/* 1887 * set the pointer to each header in this message buffer. 1888 * IN: msg: pointer to message buffer. 1889 * mhp: pointer to the buffer initialized like below: 1890 * caddr_t mhp[SADB_EXT_MAX + 1]; 1891 * OUT: -1: invalid. 1892 * 0: valid. 1893 * 1894 * XXX should be rewritten to obtain length explicitly 1895 */ 1896int 1897pfkey_align(msg, mhp) 1898 struct sadb_msg *msg; 1899 caddr_t *mhp; 1900{ 1901 struct sadb_ext *ext; 1902 int i; 1903 caddr_t p; 1904 caddr_t ep; /* XXX should be passed from upper layer */ 1905 1906 /* validity check */ 1907 if (msg == NULL || mhp == NULL) { 1908 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1909 return -1; 1910 } 1911 1912 /* initialize */ 1913 for (i = 0; i < SADB_EXT_MAX + 1; i++) 1914 mhp[i] = NULL; 1915 1916 mhp[0] = (void *)msg; 1917 1918 /* initialize */ 1919 p = (void *) msg; 1920 ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len); 1921 1922 /* skip base header */ 1923 p += sizeof(struct sadb_msg); 1924 1925 while (p < ep) { 1926 ext = (void *)p; 1927 if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) || 1928 ep < p + PFKEY_EXTLEN(ext)) { 1929 /* invalid format */ 1930 break; 1931 } 1932 1933 /* duplicate check */ 1934 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/ 1935 if (mhp[ext->sadb_ext_type] != NULL) { 1936 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1937 return -1; 1938 } 1939 1940 /* set pointer */ 1941 switch (ext->sadb_ext_type) { 1942 case SADB_EXT_SA: 1943 case SADB_EXT_LIFETIME_CURRENT: 1944 case SADB_EXT_LIFETIME_HARD: 1945 case SADB_EXT_LIFETIME_SOFT: 1946 case SADB_EXT_ADDRESS_SRC: 1947 case SADB_EXT_ADDRESS_DST: 1948 case SADB_EXT_ADDRESS_PROXY: 1949 case SADB_EXT_KEY_AUTH: 1950 /* XXX should to be check weak keys. */ 1951 case SADB_EXT_KEY_ENCRYPT: 1952 /* XXX should to be check weak keys. */ 1953 case SADB_EXT_IDENTITY_SRC: 1954 case SADB_EXT_IDENTITY_DST: 1955 case SADB_EXT_SENSITIVITY: 1956 case SADB_EXT_PROPOSAL: 1957 case SADB_EXT_SUPPORTED_AUTH: 1958 case SADB_EXT_SUPPORTED_ENCRYPT: 1959 case SADB_EXT_SPIRANGE: 1960 case SADB_X_EXT_POLICY: 1961 case SADB_X_EXT_SA2: 1962#ifdef SADB_X_EXT_NAT_T_TYPE 1963 case SADB_X_EXT_NAT_T_TYPE: 1964 case SADB_X_EXT_NAT_T_SPORT: 1965 case SADB_X_EXT_NAT_T_DPORT: 1966 case SADB_X_EXT_NAT_T_OA: 1967#endif 1968#ifdef SADB_X_EXT_TAG 1969 case SADB_X_EXT_TAG: 1970#endif 1971#ifdef SADB_X_EXT_PACKET 1972 case SADB_X_EXT_PACKET: 1973#endif 1974 1975 mhp[ext->sadb_ext_type] = (void *)ext; 1976 break; 1977 default: 1978 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1979 return -1; 1980 } 1981 1982 p += PFKEY_EXTLEN(ext); 1983 } 1984 1985 if (p != ep) { 1986 __ipsec_errcode = EIPSEC_INVAL_SADBMSG; 1987 return -1; 1988 } 1989 1990 __ipsec_errcode = EIPSEC_NO_ERROR; 1991 return 0; 1992} 1993 1994/* 1995 * check basic usage for sadb_msg, 1996 * NOTE: This routine is derived from netkey/key.c in KAME. 1997 * IN: msg: pointer to message buffer. 1998 * mhp: pointer to the buffer initialized like below: 1999 * 2000 * caddr_t mhp[SADB_EXT_MAX + 1]; 2001 * 2002 * OUT: -1: invalid. 2003 * 0: valid. 2004 */ 2005int 2006pfkey_check(mhp) 2007 caddr_t *mhp; 2008{ 2009 struct sadb_msg *msg; 2010 2011 /* validity check */ 2012 if (mhp == NULL || mhp[0] == NULL) { 2013 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 2014 return -1; 2015 } 2016 2017 msg = (void *)mhp[0]; 2018 2019 /* check version */ 2020 if (msg->sadb_msg_version != PF_KEY_V2) { 2021 __ipsec_errcode = EIPSEC_INVAL_VERSION; 2022 return -1; 2023 } 2024 2025 /* check type */ 2026 if (msg->sadb_msg_type > SADB_MAX) { 2027 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE; 2028 return -1; 2029 } 2030 2031 /* check SA type */ 2032 switch (msg->sadb_msg_satype) { 2033 case SADB_SATYPE_UNSPEC: 2034 switch (msg->sadb_msg_type) { 2035 case SADB_GETSPI: 2036 case SADB_UPDATE: 2037 case SADB_ADD: 2038 case SADB_DELETE: 2039 case SADB_GET: 2040 case SADB_ACQUIRE: 2041 case SADB_EXPIRE: 2042#ifdef SADB_X_NAT_T_NEW_MAPPING 2043 case SADB_X_NAT_T_NEW_MAPPING: 2044#endif 2045 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2046 return -1; 2047 } 2048 break; 2049 case SADB_SATYPE_ESP: 2050 case SADB_SATYPE_AH: 2051 case SADB_X_SATYPE_IPCOMP: 2052#ifdef SADB_X_SATYPE_TCPSIGNATURE 2053 case SADB_X_SATYPE_TCPSIGNATURE: 2054#endif 2055 switch (msg->sadb_msg_type) { 2056 case SADB_X_SPDADD: 2057 case SADB_X_SPDDELETE: 2058 case SADB_X_SPDGET: 2059 case SADB_X_SPDDUMP: 2060 case SADB_X_SPDFLUSH: 2061 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2062 return -1; 2063 } 2064#ifdef SADB_X_NAT_T_NEW_MAPPING 2065 if (msg->sadb_msg_type == SADB_X_NAT_T_NEW_MAPPING && 2066 msg->sadb_msg_satype != SADB_SATYPE_ESP) { 2067 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2068 return -1; 2069 } 2070#endif 2071 break; 2072 case SADB_SATYPE_RSVP: 2073 case SADB_SATYPE_OSPFV2: 2074 case SADB_SATYPE_RIPV2: 2075 case SADB_SATYPE_MIP: 2076 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 2077 return -1; 2078 case 1: /* XXX: What does it do ? */ 2079 if (msg->sadb_msg_type == SADB_X_PROMISC) 2080 break; 2081 /*FALLTHROUGH*/ 2082 default: 2083 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 2084 return -1; 2085 } 2086 2087 /* check field of upper layer protocol and address family */ 2088 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL 2089 && mhp[SADB_EXT_ADDRESS_DST] != NULL) { 2090 struct sadb_address *src0, *dst0; 2091 2092 src0 = (void *)(mhp[SADB_EXT_ADDRESS_SRC]); 2093 dst0 = (void *)(mhp[SADB_EXT_ADDRESS_DST]); 2094 2095 if (src0->sadb_address_proto != dst0->sadb_address_proto) { 2096 __ipsec_errcode = EIPSEC_PROTO_MISMATCH; 2097 return -1; 2098 } 2099 2100 if (PFKEY_ADDR_SADDR(src0)->sa_family 2101 != PFKEY_ADDR_SADDR(dst0)->sa_family) { 2102 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 2103 return -1; 2104 } 2105 2106 switch (PFKEY_ADDR_SADDR(src0)->sa_family) { 2107 case AF_INET: 2108 case AF_INET6: 2109 break; 2110 default: 2111 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 2112 return -1; 2113 } 2114 2115 /* 2116 * prefixlen == 0 is valid because there must be the case 2117 * all addresses are matched. 2118 */ 2119 } 2120 2121 __ipsec_errcode = EIPSEC_NO_ERROR; 2122 return 0; 2123} 2124 2125/* 2126 * set data into sadb_msg. 2127 * `buf' must has been allocated sufficiently. 2128 */ 2129static caddr_t 2130pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid) 2131 caddr_t buf; 2132 caddr_t lim; 2133 u_int type, satype; 2134 u_int tlen; 2135 u_int32_t seq; 2136 pid_t pid; 2137{ 2138 struct sadb_msg *p; 2139 u_int len; 2140 2141 p = (void *)buf; 2142 len = sizeof(struct sadb_msg); 2143 2144 if (buf + len > lim) 2145 return NULL; 2146 2147 memset(p, 0, len); 2148 p->sadb_msg_version = PF_KEY_V2; 2149 p->sadb_msg_type = type; 2150 p->sadb_msg_errno = 0; 2151 p->sadb_msg_satype = satype; 2152 p->sadb_msg_len = PFKEY_UNIT64(tlen); 2153 p->sadb_msg_reserved = 0; 2154 p->sadb_msg_seq = seq; 2155 p->sadb_msg_pid = (u_int32_t)pid; 2156 2157 return(buf + len); 2158} 2159 2160/* 2161 * copy secasvar data into sadb_address. 2162 * `buf' must has been allocated sufficiently. 2163 */ 2164static caddr_t 2165pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags) 2166 caddr_t buf; 2167 caddr_t lim; 2168 u_int32_t spi, flags; 2169 u_int wsize, auth, enc; 2170{ 2171 struct sadb_sa *p; 2172 u_int len; 2173 2174 p = (void *)buf; 2175 len = sizeof(struct sadb_sa); 2176 2177 if (buf + len > lim) 2178 return NULL; 2179 2180 memset(p, 0, len); 2181 p->sadb_sa_len = PFKEY_UNIT64(len); 2182 p->sadb_sa_exttype = SADB_EXT_SA; 2183 p->sadb_sa_spi = spi; 2184 p->sadb_sa_replay = wsize; 2185 p->sadb_sa_state = SADB_SASTATE_LARVAL; 2186 p->sadb_sa_auth = auth; 2187 p->sadb_sa_encrypt = enc; 2188 p->sadb_sa_flags = flags; 2189 2190 return(buf + len); 2191} 2192 2193/* 2194 * set data into sadb_address. 2195 * `buf' must has been allocated sufficiently. 2196 * prefixlen is in bits. 2197 */ 2198static caddr_t 2199pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto) 2200 caddr_t buf; 2201 caddr_t lim; 2202 u_int exttype; 2203 struct sockaddr *saddr; 2204 u_int prefixlen; 2205 u_int ul_proto; 2206{ 2207 struct sadb_address *p; 2208 u_int len; 2209 2210 p = (void *)buf; 2211 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len(saddr)); 2212 2213 if (buf + len > lim) 2214 return NULL; 2215 2216 memset(p, 0, len); 2217 p->sadb_address_len = PFKEY_UNIT64(len); 2218 p->sadb_address_exttype = exttype & 0xffff; 2219 p->sadb_address_proto = ul_proto & 0xff; 2220 p->sadb_address_prefixlen = prefixlen; 2221 p->sadb_address_reserved = 0; 2222 2223 memcpy(p + 1, saddr, (size_t)sysdep_sa_len(saddr)); 2224 2225 return(buf + len); 2226} 2227 2228/* 2229 * set sadb_key structure after clearing buffer with zero. 2230 * OUT: the pointer of buf + len. 2231 */ 2232static caddr_t 2233pfkey_setsadbkey(buf, lim, type, key, keylen) 2234 caddr_t buf; 2235 caddr_t lim; 2236 caddr_t key; 2237 u_int type, keylen; 2238{ 2239 struct sadb_key *p; 2240 u_int len; 2241 2242 p = (void *)buf; 2243 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); 2244 2245 if (buf + len > lim) 2246 return NULL; 2247 2248 memset(p, 0, len); 2249 p->sadb_key_len = PFKEY_UNIT64(len); 2250 p->sadb_key_exttype = type; 2251 p->sadb_key_bits = keylen << 3; 2252 p->sadb_key_reserved = 0; 2253 2254 memcpy(p + 1, key, keylen); 2255 2256 return buf + len; 2257} 2258 2259/* 2260 * set sadb_lifetime structure after clearing buffer with zero. 2261 * OUT: the pointer of buf + len. 2262 */ 2263static caddr_t 2264pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime) 2265 caddr_t buf; 2266 caddr_t lim; 2267 u_int type; 2268 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime; 2269{ 2270 struct sadb_lifetime *p; 2271 u_int len; 2272 2273 p = (void *)buf; 2274 len = sizeof(struct sadb_lifetime); 2275 2276 if (buf + len > lim) 2277 return NULL; 2278 2279 memset(p, 0, len); 2280 p->sadb_lifetime_len = PFKEY_UNIT64(len); 2281 p->sadb_lifetime_exttype = type; 2282 2283 switch (type) { 2284 case SADB_EXT_LIFETIME_SOFT: 2285 p->sadb_lifetime_allocations 2286 = (l_alloc * soft_lifetime_allocations_rate) /100; 2287 p->sadb_lifetime_bytes 2288 = (l_bytes * soft_lifetime_bytes_rate) /100; 2289 p->sadb_lifetime_addtime 2290 = (l_addtime * soft_lifetime_addtime_rate) /100; 2291 p->sadb_lifetime_usetime 2292 = (l_usetime * soft_lifetime_usetime_rate) /100; 2293 break; 2294 case SADB_EXT_LIFETIME_HARD: 2295 p->sadb_lifetime_allocations = l_alloc; 2296 p->sadb_lifetime_bytes = l_bytes; 2297 p->sadb_lifetime_addtime = l_addtime; 2298 p->sadb_lifetime_usetime = l_usetime; 2299 break; 2300 } 2301 2302 return buf + len; 2303} 2304 2305/* 2306 * copy secasvar data into sadb_address. 2307 * `buf' must has been allocated sufficiently. 2308 */ 2309static caddr_t 2310pfkey_setsadbxsa2(buf, lim, mode0, reqid) 2311 caddr_t buf; 2312 caddr_t lim; 2313 u_int32_t mode0; 2314 u_int32_t reqid; 2315{ 2316 struct sadb_x_sa2 *p; 2317 u_int8_t mode = mode0 & 0xff; 2318 u_int len; 2319 2320 p = (void *)buf; 2321 len = sizeof(struct sadb_x_sa2); 2322 2323 if (buf + len > lim) 2324 return NULL; 2325 2326 memset(p, 0, len); 2327 p->sadb_x_sa2_len = PFKEY_UNIT64(len); 2328 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; 2329 p->sadb_x_sa2_mode = mode; 2330 p->sadb_x_sa2_reqid = reqid; 2331 2332 return(buf + len); 2333} 2334 2335#ifdef SADB_X_EXT_NAT_T_TYPE 2336static caddr_t 2337pfkey_set_natt_type(buf, lim, type, l_natt_type) 2338 caddr_t buf; 2339 caddr_t lim; 2340 u_int type; 2341 u_int8_t l_natt_type; 2342{ 2343 struct sadb_x_nat_t_type *p; 2344 u_int len; 2345 2346 p = (void *)buf; 2347 len = sizeof(struct sadb_x_nat_t_type); 2348 2349 if (buf + len > lim) 2350 return NULL; 2351 2352 memset(p, 0, len); 2353 p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len); 2354 p->sadb_x_nat_t_type_exttype = type; 2355 p->sadb_x_nat_t_type_type = l_natt_type; 2356 2357 return(buf + len); 2358} 2359 2360static caddr_t 2361pfkey_set_natt_port(buf, lim, type, l_natt_port) 2362 caddr_t buf; 2363 caddr_t lim; 2364 u_int type; 2365 u_int16_t l_natt_port; 2366{ 2367 struct sadb_x_nat_t_port *p; 2368 u_int len; 2369 2370 p = (void *)buf; 2371 len = sizeof(struct sadb_x_nat_t_port); 2372 2373 if (buf + len > lim) 2374 return NULL; 2375 2376 memset(p, 0, len); 2377 p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len); 2378 p->sadb_x_nat_t_port_exttype = type; 2379 p->sadb_x_nat_t_port_port = htons(l_natt_port); 2380 2381 return(buf + len); 2382} 2383#endif 2384 2385#ifdef SADB_X_EXT_NAT_T_FRAG 2386static caddr_t 2387pfkey_set_natt_frag(buf, lim, type, l_natt_frag) 2388 caddr_t buf; 2389 caddr_t lim; 2390 u_int type; 2391 u_int16_t l_natt_frag; 2392{ 2393 struct sadb_x_nat_t_frag *p; 2394 u_int len; 2395 2396 p = (void *)buf; 2397 len = sizeof(struct sadb_x_nat_t_frag); 2398 2399 if (buf + len > lim) 2400 return NULL; 2401 2402 memset(p, 0, len); 2403 p->sadb_x_nat_t_frag_len = PFKEY_UNIT64(len); 2404 p->sadb_x_nat_t_frag_exttype = type; 2405 p->sadb_x_nat_t_frag_fraglen = l_natt_frag; 2406 2407 return(buf + len); 2408} 2409#endif 2410