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