1 /* $NetBSD: parse.y,v 1.12 2009/03/06 11:45:03 tteras Exp $ */ 2 3 /* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 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 %{ 35 #ifdef HAVE_CONFIG_H 36 #include "config.h" 37 #endif 38 39 #include <sys/types.h> 40 #include <sys/param.h> 41 #include <sys/socket.h> 42 43 #include <netinet/in.h> 44 #include <net/pfkeyv2.h> 45 #include PATH_IPSEC_H 46 #include <arpa/inet.h> 47 48 #include <string.h> 49 #include <unistd.h> 50 #include <stdio.h> 51 #include <netdb.h> 52 #include <ctype.h> 53 #include <errno.h> 54 #include <stdlib.h> 55 56 #include "libpfkey.h" 57 #include "vchar.h" 58 #include "extern.h" 59 60 #ifndef IPPROTO_MH 61 #define IPPROTO_MH 135 62 #endif 63 64 #define DEFAULT_NATT_PORT 4500 65 66 #ifndef UDP_ENCAP_ESPINUDP 67 #define UDP_ENCAP_ESPINUDP 2 68 #endif 69 70 #define ATOX(c) \ 71 (isdigit((int)c) ? (c - '0') : \ 72 (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10))) 73 74 u_int32_t p_spi; 75 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; 76 u_int32_t p_reqid; 77 u_int p_key_enc_len, p_key_auth_len; 78 const char *p_key_enc; 79 const char *p_key_auth; 80 time_t p_lt_hard, p_lt_soft; 81 size_t p_lb_hard, p_lb_soft; 82 83 struct security_ctx { 84 u_int8_t doi; 85 u_int8_t alg; 86 u_int16_t len; 87 char *buf; 88 }; 89 90 struct security_ctx sec_ctx; 91 92 static u_int p_natt_type; 93 static struct addrinfo * p_natt_oa = NULL; 94 95 static int p_aiflags = 0, p_aifamily = PF_UNSPEC; 96 97 static struct addrinfo *parse_addr __P((char *, char *)); 98 static int fix_portstr __P((vchar_t *, vchar_t *, vchar_t *)); 99 static int setvarbuf __P((char *, int *, struct sadb_ext *, int, 100 const void *, int)); 101 void parse_init __P((void)); 102 void free_buffer __P((void)); 103 104 int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t)); 105 static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *, 106 struct addrinfo *, int, struct addrinfo *, int)); 107 static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *)); 108 static int setkeymsg_addr __P((unsigned int, unsigned int, 109 struct addrinfo *, struct addrinfo *, int)); 110 static int setkeymsg_add __P((unsigned int, unsigned int, 111 struct addrinfo *, struct addrinfo *)); 112 %} 113 114 %union { 115 int num; 116 unsigned long ulnum; 117 vchar_t val; 118 struct addrinfo *res; 119 } 120 121 %token EOT SLASH BLCL ELCL 122 %token ADD GET DELETE DELETEALL FLUSH DUMP EXIT 123 %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP 124 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI 125 %token F_MODE MODE F_REQID 126 %token F_EXT EXTENSION NOCYCLICSEQ 127 %token ALG_AUTH ALG_AUTH_NOKEY 128 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD 129 %token ALG_COMP 130 %token F_LIFETIME_HARD F_LIFETIME_SOFT 131 %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT 132 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY 133 /* SPD management */ 134 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH 135 %token F_POLICY PL_REQUESTS 136 %token F_AIFLAGS 137 %token TAGGED 138 %token SECURITY_CTX 139 140 %type <num> prefix protocol_spec upper_spec 141 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY 142 %type <num> ALG_AUTH ALG_AUTH_NOKEY 143 %type <num> ALG_COMP 144 %type <num> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP 145 %type <num> EXTENSION MODE 146 %type <ulnum> DECSTRING 147 %type <val> PL_REQUESTS portstr key_string 148 %type <val> policy_requests 149 %type <val> QUOTEDSTRING HEXSTRING STRING 150 %type <val> F_AIFLAGS 151 %type <val> upper_misc_spec policy_spec 152 %type <res> ipaddr ipandport 153 154 %% 155 commands 156 : /*NOTHING*/ 157 | commands command 158 { 159 free_buffer(); 160 parse_init(); 161 } 162 ; 163 164 command 165 : add_command 166 | get_command 167 | delete_command 168 | deleteall_command 169 | flush_command 170 | dump_command 171 | exit_command 172 | spdadd_command 173 | spddelete_command 174 | spddump_command 175 | spdflush_command 176 ; 177 /* commands concerned with management, there is in tail of this file. */ 178 179 /* add command */ 180 add_command 181 : ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT 182 { 183 int status; 184 185 status = setkeymsg_add(SADB_ADD, $5, $3, $4); 186 if (status < 0) 187 return -1; 188 } 189 ; 190 191 /* delete */ 192 delete_command 193 : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT 194 { 195 int status; 196 197 if ($3->ai_next || $4->ai_next) { 198 yyerror("multiple address specified"); 199 return -1; 200 } 201 if (p_mode != IPSEC_MODE_ANY) 202 yyerror("WARNING: mode is obsolete"); 203 204 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0); 205 if (status < 0) 206 return -1; 207 } 208 ; 209 210 /* deleteall command */ 211 deleteall_command 212 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT 213 { 214 #ifndef __linux__ 215 if (setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1) < 0) 216 return -1; 217 #else /* __linux__ */ 218 /* linux strictly adheres to RFC2367, and returns 219 * an error if we send an SADB_DELETE request without 220 * an SPI. Therefore, we must first retrieve a list 221 * of SPIs for all matching SADB entries, and then 222 * delete each one separately. */ 223 u_int32_t *spi; 224 int i, n; 225 226 spi = sendkeymsg_spigrep($5, $3, $4, &n); 227 for (i = 0; i < n; i++) { 228 p_spi = spi[i]; 229 if (setkeymsg_addr(SADB_DELETE, 230 $5, $3, $4, 0) < 0) 231 return -1; 232 } 233 free(spi); 234 #endif /* __linux__ */ 235 } 236 ; 237 238 /* get command */ 239 get_command 240 : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT 241 { 242 int status; 243 244 if (p_mode != IPSEC_MODE_ANY) 245 yyerror("WARNING: mode is obsolete"); 246 247 status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0); 248 if (status < 0) 249 return -1; 250 } 251 ; 252 253 /* flush */ 254 flush_command 255 : FLUSH protocol_spec EOT 256 { 257 struct sadb_msg msg; 258 setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg)); 259 sendkeymsg((char *)&msg, sizeof(msg)); 260 } 261 ; 262 263 /* dump */ 264 dump_command 265 : DUMP protocol_spec EOT 266 { 267 struct sadb_msg msg; 268 setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg)); 269 sendkeymsg((char *)&msg, sizeof(msg)); 270 } 271 ; 272 273 protocol_spec 274 : /*NOTHING*/ 275 { 276 $$ = SADB_SATYPE_UNSPEC; 277 } 278 | PR_ESP 279 { 280 $$ = SADB_SATYPE_ESP; 281 if ($1 == 1) 282 p_ext |= SADB_X_EXT_OLD; 283 else 284 p_ext &= ~SADB_X_EXT_OLD; 285 } 286 | PR_AH 287 { 288 $$ = SADB_SATYPE_AH; 289 if ($1 == 1) 290 p_ext |= SADB_X_EXT_OLD; 291 else 292 p_ext &= ~SADB_X_EXT_OLD; 293 } 294 | PR_IPCOMP 295 { 296 $$ = SADB_X_SATYPE_IPCOMP; 297 } 298 | PR_ESPUDP 299 { 300 $$ = SADB_SATYPE_ESP; 301 p_ext &= ~SADB_X_EXT_OLD; 302 p_natt_oa = 0; 303 p_natt_type = UDP_ENCAP_ESPINUDP; 304 } 305 | PR_ESPUDP ipaddr 306 { 307 $$ = SADB_SATYPE_ESP; 308 p_ext &= ~SADB_X_EXT_OLD; 309 p_natt_oa = $2; 310 p_natt_type = UDP_ENCAP_ESPINUDP; 311 } 312 | PR_TCP 313 { 314 #ifdef SADB_X_SATYPE_TCPSIGNATURE 315 $$ = SADB_X_SATYPE_TCPSIGNATURE; 316 #endif 317 } 318 ; 319 320 spi 321 : DECSTRING { p_spi = $1; } 322 | HEXSTRING 323 { 324 char *ep; 325 unsigned long v; 326 327 ep = NULL; 328 v = strtoul($1.buf, &ep, 16); 329 if (!ep || *ep) { 330 yyerror("invalid SPI"); 331 return -1; 332 } 333 if (v & ~0xffffffff) { 334 yyerror("SPI too big."); 335 return -1; 336 } 337 338 p_spi = v; 339 } 340 ; 341 342 algorithm_spec 343 : esp_spec 344 | ah_spec 345 | ipcomp_spec 346 ; 347 348 esp_spec 349 : F_ENC enc_alg F_AUTH auth_alg 350 | F_ENC enc_alg 351 ; 352 353 ah_spec 354 : F_AUTH auth_alg 355 ; 356 357 ipcomp_spec 358 : F_COMP ALG_COMP 359 { 360 if ($2 < 0) { 361 yyerror("unsupported algorithm"); 362 return -1; 363 } 364 p_alg_enc = $2; 365 } 366 | F_COMP ALG_COMP F_RAWCPI 367 { 368 if ($2 < 0) { 369 yyerror("unsupported algorithm"); 370 return -1; 371 } 372 p_alg_enc = $2; 373 p_ext |= SADB_X_EXT_RAWCPI; 374 } 375 ; 376 377 enc_alg 378 : ALG_ENC_NOKEY { 379 if ($1 < 0) { 380 yyerror("unsupported algorithm"); 381 return -1; 382 } 383 p_alg_enc = $1; 384 385 p_key_enc_len = 0; 386 p_key_enc = ""; 387 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 388 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 389 yyerror(ipsec_strerror()); 390 return -1; 391 } 392 } 393 | ALG_ENC key_string { 394 if ($1 < 0) { 395 yyerror("unsupported algorithm"); 396 return -1; 397 } 398 p_alg_enc = $1; 399 400 p_key_enc_len = $2.len; 401 p_key_enc = $2.buf; 402 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 403 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 404 yyerror(ipsec_strerror()); 405 return -1; 406 } 407 } 408 | ALG_ENC_OLD { 409 if ($1 < 0) { 410 yyerror("unsupported algorithm"); 411 return -1; 412 } 413 yyerror("WARNING: obsolete algorithm"); 414 p_alg_enc = $1; 415 416 p_key_enc_len = 0; 417 p_key_enc = ""; 418 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 419 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 420 yyerror(ipsec_strerror()); 421 return -1; 422 } 423 } 424 | ALG_ENC_DESDERIV key_string 425 { 426 if ($1 < 0) { 427 yyerror("unsupported algorithm"); 428 return -1; 429 } 430 p_alg_enc = $1; 431 if (p_ext & SADB_X_EXT_OLD) { 432 yyerror("algorithm mismatched"); 433 return -1; 434 } 435 p_ext |= SADB_X_EXT_DERIV; 436 437 p_key_enc_len = $2.len; 438 p_key_enc = $2.buf; 439 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 440 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 441 yyerror(ipsec_strerror()); 442 return -1; 443 } 444 } 445 | ALG_ENC_DES32IV key_string 446 { 447 if ($1 < 0) { 448 yyerror("unsupported algorithm"); 449 return -1; 450 } 451 p_alg_enc = $1; 452 if (!(p_ext & SADB_X_EXT_OLD)) { 453 yyerror("algorithm mismatched"); 454 return -1; 455 } 456 p_ext |= SADB_X_EXT_IV4B; 457 458 p_key_enc_len = $2.len; 459 p_key_enc = $2.buf; 460 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 461 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 462 yyerror(ipsec_strerror()); 463 return -1; 464 } 465 } 466 ; 467 468 auth_alg 469 : ALG_AUTH key_string { 470 if ($1 < 0) { 471 yyerror("unsupported algorithm"); 472 return -1; 473 } 474 p_alg_auth = $1; 475 476 p_key_auth_len = $2.len; 477 p_key_auth = $2.buf; 478 #ifdef SADB_X_AALG_TCP_MD5 479 if (p_alg_auth == SADB_X_AALG_TCP_MD5) { 480 if ((p_key_auth_len < 1) || 481 (p_key_auth_len > 80)) 482 return -1; 483 } else 484 #endif 485 { 486 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, 487 p_alg_auth, 488 PFKEY_UNUNIT64(p_key_auth_len)) < 0) { 489 yyerror(ipsec_strerror()); 490 return -1; 491 } 492 } 493 } 494 | ALG_AUTH_NOKEY { 495 if ($1 < 0) { 496 yyerror("unsupported algorithm"); 497 return -1; 498 } 499 p_alg_auth = $1; 500 501 p_key_auth_len = 0; 502 p_key_auth = NULL; 503 } 504 ; 505 506 key_string 507 : QUOTEDSTRING 508 { 509 $$ = $1; 510 } 511 | HEXSTRING 512 { 513 caddr_t pp_key; 514 caddr_t bp; 515 caddr_t yp = $1.buf; 516 int l; 517 518 l = strlen(yp) % 2 + strlen(yp) / 2; 519 if ((pp_key = malloc(l)) == 0) { 520 yyerror("not enough core"); 521 return -1; 522 } 523 memset(pp_key, 0, l); 524 525 bp = pp_key; 526 if (strlen(yp) % 2) { 527 *bp = ATOX(yp[0]); 528 yp++, bp++; 529 } 530 while (*yp) { 531 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 532 yp += 2, bp++; 533 } 534 535 $$.len = l; 536 $$.buf = pp_key; 537 } 538 ; 539 540 extension_spec 541 : /*NOTHING*/ 542 | extension_spec extension 543 ; 544 545 extension 546 : F_EXT EXTENSION { p_ext |= $2; } 547 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 548 | F_MODE MODE { p_mode = $2; } 549 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 550 | F_REQID DECSTRING { p_reqid = $2; } 551 | F_REPLAY DECSTRING 552 { 553 if ((p_ext & SADB_X_EXT_OLD) != 0) { 554 yyerror("replay prevention cannot be used with " 555 "ah/esp-old"); 556 return -1; 557 } 558 p_replay = $2; 559 } 560 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 561 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 562 | F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; } 563 | F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; } 564 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING { 565 sec_ctx.doi = $2; 566 sec_ctx.alg = $3; 567 sec_ctx.len = $4.len+1; 568 sec_ctx.buf = $4.buf; 569 } 570 ; 571 572 /* definition about command for SPD management */ 573 /* spdadd */ 574 spdadd_command 575 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT 576 { 577 int status; 578 struct addrinfo *src, *dst; 579 580 #ifdef HAVE_PFKEY_POLICY_PRIORITY 581 last_msg_type = SADB_X_SPDADD; 582 #endif 583 584 /* fixed port fields if ulp is icmp */ 585 if ($10.buf != NULL) { 586 if (($9 != IPPROTO_ICMPV6) && 587 ($9 != IPPROTO_ICMP) && 588 ($9 != IPPROTO_MH)) 589 return -1; 590 free($5.buf); 591 free($8.buf); 592 if (fix_portstr(&$10, &$5, &$8)) 593 return -1; 594 } 595 596 src = parse_addr($3.buf, $5.buf); 597 dst = parse_addr($6.buf, $8.buf); 598 if (!src || !dst) { 599 /* yyerror is already called */ 600 return -1; 601 } 602 if (src->ai_next || dst->ai_next) { 603 yyerror("multiple address specified"); 604 freeaddrinfo(src); 605 freeaddrinfo(dst); 606 return -1; 607 } 608 609 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12, 610 src, $4, dst, $7); 611 freeaddrinfo(src); 612 freeaddrinfo(dst); 613 if (status < 0) 614 return -1; 615 } 616 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT 617 { 618 int status; 619 620 status = setkeymsg_spdaddr_tag(SADB_X_SPDADD, 621 $3.buf, &$4); 622 if (status < 0) 623 return -1; 624 } 625 ; 626 627 spddelete_command 628 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT 629 { 630 int status; 631 struct addrinfo *src, *dst; 632 633 /* fixed port fields if ulp is icmp */ 634 if ($10.buf != NULL) { 635 if (($9 != IPPROTO_ICMPV6) && 636 ($9 != IPPROTO_ICMP) && 637 ($9 != IPPROTO_MH)) 638 return -1; 639 free($5.buf); 640 free($8.buf); 641 if (fix_portstr(&$10, &$5, &$8)) 642 return -1; 643 } 644 645 src = parse_addr($3.buf, $5.buf); 646 dst = parse_addr($6.buf, $8.buf); 647 if (!src || !dst) { 648 /* yyerror is already called */ 649 return -1; 650 } 651 if (src->ai_next || dst->ai_next) { 652 yyerror("multiple address specified"); 653 freeaddrinfo(src); 654 freeaddrinfo(dst); 655 return -1; 656 } 657 658 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12, 659 src, $4, dst, $7); 660 freeaddrinfo(src); 661 freeaddrinfo(dst); 662 if (status < 0) 663 return -1; 664 } 665 ; 666 667 spddump_command: 668 SPDDUMP EOT 669 { 670 struct sadb_msg msg; 671 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, 672 sizeof(msg)); 673 sendkeymsg((char *)&msg, sizeof(msg)); 674 } 675 ; 676 677 spdflush_command 678 : 679 SPDFLUSH EOT 680 { 681 struct sadb_msg msg; 682 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, 683 sizeof(msg)); 684 sendkeymsg((char *)&msg, sizeof(msg)); 685 } 686 ; 687 688 ipaddropts 689 : /* nothing */ 690 | ipaddropts ipaddropt 691 ; 692 693 ipaddropt 694 : F_AIFLAGS 695 { 696 char *p; 697 698 for (p = $1.buf + 1; *p; p++) 699 switch (*p) { 700 case '4': 701 p_aifamily = AF_INET; 702 break; 703 #ifdef INET6 704 case '6': 705 p_aifamily = AF_INET6; 706 break; 707 #endif 708 case 'n': 709 p_aiflags = AI_NUMERICHOST; 710 break; 711 default: 712 yyerror("invalid flag"); 713 return -1; 714 } 715 } 716 ; 717 718 ipaddr 719 : STRING 720 { 721 $$ = parse_addr($1.buf, NULL); 722 if ($$ == NULL) { 723 /* yyerror already called by parse_addr */ 724 return -1; 725 } 726 } 727 ; 728 729 ipandport 730 : STRING 731 { 732 $$ = parse_addr($1.buf, NULL); 733 if ($$ == NULL) { 734 /* yyerror already called by parse_addr */ 735 return -1; 736 } 737 } 738 | STRING portstr 739 { 740 $$ = parse_addr($1.buf, $2.buf); 741 if ($$ == NULL) { 742 /* yyerror already called by parse_addr */ 743 return -1; 744 } 745 } 746 ; 747 748 prefix 749 : /*NOTHING*/ { $$ = -1; } 750 | SLASH DECSTRING { $$ = $2; } 751 ; 752 753 portstr 754 : /*NOTHING*/ 755 { 756 $$.buf = strdup("0"); 757 if (!$$.buf) { 758 yyerror("insufficient memory"); 759 return -1; 760 } 761 $$.len = strlen($$.buf); 762 } 763 | BLCL ANY ELCL 764 { 765 $$.buf = strdup("0"); 766 if (!$$.buf) { 767 yyerror("insufficient memory"); 768 return -1; 769 } 770 $$.len = strlen($$.buf); 771 } 772 | BLCL DECSTRING ELCL 773 { 774 char buf[20]; 775 snprintf(buf, sizeof(buf), "%lu", $2); 776 $$.buf = strdup(buf); 777 if (!$$.buf) { 778 yyerror("insufficient memory"); 779 return -1; 780 } 781 $$.len = strlen($$.buf); 782 } 783 | BLCL STRING ELCL 784 { 785 $$ = $2; 786 } 787 ; 788 789 upper_spec 790 : DECSTRING { $$ = $1; } 791 | ANY { $$ = IPSEC_ULPROTO_ANY; } 792 | PR_TCP { 793 $$ = IPPROTO_TCP; 794 } 795 | STRING 796 { 797 struct protoent *ent; 798 799 ent = getprotobyname($1.buf); 800 if (ent) 801 $$ = ent->p_proto; 802 else { 803 if (strcmp("icmp6", $1.buf) == 0) { 804 $$ = IPPROTO_ICMPV6; 805 } else if(strcmp("ip4", $1.buf) == 0) { 806 $$ = IPPROTO_IPV4; 807 } else { 808 yyerror("invalid upper layer protocol"); 809 return -1; 810 } 811 } 812 endprotoent(); 813 } 814 ; 815 816 upper_misc_spec 817 : /*NOTHING*/ 818 { 819 $$.buf = NULL; 820 $$.len = 0; 821 } 822 | STRING 823 { 824 $$.buf = strdup($1.buf); 825 if (!$$.buf) { 826 yyerror("insufficient memory"); 827 return -1; 828 } 829 $$.len = strlen($$.buf); 830 } 831 ; 832 833 context_spec 834 : /* NOTHING */ 835 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING { 836 sec_ctx.doi = $2; 837 sec_ctx.alg = $3; 838 sec_ctx.len = $4.len+1; 839 sec_ctx.buf = $4.buf; 840 } 841 ; 842 843 policy_spec 844 : F_POLICY policy_requests 845 { 846 char *policy; 847 #ifdef HAVE_PFKEY_POLICY_PRIORITY 848 struct sadb_x_policy *xpl; 849 #endif 850 851 policy = ipsec_set_policy($2.buf, $2.len); 852 if (policy == NULL) { 853 yyerror(ipsec_strerror()); 854 return -1; 855 } 856 857 $$.buf = policy; 858 $$.len = ipsec_get_policylen(policy); 859 860 #ifdef HAVE_PFKEY_POLICY_PRIORITY 861 xpl = (struct sadb_x_policy *) $$.buf; 862 last_priority = xpl->sadb_x_policy_priority; 863 #endif 864 } 865 ; 866 867 policy_requests 868 : PL_REQUESTS { $$ = $1; } 869 ; 870 871 /* exit */ 872 exit_command 873 : EXIT EOT 874 { 875 exit_now = 1; 876 YYACCEPT; 877 } 878 ; 879 %% 880 881 int 882 setkeymsg0(msg, type, satype, l) 883 struct sadb_msg *msg; 884 unsigned int type; 885 unsigned int satype; 886 size_t l; 887 { 888 889 msg->sadb_msg_version = PF_KEY_V2; 890 msg->sadb_msg_type = type; 891 msg->sadb_msg_errno = 0; 892 msg->sadb_msg_satype = satype; 893 msg->sadb_msg_reserved = 0; 894 msg->sadb_msg_seq = 0; 895 msg->sadb_msg_pid = getpid(); 896 msg->sadb_msg_len = PFKEY_UNIT64(l); 897 return 0; 898 } 899 900 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 901 static int 902 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 903 unsigned int type; 904 unsigned int upper; 905 vchar_t *policy; 906 struct addrinfo *srcs; 907 int splen; 908 struct addrinfo *dsts; 909 int dplen; 910 { 911 struct sadb_msg *msg; 912 char buf[BUFSIZ]; 913 int l, l0; 914 struct sadb_address m_addr; 915 struct addrinfo *s, *d; 916 int n; 917 int plen; 918 struct sockaddr *sa; 919 int salen; 920 struct sadb_x_policy *sp; 921 #ifdef HAVE_POLICY_FWD 922 struct sadb_x_ipsecrequest *ps = NULL; 923 int saved_level, saved_id = 0; 924 #endif 925 926 msg = (struct sadb_msg *)buf; 927 928 if (!srcs || !dsts) 929 return -1; 930 931 /* fix up length afterwards */ 932 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 933 l = sizeof(struct sadb_msg); 934 935 sp = (struct sadb_x_policy*) (buf + l); 936 memcpy(buf + l, policy->buf, policy->len); 937 l += policy->len; 938 939 l0 = l; 940 n = 0; 941 942 /* do it for all src/dst pairs */ 943 for (s = srcs; s; s = s->ai_next) { 944 for (d = dsts; d; d = d->ai_next) { 945 /* rewind pointer */ 946 l = l0; 947 948 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 949 continue; 950 switch (s->ai_addr->sa_family) { 951 case AF_INET: 952 plen = sizeof(struct in_addr) << 3; 953 break; 954 #ifdef INET6 955 case AF_INET6: 956 plen = sizeof(struct in6_addr) << 3; 957 break; 958 #endif 959 default: 960 continue; 961 } 962 963 /* set src */ 964 sa = s->ai_addr; 965 salen = sysdep_sa_len(s->ai_addr); 966 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 967 PFKEY_ALIGN8(salen)); 968 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 969 m_addr.sadb_address_proto = upper; 970 m_addr.sadb_address_prefixlen = 971 (splen >= 0 ? splen : plen); 972 m_addr.sadb_address_reserved = 0; 973 974 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 975 sizeof(m_addr), (caddr_t)sa, salen); 976 977 /* set dst */ 978 sa = d->ai_addr; 979 salen = sysdep_sa_len(d->ai_addr); 980 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 981 PFKEY_ALIGN8(salen)); 982 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 983 m_addr.sadb_address_proto = upper; 984 m_addr.sadb_address_prefixlen = 985 (dplen >= 0 ? dplen : plen); 986 m_addr.sadb_address_reserved = 0; 987 988 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 989 sizeof(m_addr), sa, salen); 990 #ifdef SADB_X_EXT_SEC_CTX 991 /* Add security context label */ 992 if (sec_ctx.doi) { 993 struct sadb_x_sec_ctx m_sec_ctx; 994 u_int slen = sizeof(struct sadb_x_sec_ctx); 995 996 memset(&m_sec_ctx, 0, slen); 997 998 m_sec_ctx.sadb_x_sec_len = 999 PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len)); 1000 1001 m_sec_ctx.sadb_x_sec_exttype = 1002 SADB_X_EXT_SEC_CTX; 1003 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/ 1004 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; 1005 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; 1006 setvarbuf(buf, &l, 1007 (struct sadb_ext *)&m_sec_ctx, slen, 1008 (caddr_t)sec_ctx.buf, sec_ctx.len); 1009 } 1010 #endif 1011 msg->sadb_msg_len = PFKEY_UNIT64(l); 1012 1013 sendkeymsg(buf, l); 1014 1015 #ifdef HAVE_POLICY_FWD 1016 /* create extra call for FWD policy */ 1017 if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) { 1018 sp->sadb_x_policy_dir = IPSEC_DIR_FWD; 1019 ps = (struct sadb_x_ipsecrequest*) (sp+1); 1020 1021 /* if request level is unique, change it to 1022 * require for fwd policy */ 1023 /* XXX: currently, only first policy is updated 1024 * only. Update following too... */ 1025 saved_level = ps->sadb_x_ipsecrequest_level; 1026 if (saved_level == IPSEC_LEVEL_UNIQUE) { 1027 saved_id = ps->sadb_x_ipsecrequest_reqid; 1028 ps->sadb_x_ipsecrequest_reqid=0; 1029 ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE; 1030 } 1031 1032 sendkeymsg(buf, l); 1033 /* restoring for next message */ 1034 sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND; 1035 if (saved_level == IPSEC_LEVEL_UNIQUE) { 1036 ps->sadb_x_ipsecrequest_reqid = saved_id; 1037 ps->sadb_x_ipsecrequest_level = saved_level; 1038 } 1039 } 1040 #endif 1041 1042 n++; 1043 } 1044 } 1045 1046 if (n == 0) 1047 return -1; 1048 else 1049 return 0; 1050 } 1051 1052 static int 1053 setkeymsg_spdaddr_tag(type, tag, policy) 1054 unsigned int type; 1055 char *tag; 1056 vchar_t *policy; 1057 { 1058 struct sadb_msg *msg; 1059 char buf[BUFSIZ]; 1060 int l, l0; 1061 #ifdef SADB_X_EXT_TAG 1062 struct sadb_x_tag m_tag; 1063 #endif 1064 int n; 1065 1066 msg = (struct sadb_msg *)buf; 1067 1068 /* fix up length afterwards */ 1069 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 1070 l = sizeof(struct sadb_msg); 1071 1072 memcpy(buf + l, policy->buf, policy->len); 1073 l += policy->len; 1074 1075 l0 = l; 1076 n = 0; 1077 1078 #ifdef SADB_X_EXT_TAG 1079 memset(&m_tag, 0, sizeof(m_tag)); 1080 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag)); 1081 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG; 1082 if (strlcpy(m_tag.sadb_x_tag_name, tag, 1083 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name)) 1084 return -1; 1085 memcpy(buf + l, &m_tag, sizeof(m_tag)); 1086 l += sizeof(m_tag); 1087 #endif 1088 1089 msg->sadb_msg_len = PFKEY_UNIT64(l); 1090 1091 sendkeymsg(buf, l); 1092 1093 return 0; 1094 } 1095 1096 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 1097 static int 1098 setkeymsg_addr(type, satype, srcs, dsts, no_spi) 1099 unsigned int type; 1100 unsigned int satype; 1101 struct addrinfo *srcs; 1102 struct addrinfo *dsts; 1103 int no_spi; 1104 { 1105 struct sadb_msg *msg; 1106 char buf[BUFSIZ]; 1107 int l, l0, len; 1108 struct sadb_sa m_sa; 1109 struct sadb_x_sa2 m_sa2; 1110 struct sadb_address m_addr; 1111 struct addrinfo *s, *d; 1112 int n; 1113 int plen; 1114 struct sockaddr *sa; 1115 int salen; 1116 1117 msg = (struct sadb_msg *)buf; 1118 1119 if (!srcs || !dsts) 1120 return -1; 1121 1122 /* fix up length afterwards */ 1123 setkeymsg0(msg, type, satype, 0); 1124 l = sizeof(struct sadb_msg); 1125 1126 if (!no_spi) { 1127 len = sizeof(struct sadb_sa); 1128 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1129 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1130 m_sa.sadb_sa_spi = htonl(p_spi); 1131 m_sa.sadb_sa_replay = p_replay; 1132 m_sa.sadb_sa_state = 0; 1133 m_sa.sadb_sa_auth = p_alg_auth; 1134 m_sa.sadb_sa_encrypt = p_alg_enc; 1135 m_sa.sadb_sa_flags = p_ext; 1136 1137 memcpy(buf + l, &m_sa, len); 1138 l += len; 1139 1140 len = sizeof(struct sadb_x_sa2); 1141 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1142 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1143 m_sa2.sadb_x_sa2_mode = p_mode; 1144 m_sa2.sadb_x_sa2_reqid = p_reqid; 1145 1146 memcpy(buf + l, &m_sa2, len); 1147 l += len; 1148 } 1149 1150 l0 = l; 1151 n = 0; 1152 1153 /* do it for all src/dst pairs */ 1154 for (s = srcs; s; s = s->ai_next) { 1155 for (d = dsts; d; d = d->ai_next) { 1156 /* rewind pointer */ 1157 l = l0; 1158 1159 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1160 continue; 1161 switch (s->ai_addr->sa_family) { 1162 case AF_INET: 1163 plen = sizeof(struct in_addr) << 3; 1164 break; 1165 #ifdef INET6 1166 case AF_INET6: 1167 plen = sizeof(struct in6_addr) << 3; 1168 break; 1169 #endif 1170 default: 1171 continue; 1172 } 1173 1174 /* set src */ 1175 sa = s->ai_addr; 1176 salen = sysdep_sa_len(s->ai_addr); 1177 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1178 PFKEY_ALIGN8(salen)); 1179 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1180 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1181 m_addr.sadb_address_prefixlen = plen; 1182 m_addr.sadb_address_reserved = 0; 1183 1184 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1185 sizeof(m_addr), sa, salen); 1186 1187 /* set dst */ 1188 sa = d->ai_addr; 1189 salen = sysdep_sa_len(d->ai_addr); 1190 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1191 PFKEY_ALIGN8(salen)); 1192 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1193 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1194 m_addr.sadb_address_prefixlen = plen; 1195 m_addr.sadb_address_reserved = 0; 1196 1197 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1198 sizeof(m_addr), sa, salen); 1199 1200 msg->sadb_msg_len = PFKEY_UNIT64(l); 1201 1202 sendkeymsg(buf, l); 1203 1204 n++; 1205 } 1206 } 1207 1208 if (n == 0) 1209 return -1; 1210 else 1211 return 0; 1212 } 1213 1214 #ifdef SADB_X_EXT_NAT_T_TYPE 1215 static u_int16_t get_port (struct addrinfo *addr) 1216 { 1217 struct sockaddr *s = addr->ai_addr; 1218 u_int16_t port = 0; 1219 1220 switch (s->sa_family) { 1221 case AF_INET: 1222 { 1223 struct sockaddr_in *sin4 = (struct sockaddr_in *)s; 1224 port = ntohs(sin4->sin_port); 1225 break; 1226 } 1227 case AF_INET6: 1228 { 1229 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s; 1230 port = ntohs(sin6->sin6_port); 1231 break; 1232 } 1233 } 1234 1235 if (port == 0) 1236 port = DEFAULT_NATT_PORT; 1237 1238 return port; 1239 } 1240 #endif 1241 1242 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 1243 static int 1244 setkeymsg_add(type, satype, srcs, dsts) 1245 unsigned int type; 1246 unsigned int satype; 1247 struct addrinfo *srcs; 1248 struct addrinfo *dsts; 1249 { 1250 struct sadb_msg *msg; 1251 char buf[BUFSIZ]; 1252 int l, l0, len; 1253 struct sadb_sa m_sa; 1254 struct sadb_x_sa2 m_sa2; 1255 struct sadb_address m_addr; 1256 struct addrinfo *s, *d; 1257 int n; 1258 int plen; 1259 struct sockaddr *sa; 1260 int salen; 1261 1262 msg = (struct sadb_msg *)buf; 1263 1264 if (!srcs || !dsts) 1265 return -1; 1266 1267 /* fix up length afterwards */ 1268 setkeymsg0(msg, type, satype, 0); 1269 l = sizeof(struct sadb_msg); 1270 1271 /* set encryption algorithm, if present. */ 1272 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { 1273 union { 1274 struct sadb_key key; 1275 struct sadb_ext ext; 1276 } m; 1277 1278 m.key.sadb_key_len = 1279 PFKEY_UNIT64(sizeof(m.key) 1280 + PFKEY_ALIGN8(p_key_enc_len)); 1281 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 1282 m.key.sadb_key_bits = p_key_enc_len * 8; 1283 m.key.sadb_key_reserved = 0; 1284 1285 setvarbuf(buf, &l, &m.ext, sizeof(m.key), 1286 p_key_enc, p_key_enc_len); 1287 } 1288 1289 /* set authentication algorithm, if present. */ 1290 if (p_key_auth) { 1291 union { 1292 struct sadb_key key; 1293 struct sadb_ext ext; 1294 } m; 1295 1296 m.key.sadb_key_len = 1297 PFKEY_UNIT64(sizeof(m.key) 1298 + PFKEY_ALIGN8(p_key_auth_len)); 1299 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 1300 m.key.sadb_key_bits = p_key_auth_len * 8; 1301 m.key.sadb_key_reserved = 0; 1302 1303 setvarbuf(buf, &l, &m.ext, sizeof(m.key), 1304 p_key_auth, p_key_auth_len); 1305 } 1306 1307 /* set lifetime for HARD */ 1308 if (p_lt_hard != 0 || p_lb_hard != 0) { 1309 struct sadb_lifetime m_lt; 1310 u_int slen = sizeof(struct sadb_lifetime); 1311 1312 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1313 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1314 m_lt.sadb_lifetime_allocations = 0; 1315 m_lt.sadb_lifetime_bytes = p_lb_hard; 1316 m_lt.sadb_lifetime_addtime = p_lt_hard; 1317 m_lt.sadb_lifetime_usetime = 0; 1318 1319 memcpy(buf + l, &m_lt, slen); 1320 l += slen; 1321 } 1322 1323 /* set lifetime for SOFT */ 1324 if (p_lt_soft != 0 || p_lb_soft != 0) { 1325 struct sadb_lifetime m_lt; 1326 u_int slen = sizeof(struct sadb_lifetime); 1327 1328 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1329 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1330 m_lt.sadb_lifetime_allocations = 0; 1331 m_lt.sadb_lifetime_bytes = p_lb_soft; 1332 m_lt.sadb_lifetime_addtime = p_lt_soft; 1333 m_lt.sadb_lifetime_usetime = 0; 1334 1335 memcpy(buf + l, &m_lt, slen); 1336 l += slen; 1337 } 1338 1339 #ifdef SADB_X_EXT_SEC_CTX 1340 /* Add security context label */ 1341 if (sec_ctx.doi) { 1342 struct sadb_x_sec_ctx m_sec_ctx; 1343 u_int slen = sizeof(struct sadb_x_sec_ctx); 1344 1345 memset(&m_sec_ctx, 0, slen); 1346 1347 m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen + 1348 PFKEY_ALIGN8(sec_ctx.len)); 1349 m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX; 1350 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */ 1351 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; 1352 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; 1353 setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen, 1354 (caddr_t)sec_ctx.buf, sec_ctx.len); 1355 } 1356 #endif 1357 1358 len = sizeof(struct sadb_sa); 1359 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1360 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1361 m_sa.sadb_sa_spi = htonl(p_spi); 1362 m_sa.sadb_sa_replay = p_replay; 1363 m_sa.sadb_sa_state = 0; 1364 m_sa.sadb_sa_auth = p_alg_auth; 1365 m_sa.sadb_sa_encrypt = p_alg_enc; 1366 m_sa.sadb_sa_flags = p_ext; 1367 1368 memcpy(buf + l, &m_sa, len); 1369 l += len; 1370 1371 len = sizeof(struct sadb_x_sa2); 1372 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1373 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1374 m_sa2.sadb_x_sa2_mode = p_mode; 1375 m_sa2.sadb_x_sa2_reqid = p_reqid; 1376 1377 memcpy(buf + l, &m_sa2, len); 1378 l += len; 1379 1380 #ifdef SADB_X_EXT_NAT_T_TYPE 1381 if (p_natt_type) { 1382 struct sadb_x_nat_t_type natt_type; 1383 1384 len = sizeof(struct sadb_x_nat_t_type); 1385 memset(&natt_type, 0, len); 1386 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len); 1387 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; 1388 natt_type.sadb_x_nat_t_type_type = p_natt_type; 1389 1390 memcpy(buf + l, &natt_type, len); 1391 l += len; 1392 1393 if (p_natt_oa) { 1394 sa = p_natt_oa->ai_addr; 1395 switch (sa->sa_family) { 1396 case AF_INET: 1397 plen = sizeof(struct in_addr) << 3; 1398 break; 1399 #ifdef INET6 1400 case AF_INET6: 1401 plen = sizeof(struct in6_addr) << 3; 1402 break; 1403 #endif 1404 default: 1405 return -1; 1406 } 1407 salen = sysdep_sa_len(sa); 1408 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1409 PFKEY_ALIGN8(salen)); 1410 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA; 1411 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1412 m_addr.sadb_address_prefixlen = plen; 1413 m_addr.sadb_address_reserved = 0; 1414 1415 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1416 sizeof(m_addr), sa, salen); 1417 } 1418 } 1419 #endif 1420 1421 l0 = l; 1422 n = 0; 1423 1424 /* do it for all src/dst pairs */ 1425 for (s = srcs; s; s = s->ai_next) { 1426 for (d = dsts; d; d = d->ai_next) { 1427 /* rewind pointer */ 1428 l = l0; 1429 1430 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1431 continue; 1432 switch (s->ai_addr->sa_family) { 1433 case AF_INET: 1434 plen = sizeof(struct in_addr) << 3; 1435 break; 1436 #ifdef INET6 1437 case AF_INET6: 1438 plen = sizeof(struct in6_addr) << 3; 1439 break; 1440 #endif 1441 default: 1442 continue; 1443 } 1444 1445 /* set src */ 1446 sa = s->ai_addr; 1447 salen = sysdep_sa_len(s->ai_addr); 1448 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1449 PFKEY_ALIGN8(salen)); 1450 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1451 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1452 m_addr.sadb_address_prefixlen = plen; 1453 m_addr.sadb_address_reserved = 0; 1454 1455 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1456 sizeof(m_addr), sa, salen); 1457 1458 /* set dst */ 1459 sa = d->ai_addr; 1460 salen = sysdep_sa_len(d->ai_addr); 1461 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1462 PFKEY_ALIGN8(salen)); 1463 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1464 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1465 m_addr.sadb_address_prefixlen = plen; 1466 m_addr.sadb_address_reserved = 0; 1467 1468 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1469 sizeof(m_addr), sa, salen); 1470 1471 #ifdef SADB_X_EXT_NAT_T_TYPE 1472 if (p_natt_type) { 1473 struct sadb_x_nat_t_port natt_port; 1474 1475 /* NATT_SPORT */ 1476 len = sizeof(struct sadb_x_nat_t_port); 1477 memset(&natt_port, 0, len); 1478 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len); 1479 natt_port.sadb_x_nat_t_port_exttype = 1480 SADB_X_EXT_NAT_T_SPORT; 1481 natt_port.sadb_x_nat_t_port_port = htons(get_port(s)); 1482 1483 memcpy(buf + l, &natt_port, len); 1484 l += len; 1485 1486 /* NATT_DPORT */ 1487 natt_port.sadb_x_nat_t_port_exttype = 1488 SADB_X_EXT_NAT_T_DPORT; 1489 natt_port.sadb_x_nat_t_port_port = htons(get_port(d)); 1490 1491 memcpy(buf + l, &natt_port, len); 1492 l += len; 1493 } 1494 #endif 1495 msg->sadb_msg_len = PFKEY_UNIT64(l); 1496 1497 sendkeymsg(buf, l); 1498 1499 n++; 1500 } 1501 } 1502 1503 if (n == 0) 1504 return -1; 1505 else 1506 return 0; 1507 } 1508 1509 static struct addrinfo * 1510 parse_addr(host, port) 1511 char *host; 1512 char *port; 1513 { 1514 struct addrinfo hints, *res = NULL; 1515 int error; 1516 1517 memset(&hints, 0, sizeof(hints)); 1518 hints.ai_family = p_aifamily; 1519 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 1520 hints.ai_protocol = IPPROTO_UDP; /*dummy*/ 1521 hints.ai_flags = p_aiflags; 1522 error = getaddrinfo(host, port, &hints, &res); 1523 if (error != 0) { 1524 yyerror(gai_strerror(error)); 1525 return NULL; 1526 } 1527 return res; 1528 } 1529 1530 static int 1531 fix_portstr(spec, sport, dport) 1532 vchar_t *spec, *sport, *dport; 1533 { 1534 const char *p, *p2 = "0"; 1535 char *q; 1536 u_int l; 1537 1538 l = 0; 1539 for (q = spec->buf; *q != ',' && *q != '\0' && l < spec->len; q++, l++) 1540 ; 1541 if (*q != '\0') { 1542 if (*q == ',') { 1543 *q = '\0'; 1544 p2 = ++q; 1545 } 1546 for (p = p2; *p != '\0' && l < spec->len; p++, l++) 1547 ; 1548 if (*p != '\0' || *p2 == '\0') { 1549 yyerror("invalid an upper layer protocol spec"); 1550 return -1; 1551 } 1552 } 1553 1554 sport->buf = strdup(spec->buf); 1555 if (!sport->buf) { 1556 yyerror("insufficient memory"); 1557 return -1; 1558 } 1559 sport->len = strlen(sport->buf); 1560 dport->buf = strdup(p2); 1561 if (!dport->buf) { 1562 yyerror("insufficient memory"); 1563 return -1; 1564 } 1565 dport->len = strlen(dport->buf); 1566 1567 return 0; 1568 } 1569 1570 static int 1571 setvarbuf(buf, off, ebuf, elen, vbuf, vlen) 1572 char *buf; 1573 int *off; 1574 struct sadb_ext *ebuf; 1575 int elen; 1576 const void *vbuf; 1577 int vlen; 1578 { 1579 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 1580 memcpy(buf + *off, (caddr_t)ebuf, elen); 1581 memcpy(buf + *off + elen, vbuf, vlen); 1582 (*off) += PFKEY_ALIGN8(elen + vlen); 1583 1584 return 0; 1585 } 1586 1587 void 1588 parse_init() 1589 { 1590 p_spi = 0; 1591 1592 p_ext = SADB_X_EXT_CYCSEQ; 1593 p_alg_enc = SADB_EALG_NONE; 1594 p_alg_auth = SADB_AALG_NONE; 1595 p_mode = IPSEC_MODE_ANY; 1596 p_reqid = 0; 1597 p_replay = 0; 1598 p_key_enc_len = p_key_auth_len = 0; 1599 p_key_enc = p_key_auth = 0; 1600 p_lt_hard = p_lt_soft = 0; 1601 p_lb_hard = p_lb_soft = 0; 1602 1603 memset(&sec_ctx, 0, sizeof(struct security_ctx)); 1604 1605 p_aiflags = 0; 1606 p_aifamily = PF_UNSPEC; 1607 1608 /* Clear out any natt OA information */ 1609 if (p_natt_oa) 1610 freeaddrinfo (p_natt_oa); 1611 p_natt_oa = NULL; 1612 p_natt_type = 0; 1613 1614 return; 1615 } 1616 1617 void 1618 free_buffer() 1619 { 1620 /* we got tons of memory leaks in the parser anyways, leave them */ 1621 1622 return; 1623 } 1624