1 /* $FreeBSD$ */ 2 /* $KAME: parse.y,v 1.29 2000/06/10 14:17:44 sakane Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 %{ 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/socket.h> 37 38 #include <net/route.h> 39 #include <netinet/in.h> 40 #include <net/pfkeyv2.h> 41 #include <netkey/key_var.h> 42 #include <netinet6/ipsec.h> 43 #include <arpa/inet.h> 44 45 #include <string.h> 46 #include <unistd.h> 47 #include <stdio.h> 48 #include <netdb.h> 49 #include <ctype.h> 50 #include <errno.h> 51 52 #include "libpfkey.h" 53 #include "vchar.h" 54 55 #define ATOX(c) \ 56 (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) 57 58 u_int p_type; 59 u_int32_t p_spi; 60 struct sockaddr *p_src, *p_dst; 61 u_int p_prefs, p_prefd, p_upper; 62 u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; 63 u_int32_t p_reqid; 64 u_int p_key_enc_len, p_key_auth_len; 65 caddr_t p_key_enc, p_key_auth; 66 time_t p_lt_hard, p_lt_soft; 67 68 u_int p_policy_len; 69 char *p_policy; 70 71 /* temporary buffer */ 72 static struct sockaddr *pp_addr; 73 static u_int pp_prefix; 74 static u_int pp_port; 75 static caddr_t pp_key; 76 77 extern u_char m_buf[BUFSIZ]; 78 extern int m_len; 79 extern char cmdarg[8192]; 80 extern int f_debug; 81 82 int setkeymsg __P((void)); 83 static struct addrinfo *parse_addr __P((char *, char *, int)); 84 static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int)); 85 void parse_init __P((void)); 86 void free_buffer __P((void)); 87 88 extern int setkeymsg __P((void)); 89 extern int sendkeymsg __P((void)); 90 91 extern int yylex __P((void)); 92 extern void yyfatal __P((const char *)); 93 extern void yyerror __P((const char *)); 94 %} 95 96 %union { 97 unsigned long num; 98 vchar_t val; 99 } 100 101 %token EOT 102 %token ADD GET DELETE FLUSH DUMP 103 %token ADDRESS PREFIX PORT PORTANY 104 %token UP_PROTO PR_ESP PR_AH PR_IPCOMP 105 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI 106 %token F_MODE MODE F_REQID 107 %token F_EXT EXTENSION NOCYCLICSEQ 108 %token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP 109 %token F_LIFETIME_HARD F_LIFETIME_SOFT 110 %token DECSTRING QUOTEDSTRING HEXSTRING ANY 111 /* SPD management */ 112 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH 113 %token F_POLICY PL_REQUESTS 114 115 %type <num> PORT PREFIX EXTENSION MODE 116 %type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP 117 %type <num> ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP 118 %type <num> DECSTRING 119 %type <val> ADDRESS PL_REQUESTS 120 %type <val> key_string policy_requests 121 %type <val> QUOTEDSTRING HEXSTRING 122 123 %% 124 commands 125 : /*NOTHING*/ 126 | commands command 127 { 128 if (f_debug) { 129 printf("cmdarg:\n%s\n", cmdarg); 130 } else { 131 setkeymsg(); 132 sendkeymsg(); 133 } 134 free_buffer(); 135 parse_init(); 136 } 137 ; 138 139 command 140 : add_command 141 | get_command 142 | delete_command 143 | flush_command 144 | dump_command 145 | spdadd_command 146 | spddelete_command 147 | spddump_command 148 | spdflush_command 149 ; 150 /* commands concerned with management, there is in tail of this file. */ 151 152 /* add command */ 153 add_command 154 : ADD { p_type = SADB_ADD; } 155 sa_selector_spec extension_spec algorithm_spec EOT 156 ; 157 158 /* delete */ 159 delete_command 160 : DELETE { p_type = SADB_DELETE; } 161 sa_selector_spec extension_spec 162 { 163 if (p_mode != IPSEC_MODE_ANY) 164 yyerror("WARNING: mode is obsoleted."); 165 } 166 EOT 167 ; 168 169 /* get command */ 170 get_command 171 : GET { p_type = SADB_GET; } 172 sa_selector_spec extension_spec 173 { 174 if (p_mode != IPSEC_MODE_ANY) 175 yyerror("WARNING: mode is obsoleted."); 176 } 177 EOT 178 ; 179 180 /* flush */ 181 flush_command 182 : FLUSH { p_type = SADB_FLUSH; } 183 protocol_spec EOT 184 ; 185 186 /* dump */ 187 dump_command 188 : DUMP { p_type = SADB_DUMP; } 189 protocol_spec EOT 190 ; 191 192 /* sa_selector_spec */ 193 sa_selector_spec 194 : ipaddress { p_src = pp_addr; } 195 ipaddress { p_dst = pp_addr; } 196 protocol_spec spi 197 ; 198 199 protocol_spec 200 : /*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; } 201 | PR_ESP 202 { 203 p_satype = SADB_SATYPE_ESP; 204 if ($1 == 1) 205 p_ext |= SADB_X_EXT_OLD; 206 else 207 p_ext &= ~SADB_X_EXT_OLD; 208 } 209 | PR_AH 210 { 211 p_satype = SADB_SATYPE_AH; 212 if ($1 == 1) 213 p_ext |= SADB_X_EXT_OLD; 214 else 215 p_ext &= ~SADB_X_EXT_OLD; 216 } 217 | PR_IPCOMP 218 { 219 p_satype = SADB_X_SATYPE_IPCOMP; 220 } 221 ; 222 223 spi 224 : DECSTRING { p_spi = $1; } 225 | HEXSTRING 226 { 227 caddr_t bp; 228 caddr_t yp = $1.buf; 229 char buf0[4], buf[4]; 230 int i, j; 231 232 /* sanity check */ 233 if ($1.len > 4) { 234 yyerror("SPI too big."); 235 free($1.buf); 236 return -1; 237 } 238 239 bp = buf0; 240 while (*yp) { 241 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 242 yp += 2, bp++; 243 } 244 245 /* initialize */ 246 for (i = 0; i < 4; i++) buf[i] = 0; 247 248 for (j = $1.len - 1, i = 3; j >= 0; j--, i--) 249 buf[i] = buf0[j]; 250 251 /* XXX: endian */ 252 p_spi = ntohl(*(u_int32_t *)buf); 253 254 free($1.buf); 255 } 256 ; 257 258 algorithm_spec 259 : esp_spec 260 | ah_spec 261 | ipcomp_spec 262 ; 263 264 esp_spec 265 : F_ENC enc_alg enc_key F_AUTH auth_alg auth_key 266 | F_ENC enc_alg enc_key 267 ; 268 269 ah_spec 270 : F_AUTH auth_alg auth_key 271 ; 272 273 ipcomp_spec 274 : F_COMP ALG_COMP { p_alg_enc = $2; } 275 | F_COMP ALG_COMP { p_alg_enc = $2; } 276 F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; } 277 ; 278 279 enc_alg 280 : ALG_ENC { p_alg_enc = $1; } 281 | ALG_ENC_DESDERIV 282 { 283 p_alg_enc = $1; 284 if (p_ext & SADB_X_EXT_OLD) { 285 yyerror("algorithm mismatched."); 286 return -1; 287 } 288 p_ext |= SADB_X_EXT_DERIV; 289 } 290 | ALG_ENC_DES32IV 291 { 292 p_alg_enc = $1; 293 if (!(p_ext & SADB_X_EXT_OLD)) { 294 yyerror("algorithm mismatched."); 295 return -1; 296 } 297 p_ext |= SADB_X_EXT_IV4B; 298 } 299 ; 300 301 enc_key 302 : /*NOTHING*/ 303 { 304 if (p_alg_enc != SADB_EALG_NULL) { 305 yyerror("no key found."); 306 return -1; 307 } 308 } 309 | key_string 310 { 311 p_key_enc_len = $1.len; 312 p_key_enc = pp_key; 313 314 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 315 p_alg_enc, 316 PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 317 yyerror(ipsec_strerror()); 318 return -1; 319 } 320 } 321 ; 322 323 auth_alg 324 : ALG_AUTH { p_alg_auth = $1; } 325 ; 326 327 auth_key 328 : /*NOTHING*/ 329 { 330 if (p_alg_auth != SADB_AALG_NULL) { 331 yyerror("no key found."); 332 return -1; 333 } 334 } 335 | key_string 336 { 337 p_key_auth_len = $1.len; 338 p_key_auth = pp_key; 339 340 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, 341 p_alg_auth, 342 PFKEY_UNUNIT64(p_key_auth_len)) < 0) { 343 yyerror(ipsec_strerror()); 344 return -1; 345 } 346 } 347 ; 348 349 key_string 350 : QUOTEDSTRING 351 { 352 pp_key = $1.buf; 353 /* free pp_key later */ 354 } 355 | HEXSTRING 356 { 357 caddr_t bp; 358 caddr_t yp = $1.buf; 359 360 if ((pp_key = malloc($1.len)) == 0) { 361 free($1.buf); 362 yyerror("not enough core"); 363 return -1; 364 } 365 memset(pp_key, 0, $1.len); 366 367 bp = pp_key; 368 while (*yp) { 369 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 370 yp += 2, bp++; 371 } 372 373 free($1.buf); 374 } 375 ; 376 377 extension_spec 378 : /*NOTHING*/ 379 | extension_spec extension 380 ; 381 382 extension 383 : F_EXT EXTENSION { p_ext |= $2; } 384 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 385 | F_MODE MODE { p_mode = $2; } 386 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 387 | F_REQID DECSTRING { p_reqid = $2; } 388 | F_REPLAY DECSTRING 389 { 390 if (p_ext & SADB_X_EXT_OLD) { 391 yyerror("replay prevention " 392 "only use on new spec."); 393 return -1; 394 } 395 p_replay = $2; 396 } 397 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 398 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 399 ; 400 401 /* definition about command for SPD management */ 402 /* spdadd */ 403 spdadd_command 404 : SPDADD 405 { 406 p_type = SADB_X_SPDADD; 407 p_satype = SADB_SATYPE_UNSPEC; 408 } 409 sp_selector_spec policy_spec EOT 410 ; 411 412 spddelete_command: 413 SPDDELETE 414 { 415 p_type = SADB_X_SPDDELETE; 416 p_satype = SADB_SATYPE_UNSPEC; 417 } 418 sp_selector_spec policy_spec EOT 419 ; 420 421 spddump_command: 422 SPDDUMP 423 { 424 p_type = SADB_X_SPDDUMP; 425 p_satype = SADB_SATYPE_UNSPEC; 426 } 427 EOT 428 ; 429 430 spdflush_command: 431 SPDFLUSH 432 { 433 p_type = SADB_X_SPDFLUSH; 434 p_satype = SADB_SATYPE_UNSPEC; 435 } 436 EOT 437 ; 438 439 /* sp_selector_spec */ 440 sp_selector_spec 441 : ipaddress { p_src = pp_addr; } 442 prefix { p_prefs = pp_prefix; } 443 port 444 { 445 switch (p_src->sa_family) { 446 case AF_INET: 447 ((struct sockaddr_in *)p_src)->sin_port = 448 htons(pp_port); 449 break; 450 #ifdef INET6 451 case AF_INET6: 452 ((struct sockaddr_in6 *)p_src)->sin6_port = 453 htons(pp_port); 454 break; 455 #endif 456 default: 457 exit(1); /*XXX*/ 458 } 459 } 460 ipaddress { p_dst = pp_addr; } 461 prefix { p_prefd = pp_prefix; } 462 port 463 { 464 switch (p_dst->sa_family) { 465 case AF_INET: 466 ((struct sockaddr_in *)p_dst)->sin_port = 467 htons(pp_port); 468 break; 469 #ifdef INET6 470 case AF_INET6: 471 ((struct sockaddr_in6 *)p_dst)->sin6_port = 472 htons(pp_port); 473 break; 474 #endif 475 default: 476 exit(1); /*XXX*/ 477 } 478 } 479 upper_spec 480 { 481 /* XXX is it something userland should check? */ 482 #if 0 483 switch (p_upper) { 484 case IPPROTO_ICMP: 485 case IPPROTO_ICMPV6: 486 if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY 487 || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) { 488 yyerror("port number must be \"any\"."); 489 return -1; 490 } 491 if ((pp_addr->sa_family == AF_INET6 492 && p_upper == IPPROTO_ICMP) 493 || (pp_addr->sa_family == AF_INET 494 && p_upper == IPPROTO_ICMPV6)) { 495 yyerror("upper layer protocol " 496 "mismatched.\n"); 497 return -1; 498 } 499 break; 500 default: 501 break; 502 } 503 #endif 504 } 505 ; 506 507 ipaddress 508 : ADDRESS 509 { 510 struct addrinfo *res; 511 512 res = parse_addr($1.buf, NULL, AI_NUMERICHOST); 513 if (res == NULL) { 514 free($1.buf); 515 return -1; 516 } 517 pp_addr = (struct sockaddr *)malloc(res->ai_addrlen); 518 if (!pp_addr) { 519 yyerror("not enough core"); 520 goto end; 521 } 522 523 memcpy(pp_addr, res->ai_addr, res->ai_addrlen); 524 end: 525 freeaddrinfo(res); 526 free($1.buf); 527 } 528 ; 529 530 prefix 531 : /*NOTHING*/ { pp_prefix = ~0; } 532 | PREFIX { pp_prefix = $1; } 533 ; 534 535 port 536 : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; } 537 | PORT { pp_port = $1; } 538 | PORTANY { pp_port = IPSEC_PORT_ANY; } 539 ; 540 541 upper_spec 542 : DECSTRING { p_upper = $1; } 543 | UP_PROTO { p_upper = $1; } 544 | PR_ESP { p_upper = IPPROTO_ESP; }; 545 | PR_AH { p_upper = IPPROTO_AH; }; 546 | PR_IPCOMP { p_upper = IPPROTO_IPCOMP; }; 547 | ANY { p_upper = IPSEC_ULPROTO_ANY; } 548 ; 549 550 policy_spec 551 : F_POLICY policy_requests 552 { 553 p_policy = ipsec_set_policy($2.buf, $2.len); 554 if (p_policy == NULL) { 555 free($2.buf); 556 p_policy = NULL; 557 yyerror(ipsec_strerror()); 558 return -1; 559 } 560 561 p_policy_len = ipsec_get_policylen(p_policy); 562 563 free($2.buf); 564 } 565 ; 566 567 policy_requests 568 : PL_REQUESTS { $$ = $1; } 569 ; 570 571 %% 572 573 int 574 setkeymsg() 575 { 576 struct sadb_msg m_msg; 577 578 m_msg.sadb_msg_version = PF_KEY_V2; 579 m_msg.sadb_msg_type = p_type; 580 m_msg.sadb_msg_errno = 0; 581 m_msg.sadb_msg_satype = p_satype; 582 m_msg.sadb_msg_reserved = 0; 583 m_msg.sadb_msg_seq = 0; 584 m_msg.sadb_msg_pid = getpid(); 585 586 m_len = sizeof(struct sadb_msg); 587 memcpy(m_buf, &m_msg, m_len); 588 589 switch (p_type) { 590 case SADB_FLUSH: 591 case SADB_DUMP: 592 break; 593 594 case SADB_ADD: 595 /* set encryption algorithm, if present. */ 596 if (p_satype != SADB_X_SATYPE_IPCOMP && p_alg_enc != SADB_EALG_NONE) { 597 struct sadb_key m_key; 598 599 m_key.sadb_key_len = 600 PFKEY_UNIT64(sizeof(m_key) 601 + PFKEY_ALIGN8(p_key_enc_len)); 602 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 603 m_key.sadb_key_bits = p_key_enc_len * 8; 604 m_key.sadb_key_reserved = 0; 605 606 setvarbuf(&m_len, 607 (struct sadb_ext *)&m_key, sizeof(m_key), 608 (caddr_t)p_key_enc, p_key_enc_len); 609 } 610 611 /* set authentication algorithm, if present. */ 612 if (p_alg_auth != SADB_AALG_NONE) { 613 struct sadb_key m_key; 614 615 m_key.sadb_key_len = 616 PFKEY_UNIT64(sizeof(m_key) 617 + PFKEY_ALIGN8(p_key_auth_len)); 618 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 619 m_key.sadb_key_bits = p_key_auth_len * 8; 620 m_key.sadb_key_reserved = 0; 621 622 setvarbuf(&m_len, 623 (struct sadb_ext *)&m_key, sizeof(m_key), 624 (caddr_t)p_key_auth, p_key_auth_len); 625 } 626 627 /* set lifetime for HARD */ 628 if (p_lt_hard != 0) { 629 struct sadb_lifetime m_lt; 630 u_int len = sizeof(struct sadb_lifetime); 631 632 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); 633 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 634 m_lt.sadb_lifetime_allocations = 0; 635 m_lt.sadb_lifetime_bytes = 0; 636 m_lt.sadb_lifetime_addtime = p_lt_hard; 637 m_lt.sadb_lifetime_usetime = 0; 638 639 memcpy(m_buf + m_len, &m_lt, len); 640 m_len += len; 641 } 642 643 /* set lifetime for SOFT */ 644 if (p_lt_soft != 0) { 645 struct sadb_lifetime m_lt; 646 u_int len = sizeof(struct sadb_lifetime); 647 648 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); 649 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 650 m_lt.sadb_lifetime_allocations = 0; 651 m_lt.sadb_lifetime_bytes = 0; 652 m_lt.sadb_lifetime_addtime = p_lt_soft; 653 m_lt.sadb_lifetime_usetime = 0; 654 655 memcpy(m_buf + m_len, &m_lt, len); 656 m_len += len; 657 } 658 /* FALLTHROUGH */ 659 660 case SADB_DELETE: 661 case SADB_GET: 662 { 663 struct sadb_sa m_sa; 664 struct sadb_x_sa2 m_sa2; 665 struct sadb_address m_addr; 666 u_int len; 667 668 len = sizeof(struct sadb_sa); 669 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 670 m_sa.sadb_sa_exttype = SADB_EXT_SA; 671 m_sa.sadb_sa_spi = htonl(p_spi); 672 m_sa.sadb_sa_replay = p_replay; 673 m_sa.sadb_sa_state = 0; 674 m_sa.sadb_sa_auth = p_alg_auth; 675 m_sa.sadb_sa_encrypt = p_alg_enc; 676 m_sa.sadb_sa_flags = p_ext; 677 678 memcpy(m_buf + m_len, &m_sa, len); 679 m_len += len; 680 681 len = sizeof(struct sadb_x_sa2); 682 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 683 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 684 m_sa2.sadb_x_sa2_mode = p_mode; 685 m_sa2.sadb_x_sa2_reqid = p_reqid; 686 687 memcpy(m_buf + m_len, &m_sa2, len); 688 m_len += len; 689 690 /* set src */ 691 m_addr.sadb_address_len = 692 PFKEY_UNIT64(sizeof(m_addr) 693 + PFKEY_ALIGN8(p_src->sa_len)); 694 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 695 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 696 switch (p_src->sa_family) { 697 case AF_INET: 698 m_addr.sadb_address_prefixlen = 699 sizeof(struct in_addr) << 3; 700 break; 701 #ifdef INET6 702 case AF_INET6: 703 m_addr.sadb_address_prefixlen = 704 sizeof(struct in6_addr) << 3; 705 break; 706 #endif 707 default: 708 yyerror("unsupported address family"); 709 exit(1); /*XXX*/ 710 } 711 m_addr.sadb_address_reserved = 0; 712 713 setvarbuf(&m_len, 714 (struct sadb_ext *)&m_addr, sizeof(m_addr), 715 (caddr_t)p_src, p_src->sa_len); 716 717 /* set dst */ 718 m_addr.sadb_address_len = 719 PFKEY_UNIT64(sizeof(m_addr) 720 + PFKEY_ALIGN8(p_dst->sa_len)); 721 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 722 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 723 switch (p_dst->sa_family) { 724 case AF_INET: 725 m_addr.sadb_address_prefixlen = 726 sizeof(struct in_addr) << 3; 727 break; 728 #ifdef INET6 729 case AF_INET6: 730 m_addr.sadb_address_prefixlen = 731 sizeof(struct in6_addr) << 3; 732 break; 733 #endif 734 default: 735 yyerror("unsupported address family"); 736 exit(1); /*XXX*/ 737 } 738 m_addr.sadb_address_reserved = 0; 739 740 setvarbuf(&m_len, 741 (struct sadb_ext *)&m_addr, sizeof(m_addr), 742 (caddr_t)p_dst, p_dst->sa_len); 743 } 744 break; 745 746 /* for SPD management */ 747 case SADB_X_SPDFLUSH: 748 case SADB_X_SPDDUMP: 749 break; 750 751 case SADB_X_SPDADD: 752 case SADB_X_SPDDELETE: 753 { 754 struct sadb_address m_addr; 755 u_int8_t plen; 756 757 memcpy(m_buf + m_len, p_policy, p_policy_len); 758 m_len += p_policy_len; 759 free(p_policy); 760 p_policy = NULL; 761 762 /* set src */ 763 m_addr.sadb_address_len = 764 PFKEY_UNIT64(sizeof(m_addr) 765 + PFKEY_ALIGN8(p_src->sa_len)); 766 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 767 m_addr.sadb_address_proto = p_upper; 768 switch (p_src->sa_family) { 769 case AF_INET: 770 plen = sizeof(struct in_addr) << 3; 771 break; 772 #ifdef INET6 773 case AF_INET6: 774 plen = sizeof(struct in6_addr) << 3; 775 break; 776 #endif 777 default: 778 yyerror("unsupported address family"); 779 exit(1); /*XXX*/ 780 } 781 m_addr.sadb_address_prefixlen = 782 (p_prefs != ~0 ? p_prefs : plen); 783 m_addr.sadb_address_reserved = 0; 784 785 setvarbuf(&m_len, 786 (struct sadb_ext *)&m_addr, sizeof(m_addr), 787 (caddr_t)p_src, p_src->sa_len); 788 789 /* set dst */ 790 m_addr.sadb_address_len = 791 PFKEY_UNIT64(sizeof(m_addr) 792 + PFKEY_ALIGN8(p_dst->sa_len)); 793 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 794 m_addr.sadb_address_proto = p_upper; 795 switch (p_dst->sa_family) { 796 case AF_INET: 797 plen = sizeof(struct in_addr) << 3; 798 break; 799 #ifdef INET6 800 case AF_INET6: 801 plen = sizeof(struct in6_addr) << 3; 802 break; 803 #endif 804 default: 805 yyerror("unsupported address family"); 806 exit(1); /*XXX*/ 807 } 808 m_addr.sadb_address_prefixlen = 809 (p_prefd != ~0 ? p_prefd : plen); 810 m_addr.sadb_address_reserved = 0; 811 812 setvarbuf(&m_len, 813 (struct sadb_ext *)&m_addr, sizeof(m_addr), 814 (caddr_t)p_dst, p_dst->sa_len); 815 } 816 break; 817 } 818 819 ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); 820 821 return 0; 822 } 823 824 static struct addrinfo * 825 parse_addr(host, port, flag) 826 char *host; 827 char *port; 828 int flag; 829 { 830 struct addrinfo hints, *res = NULL; 831 int error; 832 833 memset(&hints, 0, sizeof(hints)); 834 hints.ai_family = PF_UNSPEC; 835 hints.ai_socktype = SOCK_DGRAM; 836 hints.ai_flags = flag; 837 error = getaddrinfo(host, port, &hints, &res); 838 if (error != 0) { 839 yyerror(gai_strerror(error)); 840 return NULL; 841 } 842 if (res->ai_next != NULL) { 843 yyerror(gai_strerror(error)); 844 } 845 return res; 846 } 847 848 static int 849 setvarbuf(off, ebuf, elen, vbuf, vlen) 850 caddr_t vbuf; 851 struct sadb_ext *ebuf; 852 int *off, elen, vlen; 853 { 854 memset(m_buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 855 memcpy(m_buf + *off, (caddr_t)ebuf, elen); 856 memcpy(m_buf + *off + elen, vbuf, vlen); 857 (*off) += PFKEY_ALIGN8(elen + vlen); 858 859 return 0; 860 } 861 862 void 863 parse_init() 864 { 865 p_type = 0; 866 p_spi = 0; 867 868 p_src = 0, p_dst = 0; 869 pp_prefix = p_prefs = p_prefd = ~0; 870 pp_port = IPSEC_PORT_ANY; 871 p_upper = 0; 872 873 p_satype = 0; 874 p_ext = SADB_X_EXT_CYCSEQ; 875 p_alg_enc = SADB_EALG_NONE; 876 p_alg_auth = SADB_AALG_NONE; 877 p_mode = IPSEC_MODE_ANY; 878 p_reqid = 0; 879 p_replay = 0; 880 p_key_enc_len = p_key_auth_len = 0; 881 p_key_enc = p_key_auth = 0; 882 p_lt_hard = p_lt_soft = 0; 883 884 p_policy_len = 0; 885 p_policy = NULL; 886 887 memset(cmdarg, 0, sizeof(cmdarg)); 888 889 return; 890 } 891 892 void 893 free_buffer() 894 { 895 if (p_src) free(p_src); 896 if (p_dst) free(p_dst); 897 if (p_key_enc) free(p_key_enc); 898 if (p_key_auth) free(p_key_auth); 899 900 return; 901 } 902 903