summaryrefslogtreecommitdiffstats
path: root/sbin/setkey/parse.y
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-11-05 09:47:54 +0000
committerume <ume@FreeBSD.org>2003-11-05 09:47:54 +0000
commit832d3f0af5caaf598c2d5fad02933d42fad01078 (patch)
treef650d6c8624acdedbc28ef079442ba99097fdba0 /sbin/setkey/parse.y
parent1b0d2b237ef5dc12f3fb211efc7b75ca8569ceea (diff)
downloadFreeBSD-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.y1382
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;
}
-
OpenPOWER on IntegriCloud