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