diff options
author | ume <ume@FreeBSD.org> | 2003-11-05 09:47:54 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2003-11-05 09:47:54 +0000 |
commit | 832d3f0af5caaf598c2d5fad02933d42fad01078 (patch) | |
tree | f650d6c8624acdedbc28ef079442ba99097fdba0 /sbin/setkey/parse.y | |
parent | 1b0d2b237ef5dc12f3fb211efc7b75ca8569ceea (diff) | |
download | FreeBSD-src-832d3f0af5caaf598c2d5fad02933d42fad01078.zip FreeBSD-src-832d3f0af5caaf598c2d5fad02933d42fad01078.tar.gz |
- do hexdump on send. set length field properly
- check for encryption/authentication key together with algorithm.
- warned if a deprecated encryption algorithm (that includes "simple")
is specified.
- changed the syntax how to define a policy of a ICMPv6 type and/or a
code, like spdadd ::/0 ::/0 icmp6 134,0 -P out none;
- random cleanup in parser.
- use yyfatal, or return -1 after yyerror.
- deal with strdup() failure.
- permit scope notation in policy string (-P
esp/tunnel/foo%scope-bar%scope/use)
- simplify /prefix and [port].
- g/c some unused symbols.
Obtained from: KAME
Diffstat (limited to 'sbin/setkey/parse.y')
-rw-r--r-- | sbin/setkey/parse.y | 1382 |
1 files changed, 848 insertions, 534 deletions
diff --git a/sbin/setkey/parse.y b/sbin/setkey/parse.y index 1d43dc4..80b9d17 100644 --- a/sbin/setkey/parse.y +++ b/sbin/setkey/parse.y @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $KAME: kame/kame/kame/setkey/parse.y,v 1.36 2001/06/07 15:53:12 sakane Exp $ */ +/* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. @@ -53,40 +53,32 @@ #include "vchar.h" #define ATOX(c) \ - (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) + (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10))) -u_int p_type; u_int32_t p_spi; -int p_no_spi; -struct sockaddr *p_src, *p_dst; -u_int p_prefs, p_prefd, p_upper; -u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; +u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; u_int32_t p_reqid; u_int p_key_enc_len, p_key_auth_len; caddr_t p_key_enc, p_key_auth; time_t p_lt_hard, p_lt_soft; -u_int p_policy_len; -char *p_policy; +static int p_aiflags = 0, p_aifamily = PF_UNSPEC; -/* temporary buffer */ -static struct sockaddr *pp_addr; -static u_int pp_prefix; -static u_int pp_port; -static caddr_t pp_key; - -extern u_char m_buf[BUFSIZ]; -extern int m_len; -extern char cmdarg[8192]; -extern int f_debug; - -static struct addrinfo *parse_addr __P((char *, char *, int)); -static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int)); +static struct addrinfo *parse_addr __P((char *, char *)); +static int fix_portstr __P((vchar_t *, vchar_t *, vchar_t *)); +static int setvarbuf __P((char *, int *, struct sadb_ext *, int, caddr_t, int)); void parse_init __P((void)); void free_buffer __P((void)); -extern int setkeymsg __P((void)); -extern int sendkeymsg __P((void)); +int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t)); +static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *, + struct addrinfo *, int, struct addrinfo *, int)); +static int setkeymsg_addr __P((unsigned int, unsigned int, + struct addrinfo *, struct addrinfo *, int)); +static int setkeymsg_add __P((unsigned int, unsigned int, + struct addrinfo *, struct addrinfo *)); +extern int setkeymsg __P((char *, size_t *)); +extern int sendkeymsg __P((char *, size_t)); extern int yylex __P((void)); extern void yyfatal __P((const char *)); @@ -94,43 +86,48 @@ extern void yyerror __P((const char *)); %} %union { - unsigned long num; + int num; + unsigned long ulnum; vchar_t val; + struct addrinfo *res; } -%token EOT -%token ADD GET DELETE FLUSH DUMP -%token ADDRESS PREFIX PORT PORTANY -%token UP_PROTO PR_ESP PR_AH PR_IPCOMP +%token EOT SLASH BLCL ELCL +%token ADD GET DELETE DELETEALL FLUSH DUMP +%token PR_ESP PR_AH PR_IPCOMP %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI %token F_MODE MODE F_REQID %token F_EXT EXTENSION NOCYCLICSEQ -%token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP +%token ALG_AUTH ALG_AUTH_NOKEY +%token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD +%token ALG_COMP %token F_LIFETIME_HARD F_LIFETIME_SOFT %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY /* SPD management */ %token SPDADD SPDDELETE SPDDUMP SPDFLUSH %token F_POLICY PL_REQUESTS - -%type <num> PORT PREFIX EXTENSION MODE -%type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP -%type <num> ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP -%type <num> DECSTRING -%type <val> ADDRESS PL_REQUESTS -%type <val> key_string policy_requests +%token F_AIFLAGS +%token TAGGED + +%type <num> prefix protocol_spec upper_spec +%type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY +%type <num> ALG_AUTH ALG_AUTH_NOKEY +%type <num> ALG_COMP +%type <num> PR_ESP PR_AH PR_IPCOMP +%type <num> EXTENSION MODE +%type <ulnum> DECSTRING +%type <val> PL_REQUESTS portstr key_string +%type <val> policy_requests %type <val> QUOTEDSTRING HEXSTRING STRING +%type <val> F_AIFLAGS +%type <val> upper_misc_spec policy_spec +%type <res> ipaddr %% commands : /*NOTHING*/ | commands command { - if (f_debug) { - printf("cmdarg:\n%s\n", cmdarg); - } else { - setkeymsg(); - sendkeymsg(); - } free_buffer(); parse_init(); } @@ -152,66 +149,90 @@ command /* add command */ add_command - : ADD { p_type = SADB_ADD; } - sa_selector_spec extension_spec algorithm_spec EOT + : ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT + { + int status; + + status = setkeymsg_add(SADB_ADD, $5, $3, $4); + if (status < 0) + return -1; + } ; /* delete */ delete_command - : DELETE { p_type = SADB_DELETE; } - sa_selector_spec extension_spec + : DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT { + int status; + + if ($3->ai_next || $4->ai_next) { + yyerror("multiple address specified"); + return -1; + } if (p_mode != IPSEC_MODE_ANY) - yyerror("WARNING: mode is obsoleted."); + yyerror("WARNING: mode is obsolete"); + + status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0); + if (status < 0) + return -1; } - EOT ; /* deleteall command */ deleteall_command - : DELETEALL { p_type = SADB_DELETE; } - ipaddress { p_src = pp_addr; } - ipaddress { p_dst = pp_addr; } - protocol_spec - { p_no_spi = 1; } - EOT + : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT + { + int status; + + status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1); + if (status < 0) + return -1; + } ; /* get command */ get_command - : GET { p_type = SADB_GET; } - sa_selector_spec extension_spec + : GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT { + int status; + if (p_mode != IPSEC_MODE_ANY) - yyerror("WARNING: mode is obsoleted."); + yyerror("WARNING: mode is obsolete"); + + status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0); + if (status < 0) + return -1; } - EOT ; /* flush */ flush_command - : FLUSH { p_type = SADB_FLUSH; } - protocol_spec EOT + : FLUSH protocol_spec EOT + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } ; /* dump */ dump_command - : DUMP { p_type = SADB_DUMP; } - protocol_spec EOT - ; - - /* sa_selector_spec */ -sa_selector_spec - : ipaddress { p_src = pp_addr; } - ipaddress { p_dst = pp_addr; } - protocol_spec spi + : DUMP protocol_spec EOT + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } ; protocol_spec - : /*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; } + : /*NOTHING*/ + { + $$ = SADB_SATYPE_UNSPEC; + } | PR_ESP { - p_satype = SADB_SATYPE_ESP; + $$ = SADB_SATYPE_ESP; if ($1 == 1) p_ext |= SADB_X_EXT_OLD; else @@ -219,7 +240,7 @@ protocol_spec } | PR_AH { - p_satype = SADB_SATYPE_AH; + $$ = SADB_SATYPE_AH; if ($1 == 1) p_ext |= SADB_X_EXT_OLD; else @@ -227,7 +248,7 @@ protocol_spec } | PR_IPCOMP { - p_satype = SADB_X_SATYPE_IPCOMP; + $$ = SADB_X_SATYPE_IPCOMP; } ; @@ -235,34 +256,21 @@ spi : DECSTRING { p_spi = $1; } | HEXSTRING { - caddr_t bp; - caddr_t yp = $1.buf; - char buf0[4], buf[4]; - int i, j; + char *ep; + unsigned long v; - /* sanity check */ - if ($1.len > 4) { - yyerror("SPI too big."); - free($1.buf); + ep = NULL; + v = strtoul($1.buf, &ep, 16); + if (!ep || *ep) { + yyerror("invalid SPI"); return -1; } - - bp = buf0; - while (*yp) { - *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); - yp += 2, bp++; + if (v & ~0xffffffff) { + yyerror("SPI too big."); + return -1; } - /* initialize */ - for (i = 0; i < 4; i++) buf[i] = 0; - - for (j = $1.len - 1, i = 3; j >= 0; j--, i--) - buf[i] = buf0[j]; - - /* XXX: endian */ - p_spi = ntohl(*(u_int32_t *)buf); - - free($1.buf); + p_spi = v; } ; @@ -273,58 +281,109 @@ algorithm_spec ; esp_spec - : F_ENC enc_alg enc_key F_AUTH auth_alg auth_key - | F_ENC enc_alg enc_key + : F_ENC enc_alg F_AUTH auth_alg + | F_ENC enc_alg ; ah_spec - : F_AUTH auth_alg auth_key + : F_AUTH auth_alg ; ipcomp_spec - : F_COMP ALG_COMP { p_alg_enc = $2; } - | F_COMP ALG_COMP { p_alg_enc = $2; } - F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; } + : F_COMP ALG_COMP + { + if ($2 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $2; + } + | F_COMP ALG_COMP F_RAWCPI + { + if ($2 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $2; + p_ext |= SADB_X_EXT_RAWCPI; + } ; enc_alg - : ALG_ENC { p_alg_enc = $1; } - | ALG_ENC_DESDERIV - { - p_alg_enc = $1; - if (p_ext & SADB_X_EXT_OLD) { - yyerror("algorithm mismatched."); + : ALG_ENC_NOKEY { + if ($1 < 0) { + yyerror("unsupported algorithm"); return -1; } - p_ext |= SADB_X_EXT_DERIV; + p_alg_enc = $1; + + p_key_enc_len = 0; + p_key_enc = NULL; } - | ALG_ENC_DES32IV - { + | ALG_ENC key_string { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } p_alg_enc = $1; - if (!(p_ext & SADB_X_EXT_OLD)) { - yyerror("algorithm mismatched."); + + p_key_enc_len = $2.len; + p_key_enc = $2.buf; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); return -1; } - p_ext |= SADB_X_EXT_IV4B; } - ; + | ALG_ENC_OLD { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + yyerror("WARNING: obsolete algorithm"); + p_alg_enc = $1; -enc_key - : /*NOTHING*/ + p_key_enc_len = 0; + p_key_enc = NULL; + } + | ALG_ENC_DESDERIV key_string { - if (p_alg_enc != SADB_EALG_NULL) { - yyerror("no key found."); + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $1; + if (p_ext & SADB_X_EXT_OLD) { + yyerror("algorithm mismatched"); + return -1; + } + p_ext |= SADB_X_EXT_DERIV; + + p_key_enc_len = $2.len; + p_key_enc = $2.buf; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); return -1; } } - | key_string + | ALG_ENC_DES32IV key_string { - p_key_enc_len = $1.len; - p_key_enc = pp_key; + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $1; + if (!(p_ext & SADB_X_EXT_OLD)) { + yyerror("algorithm mismatched"); + return -1; + } + p_ext |= SADB_X_EXT_IV4B; + p_key_enc_len = $2.len; + p_key_enc = $2.buf; if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, - p_alg_enc, - PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { yyerror(ipsec_strerror()); return -1; } @@ -332,56 +391,64 @@ enc_key ; auth_alg - : ALG_AUTH { p_alg_auth = $1; } - ; - -auth_key - : /*NOTHING*/ - { - if (p_alg_auth != SADB_X_AALG_NULL) { - yyerror("no key found."); + : ALG_AUTH key_string { + if ($1 < 0) { + yyerror("unsupported algorithm"); return -1; } - } - | key_string - { - p_key_auth_len = $1.len; - p_key_auth = pp_key; + p_alg_auth = $1; + p_key_auth_len = $2.len; + p_key_auth = $2.buf; if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, - p_alg_auth, - PFKEY_UNUNIT64(p_key_auth_len)) < 0) { + p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { yyerror(ipsec_strerror()); return -1; } } + | ALG_AUTH_NOKEY { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_auth = $1; + + p_key_auth_len = 0; + p_key_auth = NULL; + } ; key_string : QUOTEDSTRING { - pp_key = $1.buf; - /* free pp_key later */ + $$ = $1; } | HEXSTRING { + caddr_t pp_key; caddr_t bp; caddr_t yp = $1.buf; + int l; - if ((pp_key = malloc($1.len)) == 0) { - free($1.buf); + l = strlen(yp) % 2 + strlen(yp) / 2; + if ((pp_key = malloc(l)) == 0) { yyerror("not enough core"); return -1; } - memset(pp_key, 0, $1.len); + memset(pp_key, 0, l); bp = pp_key; + if (strlen(yp) % 2) { + *bp = ATOX(yp[0]); + yp++, bp++; + } while (*yp) { *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); yp += 2, bp++; } - free($1.buf); + $$.len = l; + $$.buf = pp_key; } ; @@ -398,9 +465,9 @@ extension | F_REQID DECSTRING { p_reqid = $2; } | F_REPLAY DECSTRING { - if (p_ext & SADB_X_EXT_OLD) { - yyerror("replay prevention " - "only use on new spec."); + if ((p_ext & SADB_X_EXT_OLD) != 0) { + yyerror("replay prevention cannot be used with " + "ah/esp-old"); return -1; } p_replay = $2; @@ -412,183 +479,241 @@ extension /* definition about command for SPD management */ /* spdadd */ spdadd_command - : SPDADD + : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT { - p_type = SADB_X_SPDADD; - p_satype = SADB_SATYPE_UNSPEC; + int status; + struct addrinfo *src, *dst; + + /* fixed port fields if ulp is icmpv6 */ + if ($10.buf != NULL) { + if ($9 != IPPROTO_ICMPV6) + return -1; + free($5.buf); + free($8.buf); + if (fix_portstr(&$10, &$5, &$8)) + return -1; + } + + src = parse_addr($3.buf, $5.buf); + dst = parse_addr($6.buf, $8.buf); + if (!src || !dst) { + /* yyerror is already called */ + return -1; + } + if (src->ai_next || dst->ai_next) { + yyerror("multiple address specified"); + freeaddrinfo(src); + freeaddrinfo(dst); + return -1; + } + + status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11, + src, $4, dst, $7); + freeaddrinfo(src); + freeaddrinfo(dst); + if (status < 0) + return -1; + } + | SPDADD TAGGED QUOTEDSTRING policy_spec EOT + { + return -1; } - sp_selector_spec policy_spec EOT ; -spddelete_command: - SPDDELETE +spddelete_command + : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT { - p_type = SADB_X_SPDDELETE; - p_satype = SADB_SATYPE_UNSPEC; + int status; + struct addrinfo *src, *dst; + + /* fixed port fields if ulp is icmpv6 */ + if ($10.buf != NULL) { + if ($9 != IPPROTO_ICMPV6) + return -1; + free($5.buf); + free($8.buf); + if (fix_portstr(&$10, &$5, &$8)) + return -1; + } + + src = parse_addr($3.buf, $5.buf); + dst = parse_addr($6.buf, $8.buf); + if (!src || !dst) { + /* yyerror is already called */ + return -1; + } + if (src->ai_next || dst->ai_next) { + yyerror("multiple address specified"); + freeaddrinfo(src); + freeaddrinfo(dst); + return -1; + } + + status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11, + src, $4, dst, $7); + freeaddrinfo(src); + freeaddrinfo(dst); + if (status < 0) + return -1; } - sp_selector_spec policy_spec EOT ; spddump_command: - SPDDUMP + SPDDUMP EOT { - p_type = SADB_X_SPDDUMP; - p_satype = SADB_SATYPE_UNSPEC; + struct sadb_msg msg; + setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, + sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); } - EOT ; spdflush_command: - SPDFLUSH + SPDFLUSH EOT { - p_type = SADB_X_SPDFLUSH; - p_satype = SADB_SATYPE_UNSPEC; + struct sadb_msg msg; + setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, + sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); } - EOT ; - /* sp_selector_spec */ -sp_selector_spec - : ipaddress { p_src = pp_addr; } - prefix { p_prefs = pp_prefix; } - port - { - switch (p_src->sa_family) { - case AF_INET: - ((struct sockaddr_in *)p_src)->sin_port = - htons(pp_port); - break; -#ifdef INET6 - case AF_INET6: - ((struct sockaddr_in6 *)p_src)->sin6_port = - htons(pp_port); - break; -#endif - default: - exit(1); /*XXX*/ - } - } - ipaddress { p_dst = pp_addr; } - prefix { p_prefd = pp_prefix; } - port +ipaddropts + : /* nothing */ + | ipaddropts ipaddropt + ; + +ipaddropt + : F_AIFLAGS { - switch (p_dst->sa_family) { - case AF_INET: - ((struct sockaddr_in *)p_dst)->sin_port = - htons(pp_port); - break; + char *p; + + for (p = $1.buf + 1; *p; p++) + switch (*p) { + case '4': + p_aifamily = AF_INET; + break; #ifdef INET6 - case AF_INET6: - ((struct sockaddr_in6 *)p_dst)->sin6_port = - htons(pp_port); - break; + case '6': + p_aifamily = AF_INET6; + break; #endif - default: - exit(1); /*XXX*/ - } - } - upper_spec - { - /* XXX is it something userland should check? */ -#if 0 - switch (p_upper) { - case IPPROTO_ICMP: - case IPPROTO_ICMPV6: - if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY - || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) { - yyerror("port number must be \"any\"."); + case 'n': + p_aiflags = AI_NUMERICHOST; + break; + default: + yyerror("invalid flag"); return -1; } - if ((pp_addr->sa_family == AF_INET6 - && p_upper == IPPROTO_ICMP) - || (pp_addr->sa_family == AF_INET - && p_upper == IPPROTO_ICMPV6)) { - yyerror("upper layer protocol " - "mismatched.\n"); - return -1; - } - break; - default: - break; - } -#endif } ; -ipaddress - : ADDRESS +ipaddr + : STRING { - struct addrinfo *res; - - res = parse_addr($1.buf, NULL, AI_NUMERICHOST); - if (res == NULL) { - free($1.buf); + $$ = parse_addr($1.buf, NULL); + if ($$ == NULL) { + /* yyerror already called by parse_addr */ return -1; } - pp_addr = (struct sockaddr *)malloc(res->ai_addrlen); - if (!pp_addr) { - yyerror("not enough core"); - goto end; - } - - memcpy(pp_addr, res->ai_addr, res->ai_addrlen); - end: - freeaddrinfo(res); - free($1.buf); } ; prefix - : /*NOTHING*/ { pp_prefix = ~0; } - | PREFIX { pp_prefix = $1; } + : /*NOTHING*/ { $$ = -1; } + | SLASH DECSTRING { $$ = $2; } ; -port - : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; } - | PORT { pp_port = $1; } - | PORTANY { pp_port = IPSEC_PORT_ANY; } +portstr + : /*NOTHING*/ + { + $$.buf = strdup("0"); + if (!$$.buf) { + yyerror("insufficient memory"); + return -1; + } + $$.len = strlen($$.buf); + } + | BLCL ANY ELCL + { + $$.buf = strdup("0"); + if (!$$.buf) { + yyerror("insufficient memory"); + return -1; + } + $$.len = strlen($$.buf); + } + | BLCL DECSTRING ELCL + { + char buf[20]; + snprintf(buf, sizeof(buf), "%lu", $2); + $$.buf = strdup(buf); + if (!$$.buf) { + yyerror("insufficient memory"); + return -1; + } + $$.len = strlen($$.buf); + } + | BLCL STRING ELCL + { + $$ = $2; + } ; upper_spec - : DECSTRING { p_upper = $1; } - | UP_PROTO { p_upper = $1; } - | ANY { p_upper = IPSEC_ULPROTO_ANY; } + : DECSTRING { $$ = $1; } + | ANY { $$ = IPSEC_ULPROTO_ANY; } | STRING { struct protoent *ent; ent = getprotobyname($1.buf); if (ent) - p_upper = ent->p_proto; + $$ = ent->p_proto; else { if (strcmp("icmp6", $1.buf) == 0) { - p_upper = IPPROTO_ICMPV6; + $$ = IPPROTO_ICMPV6; } else if(strcmp("ip4", $1.buf) == 0) { - p_upper = IPPROTO_IPV4; + $$ = IPPROTO_IPV4; } else { yyerror("invalid upper layer protocol"); - free($1.buf); return -1; } } - free($1.buf); + endprotoent(); + } + ; + +upper_misc_spec + : /*NOTHING*/ + { + $$.buf = NULL; + $$.len = 0; + } + | STRING + { + $$.buf = strdup($1.buf); + if (!$$.buf) { + yyerror("insufficient memory"); + return -1; + } + $$.len = strlen($$.buf); } ; policy_spec : F_POLICY policy_requests { - p_policy = ipsec_set_policy($2.buf, $2.len); - if (p_policy == NULL) { - free($2.buf); - p_policy = NULL; + char *policy; + + policy = ipsec_set_policy($2.buf, $2.len); + if (policy == NULL) { yyerror(ipsec_strerror()); return -1; } - p_policy_len = ipsec_get_policylen(p_policy); - - free($2.buf); + $$.buf = policy; + $$.len = ipsec_get_policylen(policy); } ; @@ -599,291 +724,494 @@ policy_requests %% int -setkeymsg() +setkeymsg0(msg, type, satype, l) + struct sadb_msg *msg; + unsigned int type; + unsigned int satype; + size_t l; { - struct sadb_msg m_msg; - - m_msg.sadb_msg_version = PF_KEY_V2; - m_msg.sadb_msg_type = p_type; - m_msg.sadb_msg_errno = 0; - m_msg.sadb_msg_satype = p_satype; - m_msg.sadb_msg_reserved = 0; - m_msg.sadb_msg_seq = 0; - m_msg.sadb_msg_pid = getpid(); - - m_len = sizeof(struct sadb_msg); - memcpy(m_buf, &m_msg, m_len); - - switch (p_type) { - case SADB_FLUSH: - case SADB_DUMP: - break; - - case SADB_ADD: - /* set encryption algorithm, if present. */ - if (p_satype != SADB_X_SATYPE_IPCOMP && p_alg_enc != SADB_EALG_NONE) { - struct sadb_key m_key; - - m_key.sadb_key_len = - PFKEY_UNIT64(sizeof(m_key) - + PFKEY_ALIGN8(p_key_enc_len)); - m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; - m_key.sadb_key_bits = p_key_enc_len * 8; - m_key.sadb_key_reserved = 0; - - setvarbuf(&m_len, - (struct sadb_ext *)&m_key, sizeof(m_key), - (caddr_t)p_key_enc, p_key_enc_len); - } - - /* set authentication algorithm, if present. */ - if (p_alg_auth != SADB_AALG_NONE) { - struct sadb_key m_key; - - m_key.sadb_key_len = - PFKEY_UNIT64(sizeof(m_key) - + PFKEY_ALIGN8(p_key_auth_len)); - m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; - m_key.sadb_key_bits = p_key_auth_len * 8; - m_key.sadb_key_reserved = 0; - - setvarbuf(&m_len, - (struct sadb_ext *)&m_key, sizeof(m_key), - (caddr_t)p_key_auth, p_key_auth_len); - } - - /* set lifetime for HARD */ - if (p_lt_hard != 0) { - struct sadb_lifetime m_lt; - u_int len = sizeof(struct sadb_lifetime); - - m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); - m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; - m_lt.sadb_lifetime_allocations = 0; - m_lt.sadb_lifetime_bytes = 0; - m_lt.sadb_lifetime_addtime = p_lt_hard; - m_lt.sadb_lifetime_usetime = 0; - - memcpy(m_buf + m_len, &m_lt, len); - m_len += len; - } - - /* set lifetime for SOFT */ - if (p_lt_soft != 0) { - struct sadb_lifetime m_lt; - u_int len = sizeof(struct sadb_lifetime); - - m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); - m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; - m_lt.sadb_lifetime_allocations = 0; - m_lt.sadb_lifetime_bytes = 0; - m_lt.sadb_lifetime_addtime = p_lt_soft; - m_lt.sadb_lifetime_usetime = 0; - - memcpy(m_buf + m_len, &m_lt, len); - m_len += len; - } - /* FALLTHROUGH */ - - case SADB_DELETE: - case SADB_GET: - { - struct sadb_sa m_sa; - struct sadb_x_sa2 m_sa2; - struct sadb_address m_addr; - u_int len; - - if (p_no_spi == 0) { - len = sizeof(struct sadb_sa); - m_sa.sadb_sa_len = PFKEY_UNIT64(len); - m_sa.sadb_sa_exttype = SADB_EXT_SA; - m_sa.sadb_sa_spi = htonl(p_spi); - m_sa.sadb_sa_replay = p_replay; - m_sa.sadb_sa_state = 0; - m_sa.sadb_sa_auth = p_alg_auth; - m_sa.sadb_sa_encrypt = p_alg_enc; - m_sa.sadb_sa_flags = p_ext; - - memcpy(m_buf + m_len, &m_sa, len); - m_len += len; - - len = sizeof(struct sadb_x_sa2); - m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); - m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; - m_sa2.sadb_x_sa2_mode = p_mode; - m_sa2.sadb_x_sa2_reqid = p_reqid; - - memcpy(m_buf + m_len, &m_sa2, len); - m_len += len; - } - - /* set src */ - m_addr.sadb_address_len = - PFKEY_UNIT64(sizeof(m_addr) - + PFKEY_ALIGN8(p_src->sa_len)); - m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; - m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; - switch (p_src->sa_family) { - case AF_INET: - m_addr.sadb_address_prefixlen = - sizeof(struct in_addr) << 3; - break; + + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = type; + msg->sadb_msg_errno = 0; + msg->sadb_msg_satype = satype; + msg->sadb_msg_reserved = 0; + msg->sadb_msg_seq = 0; + msg->sadb_msg_pid = getpid(); + msg->sadb_msg_len = PFKEY_UNIT64(l); + return 0; +} + +/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ +static int +setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) + unsigned int type; + unsigned int upper; + vchar_t *policy; + struct addrinfo *srcs; + int splen; + struct addrinfo *dsts; + int dplen; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0; + struct sadb_address m_addr; + struct addrinfo *s, *d; + int n; + int plen; + struct sockaddr *sa; + int salen; + + msg = (struct sadb_msg *)buf; + + if (!srcs || !dsts) + return -1; + + /* fix up length afterwards */ + setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); + l = sizeof(struct sadb_msg); + + memcpy(buf + l, policy->buf, policy->len); + l += policy->len; + + l0 = l; + n = 0; + + /* do it for all src/dst pairs */ + for (s = srcs; s; s = s->ai_next) { + for (d = dsts; d; d = d->ai_next) { + /* rewind pointer */ + l = l0; + + if (s->ai_addr->sa_family != d->ai_addr->sa_family) + continue; + switch (s->ai_addr->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; #ifdef INET6 - case AF_INET6: - m_addr.sadb_address_prefixlen = - sizeof(struct in6_addr) << 3; - break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; #endif - default: - yyerror("unsupported address family"); - exit(1); /*XXX*/ - } - m_addr.sadb_address_reserved = 0; - - setvarbuf(&m_len, - (struct sadb_ext *)&m_addr, sizeof(m_addr), - (caddr_t)p_src, p_src->sa_len); - - /* set dst */ - m_addr.sadb_address_len = - PFKEY_UNIT64(sizeof(m_addr) - + PFKEY_ALIGN8(p_dst->sa_len)); - m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; - m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; - switch (p_dst->sa_family) { - case AF_INET: + default: + continue; + } + + /* set src */ + sa = s->ai_addr; + salen = s->ai_addr->sa_len; + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + m_addr.sadb_address_proto = upper; m_addr.sadb_address_prefixlen = - sizeof(struct in_addr) << 3; - break; -#ifdef INET6 - case AF_INET6: + (splen >= 0 ? splen : plen); + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), (caddr_t)sa, salen); + + /* set dst */ + sa = d->ai_addr; + salen = d->ai_addr->sa_len; + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + m_addr.sadb_address_proto = upper; m_addr.sadb_address_prefixlen = - sizeof(struct in6_addr) << 3; - break; -#endif - default: - yyerror("unsupported address family"); - exit(1); /*XXX*/ - } - m_addr.sadb_address_reserved = 0; - - setvarbuf(&m_len, - (struct sadb_ext *)&m_addr, sizeof(m_addr), - (caddr_t)p_dst, p_dst->sa_len); - } - break; - - /* for SPD management */ - case SADB_X_SPDFLUSH: - case SADB_X_SPDDUMP: - break; - - case SADB_X_SPDADD: - case SADB_X_SPDDELETE: - { - struct sadb_address m_addr; - u_int8_t plen; - - memcpy(m_buf + m_len, p_policy, p_policy_len); - m_len += p_policy_len; - free(p_policy); - p_policy = NULL; - - /* set src */ - m_addr.sadb_address_len = - PFKEY_UNIT64(sizeof(m_addr) - + PFKEY_ALIGN8(p_src->sa_len)); - m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; - m_addr.sadb_address_proto = p_upper; - switch (p_src->sa_family) { - case AF_INET: - plen = sizeof(struct in_addr) << 3; - break; + (dplen >= 0 ? dplen : plen); + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), (caddr_t)sa, salen); + + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + + n++; + } + } + + if (n == 0) + return -1; + else + return 0; +} + +/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ +static int +setkeymsg_addr(type, satype, srcs, dsts, no_spi) + unsigned int type; + unsigned int satype; + struct addrinfo *srcs; + struct addrinfo *dsts; + int no_spi; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0, len; + struct sadb_sa m_sa; + struct sadb_x_sa2 m_sa2; + struct sadb_address m_addr; + struct addrinfo *s, *d; + int n; + int plen; + struct sockaddr *sa; + int salen; + + msg = (struct sadb_msg *)buf; + + if (!srcs || !dsts) + return -1; + + /* fix up length afterwards */ + setkeymsg0(msg, type, satype, 0); + l = sizeof(struct sadb_msg); + + if (!no_spi) { + len = sizeof(struct sadb_sa); + m_sa.sadb_sa_len = PFKEY_UNIT64(len); + m_sa.sadb_sa_exttype = SADB_EXT_SA; + m_sa.sadb_sa_spi = htonl(p_spi); + m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_state = 0; + m_sa.sadb_sa_auth = p_alg_auth; + m_sa.sadb_sa_encrypt = p_alg_enc; + m_sa.sadb_sa_flags = p_ext; + + memcpy(buf + l, &m_sa, len); + l += len; + + len = sizeof(struct sadb_x_sa2); + m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); + m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; + m_sa2.sadb_x_sa2_mode = p_mode; + m_sa2.sadb_x_sa2_reqid = p_reqid; + + memcpy(buf + l, &m_sa2, len); + l += len; + } + + l0 = l; + n = 0; + + /* do it for all src/dst pairs */ + for (s = srcs; s; s = s->ai_next) { + for (d = dsts; d; d = d->ai_next) { + /* rewind pointer */ + l = l0; + + if (s->ai_addr->sa_family != d->ai_addr->sa_family) + continue; + switch (s->ai_addr->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; #ifdef INET6 - case AF_INET6: - plen = sizeof(struct in6_addr) << 3; - break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; #endif - default: - yyerror("unsupported address family"); - exit(1); /*XXX*/ - } - m_addr.sadb_address_prefixlen = - (p_prefs != ~0 ? p_prefs : plen); - m_addr.sadb_address_reserved = 0; - - setvarbuf(&m_len, - (struct sadb_ext *)&m_addr, sizeof(m_addr), - (caddr_t)p_src, p_src->sa_len); - - /* set dst */ - m_addr.sadb_address_len = - PFKEY_UNIT64(sizeof(m_addr) - + PFKEY_ALIGN8(p_dst->sa_len)); - m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; - m_addr.sadb_address_proto = p_upper; - switch (p_dst->sa_family) { - case AF_INET: - plen = sizeof(struct in_addr) << 3; - break; + default: + continue; + } + + /* set src */ + sa = s->ai_addr; + salen = s->ai_addr->sa_len; + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), (caddr_t)sa, salen); + + /* set dst */ + sa = d->ai_addr; + salen = d->ai_addr->sa_len; + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), (caddr_t)sa, salen); + + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + + n++; + } + } + + if (n == 0) + return -1; + else + return 0; +} + +/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ +static int +setkeymsg_add(type, satype, srcs, dsts) + unsigned int type; + unsigned int satype; + struct addrinfo *srcs; + struct addrinfo *dsts; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0, len; + struct sadb_sa m_sa; + struct sadb_x_sa2 m_sa2; + struct sadb_address m_addr; + struct addrinfo *s, *d; + int n; + int plen; + struct sockaddr *sa; + int salen; + + msg = (struct sadb_msg *)buf; + + if (!srcs || !dsts) + return -1; + + /* fix up length afterwards */ + setkeymsg0(msg, type, satype, 0); + l = sizeof(struct sadb_msg); + + /* set encryption algorithm, if present. */ + if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { + struct sadb_key m_key; + + m_key.sadb_key_len = + PFKEY_UNIT64(sizeof(m_key) + + PFKEY_ALIGN8(p_key_enc_len)); + m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; + m_key.sadb_key_bits = p_key_enc_len * 8; + m_key.sadb_key_reserved = 0; + + setvarbuf(buf, &l, + (struct sadb_ext *)&m_key, sizeof(m_key), + (caddr_t)p_key_enc, p_key_enc_len); + } + + /* set authentication algorithm, if present. */ + if (p_key_auth) { + struct sadb_key m_key; + + m_key.sadb_key_len = + PFKEY_UNIT64(sizeof(m_key) + + PFKEY_ALIGN8(p_key_auth_len)); + m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; + m_key.sadb_key_bits = p_key_auth_len * 8; + m_key.sadb_key_reserved = 0; + + setvarbuf(buf, &l, + (struct sadb_ext *)&m_key, sizeof(m_key), + (caddr_t)p_key_auth, p_key_auth_len); + } + + /* set lifetime for HARD */ + if (p_lt_hard != 0) { + struct sadb_lifetime m_lt; + u_int slen = sizeof(struct sadb_lifetime); + + m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); + m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; + m_lt.sadb_lifetime_allocations = 0; + m_lt.sadb_lifetime_bytes = 0; + m_lt.sadb_lifetime_addtime = p_lt_hard; + m_lt.sadb_lifetime_usetime = 0; + + memcpy(buf + l, &m_lt, slen); + l += len; + } + + /* set lifetime for SOFT */ + if (p_lt_soft != 0) { + struct sadb_lifetime m_lt; + u_int slen = sizeof(struct sadb_lifetime); + + m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); + m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; + m_lt.sadb_lifetime_allocations = 0; + m_lt.sadb_lifetime_bytes = 0; + m_lt.sadb_lifetime_addtime = p_lt_soft; + m_lt.sadb_lifetime_usetime = 0; + + memcpy(buf + l, &m_lt, slen); + l += len; + } + + len = sizeof(struct sadb_sa); + m_sa.sadb_sa_len = PFKEY_UNIT64(len); + m_sa.sadb_sa_exttype = SADB_EXT_SA; + m_sa.sadb_sa_spi = htonl(p_spi); + m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_state = 0; + m_sa.sadb_sa_auth = p_alg_auth; + m_sa.sadb_sa_encrypt = p_alg_enc; + m_sa.sadb_sa_flags = p_ext; + + memcpy(buf + l, &m_sa, len); + l += len; + + len = sizeof(struct sadb_x_sa2); + m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); + m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; + m_sa2.sadb_x_sa2_mode = p_mode; + m_sa2.sadb_x_sa2_reqid = p_reqid; + + memcpy(buf + l, &m_sa2, len); + l += len; + + l0 = l; + n = 0; + + /* do it for all src/dst pairs */ + for (s = srcs; s; s = s->ai_next) { + for (d = dsts; d; d = d->ai_next) { + /* rewind pointer */ + l = l0; + + if (s->ai_addr->sa_family != d->ai_addr->sa_family) + continue; + switch (s->ai_addr->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; #ifdef INET6 - case AF_INET6: - plen = sizeof(struct in6_addr) << 3; - break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; #endif - default: - yyerror("unsupported address family"); - exit(1); /*XXX*/ - } - m_addr.sadb_address_prefixlen = - (p_prefd != ~0 ? p_prefd : plen); - m_addr.sadb_address_reserved = 0; - - setvarbuf(&m_len, - (struct sadb_ext *)&m_addr, sizeof(m_addr), - (caddr_t)p_dst, p_dst->sa_len); - } - break; - } + default: + continue; + } - ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); + /* set src */ + sa = s->ai_addr; + salen = s->ai_addr->sa_len; + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), (caddr_t)sa, salen); + + /* set dst */ + sa = d->ai_addr; + salen = d->ai_addr->sa_len; + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), (caddr_t)sa, salen); + + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + + n++; + } + } - return 0; + if (n == 0) + return -1; + else + return 0; } static struct addrinfo * -parse_addr(host, port, flag) +parse_addr(host, port) char *host; char *port; - int flag; { struct addrinfo hints, *res = NULL; int error; memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = flag; + hints.ai_family = p_aifamily; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_protocol = IPPROTO_UDP; /*dummy*/ + hints.ai_flags = p_aiflags; error = getaddrinfo(host, port, &hints, &res); if (error != 0) { yyerror(gai_strerror(error)); return NULL; } - if (res->ai_next != NULL) { - yyerror(gai_strerror(error)); - } return res; } static int -setvarbuf(off, ebuf, elen, vbuf, vlen) - caddr_t vbuf; +fix_portstr(spec, sport, dport) + vchar_t *spec, *sport, *dport; +{ + char *p, *p2; + u_int l; + + l = 0; + for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++) + ; + if (*p == '\0') { + p2 = "0"; + } else { + if (*p == ',') { + *p = '\0'; + p2 = ++p; + } + for (p = p2; *p != '\0' && l < spec->len; p++, l++) + ; + if (*p != '\0' || *p2 == '\0') { + yyerror("invalid an upper layer protocol spec"); + return -1; + } + } + + sport->buf = strdup(spec->buf); + if (!sport->buf) { + yyerror("insufficient memory"); + return -1; + } + sport->len = strlen(sport->buf); + dport->buf = strdup(p2); + if (!dport->buf) { + yyerror("insufficient memory"); + return -1; + } + dport->len = strlen(dport->buf); + + return 0; +} + +static int +setvarbuf(buf, off, ebuf, elen, vbuf, vlen) + char *buf; + int *off; struct sadb_ext *ebuf; - int *off, elen, vlen; + int elen; + caddr_t vbuf; + int vlen; { - memset(m_buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); - memcpy(m_buf + *off, (caddr_t)ebuf, elen); - memcpy(m_buf + *off + elen, vbuf, vlen); + memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); + memcpy(buf + *off, (caddr_t)ebuf, elen); + memcpy(buf + *off + elen, vbuf, vlen); (*off) += PFKEY_ALIGN8(elen + vlen); return 0; @@ -892,16 +1220,8 @@ setvarbuf(off, ebuf, elen, vbuf, vlen) void parse_init() { - p_type = 0; p_spi = 0; - p_no_spi = 0; - - p_src = 0, p_dst = 0; - pp_prefix = p_prefs = p_prefd = ~0; - pp_port = IPSEC_PORT_ANY; - p_upper = 0; - p_satype = 0; p_ext = SADB_X_EXT_CYCSEQ; p_alg_enc = SADB_EALG_NONE; p_alg_auth = SADB_AALG_NONE; @@ -912,10 +1232,8 @@ parse_init() p_key_enc = p_key_auth = 0; p_lt_hard = p_lt_soft = 0; - p_policy_len = 0; - p_policy = NULL; - - memset(cmdarg, 0, sizeof(cmdarg)); + p_aiflags = 0; + p_aifamily = PF_UNSPEC; return; } @@ -923,11 +1241,7 @@ parse_init() void free_buffer() { - if (p_src) free(p_src); - if (p_dst) free(p_dst); - if (p_key_enc) free(p_key_enc); - if (p_key_auth) free(p_key_auth); + /* we got tons of memory leaks in the parser anyways, leave them */ return; } - |