162583Sitojun/* $FreeBSD: releng/10.2/sbin/setkey/parse.y 175248 2008-01-12 20:00:23Z maxim $ */ 2151293Sume/* $KAME: parse.y,v 1.83 2004/05/18 08:48:23 sakane Exp $ */ 362583Sitojun 455505Sshin/* 555505Sshin * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 655505Sshin * All rights reserved. 762583Sitojun * 855505Sshin * Redistribution and use in source and binary forms, with or without 955505Sshin * modification, are permitted provided that the following conditions 1055505Sshin * are met: 1155505Sshin * 1. Redistributions of source code must retain the above copyright 1255505Sshin * notice, this list of conditions and the following disclaimer. 1355505Sshin * 2. Redistributions in binary form must reproduce the above copyright 1455505Sshin * notice, this list of conditions and the following disclaimer in the 1555505Sshin * documentation and/or other materials provided with the distribution. 1655505Sshin * 3. Neither the name of the project nor the names of its contributors 1755505Sshin * may be used to endorse or promote products derived from this software 1855505Sshin * without specific prior written permission. 1962583Sitojun * 2055505Sshin * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2155505Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2255505Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2355505Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2455505Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2555505Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2655505Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2755505Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2855505Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2955505Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3055505Sshin * SUCH DAMAGE. 3155505Sshin */ 3255505Sshin 3355505Sshin%{ 3455505Sshin#include <sys/types.h> 3555505Sshin#include <sys/param.h> 3655505Sshin#include <sys/socket.h> 3755505Sshin 3855505Sshin#include <net/route.h> 3955505Sshin#include <netinet/in.h> 4055505Sshin#include <net/pfkeyv2.h> 41171135Sgnn#include <netipsec/key_var.h> 42171135Sgnn#include <netipsec/ipsec.h> 4355505Sshin#include <arpa/inet.h> 4455505Sshin 4555505Sshin#include <string.h> 4655505Sshin#include <unistd.h> 4755505Sshin#include <stdio.h> 4862583Sitojun#include <netdb.h> 4955505Sshin#include <ctype.h> 5055505Sshin#include <errno.h> 5155505Sshin 5262583Sitojun#include "libpfkey.h" 5355505Sshin#include "vchar.h" 5455505Sshin 5555505Sshin#define ATOX(c) \ 56122108Sume (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10))) 5755505Sshin 5862583Sitojunu_int32_t p_spi; 59122108Sumeu_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; 6062583Sitojunu_int32_t p_reqid; 6162583Sitojunu_int p_key_enc_len, p_key_auth_len; 6262583Sitojuncaddr_t p_key_enc, p_key_auth; 6362583Sitojuntime_t p_lt_hard, p_lt_soft; 6455505Sshin 65122108Sumestatic int p_aiflags = 0, p_aifamily = PF_UNSPEC; 6655505Sshin 67173412Skevlostatic struct addrinfo *parse_addr(char *, char *); 68173412Skevlostatic int fix_portstr(vchar_t *, vchar_t *, vchar_t *); 69173412Skevlostatic int setvarbuf(char *, int *, struct sadb_ext *, int, caddr_t, int); 70173412Skevlovoid parse_init(void); 71173412Skevlovoid free_buffer(void); 7255505Sshin 73173412Skevloint setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t); 74173412Skevlostatic int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *, 75173412Skevlo struct addrinfo *, int, struct addrinfo *, int); 76173412Skevlostatic int setkeymsg_addr(unsigned int, unsigned int, 77173412Skevlo struct addrinfo *, struct addrinfo *, int); 78173412Skevlostatic int setkeymsg_add(unsigned int, unsigned int, 79173412Skevlo struct addrinfo *, struct addrinfo *); 80173412Skevloextern int setkeymsg(char *, size_t *); 81173412Skevloextern int sendkeymsg(char *, size_t); 8255505Sshin 83173412Skevloextern int yylex(void); 84173412Skevloextern void yyfatal(const char *); 85173412Skevloextern void yyerror(const char *); 8655505Sshin%} 8755505Sshin 8855505Sshin%union { 89122108Sume int num; 90122108Sume unsigned long ulnum; 9155505Sshin vchar_t val; 92122108Sume struct addrinfo *res; 9355505Sshin} 9455505Sshin 95122108Sume%token EOT SLASH BLCL ELCL 96122108Sume%token ADD GET DELETE DELETEALL FLUSH DUMP 97125681Sbms%token PR_ESP PR_AH PR_IPCOMP PR_TCP 9855505Sshin%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI 9962583Sitojun%token F_MODE MODE F_REQID 10062583Sitojun%token F_EXT EXTENSION NOCYCLICSEQ 101122108Sume%token ALG_AUTH ALG_AUTH_NOKEY 102122108Sume%token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD 103122108Sume%token ALG_COMP 10455505Sshin%token F_LIFETIME_HARD F_LIFETIME_SOFT 10578064Sume%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY 10655505Sshin /* SPD management */ 10755505Sshin%token SPDADD SPDDELETE SPDDUMP SPDFLUSH 10855505Sshin%token F_POLICY PL_REQUESTS 109122108Sume%token F_AIFLAGS 110122108Sume%token TAGGED 11155505Sshin 112122108Sume%type <num> prefix protocol_spec upper_spec 113122108Sume%type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY 114122108Sume%type <num> ALG_AUTH ALG_AUTH_NOKEY 115122108Sume%type <num> ALG_COMP 116125681Sbms%type <num> PR_ESP PR_AH PR_IPCOMP PR_TCP 117122108Sume%type <num> EXTENSION MODE 118122108Sume%type <ulnum> DECSTRING 119122108Sume%type <val> PL_REQUESTS portstr key_string 120122108Sume%type <val> policy_requests 12178064Sume%type <val> QUOTEDSTRING HEXSTRING STRING 122122108Sume%type <val> F_AIFLAGS 123122108Sume%type <val> upper_misc_spec policy_spec 124122108Sume%type <res> ipaddr 12562583Sitojun 12655505Sshin%% 12755505Sshincommands 12855505Sshin : /*NOTHING*/ 12955505Sshin | commands command 13055505Sshin { 13155505Sshin free_buffer(); 13255505Sshin parse_init(); 13355505Sshin } 13455505Sshin ; 13555505Sshin 13655505Sshincommand 13755505Sshin : add_command 13855505Sshin | get_command 13955505Sshin | delete_command 14078064Sume | deleteall_command 14155505Sshin | flush_command 14255505Sshin | dump_command 14355505Sshin | spdadd_command 14455505Sshin | spddelete_command 14555505Sshin | spddump_command 14655505Sshin | spdflush_command 14755505Sshin ; 14855505Sshin /* commands concerned with management, there is in tail of this file. */ 14955505Sshin 15055505Sshin /* add command */ 15155505Sshinadd_command 152122108Sume : ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT 153122108Sume { 154122108Sume int status; 155122108Sume 156122108Sume status = setkeymsg_add(SADB_ADD, $5, $3, $4); 157122108Sume if (status < 0) 158122108Sume return -1; 159122108Sume } 16055505Sshin ; 16155505Sshin 16255505Sshin /* delete */ 16355505Sshindelete_command 164122108Sume : DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT 16562583Sitojun { 166122108Sume int status; 167122108Sume 168122108Sume if ($3->ai_next || $4->ai_next) { 169122108Sume yyerror("multiple address specified"); 170122108Sume return -1; 171122108Sume } 17262583Sitojun if (p_mode != IPSEC_MODE_ANY) 173122108Sume yyerror("WARNING: mode is obsolete"); 174122108Sume 175122108Sume status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0); 176122108Sume if (status < 0) 177122108Sume return -1; 17862583Sitojun } 17955505Sshin ; 18055505Sshin 18178064Sume /* deleteall command */ 18278064Sumedeleteall_command 183122108Sume : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT 184122108Sume { 185122108Sume int status; 186122108Sume 187122108Sume status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1); 188122108Sume if (status < 0) 189122108Sume return -1; 190122108Sume } 19178064Sume ; 19278064Sume 19355505Sshin /* get command */ 19455505Sshinget_command 195122108Sume : GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT 19662583Sitojun { 197122108Sume int status; 198122108Sume 19962583Sitojun if (p_mode != IPSEC_MODE_ANY) 200122108Sume yyerror("WARNING: mode is obsolete"); 201122108Sume 202122108Sume status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0); 203122108Sume if (status < 0) 204122108Sume return -1; 20562583Sitojun } 20655505Sshin ; 20755505Sshin 20855505Sshin /* flush */ 20955505Sshinflush_command 210122108Sume : FLUSH protocol_spec EOT 211122108Sume { 212122108Sume struct sadb_msg msg; 213122108Sume setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg)); 214122108Sume sendkeymsg((char *)&msg, sizeof(msg)); 215122108Sume } 21655505Sshin ; 21755505Sshin 21855505Sshin /* dump */ 21955505Sshindump_command 220122108Sume : DUMP protocol_spec EOT 221122108Sume { 222122108Sume struct sadb_msg msg; 223122108Sume setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg)); 224122108Sume sendkeymsg((char *)&msg, sizeof(msg)); 225122108Sume } 22655505Sshin ; 22755505Sshin 22855505Sshinprotocol_spec 229122108Sume : /*NOTHING*/ 230122108Sume { 231122108Sume $$ = SADB_SATYPE_UNSPEC; 232122108Sume } 23355505Sshin | PR_ESP 23455505Sshin { 235122108Sume $$ = SADB_SATYPE_ESP; 23662583Sitojun if ($1 == 1) 23755505Sshin p_ext |= SADB_X_EXT_OLD; 23855505Sshin else 23955505Sshin p_ext &= ~SADB_X_EXT_OLD; 24055505Sshin } 24155505Sshin | PR_AH 24255505Sshin { 243122108Sume $$ = SADB_SATYPE_AH; 24462583Sitojun if ($1 == 1) 24555505Sshin p_ext |= SADB_X_EXT_OLD; 24655505Sshin else 24755505Sshin p_ext &= ~SADB_X_EXT_OLD; 24855505Sshin } 24955505Sshin | PR_IPCOMP 25055505Sshin { 251122108Sume $$ = SADB_X_SATYPE_IPCOMP; 25255505Sshin } 253125681Sbms | PR_TCP 254125681Sbms { 255125681Sbms $$ = SADB_X_SATYPE_TCPSIGNATURE; 256125681Sbms } 25755505Sshin ; 258125681Sbms 25955505Sshinspi 26062583Sitojun : DECSTRING { p_spi = $1; } 26155505Sshin | HEXSTRING 26255505Sshin { 263122108Sume char *ep; 264122108Sume unsigned long v; 26555505Sshin 266122108Sume ep = NULL; 267122108Sume v = strtoul($1.buf, &ep, 16); 268122108Sume if (!ep || *ep) { 269122108Sume yyerror("invalid SPI"); 270122108Sume return -1; 271122108Sume } 272122108Sume if (v & ~0xffffffff) { 27355505Sshin yyerror("SPI too big."); 27455505Sshin return -1; 27555505Sshin } 27655505Sshin 277122108Sume p_spi = v; 27855505Sshin } 27955505Sshin ; 28055505Sshin 28155505Sshinalgorithm_spec 28255505Sshin : esp_spec 28355505Sshin | ah_spec 28455505Sshin | ipcomp_spec 28555505Sshin ; 28655505Sshin 28755505Sshinesp_spec 288122108Sume : F_ENC enc_alg F_AUTH auth_alg 289122108Sume | F_ENC enc_alg 29055505Sshin ; 29155505Sshin 29255505Sshinah_spec 293122108Sume : F_AUTH auth_alg 29455505Sshin ; 29555505Sshin 29655505Sshinipcomp_spec 297122108Sume : F_COMP ALG_COMP 298122108Sume { 299122108Sume if ($2 < 0) { 300122108Sume yyerror("unsupported algorithm"); 301122108Sume return -1; 302122108Sume } 303122108Sume p_alg_enc = $2; 304122108Sume } 305122108Sume | F_COMP ALG_COMP F_RAWCPI 306122108Sume { 307122108Sume if ($2 < 0) { 308122108Sume yyerror("unsupported algorithm"); 309122108Sume return -1; 310122108Sume } 311122108Sume p_alg_enc = $2; 312122108Sume p_ext |= SADB_X_EXT_RAWCPI; 313122108Sume } 31455505Sshin ; 31555505Sshin 31655505Sshinenc_alg 317122108Sume : ALG_ENC_NOKEY { 318122108Sume if ($1 < 0) { 319122108Sume yyerror("unsupported algorithm"); 320122108Sume return -1; 321122108Sume } 322122108Sume p_alg_enc = $1; 323122108Sume 324122108Sume p_key_enc_len = 0; 325122108Sume p_key_enc = NULL; 326129183Sume if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 327129183Sume p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 328129183Sume yyerror(ipsec_strerror()); 329129183Sume return -1; 330129183Sume } 331122108Sume } 332122108Sume | ALG_ENC key_string { 333122108Sume if ($1 < 0) { 334122108Sume yyerror("unsupported algorithm"); 335122108Sume return -1; 336122108Sume } 337122108Sume p_alg_enc = $1; 338122108Sume 339122108Sume p_key_enc_len = $2.len; 340122108Sume p_key_enc = $2.buf; 341122108Sume if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 342122108Sume p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 343122108Sume yyerror(ipsec_strerror()); 344122108Sume return -1; 345122108Sume } 346122108Sume } 347122108Sume | ALG_ENC_OLD { 348122108Sume if ($1 < 0) { 349122108Sume yyerror("unsupported algorithm"); 350122108Sume return -1; 351122108Sume } 352122108Sume yyerror("WARNING: obsolete algorithm"); 353122108Sume p_alg_enc = $1; 354122108Sume 355122108Sume p_key_enc_len = 0; 356122108Sume p_key_enc = NULL; 357129183Sume if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 358129183Sume p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 359129183Sume yyerror(ipsec_strerror()); 360129183Sume return -1; 361129183Sume } 362122108Sume } 363122108Sume | ALG_ENC_DESDERIV key_string 36455505Sshin { 365122108Sume if ($1 < 0) { 366122108Sume yyerror("unsupported algorithm"); 367122108Sume return -1; 368122108Sume } 36962583Sitojun p_alg_enc = $1; 37055505Sshin if (p_ext & SADB_X_EXT_OLD) { 371122108Sume yyerror("algorithm mismatched"); 37255505Sshin return -1; 37355505Sshin } 37455505Sshin p_ext |= SADB_X_EXT_DERIV; 375122108Sume 376122108Sume p_key_enc_len = $2.len; 377122108Sume p_key_enc = $2.buf; 378122108Sume if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 379122108Sume p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 380122108Sume yyerror(ipsec_strerror()); 381122108Sume return -1; 382122108Sume } 38355505Sshin } 384122108Sume | ALG_ENC_DES32IV key_string 38555505Sshin { 386122108Sume if ($1 < 0) { 387122108Sume yyerror("unsupported algorithm"); 388122108Sume return -1; 389122108Sume } 39062583Sitojun p_alg_enc = $1; 39155505Sshin if (!(p_ext & SADB_X_EXT_OLD)) { 392122108Sume yyerror("algorithm mismatched"); 39355505Sshin return -1; 39455505Sshin } 39555505Sshin p_ext |= SADB_X_EXT_IV4B; 39655505Sshin 397122108Sume p_key_enc_len = $2.len; 398122108Sume p_key_enc = $2.buf; 39955505Sshin if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 400122108Sume p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 40155505Sshin yyerror(ipsec_strerror()); 40255505Sshin return -1; 40355505Sshin } 40455505Sshin } 40555505Sshin ; 40655505Sshin 40755505Sshinauth_alg 408122108Sume : ALG_AUTH key_string { 409122108Sume if ($1 < 0) { 410122108Sume yyerror("unsupported algorithm"); 41155505Sshin return -1; 41255505Sshin } 413122108Sume p_alg_auth = $1; 41455505Sshin 415122108Sume p_key_auth_len = $2.len; 416122108Sume p_key_auth = $2.buf; 417125681Sbms 418125681Sbms if (p_alg_auth == SADB_X_AALG_TCP_MD5) { 419125681Sbms if ((p_key_auth_len < 1) || (p_key_auth_len > 420125681Sbms 80)) 421125681Sbms return -1; 422125681Sbms } else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, 423122108Sume p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { 42455505Sshin yyerror(ipsec_strerror()); 42555505Sshin return -1; 42655505Sshin } 42755505Sshin } 428122108Sume | ALG_AUTH_NOKEY { 429122108Sume if ($1 < 0) { 430122108Sume yyerror("unsupported algorithm"); 431122108Sume return -1; 432122108Sume } 433122108Sume p_alg_auth = $1; 434122108Sume 435122108Sume p_key_auth_len = 0; 436122108Sume p_key_auth = NULL; 437122108Sume } 43855505Sshin ; 43955505Sshin 44055505Sshinkey_string 44155505Sshin : QUOTEDSTRING 44255505Sshin { 443122108Sume $$ = $1; 44455505Sshin } 44555505Sshin | HEXSTRING 44655505Sshin { 447122108Sume caddr_t pp_key; 44855505Sshin caddr_t bp; 44962583Sitojun caddr_t yp = $1.buf; 450122108Sume int l; 45155505Sshin 452122108Sume l = strlen(yp) % 2 + strlen(yp) / 2; 453122108Sume if ((pp_key = malloc(l)) == 0) { 45462583Sitojun yyerror("not enough core"); 45555505Sshin return -1; 45655505Sshin } 457122108Sume memset(pp_key, 0, l); 45855505Sshin 45955505Sshin bp = pp_key; 460122108Sume if (strlen(yp) % 2) { 461122108Sume *bp = ATOX(yp[0]); 462122108Sume yp++, bp++; 463122108Sume } 46455505Sshin while (*yp) { 46555505Sshin *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 46655505Sshin yp += 2, bp++; 46755505Sshin } 46855505Sshin 469122108Sume $$.len = l; 470122108Sume $$.buf = pp_key; 47155505Sshin } 47255505Sshin ; 47355505Sshin 47455505Sshinextension_spec 47555505Sshin : /*NOTHING*/ 47655505Sshin | extension_spec extension 47755505Sshin ; 47855505Sshin 47955505Sshinextension 48062583Sitojun : F_EXT EXTENSION { p_ext |= $2; } 48162583Sitojun | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 48262583Sitojun | F_MODE MODE { p_mode = $2; } 48355505Sshin | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 48462583Sitojun | F_REQID DECSTRING { p_reqid = $2; } 48555505Sshin | F_REPLAY DECSTRING 48655505Sshin { 487122108Sume if ((p_ext & SADB_X_EXT_OLD) != 0) { 488122108Sume yyerror("replay prevention cannot be used with " 489122108Sume "ah/esp-old"); 49055505Sshin return -1; 49155505Sshin } 49262583Sitojun p_replay = $2; 49355505Sshin } 49462583Sitojun | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 49562583Sitojun | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 49655505Sshin ; 49755505Sshin 49855505Sshin /* definition about command for SPD management */ 49955505Sshin /* spdadd */ 50055505Sshinspdadd_command 501122108Sume : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT 50255505Sshin { 503122108Sume int status; 504122108Sume struct addrinfo *src, *dst; 505122108Sume 506122108Sume /* fixed port fields if ulp is icmpv6 */ 507122108Sume if ($10.buf != NULL) { 508122108Sume if ($9 != IPPROTO_ICMPV6) 509122108Sume return -1; 510122108Sume free($5.buf); 511122108Sume free($8.buf); 512122108Sume if (fix_portstr(&$10, &$5, &$8)) 513122108Sume return -1; 514122108Sume } 515122108Sume 516122108Sume src = parse_addr($3.buf, $5.buf); 517122108Sume dst = parse_addr($6.buf, $8.buf); 518122108Sume if (!src || !dst) { 519122108Sume /* yyerror is already called */ 520122108Sume return -1; 521122108Sume } 522122108Sume if (src->ai_next || dst->ai_next) { 523122108Sume yyerror("multiple address specified"); 524122108Sume freeaddrinfo(src); 525122108Sume freeaddrinfo(dst); 526122108Sume return -1; 527122108Sume } 528122108Sume 529122108Sume status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11, 530122108Sume src, $4, dst, $7); 531122108Sume freeaddrinfo(src); 532122108Sume freeaddrinfo(dst); 533122108Sume if (status < 0) 534122108Sume return -1; 53555505Sshin } 536122108Sume | SPDADD TAGGED QUOTEDSTRING policy_spec EOT 537122108Sume { 538122108Sume return -1; 539122108Sume } 54055505Sshin ; 54155505Sshin 542122108Sumespddelete_command 543122108Sume : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT 54455505Sshin { 545122108Sume int status; 546122108Sume struct addrinfo *src, *dst; 547122108Sume 548122108Sume /* fixed port fields if ulp is icmpv6 */ 549122108Sume if ($10.buf != NULL) { 550122108Sume if ($9 != IPPROTO_ICMPV6) 551122108Sume return -1; 552122108Sume free($5.buf); 553122108Sume free($8.buf); 554122108Sume if (fix_portstr(&$10, &$5, &$8)) 555122108Sume return -1; 556122108Sume } 557122108Sume 558122108Sume src = parse_addr($3.buf, $5.buf); 559122108Sume dst = parse_addr($6.buf, $8.buf); 560122108Sume if (!src || !dst) { 561122108Sume /* yyerror is already called */ 562122108Sume return -1; 563122108Sume } 564122108Sume if (src->ai_next || dst->ai_next) { 565122108Sume yyerror("multiple address specified"); 566122108Sume freeaddrinfo(src); 567122108Sume freeaddrinfo(dst); 568122108Sume return -1; 569122108Sume } 570122108Sume 571122108Sume status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11, 572122108Sume src, $4, dst, $7); 573122108Sume freeaddrinfo(src); 574122108Sume freeaddrinfo(dst); 575122108Sume if (status < 0) 576122108Sume return -1; 57755505Sshin } 57855505Sshin ; 57955505Sshin 58055505Sshinspddump_command: 581122108Sume SPDDUMP EOT 58255505Sshin { 583122108Sume struct sadb_msg msg; 584122108Sume setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, 585122108Sume sizeof(msg)); 586122108Sume sendkeymsg((char *)&msg, sizeof(msg)); 58755505Sshin } 58855505Sshin ; 58955505Sshin 59055505Sshinspdflush_command: 591122108Sume SPDFLUSH EOT 59255505Sshin { 593122108Sume struct sadb_msg msg; 594122108Sume setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, 595122108Sume sizeof(msg)); 596122108Sume sendkeymsg((char *)&msg, sizeof(msg)); 59755505Sshin } 59855505Sshin ; 59955505Sshin 600122108Sumeipaddropts 601122108Sume : /* nothing */ 602122108Sume | ipaddropts ipaddropt 603122108Sume ; 604122108Sume 605122108Sumeipaddropt 606122108Sume : F_AIFLAGS 60762583Sitojun { 608122108Sume char *p; 609122108Sume 610122108Sume for (p = $1.buf + 1; *p; p++) 611122108Sume switch (*p) { 612122108Sume case '4': 613122108Sume p_aifamily = AF_INET; 614122108Sume break; 61562583Sitojun#ifdef INET6 616122108Sume case '6': 617122108Sume p_aifamily = AF_INET6; 618122108Sume break; 61962583Sitojun#endif 620122108Sume case 'n': 621122108Sume p_aiflags = AI_NUMERICHOST; 622122108Sume break; 623122108Sume default: 624122108Sume yyerror("invalid flag"); 62562583Sitojun return -1; 62662583Sitojun } 62762583Sitojun } 62855505Sshin ; 62955505Sshin 630122108Sumeipaddr 631122108Sume : STRING 63255505Sshin { 633122108Sume $$ = parse_addr($1.buf, NULL); 634122108Sume if ($$ == NULL) { 635122108Sume /* yyerror already called by parse_addr */ 63655505Sshin return -1; 63755505Sshin } 63855505Sshin } 63955505Sshin ; 64055505Sshin 64155505Sshinprefix 642122108Sume : /*NOTHING*/ { $$ = -1; } 643122108Sume | SLASH DECSTRING { $$ = $2; } 64455505Sshin ; 64555505Sshin 646122108Sumeportstr 647122108Sume : /*NOTHING*/ 648122108Sume { 649122108Sume $$.buf = strdup("0"); 650122108Sume if (!$$.buf) { 651122108Sume yyerror("insufficient memory"); 652122108Sume return -1; 653122108Sume } 654122108Sume $$.len = strlen($$.buf); 655122108Sume } 656122108Sume | BLCL ANY ELCL 657122108Sume { 658122108Sume $$.buf = strdup("0"); 659122108Sume if (!$$.buf) { 660122108Sume yyerror("insufficient memory"); 661122108Sume return -1; 662122108Sume } 663122108Sume $$.len = strlen($$.buf); 664122108Sume } 665122108Sume | BLCL DECSTRING ELCL 666122108Sume { 667122108Sume char buf[20]; 668122108Sume snprintf(buf, sizeof(buf), "%lu", $2); 669122108Sume $$.buf = strdup(buf); 670122108Sume if (!$$.buf) { 671122108Sume yyerror("insufficient memory"); 672122108Sume return -1; 673122108Sume } 674122108Sume $$.len = strlen($$.buf); 675122108Sume } 676122108Sume | BLCL STRING ELCL 677122108Sume { 678122108Sume $$ = $2; 679122108Sume } 68055505Sshin ; 68155505Sshin 68255505Sshinupper_spec 683122108Sume : DECSTRING { $$ = $1; } 684122108Sume | ANY { $$ = IPSEC_ULPROTO_ANY; } 685127684Sbms | PR_TCP { $$ = IPPROTO_TCP; } 686175248Smaxim | PR_ESP { $$ = IPPROTO_ESP; } 68778064Sume | STRING 68878064Sume { 68978064Sume struct protoent *ent; 69078064Sume 69178064Sume ent = getprotobyname($1.buf); 69278064Sume if (ent) 693122108Sume $$ = ent->p_proto; 69478064Sume else { 69578064Sume if (strcmp("icmp6", $1.buf) == 0) { 696122108Sume $$ = IPPROTO_ICMPV6; 69778064Sume } else if(strcmp("ip4", $1.buf) == 0) { 698122108Sume $$ = IPPROTO_IPV4; 69978064Sume } else { 70078064Sume yyerror("invalid upper layer protocol"); 70178064Sume return -1; 70278064Sume } 70378064Sume } 704122108Sume endprotoent(); 70578064Sume } 70655505Sshin ; 70755505Sshin 708122108Sumeupper_misc_spec 709122108Sume : /*NOTHING*/ 710122108Sume { 711122108Sume $$.buf = NULL; 712122108Sume $$.len = 0; 713122108Sume } 714122108Sume | STRING 715122108Sume { 716122108Sume $$.buf = strdup($1.buf); 717122108Sume if (!$$.buf) { 718122108Sume yyerror("insufficient memory"); 719122108Sume return -1; 720122108Sume } 721122108Sume $$.len = strlen($$.buf); 722122108Sume } 723122108Sume ; 724122108Sume 72555505Sshinpolicy_spec 72655505Sshin : F_POLICY policy_requests 72755505Sshin { 728122108Sume char *policy; 729122108Sume 730122108Sume policy = ipsec_set_policy($2.buf, $2.len); 731122108Sume if (policy == NULL) { 73255505Sshin yyerror(ipsec_strerror()); 73355505Sshin return -1; 73455505Sshin } 73555505Sshin 736122108Sume $$.buf = policy; 737122108Sume $$.len = ipsec_get_policylen(policy); 73855505Sshin } 73955505Sshin ; 74055505Sshin 74162583Sitojunpolicy_requests 74262583Sitojun : PL_REQUESTS { $$ = $1; } 74355505Sshin ; 74455505Sshin 74555505Sshin%% 74655505Sshin 74755505Sshinint 748122108Sumesetkeymsg0(msg, type, satype, l) 749122108Sume struct sadb_msg *msg; 750122108Sume unsigned int type; 751122108Sume unsigned int satype; 752122108Sume size_t l; 75355505Sshin{ 75455505Sshin 755122108Sume msg->sadb_msg_version = PF_KEY_V2; 756122108Sume msg->sadb_msg_type = type; 757122108Sume msg->sadb_msg_errno = 0; 758122108Sume msg->sadb_msg_satype = satype; 759122108Sume msg->sadb_msg_reserved = 0; 760122108Sume msg->sadb_msg_seq = 0; 761122108Sume msg->sadb_msg_pid = getpid(); 762122108Sume msg->sadb_msg_len = PFKEY_UNIT64(l); 763122108Sume return 0; 764122108Sume} 76555505Sshin 766122108Sume/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 767122108Sumestatic int 768122108Sumesetkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 769122108Sume unsigned int type; 770122108Sume unsigned int upper; 771122108Sume vchar_t *policy; 772122108Sume struct addrinfo *srcs; 773122108Sume int splen; 774122108Sume struct addrinfo *dsts; 775122108Sume int dplen; 776122108Sume{ 777122108Sume struct sadb_msg *msg; 778122108Sume char buf[BUFSIZ]; 779122108Sume int l, l0; 780122108Sume struct sadb_address m_addr; 781122108Sume struct addrinfo *s, *d; 782122108Sume int n; 783122108Sume int plen; 784122108Sume struct sockaddr *sa; 785122108Sume int salen; 78655505Sshin 787122108Sume msg = (struct sadb_msg *)buf; 78855505Sshin 789122108Sume if (!srcs || !dsts) 790122108Sume return -1; 79155505Sshin 792122108Sume /* fix up length afterwards */ 793122108Sume setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 794122108Sume l = sizeof(struct sadb_msg); 79555505Sshin 796122108Sume memcpy(buf + l, policy->buf, policy->len); 797122108Sume l += policy->len; 79855505Sshin 799122108Sume l0 = l; 800122108Sume n = 0; 80155505Sshin 802122108Sume /* do it for all src/dst pairs */ 803122108Sume for (s = srcs; s; s = s->ai_next) { 804122108Sume for (d = dsts; d; d = d->ai_next) { 805122108Sume /* rewind pointer */ 806122108Sume l = l0; 80755505Sshin 808122108Sume if (s->ai_addr->sa_family != d->ai_addr->sa_family) 809122108Sume continue; 810122108Sume switch (s->ai_addr->sa_family) { 811122108Sume case AF_INET: 812122108Sume plen = sizeof(struct in_addr) << 3; 813122108Sume break; 814122108Sume#ifdef INET6 815122108Sume case AF_INET6: 816122108Sume plen = sizeof(struct in6_addr) << 3; 817122108Sume break; 818122108Sume#endif 819122108Sume default: 820122108Sume continue; 821122108Sume } 82255505Sshin 823122108Sume /* set src */ 824122108Sume sa = s->ai_addr; 825122108Sume salen = s->ai_addr->sa_len; 826122108Sume m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 827122108Sume PFKEY_ALIGN8(salen)); 828122108Sume m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 829122108Sume m_addr.sadb_address_proto = upper; 830122108Sume m_addr.sadb_address_prefixlen = 831122108Sume (splen >= 0 ? splen : plen); 832122108Sume m_addr.sadb_address_reserved = 0; 83355505Sshin 834122108Sume setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 835122108Sume sizeof(m_addr), (caddr_t)sa, salen); 83655505Sshin 837122108Sume /* set dst */ 838122108Sume sa = d->ai_addr; 839122108Sume salen = d->ai_addr->sa_len; 840122108Sume m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 841122108Sume PFKEY_ALIGN8(salen)); 842122108Sume m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 843122108Sume m_addr.sadb_address_proto = upper; 844122108Sume m_addr.sadb_address_prefixlen = 845122108Sume (dplen >= 0 ? dplen : plen); 846122108Sume m_addr.sadb_address_reserved = 0; 84755505Sshin 848122108Sume setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 849122108Sume sizeof(m_addr), (caddr_t)sa, salen); 85055505Sshin 851122108Sume msg->sadb_msg_len = PFKEY_UNIT64(l); 85255505Sshin 853122108Sume sendkeymsg(buf, l); 854122108Sume 855122108Sume n++; 85655505Sshin } 857122108Sume } 85855505Sshin 859122108Sume if (n == 0) 860122108Sume return -1; 861122108Sume else 862122108Sume return 0; 863122108Sume} 86455505Sshin 865122108Sume/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 866122108Sumestatic int 867122108Sumesetkeymsg_addr(type, satype, srcs, dsts, no_spi) 868122108Sume unsigned int type; 869122108Sume unsigned int satype; 870122108Sume struct addrinfo *srcs; 871122108Sume struct addrinfo *dsts; 872122108Sume int no_spi; 873122108Sume{ 874122108Sume struct sadb_msg *msg; 875122108Sume char buf[BUFSIZ]; 876122108Sume int l, l0, len; 877122108Sume struct sadb_sa m_sa; 878122108Sume struct sadb_x_sa2 m_sa2; 879122108Sume struct sadb_address m_addr; 880122108Sume struct addrinfo *s, *d; 881122108Sume int n; 882122108Sume int plen; 883122108Sume struct sockaddr *sa; 884122108Sume int salen; 88555505Sshin 886122108Sume msg = (struct sadb_msg *)buf; 88755505Sshin 888122108Sume if (!srcs || !dsts) 889122108Sume return -1; 89062583Sitojun 891122108Sume /* fix up length afterwards */ 892122108Sume setkeymsg0(msg, type, satype, 0); 893122108Sume l = sizeof(struct sadb_msg); 89462583Sitojun 895122108Sume if (!no_spi) { 896122108Sume len = sizeof(struct sadb_sa); 897122108Sume m_sa.sadb_sa_len = PFKEY_UNIT64(len); 898122108Sume m_sa.sadb_sa_exttype = SADB_EXT_SA; 899122108Sume m_sa.sadb_sa_spi = htonl(p_spi); 900122108Sume m_sa.sadb_sa_replay = p_replay; 901122108Sume m_sa.sadb_sa_state = 0; 902122108Sume m_sa.sadb_sa_auth = p_alg_auth; 903122108Sume m_sa.sadb_sa_encrypt = p_alg_enc; 904122108Sume m_sa.sadb_sa_flags = p_ext; 905122108Sume 906122108Sume memcpy(buf + l, &m_sa, len); 907122108Sume l += len; 908122108Sume 909122108Sume len = sizeof(struct sadb_x_sa2); 910122108Sume m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 911122108Sume m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 912122108Sume m_sa2.sadb_x_sa2_mode = p_mode; 913122108Sume m_sa2.sadb_x_sa2_reqid = p_reqid; 914122108Sume 915122108Sume memcpy(buf + l, &m_sa2, len); 916122108Sume l += len; 917122108Sume } 918122108Sume 919122108Sume l0 = l; 920122108Sume n = 0; 921122108Sume 922122108Sume /* do it for all src/dst pairs */ 923122108Sume for (s = srcs; s; s = s->ai_next) { 924122108Sume for (d = dsts; d; d = d->ai_next) { 925122108Sume /* rewind pointer */ 926122108Sume l = l0; 927122108Sume 928122108Sume if (s->ai_addr->sa_family != d->ai_addr->sa_family) 929122108Sume continue; 930122108Sume switch (s->ai_addr->sa_family) { 931122108Sume case AF_INET: 932122108Sume plen = sizeof(struct in_addr) << 3; 933122108Sume break; 93462583Sitojun#ifdef INET6 935122108Sume case AF_INET6: 936122108Sume plen = sizeof(struct in6_addr) << 3; 937122108Sume break; 93862583Sitojun#endif 939122108Sume default: 940122108Sume continue; 941122108Sume } 94255505Sshin 943122108Sume /* set src */ 944122108Sume sa = s->ai_addr; 945122108Sume salen = s->ai_addr->sa_len; 946122108Sume m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 947122108Sume PFKEY_ALIGN8(salen)); 948122108Sume m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 949122108Sume m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 950122108Sume m_addr.sadb_address_prefixlen = plen; 951122108Sume m_addr.sadb_address_reserved = 0; 95255505Sshin 953122108Sume setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 954122108Sume sizeof(m_addr), (caddr_t)sa, salen); 955122108Sume 956122108Sume /* set dst */ 957122108Sume sa = d->ai_addr; 958122108Sume salen = d->ai_addr->sa_len; 959122108Sume m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 960122108Sume PFKEY_ALIGN8(salen)); 961122108Sume m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 962122108Sume m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 963122108Sume m_addr.sadb_address_prefixlen = plen; 964122108Sume m_addr.sadb_address_reserved = 0; 965122108Sume 966122108Sume setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 967122108Sume sizeof(m_addr), (caddr_t)sa, salen); 968122108Sume 969122108Sume msg->sadb_msg_len = PFKEY_UNIT64(l); 970122108Sume 971122108Sume sendkeymsg(buf, l); 972122108Sume 973122108Sume n++; 97462583Sitojun } 975122108Sume } 97655505Sshin 977122108Sume if (n == 0) 978122108Sume return -1; 979122108Sume else 980122108Sume return 0; 981122108Sume} 98255505Sshin 983122108Sume/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 984122108Sumestatic int 985122108Sumesetkeymsg_add(type, satype, srcs, dsts) 986122108Sume unsigned int type; 987122108Sume unsigned int satype; 988122108Sume struct addrinfo *srcs; 989122108Sume struct addrinfo *dsts; 990122108Sume{ 991122108Sume struct sadb_msg *msg; 992122108Sume char buf[BUFSIZ]; 993122108Sume int l, l0, len; 994122108Sume struct sadb_sa m_sa; 995122108Sume struct sadb_x_sa2 m_sa2; 996122108Sume struct sadb_address m_addr; 997122108Sume struct addrinfo *s, *d; 998122108Sume int n; 999122108Sume int plen; 1000122108Sume struct sockaddr *sa; 1001122108Sume int salen; 100255505Sshin 1003122108Sume msg = (struct sadb_msg *)buf; 100462583Sitojun 1005122108Sume if (!srcs || !dsts) 1006122108Sume return -1; 100755505Sshin 1008122108Sume /* fix up length afterwards */ 1009122108Sume setkeymsg0(msg, type, satype, 0); 1010122108Sume l = sizeof(struct sadb_msg); 1011122108Sume 1012122108Sume /* set encryption algorithm, if present. */ 1013122108Sume if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { 1014122108Sume struct sadb_key m_key; 1015122108Sume 1016122108Sume m_key.sadb_key_len = 1017122108Sume PFKEY_UNIT64(sizeof(m_key) 1018122108Sume + PFKEY_ALIGN8(p_key_enc_len)); 1019122108Sume m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 1020122108Sume m_key.sadb_key_bits = p_key_enc_len * 8; 1021122108Sume m_key.sadb_key_reserved = 0; 1022122108Sume 1023122108Sume setvarbuf(buf, &l, 1024122108Sume (struct sadb_ext *)&m_key, sizeof(m_key), 1025122108Sume (caddr_t)p_key_enc, p_key_enc_len); 1026122108Sume } 1027122108Sume 1028122108Sume /* set authentication algorithm, if present. */ 1029122108Sume if (p_key_auth) { 1030122108Sume struct sadb_key m_key; 1031122108Sume 1032122108Sume m_key.sadb_key_len = 1033122108Sume PFKEY_UNIT64(sizeof(m_key) 1034122108Sume + PFKEY_ALIGN8(p_key_auth_len)); 1035122108Sume m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 1036122108Sume m_key.sadb_key_bits = p_key_auth_len * 8; 1037122108Sume m_key.sadb_key_reserved = 0; 1038122108Sume 1039122108Sume setvarbuf(buf, &l, 1040122108Sume (struct sadb_ext *)&m_key, sizeof(m_key), 1041122108Sume (caddr_t)p_key_auth, p_key_auth_len); 1042122108Sume } 1043122108Sume 1044122108Sume /* set lifetime for HARD */ 1045122108Sume if (p_lt_hard != 0) { 1046122108Sume struct sadb_lifetime m_lt; 1047122108Sume u_int slen = sizeof(struct sadb_lifetime); 1048122108Sume 1049122108Sume m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1050122108Sume m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1051122108Sume m_lt.sadb_lifetime_allocations = 0; 1052122108Sume m_lt.sadb_lifetime_bytes = 0; 1053122108Sume m_lt.sadb_lifetime_addtime = p_lt_hard; 1054122108Sume m_lt.sadb_lifetime_usetime = 0; 1055122108Sume 1056122108Sume memcpy(buf + l, &m_lt, slen); 1057151293Sume l += slen; 1058122108Sume } 1059122108Sume 1060122108Sume /* set lifetime for SOFT */ 1061122108Sume if (p_lt_soft != 0) { 1062122108Sume struct sadb_lifetime m_lt; 1063122108Sume u_int slen = sizeof(struct sadb_lifetime); 1064122108Sume 1065122108Sume m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1066122108Sume m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1067122108Sume m_lt.sadb_lifetime_allocations = 0; 1068122108Sume m_lt.sadb_lifetime_bytes = 0; 1069122108Sume m_lt.sadb_lifetime_addtime = p_lt_soft; 1070122108Sume m_lt.sadb_lifetime_usetime = 0; 1071122108Sume 1072122108Sume memcpy(buf + l, &m_lt, slen); 1073151293Sume l += slen; 1074122108Sume } 1075122108Sume 1076122108Sume len = sizeof(struct sadb_sa); 1077122108Sume m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1078122108Sume m_sa.sadb_sa_exttype = SADB_EXT_SA; 1079122108Sume m_sa.sadb_sa_spi = htonl(p_spi); 1080122108Sume m_sa.sadb_sa_replay = p_replay; 1081122108Sume m_sa.sadb_sa_state = 0; 1082122108Sume m_sa.sadb_sa_auth = p_alg_auth; 1083122108Sume m_sa.sadb_sa_encrypt = p_alg_enc; 1084122108Sume m_sa.sadb_sa_flags = p_ext; 1085122108Sume 1086122108Sume memcpy(buf + l, &m_sa, len); 1087122108Sume l += len; 1088122108Sume 1089122108Sume len = sizeof(struct sadb_x_sa2); 1090122108Sume m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1091122108Sume m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1092122108Sume m_sa2.sadb_x_sa2_mode = p_mode; 1093122108Sume m_sa2.sadb_x_sa2_reqid = p_reqid; 1094122108Sume 1095122108Sume memcpy(buf + l, &m_sa2, len); 1096122108Sume l += len; 1097122108Sume 1098122108Sume l0 = l; 1099122108Sume n = 0; 1100122108Sume 1101122108Sume /* do it for all src/dst pairs */ 1102122108Sume for (s = srcs; s; s = s->ai_next) { 1103122108Sume for (d = dsts; d; d = d->ai_next) { 1104122108Sume /* rewind pointer */ 1105122108Sume l = l0; 1106122108Sume 1107122108Sume if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1108122108Sume continue; 1109122108Sume switch (s->ai_addr->sa_family) { 1110122108Sume case AF_INET: 1111122108Sume plen = sizeof(struct in_addr) << 3; 1112122108Sume break; 111362583Sitojun#ifdef INET6 1114122108Sume case AF_INET6: 1115122108Sume plen = sizeof(struct in6_addr) << 3; 1116122108Sume break; 111762583Sitojun#endif 1118122108Sume default: 1119122108Sume continue; 1120122108Sume } 112155505Sshin 1122122108Sume /* set src */ 1123122108Sume sa = s->ai_addr; 1124122108Sume salen = s->ai_addr->sa_len; 1125122108Sume m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1126122108Sume PFKEY_ALIGN8(salen)); 1127122108Sume m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1128122108Sume m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1129122108Sume m_addr.sadb_address_prefixlen = plen; 1130122108Sume m_addr.sadb_address_reserved = 0; 113155505Sshin 1132122108Sume setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1133122108Sume sizeof(m_addr), (caddr_t)sa, salen); 1134122108Sume 1135122108Sume /* set dst */ 1136122108Sume sa = d->ai_addr; 1137122108Sume salen = d->ai_addr->sa_len; 1138122108Sume m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1139122108Sume PFKEY_ALIGN8(salen)); 1140122108Sume m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1141122108Sume m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1142122108Sume m_addr.sadb_address_prefixlen = plen; 1143122108Sume m_addr.sadb_address_reserved = 0; 1144122108Sume 1145122108Sume setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1146122108Sume sizeof(m_addr), (caddr_t)sa, salen); 1147122108Sume 1148122108Sume msg->sadb_msg_len = PFKEY_UNIT64(l); 1149122108Sume 1150122108Sume sendkeymsg(buf, l); 1151122108Sume 1152122108Sume n++; 115362583Sitojun } 115455505Sshin } 115555505Sshin 1156122108Sume if (n == 0) 1157122108Sume return -1; 1158122108Sume else 1159122108Sume return 0; 116055505Sshin} 116155505Sshin 116262583Sitojunstatic struct addrinfo * 1163122108Sumeparse_addr(host, port) 116462583Sitojun char *host; 116562583Sitojun char *port; 116662583Sitojun{ 116762583Sitojun struct addrinfo hints, *res = NULL; 116862583Sitojun int error; 116962583Sitojun 117062583Sitojun memset(&hints, 0, sizeof(hints)); 1171122108Sume hints.ai_family = p_aifamily; 1172122108Sume hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 1173122108Sume hints.ai_protocol = IPPROTO_UDP; /*dummy*/ 1174122108Sume hints.ai_flags = p_aiflags; 117562583Sitojun error = getaddrinfo(host, port, &hints, &res); 117662583Sitojun if (error != 0) { 117762583Sitojun yyerror(gai_strerror(error)); 117862583Sitojun return NULL; 117962583Sitojun } 118062583Sitojun return res; 118162583Sitojun} 118262583Sitojun 118355505Sshinstatic int 1184122108Sumefix_portstr(spec, sport, dport) 1185122108Sume vchar_t *spec, *sport, *dport; 1186122108Sume{ 1187122108Sume char *p, *p2; 1188122108Sume u_int l; 1189122108Sume 1190122108Sume l = 0; 1191122108Sume for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++) 1192122108Sume ; 1193122108Sume if (*p == '\0') { 1194122108Sume p2 = "0"; 1195122108Sume } else { 1196122108Sume if (*p == ',') { 1197122108Sume *p = '\0'; 1198122108Sume p2 = ++p; 1199122108Sume } 1200122108Sume for (p = p2; *p != '\0' && l < spec->len; p++, l++) 1201122108Sume ; 1202122108Sume if (*p != '\0' || *p2 == '\0') { 1203122108Sume yyerror("invalid an upper layer protocol spec"); 1204122108Sume return -1; 1205122108Sume } 1206122108Sume } 1207122108Sume 1208122108Sume sport->buf = strdup(spec->buf); 1209122108Sume if (!sport->buf) { 1210122108Sume yyerror("insufficient memory"); 1211122108Sume return -1; 1212122108Sume } 1213122108Sume sport->len = strlen(sport->buf); 1214122108Sume dport->buf = strdup(p2); 1215122108Sume if (!dport->buf) { 1216122108Sume yyerror("insufficient memory"); 1217122108Sume return -1; 1218122108Sume } 1219122108Sume dport->len = strlen(dport->buf); 1220122108Sume 1221122108Sume return 0; 1222122108Sume} 1223122108Sume 1224122108Sumestatic int 1225122108Sumesetvarbuf(buf, off, ebuf, elen, vbuf, vlen) 1226122108Sume char *buf; 1227122108Sume int *off; 1228122108Sume struct sadb_ext *ebuf; 1229122108Sume int elen; 123055505Sshin caddr_t vbuf; 1231122108Sume int vlen; 123255505Sshin{ 1233122108Sume memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 1234122108Sume memcpy(buf + *off, (caddr_t)ebuf, elen); 1235122108Sume memcpy(buf + *off + elen, vbuf, vlen); 123655505Sshin (*off) += PFKEY_ALIGN8(elen + vlen); 123755505Sshin 123855505Sshin return 0; 123955505Sshin} 124055505Sshin 124155505Sshinvoid 124255505Sshinparse_init() 124355505Sshin{ 124455505Sshin p_spi = 0; 124555505Sshin 124662583Sitojun p_ext = SADB_X_EXT_CYCSEQ; 124755505Sshin p_alg_enc = SADB_EALG_NONE; 124855505Sshin p_alg_auth = SADB_AALG_NONE; 124955505Sshin p_mode = IPSEC_MODE_ANY; 125062583Sitojun p_reqid = 0; 125162583Sitojun p_replay = 0; 125255505Sshin p_key_enc_len = p_key_auth_len = 0; 125355505Sshin p_key_enc = p_key_auth = 0; 125455505Sshin p_lt_hard = p_lt_soft = 0; 125555505Sshin 1256122108Sume p_aiflags = 0; 1257122108Sume p_aifamily = PF_UNSPEC; 125855505Sshin 125955505Sshin return; 126055505Sshin} 126155505Sshin 126255505Sshinvoid 126355505Sshinfree_buffer() 126455505Sshin{ 1265122108Sume /* we got tons of memory leaks in the parser anyways, leave them */ 126655505Sshin 126755505Sshin return; 126855505Sshin} 1269