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