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