1 /* $FreeBSD$ */ 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 <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 int p_no_spi; 61 struct sockaddr *p_src, *p_dst; 62 u_int p_prefs, p_prefd, p_upper; 63 u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; 64 u_int32_t p_reqid; 65 u_int p_key_enc_len, p_key_auth_len; 66 caddr_t p_key_enc, p_key_auth; 67 time_t p_lt_hard, p_lt_soft; 68 69 u_int p_policy_len; 70 char *p_policy; 71 72 /* temporary buffer */ 73 static struct sockaddr *pp_addr; 74 static u_int pp_prefix; 75 static u_int pp_port; 76 static caddr_t pp_key; 77 78 extern u_char m_buf[BUFSIZ]; 79 extern int m_len; 80 extern char cmdarg[8192]; 81 extern int f_debug; 82 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 STRING 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 STRING 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 | deleteall_command 144 | flush_command 145 | dump_command 146 | spdadd_command 147 | spddelete_command 148 | spddump_command 149 | spdflush_command 150 ; 151 /* commands concerned with management, there is in tail of this file. */ 152 153 /* add command */ 154 add_command 155 : ADD { p_type = SADB_ADD; } 156 sa_selector_spec extension_spec algorithm_spec EOT 157 ; 158 159 /* delete */ 160 delete_command 161 : DELETE { p_type = SADB_DELETE; } 162 sa_selector_spec extension_spec 163 { 164 if (p_mode != IPSEC_MODE_ANY) 165 yyerror("WARNING: mode is obsoleted."); 166 } 167 EOT 168 ; 169 170 /* deleteall command */ 171 deleteall_command 172 : DELETEALL { p_type = SADB_DELETE; } 173 ipaddress { p_src = pp_addr; } 174 ipaddress { p_dst = pp_addr; } 175 protocol_spec 176 { p_no_spi = 1; } 177 EOT 178 ; 179 180 /* get command */ 181 get_command 182 : GET { p_type = SADB_GET; } 183 sa_selector_spec extension_spec 184 { 185 if (p_mode != IPSEC_MODE_ANY) 186 yyerror("WARNING: mode is obsoleted."); 187 } 188 EOT 189 ; 190 191 /* flush */ 192 flush_command 193 : FLUSH { p_type = SADB_FLUSH; } 194 protocol_spec EOT 195 ; 196 197 /* dump */ 198 dump_command 199 : DUMP { p_type = SADB_DUMP; } 200 protocol_spec EOT 201 ; 202 203 /* sa_selector_spec */ 204 sa_selector_spec 205 : ipaddress { p_src = pp_addr; } 206 ipaddress { p_dst = pp_addr; } 207 protocol_spec spi 208 ; 209 210 protocol_spec 211 : /*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; } 212 | PR_ESP 213 { 214 p_satype = SADB_SATYPE_ESP; 215 if ($1 == 1) 216 p_ext |= SADB_X_EXT_OLD; 217 else 218 p_ext &= ~SADB_X_EXT_OLD; 219 } 220 | PR_AH 221 { 222 p_satype = SADB_SATYPE_AH; 223 if ($1 == 1) 224 p_ext |= SADB_X_EXT_OLD; 225 else 226 p_ext &= ~SADB_X_EXT_OLD; 227 } 228 | PR_IPCOMP 229 { 230 p_satype = SADB_X_SATYPE_IPCOMP; 231 } 232 ; 233 234 spi 235 : DECSTRING { p_spi = $1; } 236 | HEXSTRING 237 { 238 caddr_t bp; 239 caddr_t yp = $1.buf; 240 char buf0[4], buf[4]; 241 int i, j; 242 243 /* sanity check */ 244 if ($1.len > 4) { 245 yyerror("SPI too big."); 246 free($1.buf); 247 return -1; 248 } 249 250 bp = buf0; 251 while (*yp) { 252 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 253 yp += 2, bp++; 254 } 255 256 /* initialize */ 257 for (i = 0; i < 4; i++) buf[i] = 0; 258 259 for (j = $1.len - 1, i = 3; j >= 0; j--, i--) 260 buf[i] = buf0[j]; 261 262 /* XXX: endian */ 263 p_spi = ntohl(*(u_int32_t *)buf); 264 265 free($1.buf); 266 } 267 ; 268 269 algorithm_spec 270 : esp_spec 271 | ah_spec 272 | ipcomp_spec 273 ; 274 275 esp_spec 276 : F_ENC enc_alg enc_key F_AUTH auth_alg auth_key 277 | F_ENC enc_alg enc_key 278 ; 279 280 ah_spec 281 : F_AUTH auth_alg auth_key 282 ; 283 284 ipcomp_spec 285 : F_COMP ALG_COMP { p_alg_enc = $2; } 286 | F_COMP ALG_COMP { p_alg_enc = $2; } 287 F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; } 288 ; 289 290 enc_alg 291 : ALG_ENC { p_alg_enc = $1; } 292 | ALG_ENC_DESDERIV 293 { 294 p_alg_enc = $1; 295 if (p_ext & SADB_X_EXT_OLD) { 296 yyerror("algorithm mismatched."); 297 return -1; 298 } 299 p_ext |= SADB_X_EXT_DERIV; 300 } 301 | ALG_ENC_DES32IV 302 { 303 p_alg_enc = $1; 304 if (!(p_ext & SADB_X_EXT_OLD)) { 305 yyerror("algorithm mismatched."); 306 return -1; 307 } 308 p_ext |= SADB_X_EXT_IV4B; 309 } 310 ; 311 312 enc_key 313 : /*NOTHING*/ 314 { 315 if (p_alg_enc != SADB_EALG_NULL) { 316 yyerror("no key found."); 317 return -1; 318 } 319 } 320 | key_string 321 { 322 p_key_enc_len = $1.len; 323 p_key_enc = pp_key; 324 325 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 326 p_alg_enc, 327 PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 328 yyerror(ipsec_strerror()); 329 return -1; 330 } 331 } 332 ; 333 334 auth_alg 335 : ALG_AUTH { p_alg_auth = $1; } 336 ; 337 338 auth_key 339 : /*NOTHING*/ 340 { 341 if (p_alg_auth != SADB_X_AALG_NULL) { 342 yyerror("no key found."); 343 return -1; 344 } 345 } 346 | key_string 347 { 348 p_key_auth_len = $1.len; 349 p_key_auth = pp_key; 350 351 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, 352 p_alg_auth, 353 PFKEY_UNUNIT64(p_key_auth_len)) < 0) { 354 yyerror(ipsec_strerror()); 355 return -1; 356 } 357 } 358 ; 359 360 key_string 361 : QUOTEDSTRING 362 { 363 pp_key = $1.buf; 364 /* free pp_key later */ 365 } 366 | HEXSTRING 367 { 368 caddr_t bp; 369 caddr_t yp = $1.buf; 370 371 if ((pp_key = malloc($1.len)) == 0) { 372 free($1.buf); 373 yyerror("not enough core"); 374 return -1; 375 } 376 memset(pp_key, 0, $1.len); 377 378 bp = pp_key; 379 while (*yp) { 380 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 381 yp += 2, bp++; 382 } 383 384 free($1.buf); 385 } 386 ; 387 388 extension_spec 389 : /*NOTHING*/ 390 | extension_spec extension 391 ; 392 393 extension 394 : F_EXT EXTENSION { p_ext |= $2; } 395 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 396 | F_MODE MODE { p_mode = $2; } 397 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 398 | F_REQID DECSTRING { p_reqid = $2; } 399 | F_REPLAY DECSTRING 400 { 401 if (p_ext & SADB_X_EXT_OLD) { 402 yyerror("replay prevention " 403 "only use on new spec."); 404 return -1; 405 } 406 p_replay = $2; 407 } 408 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 409 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 410 ; 411 412 /* definition about command for SPD management */ 413 /* spdadd */ 414 spdadd_command 415 : SPDADD 416 { 417 p_type = SADB_X_SPDADD; 418 p_satype = SADB_SATYPE_UNSPEC; 419 } 420 sp_selector_spec policy_spec EOT 421 ; 422 423 spddelete_command: 424 SPDDELETE 425 { 426 p_type = SADB_X_SPDDELETE; 427 p_satype = SADB_SATYPE_UNSPEC; 428 } 429 sp_selector_spec policy_spec EOT 430 ; 431 432 spddump_command: 433 SPDDUMP 434 { 435 p_type = SADB_X_SPDDUMP; 436 p_satype = SADB_SATYPE_UNSPEC; 437 } 438 EOT 439 ; 440 441 spdflush_command: 442 SPDFLUSH 443 { 444 p_type = SADB_X_SPDFLUSH; 445 p_satype = SADB_SATYPE_UNSPEC; 446 } 447 EOT 448 ; 449 450 /* sp_selector_spec */ 451 sp_selector_spec 452 : ipaddress { p_src = pp_addr; } 453 prefix { p_prefs = pp_prefix; } 454 port 455 { 456 switch (p_src->sa_family) { 457 case AF_INET: 458 ((struct sockaddr_in *)p_src)->sin_port = 459 htons(pp_port); 460 break; 461 #ifdef INET6 462 case AF_INET6: 463 ((struct sockaddr_in6 *)p_src)->sin6_port = 464 htons(pp_port); 465 break; 466 #endif 467 default: 468 exit(1); /*XXX*/ 469 } 470 } 471 ipaddress { p_dst = pp_addr; } 472 prefix { p_prefd = pp_prefix; } 473 port 474 { 475 switch (p_dst->sa_family) { 476 case AF_INET: 477 ((struct sockaddr_in *)p_dst)->sin_port = 478 htons(pp_port); 479 break; 480 #ifdef INET6 481 case AF_INET6: 482 ((struct sockaddr_in6 *)p_dst)->sin6_port = 483 htons(pp_port); 484 break; 485 #endif 486 default: 487 exit(1); /*XXX*/ 488 } 489 } 490 upper_spec 491 { 492 /* XXX is it something userland should check? */ 493 #if 0 494 switch (p_upper) { 495 case IPPROTO_ICMP: 496 case IPPROTO_ICMPV6: 497 if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY 498 || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) { 499 yyerror("port number must be \"any\"."); 500 return -1; 501 } 502 if ((pp_addr->sa_family == AF_INET6 503 && p_upper == IPPROTO_ICMP) 504 || (pp_addr->sa_family == AF_INET 505 && p_upper == IPPROTO_ICMPV6)) { 506 yyerror("upper layer protocol " 507 "mismatched.\n"); 508 return -1; 509 } 510 break; 511 default: 512 break; 513 } 514 #endif 515 } 516 ; 517 518 ipaddress 519 : ADDRESS 520 { 521 struct addrinfo *res; 522 523 res = parse_addr($1.buf, NULL, AI_NUMERICHOST); 524 if (res == NULL) { 525 free($1.buf); 526 return -1; 527 } 528 pp_addr = (struct sockaddr *)malloc(res->ai_addrlen); 529 if (!pp_addr) { 530 yyerror("not enough core"); 531 goto end; 532 } 533 534 memcpy(pp_addr, res->ai_addr, res->ai_addrlen); 535 end: 536 freeaddrinfo(res); 537 free($1.buf); 538 } 539 ; 540 541 prefix 542 : /*NOTHING*/ { pp_prefix = ~0; } 543 | PREFIX { pp_prefix = $1; } 544 ; 545 546 port 547 : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; } 548 | PORT { pp_port = $1; } 549 | PORTANY { pp_port = IPSEC_PORT_ANY; } 550 ; 551 552 upper_spec 553 : DECSTRING { p_upper = $1; } 554 | UP_PROTO { p_upper = $1; } 555 | ANY { p_upper = IPSEC_ULPROTO_ANY; } 556 | STRING 557 { 558 struct protoent *ent; 559 560 ent = getprotobyname($1.buf); 561 if (ent) 562 p_upper = ent->p_proto; 563 else { 564 if (strcmp("icmp6", $1.buf) == 0) { 565 p_upper = IPPROTO_ICMPV6; 566 } else if(strcmp("ip4", $1.buf) == 0) { 567 p_upper = IPPROTO_IPV4; 568 } else { 569 yyerror("invalid upper layer protocol"); 570 free($1.buf); 571 return -1; 572 } 573 } 574 free($1.buf); 575 } 576 ; 577 578 policy_spec 579 : F_POLICY policy_requests 580 { 581 p_policy = ipsec_set_policy($2.buf, $2.len); 582 if (p_policy == NULL) { 583 free($2.buf); 584 p_policy = NULL; 585 yyerror(ipsec_strerror()); 586 return -1; 587 } 588 589 p_policy_len = ipsec_get_policylen(p_policy); 590 591 free($2.buf); 592 } 593 ; 594 595 policy_requests 596 : PL_REQUESTS { $$ = $1; } 597 ; 598 599 %% 600 601 int 602 setkeymsg() 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(p_src->sa_len)); 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, p_src->sa_len); 746 747 /* set dst */ 748 m_addr.sadb_address_len = 749 PFKEY_UNIT64(sizeof(m_addr) 750 + PFKEY_ALIGN8(p_dst->sa_len)); 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, p_dst->sa_len); 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(p_src->sa_len)); 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, p_src->sa_len); 818 819 /* set dst */ 820 m_addr.sadb_address_len = 821 PFKEY_UNIT64(sizeof(m_addr) 822 + PFKEY_ALIGN8(p_dst->sa_len)); 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, p_dst->sa_len); 845 } 846 break; 847 } 848 849 ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); 850 851 return 0; 852 } 853 854 static struct addrinfo * 855 parse_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 878 static int 879 setvarbuf(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 892 void 893 parse_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 923 void 924 free_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