xref: /freebsd/sbin/setkey/parse.y (revision 2fa1b8617fdf68d0043efb7ae7c524702afba27c)
13c62e87aSJun-ichiro itojun Hagino /*	$FreeBSD$	*/
2d02b24bcSHajimu UMEMOTO /*	$KAME: parse.y,v 1.83 2004/05/18 08:48:23 sakane Exp $	*/
33c62e87aSJun-ichiro itojun Hagino 
48a16b7a1SPedro F. Giffuni /*-
58a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
68a16b7a1SPedro F. Giffuni  *
79a4365d0SYoshinobu Inoue  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
89a4365d0SYoshinobu Inoue  * All rights reserved.
99a4365d0SYoshinobu Inoue  *
109a4365d0SYoshinobu Inoue  * Redistribution and use in source and binary forms, with or without
119a4365d0SYoshinobu Inoue  * modification, are permitted provided that the following conditions
129a4365d0SYoshinobu Inoue  * are met:
139a4365d0SYoshinobu Inoue  * 1. Redistributions of source code must retain the above copyright
149a4365d0SYoshinobu Inoue  *    notice, this list of conditions and the following disclaimer.
159a4365d0SYoshinobu Inoue  * 2. Redistributions in binary form must reproduce the above copyright
169a4365d0SYoshinobu Inoue  *    notice, this list of conditions and the following disclaimer in the
179a4365d0SYoshinobu Inoue  *    documentation and/or other materials provided with the distribution.
189a4365d0SYoshinobu Inoue  * 3. Neither the name of the project nor the names of its contributors
199a4365d0SYoshinobu Inoue  *    may be used to endorse or promote products derived from this software
209a4365d0SYoshinobu Inoue  *    without specific prior written permission.
219a4365d0SYoshinobu Inoue  *
229a4365d0SYoshinobu Inoue  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
239a4365d0SYoshinobu Inoue  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
249a4365d0SYoshinobu Inoue  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
259a4365d0SYoshinobu Inoue  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
269a4365d0SYoshinobu Inoue  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
279a4365d0SYoshinobu Inoue  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
289a4365d0SYoshinobu Inoue  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
299a4365d0SYoshinobu Inoue  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
309a4365d0SYoshinobu Inoue  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
319a4365d0SYoshinobu Inoue  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
329a4365d0SYoshinobu Inoue  * SUCH DAMAGE.
339a4365d0SYoshinobu Inoue  */
349a4365d0SYoshinobu Inoue 
359a4365d0SYoshinobu Inoue %{
369a4365d0SYoshinobu Inoue #include <sys/types.h>
379a4365d0SYoshinobu Inoue #include <sys/param.h>
389a4365d0SYoshinobu Inoue #include <sys/socket.h>
399a4365d0SYoshinobu Inoue 
409a4365d0SYoshinobu Inoue #include <net/route.h>
419a4365d0SYoshinobu Inoue #include <netinet/in.h>
429a4365d0SYoshinobu Inoue #include <net/pfkeyv2.h>
438409aedfSGeorge V. Neville-Neil #include <netipsec/key_var.h>
448409aedfSGeorge V. Neville-Neil #include <netipsec/ipsec.h>
459a4365d0SYoshinobu Inoue #include <arpa/inet.h>
46*2fa1b861SKonstantin Belousov #include <netinet/udp.h>
479a4365d0SYoshinobu Inoue 
489a4365d0SYoshinobu Inoue #include <string.h>
499a4365d0SYoshinobu Inoue #include <unistd.h>
509a4365d0SYoshinobu Inoue #include <stdio.h>
514e0e8f31SAndrey V. Elsukov #include <stdint.h>
523c62e87aSJun-ichiro itojun Hagino #include <netdb.h>
539a4365d0SYoshinobu Inoue #include <ctype.h>
549a4365d0SYoshinobu Inoue #include <errno.h>
559a4365d0SYoshinobu Inoue 
563c62e87aSJun-ichiro itojun Hagino #include "libpfkey.h"
579a4365d0SYoshinobu Inoue #include "vchar.h"
589a4365d0SYoshinobu Inoue 
599a4365d0SYoshinobu Inoue #define ATOX(c) \
609a4365d0SYoshinobu Inoue   (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10)))
619a4365d0SYoshinobu Inoue 
629a4365d0SYoshinobu Inoue u_int32_t p_spi;
63cf43a054SHajimu UMEMOTO u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
643c62e87aSJun-ichiro itojun Hagino u_int32_t p_reqid;
659a4365d0SYoshinobu Inoue u_int p_key_enc_len, p_key_auth_len;
669a4365d0SYoshinobu Inoue caddr_t p_key_enc, p_key_auth;
679a4365d0SYoshinobu Inoue time_t p_lt_hard, p_lt_soft;
68*2fa1b861SKonstantin Belousov u_int p_natt_type;
69*2fa1b861SKonstantin Belousov struct addrinfo *p_natt_oai, *p_natt_oar;
70*2fa1b861SKonstantin Belousov int p_natt_sport, p_natt_dport;
71*2fa1b861SKonstantin Belousov int p_natt_fraglen;
729a4365d0SYoshinobu Inoue 
73cf43a054SHajimu UMEMOTO static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
749a4365d0SYoshinobu Inoue 
75784bddbcSKevin Lo static struct addrinfo *parse_addr(char *, char *);
76784bddbcSKevin Lo static int fix_portstr(vchar_t *, vchar_t *, vchar_t *);
77784bddbcSKevin Lo static int setvarbuf(char *, int *, struct sadb_ext *, int, caddr_t, int);
78784bddbcSKevin Lo void parse_init(void);
79784bddbcSKevin Lo void free_buffer(void);
809a4365d0SYoshinobu Inoue 
81784bddbcSKevin Lo int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t);
82784bddbcSKevin Lo static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *,
83784bddbcSKevin Lo 	struct addrinfo *, int, struct addrinfo *, int);
84784bddbcSKevin Lo static int setkeymsg_addr(unsigned int, unsigned int,
85784bddbcSKevin Lo 	struct addrinfo *, struct addrinfo *, int);
86784bddbcSKevin Lo static int setkeymsg_add(unsigned int, unsigned int,
87784bddbcSKevin Lo 	struct addrinfo *, struct addrinfo *);
88784bddbcSKevin Lo extern int setkeymsg(char *, size_t *);
89784bddbcSKevin Lo extern int sendkeymsg(char *, size_t);
909a4365d0SYoshinobu Inoue 
91784bddbcSKevin Lo extern int yylex(void);
92784bddbcSKevin Lo extern void yyfatal(const char *);
93784bddbcSKevin Lo extern void yyerror(const char *);
949a4365d0SYoshinobu Inoue %}
959a4365d0SYoshinobu Inoue 
969a4365d0SYoshinobu Inoue %union {
97cf43a054SHajimu UMEMOTO 	int num;
98cf43a054SHajimu UMEMOTO 	unsigned long ulnum;
999a4365d0SYoshinobu Inoue 	vchar_t val;
100cf43a054SHajimu UMEMOTO 	struct addrinfo *res;
1019a4365d0SYoshinobu Inoue }
1029a4365d0SYoshinobu Inoue 
103cf43a054SHajimu UMEMOTO %token EOT SLASH BLCL ELCL
104cf43a054SHajimu UMEMOTO %token ADD GET DELETE DELETEALL FLUSH DUMP
1051922fd12SBruce M Simpson %token PR_ESP PR_AH PR_IPCOMP PR_TCP
1069a4365d0SYoshinobu Inoue %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
1073c62e87aSJun-ichiro itojun Hagino %token F_MODE MODE F_REQID
1083c62e87aSJun-ichiro itojun Hagino %token F_EXT EXTENSION NOCYCLICSEQ
109cf43a054SHajimu UMEMOTO %token ALG_AUTH ALG_AUTH_NOKEY
110cf43a054SHajimu UMEMOTO %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
111afd010c1SGeorge V. Neville-Neil %token ALG_ENC_SALT
112cf43a054SHajimu UMEMOTO %token ALG_COMP
1139a4365d0SYoshinobu Inoue %token F_LIFETIME_HARD F_LIFETIME_SOFT
11433841545SHajimu UMEMOTO %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
1159a4365d0SYoshinobu Inoue 	/* SPD management */
1169a4365d0SYoshinobu Inoue %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
1179a4365d0SYoshinobu Inoue %token F_POLICY PL_REQUESTS
118*2fa1b861SKonstantin Belousov %token F_AIFLAGS F_NATT F_NATT_MTU
119cf43a054SHajimu UMEMOTO %token TAGGED
1209a4365d0SYoshinobu Inoue 
121cf43a054SHajimu UMEMOTO %type <num> prefix protocol_spec upper_spec
122cf43a054SHajimu UMEMOTO %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
123afd010c1SGeorge V. Neville-Neil %type <num> ALG_ENC_SALT
124cf43a054SHajimu UMEMOTO %type <num> ALG_AUTH ALG_AUTH_NOKEY
125cf43a054SHajimu UMEMOTO %type <num> ALG_COMP
1261922fd12SBruce M Simpson %type <num> PR_ESP PR_AH PR_IPCOMP PR_TCP
127cf43a054SHajimu UMEMOTO %type <num> EXTENSION MODE
128cf43a054SHajimu UMEMOTO %type <ulnum> DECSTRING
129cf43a054SHajimu UMEMOTO %type <val> PL_REQUESTS portstr key_string
130cf43a054SHajimu UMEMOTO %type <val> policy_requests
13133841545SHajimu UMEMOTO %type <val> QUOTEDSTRING HEXSTRING STRING
132cf43a054SHajimu UMEMOTO %type <val> F_AIFLAGS
133cf43a054SHajimu UMEMOTO %type <val> upper_misc_spec policy_spec
134cf43a054SHajimu UMEMOTO %type <res> ipaddr
1353c62e87aSJun-ichiro itojun Hagino 
1369a4365d0SYoshinobu Inoue %%
1379a4365d0SYoshinobu Inoue commands
1389a4365d0SYoshinobu Inoue 	:	/*NOTHING*/
1399a4365d0SYoshinobu Inoue 	|	commands command
1409a4365d0SYoshinobu Inoue 		{
1419a4365d0SYoshinobu Inoue 			free_buffer();
1429a4365d0SYoshinobu Inoue 			parse_init();
1439a4365d0SYoshinobu Inoue 		}
1449a4365d0SYoshinobu Inoue 	;
1459a4365d0SYoshinobu Inoue 
1469a4365d0SYoshinobu Inoue command
1479a4365d0SYoshinobu Inoue 	:	add_command
1489a4365d0SYoshinobu Inoue 	|	get_command
1499a4365d0SYoshinobu Inoue 	|	delete_command
15033841545SHajimu UMEMOTO 	|	deleteall_command
1519a4365d0SYoshinobu Inoue 	|	flush_command
1529a4365d0SYoshinobu Inoue 	|	dump_command
1539a4365d0SYoshinobu Inoue 	|	spdadd_command
1549a4365d0SYoshinobu Inoue 	|	spddelete_command
1559a4365d0SYoshinobu Inoue 	|	spddump_command
1569a4365d0SYoshinobu Inoue 	|	spdflush_command
1579a4365d0SYoshinobu Inoue 	;
1589a4365d0SYoshinobu Inoue 	/* commands concerned with management, there is in tail of this file. */
1599a4365d0SYoshinobu Inoue 
1609a4365d0SYoshinobu Inoue 	/* add command */
1619a4365d0SYoshinobu Inoue add_command
162cf43a054SHajimu UMEMOTO 	:	ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT
163cf43a054SHajimu UMEMOTO 		{
164cf43a054SHajimu UMEMOTO 			int status;
165cf43a054SHajimu UMEMOTO 
166cf43a054SHajimu UMEMOTO 			status = setkeymsg_add(SADB_ADD, $5, $3, $4);
167cf43a054SHajimu UMEMOTO 			if (status < 0)
168cf43a054SHajimu UMEMOTO 				return -1;
169cf43a054SHajimu UMEMOTO 		}
1709a4365d0SYoshinobu Inoue 	;
1719a4365d0SYoshinobu Inoue 
1729a4365d0SYoshinobu Inoue 	/* delete */
1739a4365d0SYoshinobu Inoue delete_command
174cf43a054SHajimu UMEMOTO 	:	DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
1753c62e87aSJun-ichiro itojun Hagino 		{
176cf43a054SHajimu UMEMOTO 			int status;
177cf43a054SHajimu UMEMOTO 
178cf43a054SHajimu UMEMOTO 			if ($3->ai_next || $4->ai_next) {
179cf43a054SHajimu UMEMOTO 				yyerror("multiple address specified");
180cf43a054SHajimu UMEMOTO 				return -1;
1813c62e87aSJun-ichiro itojun Hagino 			}
182cf43a054SHajimu UMEMOTO 			if (p_mode != IPSEC_MODE_ANY)
183cf43a054SHajimu UMEMOTO 				yyerror("WARNING: mode is obsolete");
184cf43a054SHajimu UMEMOTO 
185cf43a054SHajimu UMEMOTO 			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
186cf43a054SHajimu UMEMOTO 			if (status < 0)
187cf43a054SHajimu UMEMOTO 				return -1;
188cf43a054SHajimu UMEMOTO 		}
1899a4365d0SYoshinobu Inoue 	;
1909a4365d0SYoshinobu Inoue 
19133841545SHajimu UMEMOTO 	/* deleteall command */
19233841545SHajimu UMEMOTO deleteall_command
193cf43a054SHajimu UMEMOTO 	:	DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
194cf43a054SHajimu UMEMOTO 		{
195cf43a054SHajimu UMEMOTO 			int status;
196cf43a054SHajimu UMEMOTO 
197cf43a054SHajimu UMEMOTO 			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
198cf43a054SHajimu UMEMOTO 			if (status < 0)
199cf43a054SHajimu UMEMOTO 				return -1;
200cf43a054SHajimu UMEMOTO 		}
20133841545SHajimu UMEMOTO 	;
20233841545SHajimu UMEMOTO 
2039a4365d0SYoshinobu Inoue 	/* get command */
2049a4365d0SYoshinobu Inoue get_command
205cf43a054SHajimu UMEMOTO 	:	GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
2063c62e87aSJun-ichiro itojun Hagino 		{
207cf43a054SHajimu UMEMOTO 			int status;
208cf43a054SHajimu UMEMOTO 
2093c62e87aSJun-ichiro itojun Hagino 			if (p_mode != IPSEC_MODE_ANY)
210cf43a054SHajimu UMEMOTO 				yyerror("WARNING: mode is obsolete");
211cf43a054SHajimu UMEMOTO 
212cf43a054SHajimu UMEMOTO 			status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
213cf43a054SHajimu UMEMOTO 			if (status < 0)
214cf43a054SHajimu UMEMOTO 				return -1;
2153c62e87aSJun-ichiro itojun Hagino 		}
2169a4365d0SYoshinobu Inoue 	;
2179a4365d0SYoshinobu Inoue 
2189a4365d0SYoshinobu Inoue 	/* flush */
2199a4365d0SYoshinobu Inoue flush_command
220cf43a054SHajimu UMEMOTO 	:	FLUSH protocol_spec EOT
221cf43a054SHajimu UMEMOTO 		{
222cf43a054SHajimu UMEMOTO 			struct sadb_msg msg;
223cf43a054SHajimu UMEMOTO 			setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
224cf43a054SHajimu UMEMOTO 			sendkeymsg((char *)&msg, sizeof(msg));
225cf43a054SHajimu UMEMOTO 		}
2269a4365d0SYoshinobu Inoue 	;
2279a4365d0SYoshinobu Inoue 
2289a4365d0SYoshinobu Inoue 	/* dump */
2299a4365d0SYoshinobu Inoue dump_command
230cf43a054SHajimu UMEMOTO 	:	DUMP protocol_spec EOT
231cf43a054SHajimu UMEMOTO 		{
232cf43a054SHajimu UMEMOTO 			struct sadb_msg msg;
233cf43a054SHajimu UMEMOTO 			setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
234cf43a054SHajimu UMEMOTO 			sendkeymsg((char *)&msg, sizeof(msg));
235cf43a054SHajimu UMEMOTO 		}
2369a4365d0SYoshinobu Inoue 	;
2379a4365d0SYoshinobu Inoue 
2389a4365d0SYoshinobu Inoue protocol_spec
239cf43a054SHajimu UMEMOTO 	:	/*NOTHING*/
240cf43a054SHajimu UMEMOTO 		{
241cf43a054SHajimu UMEMOTO 			$$ = SADB_SATYPE_UNSPEC;
242cf43a054SHajimu UMEMOTO 		}
2439a4365d0SYoshinobu Inoue 	|	PR_ESP
2449a4365d0SYoshinobu Inoue 		{
245cf43a054SHajimu UMEMOTO 			$$ = SADB_SATYPE_ESP;
2463c62e87aSJun-ichiro itojun Hagino 			if ($1 == 1)
2479a4365d0SYoshinobu Inoue 				p_ext |= SADB_X_EXT_OLD;
2489a4365d0SYoshinobu Inoue 			else
2499a4365d0SYoshinobu Inoue 				p_ext &= ~SADB_X_EXT_OLD;
2509a4365d0SYoshinobu Inoue 		}
2519a4365d0SYoshinobu Inoue 	|	PR_AH
2529a4365d0SYoshinobu Inoue 		{
253cf43a054SHajimu UMEMOTO 			$$ = SADB_SATYPE_AH;
2543c62e87aSJun-ichiro itojun Hagino 			if ($1 == 1)
2559a4365d0SYoshinobu Inoue 				p_ext |= SADB_X_EXT_OLD;
2569a4365d0SYoshinobu Inoue 			else
2579a4365d0SYoshinobu Inoue 				p_ext &= ~SADB_X_EXT_OLD;
2589a4365d0SYoshinobu Inoue 		}
2599a4365d0SYoshinobu Inoue 	|	PR_IPCOMP
2609a4365d0SYoshinobu Inoue 		{
261cf43a054SHajimu UMEMOTO 			$$ = SADB_X_SATYPE_IPCOMP;
2629a4365d0SYoshinobu Inoue 		}
2631922fd12SBruce M Simpson 	|	PR_TCP
2641922fd12SBruce M Simpson 		{
2651922fd12SBruce M Simpson 			$$ = SADB_X_SATYPE_TCPSIGNATURE;
2661922fd12SBruce M Simpson 		}
2679a4365d0SYoshinobu Inoue 	;
2689a4365d0SYoshinobu Inoue 
2699a4365d0SYoshinobu Inoue spi
2703c62e87aSJun-ichiro itojun Hagino 	:	DECSTRING { p_spi = $1; }
2719a4365d0SYoshinobu Inoue 	|	HEXSTRING
2729a4365d0SYoshinobu Inoue 		{
273cf43a054SHajimu UMEMOTO 			char *ep;
274cf43a054SHajimu UMEMOTO 			unsigned long v;
2759a4365d0SYoshinobu Inoue 
276cf43a054SHajimu UMEMOTO 			ep = NULL;
277cf43a054SHajimu UMEMOTO 			v = strtoul($1.buf, &ep, 16);
278cf43a054SHajimu UMEMOTO 			if (!ep || *ep) {
279cf43a054SHajimu UMEMOTO 				yyerror("invalid SPI");
280cf43a054SHajimu UMEMOTO 				return -1;
281cf43a054SHajimu UMEMOTO 			}
282cf43a054SHajimu UMEMOTO 			if (v & ~0xffffffff) {
2839a4365d0SYoshinobu Inoue 				yyerror("SPI too big.");
2849a4365d0SYoshinobu Inoue 				return -1;
2859a4365d0SYoshinobu Inoue 			}
2869a4365d0SYoshinobu Inoue 
287cf43a054SHajimu UMEMOTO 			p_spi = v;
2889a4365d0SYoshinobu Inoue 		}
2899a4365d0SYoshinobu Inoue 	;
2909a4365d0SYoshinobu Inoue 
2919a4365d0SYoshinobu Inoue algorithm_spec
2929a4365d0SYoshinobu Inoue 	:	esp_spec
2939a4365d0SYoshinobu Inoue 	|	ah_spec
2949a4365d0SYoshinobu Inoue 	|	ipcomp_spec
2959a4365d0SYoshinobu Inoue 	;
2969a4365d0SYoshinobu Inoue 
2979a4365d0SYoshinobu Inoue esp_spec
298cf43a054SHajimu UMEMOTO 	:	F_ENC enc_alg F_AUTH auth_alg
299cf43a054SHajimu UMEMOTO 	|	F_ENC enc_alg
3009a4365d0SYoshinobu Inoue 	;
3019a4365d0SYoshinobu Inoue 
3029a4365d0SYoshinobu Inoue ah_spec
303cf43a054SHajimu UMEMOTO 	:	F_AUTH auth_alg
3049a4365d0SYoshinobu Inoue 	;
3059a4365d0SYoshinobu Inoue 
3069a4365d0SYoshinobu Inoue ipcomp_spec
307cf43a054SHajimu UMEMOTO 	:	F_COMP ALG_COMP
308cf43a054SHajimu UMEMOTO 		{
309cf43a054SHajimu UMEMOTO 			if ($2 < 0) {
310cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
311cf43a054SHajimu UMEMOTO 				return -1;
312cf43a054SHajimu UMEMOTO 			}
313cf43a054SHajimu UMEMOTO 			p_alg_enc = $2;
314cf43a054SHajimu UMEMOTO 		}
315cf43a054SHajimu UMEMOTO 	|	F_COMP ALG_COMP F_RAWCPI
316cf43a054SHajimu UMEMOTO 		{
317cf43a054SHajimu UMEMOTO 			if ($2 < 0) {
318cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
319cf43a054SHajimu UMEMOTO 				return -1;
320cf43a054SHajimu UMEMOTO 			}
321cf43a054SHajimu UMEMOTO 			p_alg_enc = $2;
322cf43a054SHajimu UMEMOTO 			p_ext |= SADB_X_EXT_RAWCPI;
323cf43a054SHajimu UMEMOTO 		}
3249a4365d0SYoshinobu Inoue 	;
3259a4365d0SYoshinobu Inoue 
3269a4365d0SYoshinobu Inoue enc_alg
327cf43a054SHajimu UMEMOTO 	:	ALG_ENC_NOKEY {
328cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
329cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
330cf43a054SHajimu UMEMOTO 				return -1;
331cf43a054SHajimu UMEMOTO 			}
332cf43a054SHajimu UMEMOTO 			p_alg_enc = $1;
333cf43a054SHajimu UMEMOTO 
334cf43a054SHajimu UMEMOTO 			p_key_enc_len = 0;
335cf43a054SHajimu UMEMOTO 			p_key_enc = NULL;
3368b205f5eSHajimu UMEMOTO 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
3378b205f5eSHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
3388b205f5eSHajimu UMEMOTO 				yyerror(ipsec_strerror());
3398b205f5eSHajimu UMEMOTO 				return -1;
3408b205f5eSHajimu UMEMOTO 			}
341cf43a054SHajimu UMEMOTO 		}
342cf43a054SHajimu UMEMOTO 	|	ALG_ENC key_string {
343cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
344cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
345cf43a054SHajimu UMEMOTO 				return -1;
346cf43a054SHajimu UMEMOTO 			}
347cf43a054SHajimu UMEMOTO 			p_alg_enc = $1;
348cf43a054SHajimu UMEMOTO 
349cf43a054SHajimu UMEMOTO 			p_key_enc_len = $2.len;
350cf43a054SHajimu UMEMOTO 			p_key_enc = $2.buf;
351cf43a054SHajimu UMEMOTO 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
352cf43a054SHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
353cf43a054SHajimu UMEMOTO 				yyerror(ipsec_strerror());
354cf43a054SHajimu UMEMOTO 				return -1;
355cf43a054SHajimu UMEMOTO 			}
356cf43a054SHajimu UMEMOTO 		}
357cf43a054SHajimu UMEMOTO 	|	ALG_ENC_OLD {
358cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
359cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
360cf43a054SHajimu UMEMOTO 				return -1;
361cf43a054SHajimu UMEMOTO 			}
362cf43a054SHajimu UMEMOTO 			yyerror("WARNING: obsolete algorithm");
363cf43a054SHajimu UMEMOTO 			p_alg_enc = $1;
364cf43a054SHajimu UMEMOTO 
365cf43a054SHajimu UMEMOTO 			p_key_enc_len = 0;
366cf43a054SHajimu UMEMOTO 			p_key_enc = NULL;
3678b205f5eSHajimu UMEMOTO 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
3688b205f5eSHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
3698b205f5eSHajimu UMEMOTO 				yyerror(ipsec_strerror());
3708b205f5eSHajimu UMEMOTO 				return -1;
3718b205f5eSHajimu UMEMOTO 			}
372cf43a054SHajimu UMEMOTO 		}
373cf43a054SHajimu UMEMOTO 	|	ALG_ENC_DESDERIV key_string
3749a4365d0SYoshinobu Inoue 		{
375cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
376cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
377cf43a054SHajimu UMEMOTO 				return -1;
378cf43a054SHajimu UMEMOTO 			}
3793c62e87aSJun-ichiro itojun Hagino 			p_alg_enc = $1;
3809a4365d0SYoshinobu Inoue 			if (p_ext & SADB_X_EXT_OLD) {
381cf43a054SHajimu UMEMOTO 				yyerror("algorithm mismatched");
3829a4365d0SYoshinobu Inoue 				return -1;
3839a4365d0SYoshinobu Inoue 			}
3849a4365d0SYoshinobu Inoue 			p_ext |= SADB_X_EXT_DERIV;
385cf43a054SHajimu UMEMOTO 
386cf43a054SHajimu UMEMOTO 			p_key_enc_len = $2.len;
387cf43a054SHajimu UMEMOTO 			p_key_enc = $2.buf;
388cf43a054SHajimu UMEMOTO 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
389cf43a054SHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
390cf43a054SHajimu UMEMOTO 				yyerror(ipsec_strerror());
391cf43a054SHajimu UMEMOTO 				return -1;
3929a4365d0SYoshinobu Inoue 			}
393cf43a054SHajimu UMEMOTO 		}
394cf43a054SHajimu UMEMOTO 	|	ALG_ENC_DES32IV key_string
3959a4365d0SYoshinobu Inoue 		{
396cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
397cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
398cf43a054SHajimu UMEMOTO 				return -1;
399cf43a054SHajimu UMEMOTO 			}
4003c62e87aSJun-ichiro itojun Hagino 			p_alg_enc = $1;
4019a4365d0SYoshinobu Inoue 			if (!(p_ext & SADB_X_EXT_OLD)) {
402cf43a054SHajimu UMEMOTO 				yyerror("algorithm mismatched");
4039a4365d0SYoshinobu Inoue 				return -1;
4049a4365d0SYoshinobu Inoue 			}
4059a4365d0SYoshinobu Inoue 			p_ext |= SADB_X_EXT_IV4B;
4069a4365d0SYoshinobu Inoue 
407cf43a054SHajimu UMEMOTO 			p_key_enc_len = $2.len;
408cf43a054SHajimu UMEMOTO 			p_key_enc = $2.buf;
4099a4365d0SYoshinobu Inoue 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
410cf43a054SHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
4119a4365d0SYoshinobu Inoue 				yyerror(ipsec_strerror());
4129a4365d0SYoshinobu Inoue 				return -1;
4139a4365d0SYoshinobu Inoue 			}
4149a4365d0SYoshinobu Inoue 		}
415afd010c1SGeorge V. Neville-Neil 	|	ALG_ENC_SALT key_string
416afd010c1SGeorge V. Neville-Neil 		{
417afd010c1SGeorge V. Neville-Neil 			if ($1 < 0) {
418afd010c1SGeorge V. Neville-Neil 				yyerror("unsupported algorithm");
419afd010c1SGeorge V. Neville-Neil 				return -1;
420afd010c1SGeorge V. Neville-Neil 			}
421afd010c1SGeorge V. Neville-Neil 			p_alg_enc = $1;
422afd010c1SGeorge V. Neville-Neil 
423afd010c1SGeorge V. Neville-Neil 			p_key_enc_len = $2.len;
424afd010c1SGeorge V. Neville-Neil 
425afd010c1SGeorge V. Neville-Neil 			p_key_enc = $2.buf;
426afd010c1SGeorge V. Neville-Neil 			/*
427afd010c1SGeorge V. Neville-Neil 			 * Salted keys include a 4 byte value that is
428afd010c1SGeorge V. Neville-Neil 			 * not part of the key.
429afd010c1SGeorge V. Neville-Neil 			 */
430afd010c1SGeorge V. Neville-Neil 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
431afd010c1SGeorge V. Neville-Neil 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len - 4)) < 0) {
432afd010c1SGeorge V. Neville-Neil 				yyerror(ipsec_strerror());
433afd010c1SGeorge V. Neville-Neil 				return -1;
434afd010c1SGeorge V. Neville-Neil 			}
435afd010c1SGeorge V. Neville-Neil 		}
4369a4365d0SYoshinobu Inoue 	;
4379a4365d0SYoshinobu Inoue 
4389a4365d0SYoshinobu Inoue auth_alg
439cf43a054SHajimu UMEMOTO 	:	ALG_AUTH key_string {
440cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
441cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
4429a4365d0SYoshinobu Inoue 				return -1;
4439a4365d0SYoshinobu Inoue 			}
444cf43a054SHajimu UMEMOTO 			p_alg_auth = $1;
4459a4365d0SYoshinobu Inoue 
446cf43a054SHajimu UMEMOTO 			p_key_auth_len = $2.len;
447cf43a054SHajimu UMEMOTO 			p_key_auth = $2.buf;
4481922fd12SBruce M Simpson 
4491922fd12SBruce M Simpson 			if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
4501922fd12SBruce M Simpson 				if ((p_key_auth_len < 1) || (p_key_auth_len >
4511922fd12SBruce M Simpson 				    80))
4521922fd12SBruce M Simpson 					return -1;
4531922fd12SBruce M Simpson 			} else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
454cf43a054SHajimu UMEMOTO 			    p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
4559a4365d0SYoshinobu Inoue 				yyerror(ipsec_strerror());
4569a4365d0SYoshinobu Inoue 				return -1;
4579a4365d0SYoshinobu Inoue 			}
4589a4365d0SYoshinobu Inoue 		}
459cf43a054SHajimu UMEMOTO 	|	ALG_AUTH_NOKEY {
460cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
461cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
462cf43a054SHajimu UMEMOTO 				return -1;
463cf43a054SHajimu UMEMOTO 			}
464cf43a054SHajimu UMEMOTO 			p_alg_auth = $1;
465cf43a054SHajimu UMEMOTO 
466cf43a054SHajimu UMEMOTO 			p_key_auth_len = 0;
467cf43a054SHajimu UMEMOTO 			p_key_auth = NULL;
468cf43a054SHajimu UMEMOTO 		}
4699a4365d0SYoshinobu Inoue 	;
4709a4365d0SYoshinobu Inoue 
4719a4365d0SYoshinobu Inoue key_string
4729a4365d0SYoshinobu Inoue 	:	QUOTEDSTRING
4739a4365d0SYoshinobu Inoue 		{
474cf43a054SHajimu UMEMOTO 			$$ = $1;
4759a4365d0SYoshinobu Inoue 		}
4769a4365d0SYoshinobu Inoue 	|	HEXSTRING
4779a4365d0SYoshinobu Inoue 		{
478cf43a054SHajimu UMEMOTO 			caddr_t pp_key;
4799a4365d0SYoshinobu Inoue 			caddr_t bp;
4803c62e87aSJun-ichiro itojun Hagino 			caddr_t yp = $1.buf;
481cf43a054SHajimu UMEMOTO 			int l;
4829a4365d0SYoshinobu Inoue 
483cf43a054SHajimu UMEMOTO 			l = strlen(yp) % 2 + strlen(yp) / 2;
484cf43a054SHajimu UMEMOTO 			if ((pp_key = malloc(l)) == 0) {
4853c62e87aSJun-ichiro itojun Hagino 				yyerror("not enough core");
4869a4365d0SYoshinobu Inoue 				return -1;
4879a4365d0SYoshinobu Inoue 			}
488cf43a054SHajimu UMEMOTO 			memset(pp_key, 0, l);
4899a4365d0SYoshinobu Inoue 
4909a4365d0SYoshinobu Inoue 			bp = pp_key;
491cf43a054SHajimu UMEMOTO 			if (strlen(yp) % 2) {
492cf43a054SHajimu UMEMOTO 				*bp = ATOX(yp[0]);
493cf43a054SHajimu UMEMOTO 				yp++, bp++;
494cf43a054SHajimu UMEMOTO 			}
4959a4365d0SYoshinobu Inoue 			while (*yp) {
4969a4365d0SYoshinobu Inoue 				*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
4979a4365d0SYoshinobu Inoue 				yp += 2, bp++;
4989a4365d0SYoshinobu Inoue 			}
4999a4365d0SYoshinobu Inoue 
500cf43a054SHajimu UMEMOTO 			$$.len = l;
501cf43a054SHajimu UMEMOTO 			$$.buf = pp_key;
5029a4365d0SYoshinobu Inoue 		}
5039a4365d0SYoshinobu Inoue 	;
5049a4365d0SYoshinobu Inoue 
5059a4365d0SYoshinobu Inoue extension_spec
5069a4365d0SYoshinobu Inoue 	:	/*NOTHING*/
5079a4365d0SYoshinobu Inoue 	|	extension_spec extension
5089a4365d0SYoshinobu Inoue 	;
5099a4365d0SYoshinobu Inoue 
5109a4365d0SYoshinobu Inoue extension
5113c62e87aSJun-ichiro itojun Hagino 	:	F_EXT EXTENSION { p_ext |= $2; }
5123c62e87aSJun-ichiro itojun Hagino 	|	F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
5133c62e87aSJun-ichiro itojun Hagino 	|	F_MODE MODE { p_mode = $2; }
5149a4365d0SYoshinobu Inoue 	|	F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
5153c62e87aSJun-ichiro itojun Hagino 	|	F_REQID DECSTRING { p_reqid = $2; }
5169a4365d0SYoshinobu Inoue 	|	F_REPLAY DECSTRING
5179a4365d0SYoshinobu Inoue 		{
518cf43a054SHajimu UMEMOTO 			if ((p_ext & SADB_X_EXT_OLD) != 0) {
519cf43a054SHajimu UMEMOTO 				yyerror("replay prevention cannot be used with "
520cf43a054SHajimu UMEMOTO 				    "ah/esp-old");
5219a4365d0SYoshinobu Inoue 				return -1;
5229a4365d0SYoshinobu Inoue 			}
5233c62e87aSJun-ichiro itojun Hagino 			p_replay = $2;
5244e0e8f31SAndrey V. Elsukov 			if (p_replay > (UINT32_MAX - 32) >> 3)
5254e0e8f31SAndrey V. Elsukov 				yyerror("replay window is too large");
5269a4365d0SYoshinobu Inoue 		}
5273c62e87aSJun-ichiro itojun Hagino 	|	F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
5283c62e87aSJun-ichiro itojun Hagino 	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
529*2fa1b861SKonstantin Belousov 	|	F_NATT ipaddr BLCL DECSTRING ELCL ipaddr BLCL DECSTRING ELCL
530*2fa1b861SKonstantin Belousov 		{
531*2fa1b861SKonstantin Belousov 			p_natt_type = UDP_ENCAP_ESPINUDP;
532*2fa1b861SKonstantin Belousov 			p_natt_oai = $2;
533*2fa1b861SKonstantin Belousov 			p_natt_oar = $6;
534*2fa1b861SKonstantin Belousov 			if (p_natt_oai == NULL || p_natt_oar == NULL)
535*2fa1b861SKonstantin Belousov 				return (-1);
536*2fa1b861SKonstantin Belousov 			p_natt_sport = $4;
537*2fa1b861SKonstantin Belousov 			p_natt_dport = $8;
538*2fa1b861SKonstantin Belousov 		}
539*2fa1b861SKonstantin Belousov 	|	F_NATT_MTU DECSTRING
540*2fa1b861SKonstantin Belousov 		{
541*2fa1b861SKonstantin Belousov 			p_natt_fraglen = $2;
542*2fa1b861SKonstantin Belousov 		}
5439a4365d0SYoshinobu Inoue 	;
5449a4365d0SYoshinobu Inoue 
5459a4365d0SYoshinobu Inoue 	/* definition about command for SPD management */
5469a4365d0SYoshinobu Inoue 	/* spdadd */
5479a4365d0SYoshinobu Inoue spdadd_command
548cf43a054SHajimu UMEMOTO 	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
5499a4365d0SYoshinobu Inoue 		{
550cf43a054SHajimu UMEMOTO 			int status;
551cf43a054SHajimu UMEMOTO 			struct addrinfo *src, *dst;
552cf43a054SHajimu UMEMOTO 
553cf43a054SHajimu UMEMOTO 			/* fixed port fields if ulp is icmpv6 */
554cf43a054SHajimu UMEMOTO 			if ($10.buf != NULL) {
555cf43a054SHajimu UMEMOTO 				if ($9 != IPPROTO_ICMPV6)
556cf43a054SHajimu UMEMOTO 					return -1;
557cf43a054SHajimu UMEMOTO 				free($5.buf);
558cf43a054SHajimu UMEMOTO 				free($8.buf);
559cf43a054SHajimu UMEMOTO 				if (fix_portstr(&$10, &$5, &$8))
560cf43a054SHajimu UMEMOTO 					return -1;
5619a4365d0SYoshinobu Inoue 			}
562cf43a054SHajimu UMEMOTO 
563cf43a054SHajimu UMEMOTO 			src = parse_addr($3.buf, $5.buf);
564cf43a054SHajimu UMEMOTO 			dst = parse_addr($6.buf, $8.buf);
565cf43a054SHajimu UMEMOTO 			if (!src || !dst) {
566cf43a054SHajimu UMEMOTO 				/* yyerror is already called */
567cf43a054SHajimu UMEMOTO 				return -1;
568cf43a054SHajimu UMEMOTO 			}
569cf43a054SHajimu UMEMOTO 			if (src->ai_next || dst->ai_next) {
570cf43a054SHajimu UMEMOTO 				yyerror("multiple address specified");
571cf43a054SHajimu UMEMOTO 				freeaddrinfo(src);
572cf43a054SHajimu UMEMOTO 				freeaddrinfo(dst);
573cf43a054SHajimu UMEMOTO 				return -1;
574cf43a054SHajimu UMEMOTO 			}
575cf43a054SHajimu UMEMOTO 
576cf43a054SHajimu UMEMOTO 			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
577cf43a054SHajimu UMEMOTO 			    src, $4, dst, $7);
578cf43a054SHajimu UMEMOTO 			freeaddrinfo(src);
579cf43a054SHajimu UMEMOTO 			freeaddrinfo(dst);
580cf43a054SHajimu UMEMOTO 			if (status < 0)
581cf43a054SHajimu UMEMOTO 				return -1;
582cf43a054SHajimu UMEMOTO 		}
583cf43a054SHajimu UMEMOTO 	|	SPDADD TAGGED QUOTEDSTRING policy_spec EOT
584cf43a054SHajimu UMEMOTO 		{
585cf43a054SHajimu UMEMOTO 			return -1;
586cf43a054SHajimu UMEMOTO 		}
5879a4365d0SYoshinobu Inoue 	;
5889a4365d0SYoshinobu Inoue 
589cf43a054SHajimu UMEMOTO spddelete_command
590cf43a054SHajimu UMEMOTO 	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
5919a4365d0SYoshinobu Inoue 		{
592cf43a054SHajimu UMEMOTO 			int status;
593cf43a054SHajimu UMEMOTO 			struct addrinfo *src, *dst;
594cf43a054SHajimu UMEMOTO 
595cf43a054SHajimu UMEMOTO 			/* fixed port fields if ulp is icmpv6 */
596cf43a054SHajimu UMEMOTO 			if ($10.buf != NULL) {
597cf43a054SHajimu UMEMOTO 				if ($9 != IPPROTO_ICMPV6)
598cf43a054SHajimu UMEMOTO 					return -1;
599cf43a054SHajimu UMEMOTO 				free($5.buf);
600cf43a054SHajimu UMEMOTO 				free($8.buf);
601cf43a054SHajimu UMEMOTO 				if (fix_portstr(&$10, &$5, &$8))
602cf43a054SHajimu UMEMOTO 					return -1;
6039a4365d0SYoshinobu Inoue 			}
604cf43a054SHajimu UMEMOTO 
605cf43a054SHajimu UMEMOTO 			src = parse_addr($3.buf, $5.buf);
606cf43a054SHajimu UMEMOTO 			dst = parse_addr($6.buf, $8.buf);
607cf43a054SHajimu UMEMOTO 			if (!src || !dst) {
608cf43a054SHajimu UMEMOTO 				/* yyerror is already called */
609cf43a054SHajimu UMEMOTO 				return -1;
610cf43a054SHajimu UMEMOTO 			}
611cf43a054SHajimu UMEMOTO 			if (src->ai_next || dst->ai_next) {
612cf43a054SHajimu UMEMOTO 				yyerror("multiple address specified");
613cf43a054SHajimu UMEMOTO 				freeaddrinfo(src);
614cf43a054SHajimu UMEMOTO 				freeaddrinfo(dst);
615cf43a054SHajimu UMEMOTO 				return -1;
616cf43a054SHajimu UMEMOTO 			}
617cf43a054SHajimu UMEMOTO 
618cf43a054SHajimu UMEMOTO 			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
619cf43a054SHajimu UMEMOTO 			    src, $4, dst, $7);
620cf43a054SHajimu UMEMOTO 			freeaddrinfo(src);
621cf43a054SHajimu UMEMOTO 			freeaddrinfo(dst);
622cf43a054SHajimu UMEMOTO 			if (status < 0)
623cf43a054SHajimu UMEMOTO 				return -1;
624cf43a054SHajimu UMEMOTO 		}
6259a4365d0SYoshinobu Inoue 	;
6269a4365d0SYoshinobu Inoue 
6279a4365d0SYoshinobu Inoue spddump_command:
628cf43a054SHajimu UMEMOTO 		SPDDUMP EOT
6299a4365d0SYoshinobu Inoue 		{
630cf43a054SHajimu UMEMOTO 			struct sadb_msg msg;
631cf43a054SHajimu UMEMOTO 			setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
632cf43a054SHajimu UMEMOTO 			    sizeof(msg));
633cf43a054SHajimu UMEMOTO 			sendkeymsg((char *)&msg, sizeof(msg));
6349a4365d0SYoshinobu Inoue 		}
6359a4365d0SYoshinobu Inoue 	;
6369a4365d0SYoshinobu Inoue 
6379a4365d0SYoshinobu Inoue spdflush_command:
638cf43a054SHajimu UMEMOTO 		SPDFLUSH EOT
6399a4365d0SYoshinobu Inoue 		{
640cf43a054SHajimu UMEMOTO 			struct sadb_msg msg;
641cf43a054SHajimu UMEMOTO 			setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
642cf43a054SHajimu UMEMOTO 			    sizeof(msg));
643cf43a054SHajimu UMEMOTO 			sendkeymsg((char *)&msg, sizeof(msg));
6443c62e87aSJun-ichiro itojun Hagino 		}
6459a4365d0SYoshinobu Inoue 	;
6469a4365d0SYoshinobu Inoue 
647cf43a054SHajimu UMEMOTO ipaddropts
648cf43a054SHajimu UMEMOTO 	:	/* nothing */
649cf43a054SHajimu UMEMOTO 	|	ipaddropts ipaddropt
650cf43a054SHajimu UMEMOTO 	;
6519a4365d0SYoshinobu Inoue 
652cf43a054SHajimu UMEMOTO ipaddropt
653cf43a054SHajimu UMEMOTO 	:	F_AIFLAGS
654cf43a054SHajimu UMEMOTO 		{
655cf43a054SHajimu UMEMOTO 			char *p;
656cf43a054SHajimu UMEMOTO 
657cf43a054SHajimu UMEMOTO 			for (p = $1.buf + 1; *p; p++)
658cf43a054SHajimu UMEMOTO 				switch (*p) {
659cf43a054SHajimu UMEMOTO 				case '4':
660cf43a054SHajimu UMEMOTO 					p_aifamily = AF_INET;
661cf43a054SHajimu UMEMOTO 					break;
662cf43a054SHajimu UMEMOTO #ifdef INET6
663cf43a054SHajimu UMEMOTO 				case '6':
664cf43a054SHajimu UMEMOTO 					p_aifamily = AF_INET6;
665cf43a054SHajimu UMEMOTO 					break;
666cf43a054SHajimu UMEMOTO #endif
667cf43a054SHajimu UMEMOTO 				case 'n':
668cf43a054SHajimu UMEMOTO 					p_aiflags = AI_NUMERICHOST;
669cf43a054SHajimu UMEMOTO 					break;
670cf43a054SHajimu UMEMOTO 				default:
671cf43a054SHajimu UMEMOTO 					yyerror("invalid flag");
6729a4365d0SYoshinobu Inoue 					return -1;
6739a4365d0SYoshinobu Inoue 				}
6749a4365d0SYoshinobu Inoue 		}
675cf43a054SHajimu UMEMOTO 	;
6769a4365d0SYoshinobu Inoue 
677cf43a054SHajimu UMEMOTO ipaddr
678cf43a054SHajimu UMEMOTO 	:	STRING
679cf43a054SHajimu UMEMOTO 		{
680cf43a054SHajimu UMEMOTO 			$$ = parse_addr($1.buf, NULL);
681cf43a054SHajimu UMEMOTO 			if ($$ == NULL) {
682cf43a054SHajimu UMEMOTO 				/* yyerror already called by parse_addr */
683cf43a054SHajimu UMEMOTO 				return -1;
684cf43a054SHajimu UMEMOTO 			}
6859a4365d0SYoshinobu Inoue 		}
6869a4365d0SYoshinobu Inoue 	;
6879a4365d0SYoshinobu Inoue 
6889a4365d0SYoshinobu Inoue prefix
689cf43a054SHajimu UMEMOTO 	:	/*NOTHING*/ { $$ = -1; }
690cf43a054SHajimu UMEMOTO 	|	SLASH DECSTRING { $$ = $2; }
6919a4365d0SYoshinobu Inoue 	;
6929a4365d0SYoshinobu Inoue 
693cf43a054SHajimu UMEMOTO portstr
694cf43a054SHajimu UMEMOTO 	:	/*NOTHING*/
695cf43a054SHajimu UMEMOTO 		{
696cf43a054SHajimu UMEMOTO 			$$.buf = strdup("0");
697cf43a054SHajimu UMEMOTO 			if (!$$.buf) {
698cf43a054SHajimu UMEMOTO 				yyerror("insufficient memory");
699cf43a054SHajimu UMEMOTO 				return -1;
700cf43a054SHajimu UMEMOTO 			}
701cf43a054SHajimu UMEMOTO 			$$.len = strlen($$.buf);
702cf43a054SHajimu UMEMOTO 		}
703cf43a054SHajimu UMEMOTO 	|	BLCL ANY ELCL
704cf43a054SHajimu UMEMOTO 		{
705cf43a054SHajimu UMEMOTO 			$$.buf = strdup("0");
706cf43a054SHajimu UMEMOTO 			if (!$$.buf) {
707cf43a054SHajimu UMEMOTO 				yyerror("insufficient memory");
708cf43a054SHajimu UMEMOTO 				return -1;
709cf43a054SHajimu UMEMOTO 			}
710cf43a054SHajimu UMEMOTO 			$$.len = strlen($$.buf);
711cf43a054SHajimu UMEMOTO 		}
712cf43a054SHajimu UMEMOTO 	|	BLCL DECSTRING ELCL
713cf43a054SHajimu UMEMOTO 		{
714cf43a054SHajimu UMEMOTO 			char buf[20];
715cf43a054SHajimu UMEMOTO 			snprintf(buf, sizeof(buf), "%lu", $2);
716cf43a054SHajimu UMEMOTO 			$$.buf = strdup(buf);
717cf43a054SHajimu UMEMOTO 			if (!$$.buf) {
718cf43a054SHajimu UMEMOTO 				yyerror("insufficient memory");
719cf43a054SHajimu UMEMOTO 				return -1;
720cf43a054SHajimu UMEMOTO 			}
721cf43a054SHajimu UMEMOTO 			$$.len = strlen($$.buf);
722cf43a054SHajimu UMEMOTO 		}
723cf43a054SHajimu UMEMOTO 	|	BLCL STRING ELCL
724cf43a054SHajimu UMEMOTO 		{
725cf43a054SHajimu UMEMOTO 			$$ = $2;
726cf43a054SHajimu UMEMOTO 		}
7279a4365d0SYoshinobu Inoue 	;
7289a4365d0SYoshinobu Inoue 
7299a4365d0SYoshinobu Inoue upper_spec
730cf43a054SHajimu UMEMOTO 	:	DECSTRING { $$ = $1; }
731cf43a054SHajimu UMEMOTO 	|	ANY { $$ = IPSEC_ULPROTO_ANY; }
7321ba19fe8SBruce M Simpson 	|	PR_TCP { $$ = IPPROTO_TCP; }
733b40114f7SMaxim Konovalov 	|	PR_ESP { $$ = IPPROTO_ESP; }
73433841545SHajimu UMEMOTO 	|	STRING
73533841545SHajimu UMEMOTO 		{
73633841545SHajimu UMEMOTO 			struct protoent *ent;
73733841545SHajimu UMEMOTO 
73833841545SHajimu UMEMOTO 			ent = getprotobyname($1.buf);
73933841545SHajimu UMEMOTO 			if (ent)
740cf43a054SHajimu UMEMOTO 				$$ = ent->p_proto;
74133841545SHajimu UMEMOTO 			else {
74233841545SHajimu UMEMOTO 				if (strcmp("icmp6", $1.buf) == 0) {
743cf43a054SHajimu UMEMOTO 					$$ = IPPROTO_ICMPV6;
74433841545SHajimu UMEMOTO 				} else if(strcmp("ip4", $1.buf) == 0) {
745cf43a054SHajimu UMEMOTO 					$$ = IPPROTO_IPV4;
74633841545SHajimu UMEMOTO 				} else {
74733841545SHajimu UMEMOTO 					yyerror("invalid upper layer protocol");
74833841545SHajimu UMEMOTO 					return -1;
74933841545SHajimu UMEMOTO 				}
75033841545SHajimu UMEMOTO 			}
751cf43a054SHajimu UMEMOTO 			endprotoent();
752cf43a054SHajimu UMEMOTO 		}
753cf43a054SHajimu UMEMOTO 	;
754cf43a054SHajimu UMEMOTO 
755cf43a054SHajimu UMEMOTO upper_misc_spec
756cf43a054SHajimu UMEMOTO 	:	/*NOTHING*/
757cf43a054SHajimu UMEMOTO 		{
758cf43a054SHajimu UMEMOTO 			$$.buf = NULL;
759cf43a054SHajimu UMEMOTO 			$$.len = 0;
760cf43a054SHajimu UMEMOTO 		}
761cf43a054SHajimu UMEMOTO 	|	STRING
762cf43a054SHajimu UMEMOTO 		{
763cf43a054SHajimu UMEMOTO 			$$.buf = strdup($1.buf);
764cf43a054SHajimu UMEMOTO 			if (!$$.buf) {
765cf43a054SHajimu UMEMOTO 				yyerror("insufficient memory");
766cf43a054SHajimu UMEMOTO 				return -1;
767cf43a054SHajimu UMEMOTO 			}
768cf43a054SHajimu UMEMOTO 			$$.len = strlen($$.buf);
76933841545SHajimu UMEMOTO 		}
7709a4365d0SYoshinobu Inoue 	;
7719a4365d0SYoshinobu Inoue 
7729a4365d0SYoshinobu Inoue policy_spec
7739a4365d0SYoshinobu Inoue 	:	F_POLICY policy_requests
7749a4365d0SYoshinobu Inoue 		{
775cf43a054SHajimu UMEMOTO 			char *policy;
776cf43a054SHajimu UMEMOTO 
777cf43a054SHajimu UMEMOTO 			policy = ipsec_set_policy($2.buf, $2.len);
778cf43a054SHajimu UMEMOTO 			if (policy == NULL) {
7799a4365d0SYoshinobu Inoue 				yyerror(ipsec_strerror());
7809a4365d0SYoshinobu Inoue 				return -1;
7819a4365d0SYoshinobu Inoue 			}
7829a4365d0SYoshinobu Inoue 
783cf43a054SHajimu UMEMOTO 			$$.buf = policy;
784cf43a054SHajimu UMEMOTO 			$$.len = ipsec_get_policylen(policy);
7859a4365d0SYoshinobu Inoue 		}
7869a4365d0SYoshinobu Inoue 	;
7879a4365d0SYoshinobu Inoue 
7883c62e87aSJun-ichiro itojun Hagino policy_requests
7893c62e87aSJun-ichiro itojun Hagino 	:	PL_REQUESTS { $$ = $1; }
7909a4365d0SYoshinobu Inoue 	;
7919a4365d0SYoshinobu Inoue 
7929a4365d0SYoshinobu Inoue %%
7939a4365d0SYoshinobu Inoue 
7949a4365d0SYoshinobu Inoue int
795bef81bc0SKonstantin Belousov setkeymsg0(struct sadb_msg *msg, unsigned type, unsigned satype, size_t l)
7969a4365d0SYoshinobu Inoue {
7979a4365d0SYoshinobu Inoue 
798cf43a054SHajimu UMEMOTO 	msg->sadb_msg_version = PF_KEY_V2;
799cf43a054SHajimu UMEMOTO 	msg->sadb_msg_type = type;
800cf43a054SHajimu UMEMOTO 	msg->sadb_msg_errno = 0;
801cf43a054SHajimu UMEMOTO 	msg->sadb_msg_satype = satype;
802cf43a054SHajimu UMEMOTO 	msg->sadb_msg_reserved = 0;
803cf43a054SHajimu UMEMOTO 	msg->sadb_msg_seq = 0;
804cf43a054SHajimu UMEMOTO 	msg->sadb_msg_pid = getpid();
805cf43a054SHajimu UMEMOTO 	msg->sadb_msg_len = PFKEY_UNIT64(l);
806cf43a054SHajimu UMEMOTO 	return 0;
807cf43a054SHajimu UMEMOTO }
8089a4365d0SYoshinobu Inoue 
8092c1296a3SKonstantin Belousov static int
8102c1296a3SKonstantin Belousov setkeymsg_plen(struct addrinfo *s)
8112c1296a3SKonstantin Belousov {
8122c1296a3SKonstantin Belousov 	switch (s->ai_addr->sa_family) {
8132c1296a3SKonstantin Belousov #ifdef INET
8142c1296a3SKonstantin Belousov 	case AF_INET:
8152c1296a3SKonstantin Belousov 		return (sizeof(struct in_addr) << 3);
8162c1296a3SKonstantin Belousov #endif
8172c1296a3SKonstantin Belousov #ifdef INET6
8182c1296a3SKonstantin Belousov 	case AF_INET6:
8192c1296a3SKonstantin Belousov 		return (sizeof(struct in6_addr) << 3);
8202c1296a3SKonstantin Belousov #endif
8212c1296a3SKonstantin Belousov 	default:
8222c1296a3SKonstantin Belousov 		return (-1);
8232c1296a3SKonstantin Belousov 	}
8242c1296a3SKonstantin Belousov }
8252c1296a3SKonstantin Belousov 
826cf43a054SHajimu UMEMOTO /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
827cf43a054SHajimu UMEMOTO static int
828bef81bc0SKonstantin Belousov setkeymsg_spdaddr(unsigned type, unsigned upper, vchar_t *policy,
829bef81bc0SKonstantin Belousov     struct addrinfo *srcs, int splen, struct addrinfo *dsts, int dplen)
830cf43a054SHajimu UMEMOTO {
831cf43a054SHajimu UMEMOTO 	struct sadb_msg *msg;
832cf43a054SHajimu UMEMOTO 	char buf[BUFSIZ];
833cf43a054SHajimu UMEMOTO 	int l, l0;
834cf43a054SHajimu UMEMOTO 	struct sadb_address m_addr;
835cf43a054SHajimu UMEMOTO 	struct addrinfo *s, *d;
836cf43a054SHajimu UMEMOTO 	int n;
837cf43a054SHajimu UMEMOTO 	int plen;
838cf43a054SHajimu UMEMOTO 	struct sockaddr *sa;
839cf43a054SHajimu UMEMOTO 	int salen;
8409a4365d0SYoshinobu Inoue 
841cf43a054SHajimu UMEMOTO 	msg = (struct sadb_msg *)buf;
842cf43a054SHajimu UMEMOTO 
843cf43a054SHajimu UMEMOTO 	if (!srcs || !dsts)
844cf43a054SHajimu UMEMOTO 		return -1;
845cf43a054SHajimu UMEMOTO 
846cf43a054SHajimu UMEMOTO 	/* fix up length afterwards */
847cf43a054SHajimu UMEMOTO 	setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
848cf43a054SHajimu UMEMOTO 	l = sizeof(struct sadb_msg);
849cf43a054SHajimu UMEMOTO 
850cf43a054SHajimu UMEMOTO 	memcpy(buf + l, policy->buf, policy->len);
851cf43a054SHajimu UMEMOTO 	l += policy->len;
852cf43a054SHajimu UMEMOTO 
853cf43a054SHajimu UMEMOTO 	l0 = l;
854cf43a054SHajimu UMEMOTO 	n = 0;
855cf43a054SHajimu UMEMOTO 
856cf43a054SHajimu UMEMOTO 	/* do it for all src/dst pairs */
857cf43a054SHajimu UMEMOTO 	for (s = srcs; s; s = s->ai_next) {
858cf43a054SHajimu UMEMOTO 		for (d = dsts; d; d = d->ai_next) {
859cf43a054SHajimu UMEMOTO 			/* rewind pointer */
860cf43a054SHajimu UMEMOTO 			l = l0;
861cf43a054SHajimu UMEMOTO 
862cf43a054SHajimu UMEMOTO 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
863cf43a054SHajimu UMEMOTO 				continue;
8642c1296a3SKonstantin Belousov 			plen = setkeymsg_plen(s);
8652c1296a3SKonstantin Belousov 			if (plen == -1)
866cf43a054SHajimu UMEMOTO 				continue;
8679a4365d0SYoshinobu Inoue 
868cf43a054SHajimu UMEMOTO 			/* set src */
869cf43a054SHajimu UMEMOTO 			sa = s->ai_addr;
870cf43a054SHajimu UMEMOTO 			salen = s->ai_addr->sa_len;
871cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
872cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
873cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
874cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_proto = upper;
875cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen =
876cf43a054SHajimu UMEMOTO 			    (splen >= 0 ? splen : plen);
877cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_reserved = 0;
8789a4365d0SYoshinobu Inoue 
879cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
880cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
8819a4365d0SYoshinobu Inoue 
882cf43a054SHajimu UMEMOTO 			/* set dst */
883cf43a054SHajimu UMEMOTO 			sa = d->ai_addr;
884cf43a054SHajimu UMEMOTO 			salen = d->ai_addr->sa_len;
885cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
886cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
887cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
888cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_proto = upper;
889cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen =
890cf43a054SHajimu UMEMOTO 			    (dplen >= 0 ? dplen : plen);
891cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_reserved = 0;
892cf43a054SHajimu UMEMOTO 
893cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
894cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
895cf43a054SHajimu UMEMOTO 
896cf43a054SHajimu UMEMOTO 			msg->sadb_msg_len = PFKEY_UNIT64(l);
897cf43a054SHajimu UMEMOTO 
898cf43a054SHajimu UMEMOTO 			sendkeymsg(buf, l);
899cf43a054SHajimu UMEMOTO 
900cf43a054SHajimu UMEMOTO 			n++;
901cf43a054SHajimu UMEMOTO 		}
9029a4365d0SYoshinobu Inoue 	}
9039a4365d0SYoshinobu Inoue 
904cf43a054SHajimu UMEMOTO 	if (n == 0)
905cf43a054SHajimu UMEMOTO 		return -1;
906cf43a054SHajimu UMEMOTO 	else
907cf43a054SHajimu UMEMOTO 		return 0;
9089a4365d0SYoshinobu Inoue }
9099a4365d0SYoshinobu Inoue 
910cf43a054SHajimu UMEMOTO /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
911cf43a054SHajimu UMEMOTO static int
912bef81bc0SKonstantin Belousov setkeymsg_addr(unsigned type, unsigned satype, struct addrinfo *srcs,
913bef81bc0SKonstantin Belousov     struct addrinfo *dsts, int no_spi)
9149a4365d0SYoshinobu Inoue {
915cf43a054SHajimu UMEMOTO 	struct sadb_msg *msg;
916cf43a054SHajimu UMEMOTO 	char buf[BUFSIZ];
917cf43a054SHajimu UMEMOTO 	int l, l0, len;
9189a4365d0SYoshinobu Inoue 	struct sadb_sa m_sa;
9193c62e87aSJun-ichiro itojun Hagino 	struct sadb_x_sa2 m_sa2;
9204e0e8f31SAndrey V. Elsukov 	struct sadb_x_sa_replay m_replay;
9219a4365d0SYoshinobu Inoue 	struct sadb_address m_addr;
922cf43a054SHajimu UMEMOTO 	struct addrinfo *s, *d;
923cf43a054SHajimu UMEMOTO 	int n;
924cf43a054SHajimu UMEMOTO 	int plen;
925cf43a054SHajimu UMEMOTO 	struct sockaddr *sa;
926cf43a054SHajimu UMEMOTO 	int salen;
9279a4365d0SYoshinobu Inoue 
928cf43a054SHajimu UMEMOTO 	msg = (struct sadb_msg *)buf;
929cf43a054SHajimu UMEMOTO 
930cf43a054SHajimu UMEMOTO 	if (!srcs || !dsts)
931cf43a054SHajimu UMEMOTO 		return -1;
932cf43a054SHajimu UMEMOTO 
933cf43a054SHajimu UMEMOTO 	/* fix up length afterwards */
934cf43a054SHajimu UMEMOTO 	setkeymsg0(msg, type, satype, 0);
935cf43a054SHajimu UMEMOTO 	l = sizeof(struct sadb_msg);
936cf43a054SHajimu UMEMOTO 
937cf43a054SHajimu UMEMOTO 	if (!no_spi) {
9389a4365d0SYoshinobu Inoue 		len = sizeof(struct sadb_sa);
9399a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_len = PFKEY_UNIT64(len);
9409a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_exttype = SADB_EXT_SA;
9419a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_spi = htonl(p_spi);
9424e0e8f31SAndrey V. Elsukov 		m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX:
9434e0e8f31SAndrey V. Elsukov 		    p_replay;
9449a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_state = 0;
9459a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_auth = p_alg_auth;
9469a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_encrypt = p_alg_enc;
9479a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_flags = p_ext;
9489a4365d0SYoshinobu Inoue 
949cf43a054SHajimu UMEMOTO 		memcpy(buf + l, &m_sa, len);
950cf43a054SHajimu UMEMOTO 		l += len;
9519a4365d0SYoshinobu Inoue 
9523c62e87aSJun-ichiro itojun Hagino 		len = sizeof(struct sadb_x_sa2);
9533c62e87aSJun-ichiro itojun Hagino 		m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
9543c62e87aSJun-ichiro itojun Hagino 		m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
9553c62e87aSJun-ichiro itojun Hagino 		m_sa2.sadb_x_sa2_mode = p_mode;
9563c62e87aSJun-ichiro itojun Hagino 		m_sa2.sadb_x_sa2_reqid = p_reqid;
9573c62e87aSJun-ichiro itojun Hagino 
958cf43a054SHajimu UMEMOTO 		memcpy(buf + l, &m_sa2, len);
959cf43a054SHajimu UMEMOTO 		l += len;
9604e0e8f31SAndrey V. Elsukov 
9614e0e8f31SAndrey V. Elsukov 		if (p_replay > UINT8_MAX) {
9624e0e8f31SAndrey V. Elsukov 			len = sizeof(struct sadb_x_sa_replay);
9634e0e8f31SAndrey V. Elsukov 			m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
9644e0e8f31SAndrey V. Elsukov 			m_replay.sadb_x_sa_replay_exttype =
9654e0e8f31SAndrey V. Elsukov 			    SADB_X_EXT_SA_REPLAY;
9664e0e8f31SAndrey V. Elsukov 			m_replay.sadb_x_sa_replay_replay = p_replay << 3;
9674e0e8f31SAndrey V. Elsukov 
9684e0e8f31SAndrey V. Elsukov 			memcpy(buf + l, &m_replay, len);
9694e0e8f31SAndrey V. Elsukov 			l += len;
9704e0e8f31SAndrey V. Elsukov 		}
971cf43a054SHajimu UMEMOTO 	}
972cf43a054SHajimu UMEMOTO 
973cf43a054SHajimu UMEMOTO 	l0 = l;
974cf43a054SHajimu UMEMOTO 	n = 0;
975cf43a054SHajimu UMEMOTO 
976cf43a054SHajimu UMEMOTO 	/* do it for all src/dst pairs */
977cf43a054SHajimu UMEMOTO 	for (s = srcs; s; s = s->ai_next) {
978cf43a054SHajimu UMEMOTO 		for (d = dsts; d; d = d->ai_next) {
979cf43a054SHajimu UMEMOTO 			/* rewind pointer */
980cf43a054SHajimu UMEMOTO 			l = l0;
981cf43a054SHajimu UMEMOTO 
982cf43a054SHajimu UMEMOTO 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
983cf43a054SHajimu UMEMOTO 				continue;
9842c1296a3SKonstantin Belousov 			plen = setkeymsg_plen(s);
9852c1296a3SKonstantin Belousov 			if (plen == -1)
986cf43a054SHajimu UMEMOTO 				continue;
9873c62e87aSJun-ichiro itojun Hagino 
9889a4365d0SYoshinobu Inoue 			/* set src */
989cf43a054SHajimu UMEMOTO 			sa = s->ai_addr;
990cf43a054SHajimu UMEMOTO 			salen = s->ai_addr->sa_len;
991cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
992cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
9939a4365d0SYoshinobu Inoue 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
9949a4365d0SYoshinobu Inoue 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
995cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen = plen;
9969a4365d0SYoshinobu Inoue 			m_addr.sadb_address_reserved = 0;
9979a4365d0SYoshinobu Inoue 
998cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
999cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
10009a4365d0SYoshinobu Inoue 
10019a4365d0SYoshinobu Inoue 			/* set dst */
1002cf43a054SHajimu UMEMOTO 			sa = d->ai_addr;
1003cf43a054SHajimu UMEMOTO 			salen = d->ai_addr->sa_len;
1004cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1005cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
10069a4365d0SYoshinobu Inoue 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
10079a4365d0SYoshinobu Inoue 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1008cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen = plen;
10099a4365d0SYoshinobu Inoue 			m_addr.sadb_address_reserved = 0;
10109a4365d0SYoshinobu Inoue 
1011cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1012cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
1013cf43a054SHajimu UMEMOTO 
1014cf43a054SHajimu UMEMOTO 			msg->sadb_msg_len = PFKEY_UNIT64(l);
1015cf43a054SHajimu UMEMOTO 
1016cf43a054SHajimu UMEMOTO 			sendkeymsg(buf, l);
1017cf43a054SHajimu UMEMOTO 
1018cf43a054SHajimu UMEMOTO 			n++;
10199a4365d0SYoshinobu Inoue 		}
1020cf43a054SHajimu UMEMOTO 	}
10219a4365d0SYoshinobu Inoue 
1022cf43a054SHajimu UMEMOTO 	if (n == 0)
1023cf43a054SHajimu UMEMOTO 		return -1;
1024cf43a054SHajimu UMEMOTO 	else
1025cf43a054SHajimu UMEMOTO 		return 0;
1026cf43a054SHajimu UMEMOTO }
10279a4365d0SYoshinobu Inoue 
1028cf43a054SHajimu UMEMOTO /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1029cf43a054SHajimu UMEMOTO static int
1030bef81bc0SKonstantin Belousov setkeymsg_add(unsigned type, unsigned satype, struct addrinfo *srcs,
1031bef81bc0SKonstantin Belousov     struct addrinfo *dsts)
10329a4365d0SYoshinobu Inoue {
1033cf43a054SHajimu UMEMOTO 	struct sadb_msg *msg;
1034cf43a054SHajimu UMEMOTO 	char buf[BUFSIZ];
1035cf43a054SHajimu UMEMOTO 	int l, l0, len;
1036cf43a054SHajimu UMEMOTO 	struct sadb_sa m_sa;
1037cf43a054SHajimu UMEMOTO 	struct sadb_x_sa2 m_sa2;
10383c62e87aSJun-ichiro itojun Hagino 	struct sadb_address m_addr;
10394e0e8f31SAndrey V. Elsukov 	struct sadb_x_sa_replay m_replay;
1040cf43a054SHajimu UMEMOTO 	struct addrinfo *s, *d;
1041*2fa1b861SKonstantin Belousov 	struct sadb_x_nat_t_type m_natt_type;
1042*2fa1b861SKonstantin Belousov 	struct sadb_x_nat_t_port m_natt_port;
1043*2fa1b861SKonstantin Belousov 	struct sadb_x_nat_t_frag m_natt_frag;
1044cf43a054SHajimu UMEMOTO 	int n;
1045cf43a054SHajimu UMEMOTO 	int plen;
1046cf43a054SHajimu UMEMOTO 	struct sockaddr *sa;
1047cf43a054SHajimu UMEMOTO 	int salen;
10483c62e87aSJun-ichiro itojun Hagino 
1049cf43a054SHajimu UMEMOTO 	msg = (struct sadb_msg *)buf;
1050cf43a054SHajimu UMEMOTO 
1051cf43a054SHajimu UMEMOTO 	if (!srcs || !dsts)
1052cf43a054SHajimu UMEMOTO 		return -1;
1053cf43a054SHajimu UMEMOTO 
1054cf43a054SHajimu UMEMOTO 	/* fix up length afterwards */
1055cf43a054SHajimu UMEMOTO 	setkeymsg0(msg, type, satype, 0);
1056cf43a054SHajimu UMEMOTO 	l = sizeof(struct sadb_msg);
1057cf43a054SHajimu UMEMOTO 
1058cf43a054SHajimu UMEMOTO 	/* set encryption algorithm, if present. */
1059cf43a054SHajimu UMEMOTO 	if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1060cf43a054SHajimu UMEMOTO 		struct sadb_key m_key;
1061cf43a054SHajimu UMEMOTO 
1062cf43a054SHajimu UMEMOTO 		m_key.sadb_key_len =
1063cf43a054SHajimu UMEMOTO 			PFKEY_UNIT64(sizeof(m_key)
1064cf43a054SHajimu UMEMOTO 				   + PFKEY_ALIGN8(p_key_enc_len));
1065cf43a054SHajimu UMEMOTO 		m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1066cf43a054SHajimu UMEMOTO 		m_key.sadb_key_bits = p_key_enc_len * 8;
1067cf43a054SHajimu UMEMOTO 		m_key.sadb_key_reserved = 0;
1068cf43a054SHajimu UMEMOTO 
1069cf43a054SHajimu UMEMOTO 		setvarbuf(buf, &l,
1070cf43a054SHajimu UMEMOTO 			(struct sadb_ext *)&m_key, sizeof(m_key),
1071cf43a054SHajimu UMEMOTO 			(caddr_t)p_key_enc, p_key_enc_len);
1072cf43a054SHajimu UMEMOTO 	}
1073cf43a054SHajimu UMEMOTO 
1074cf43a054SHajimu UMEMOTO 	/* set authentication algorithm, if present. */
1075cf43a054SHajimu UMEMOTO 	if (p_key_auth) {
1076cf43a054SHajimu UMEMOTO 		struct sadb_key m_key;
1077cf43a054SHajimu UMEMOTO 
1078cf43a054SHajimu UMEMOTO 		m_key.sadb_key_len =
1079cf43a054SHajimu UMEMOTO 			PFKEY_UNIT64(sizeof(m_key)
1080cf43a054SHajimu UMEMOTO 				   + PFKEY_ALIGN8(p_key_auth_len));
1081cf43a054SHajimu UMEMOTO 		m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1082cf43a054SHajimu UMEMOTO 		m_key.sadb_key_bits = p_key_auth_len * 8;
1083cf43a054SHajimu UMEMOTO 		m_key.sadb_key_reserved = 0;
1084cf43a054SHajimu UMEMOTO 
1085cf43a054SHajimu UMEMOTO 		setvarbuf(buf, &l,
1086cf43a054SHajimu UMEMOTO 			(struct sadb_ext *)&m_key, sizeof(m_key),
1087cf43a054SHajimu UMEMOTO 			(caddr_t)p_key_auth, p_key_auth_len);
1088cf43a054SHajimu UMEMOTO 	}
1089cf43a054SHajimu UMEMOTO 
1090cf43a054SHajimu UMEMOTO 	/* set lifetime for HARD */
1091cf43a054SHajimu UMEMOTO 	if (p_lt_hard != 0) {
1092cf43a054SHajimu UMEMOTO 		struct sadb_lifetime m_lt;
1093cf43a054SHajimu UMEMOTO 		u_int slen = sizeof(struct sadb_lifetime);
1094cf43a054SHajimu UMEMOTO 
1095cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1096cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1097cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_allocations = 0;
1098cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_bytes = 0;
1099cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_addtime = p_lt_hard;
1100cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_usetime = 0;
1101cf43a054SHajimu UMEMOTO 
1102cf43a054SHajimu UMEMOTO 		memcpy(buf + l, &m_lt, slen);
1103d02b24bcSHajimu UMEMOTO 		l += slen;
1104cf43a054SHajimu UMEMOTO 	}
1105cf43a054SHajimu UMEMOTO 
1106cf43a054SHajimu UMEMOTO 	/* set lifetime for SOFT */
1107cf43a054SHajimu UMEMOTO 	if (p_lt_soft != 0) {
1108cf43a054SHajimu UMEMOTO 		struct sadb_lifetime m_lt;
1109cf43a054SHajimu UMEMOTO 		u_int slen = sizeof(struct sadb_lifetime);
1110cf43a054SHajimu UMEMOTO 
1111cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1112cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1113cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_allocations = 0;
1114cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_bytes = 0;
1115cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_addtime = p_lt_soft;
1116cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_usetime = 0;
1117cf43a054SHajimu UMEMOTO 
1118cf43a054SHajimu UMEMOTO 		memcpy(buf + l, &m_lt, slen);
1119d02b24bcSHajimu UMEMOTO 		l += slen;
1120cf43a054SHajimu UMEMOTO 	}
1121cf43a054SHajimu UMEMOTO 
1122cf43a054SHajimu UMEMOTO 	len = sizeof(struct sadb_sa);
1123cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1124cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_exttype = SADB_EXT_SA;
1125cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_spi = htonl(p_spi);
11264e0e8f31SAndrey V. Elsukov 	m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX: p_replay;
1127cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_state = 0;
1128cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_auth = p_alg_auth;
1129cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_encrypt = p_alg_enc;
1130cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_flags = p_ext;
1131cf43a054SHajimu UMEMOTO 
1132cf43a054SHajimu UMEMOTO 	memcpy(buf + l, &m_sa, len);
1133cf43a054SHajimu UMEMOTO 	l += len;
1134cf43a054SHajimu UMEMOTO 
1135cf43a054SHajimu UMEMOTO 	len = sizeof(struct sadb_x_sa2);
1136cf43a054SHajimu UMEMOTO 	m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1137cf43a054SHajimu UMEMOTO 	m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1138cf43a054SHajimu UMEMOTO 	m_sa2.sadb_x_sa2_mode = p_mode;
1139cf43a054SHajimu UMEMOTO 	m_sa2.sadb_x_sa2_reqid = p_reqid;
1140cf43a054SHajimu UMEMOTO 
1141cf43a054SHajimu UMEMOTO 	memcpy(buf + l, &m_sa2, len);
1142cf43a054SHajimu UMEMOTO 	l += len;
1143cf43a054SHajimu UMEMOTO 
11444e0e8f31SAndrey V. Elsukov 	if (p_replay > UINT8_MAX) {
11454e0e8f31SAndrey V. Elsukov 		len = sizeof(struct sadb_x_sa_replay);
11464e0e8f31SAndrey V. Elsukov 		m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
11474e0e8f31SAndrey V. Elsukov 		m_replay.sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY;
11484e0e8f31SAndrey V. Elsukov 		m_replay.sadb_x_sa_replay_replay = p_replay << 3;
11494e0e8f31SAndrey V. Elsukov 
11504e0e8f31SAndrey V. Elsukov 		memcpy(buf + l, &m_replay, len);
11514e0e8f31SAndrey V. Elsukov 		l += len;
11524e0e8f31SAndrey V. Elsukov 	}
1153*2fa1b861SKonstantin Belousov 
1154*2fa1b861SKonstantin Belousov 	if (p_natt_type != 0) {
1155*2fa1b861SKonstantin Belousov 		len = sizeof(m_natt_type);
1156*2fa1b861SKonstantin Belousov 		memset(&m_natt_type, 0, sizeof(m_natt_type));
1157*2fa1b861SKonstantin Belousov 		m_natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1158*2fa1b861SKonstantin Belousov 		m_natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1159*2fa1b861SKonstantin Belousov 		m_natt_type.sadb_x_nat_t_type_type = p_natt_type;
1160*2fa1b861SKonstantin Belousov 		memcpy(buf + l, &m_natt_type, len);
1161*2fa1b861SKonstantin Belousov 		l += len;
1162*2fa1b861SKonstantin Belousov 
1163*2fa1b861SKonstantin Belousov 		memset(&m_addr, 0, sizeof(m_addr));
1164*2fa1b861SKonstantin Belousov 		m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OAI;
1165*2fa1b861SKonstantin Belousov 		sa = p_natt_oai->ai_addr;
1166*2fa1b861SKonstantin Belousov 		salen = p_natt_oai->ai_addr->sa_len;
1167*2fa1b861SKonstantin Belousov 		m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1168*2fa1b861SKonstantin Belousov 		    PFKEY_ALIGN8(salen));
1169*2fa1b861SKonstantin Belousov 		m_addr.sadb_address_prefixlen = setkeymsg_plen(p_natt_oai);
1170*2fa1b861SKonstantin Belousov 		setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1171*2fa1b861SKonstantin Belousov 		    sizeof(m_addr), (caddr_t)sa, salen);
1172*2fa1b861SKonstantin Belousov 
1173*2fa1b861SKonstantin Belousov 		len = sizeof(m_natt_port);
1174*2fa1b861SKonstantin Belousov 		memset(&m_natt_port, 0, sizeof(m_natt_port));
1175*2fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1176*2fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
1177*2fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_port = htons(p_natt_sport);
1178*2fa1b861SKonstantin Belousov 		memcpy(buf + l, &m_natt_port, len);
1179*2fa1b861SKonstantin Belousov 		l += len;
1180*2fa1b861SKonstantin Belousov 
1181*2fa1b861SKonstantin Belousov 		memset(&m_addr, 0, sizeof(m_addr));
1182*2fa1b861SKonstantin Belousov 		m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OAR;
1183*2fa1b861SKonstantin Belousov 		sa = p_natt_oar->ai_addr;
1184*2fa1b861SKonstantin Belousov 		salen = p_natt_oar->ai_addr->sa_len;
1185*2fa1b861SKonstantin Belousov 		m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1186*2fa1b861SKonstantin Belousov 		    PFKEY_ALIGN8(salen));
1187*2fa1b861SKonstantin Belousov 		m_addr.sadb_address_prefixlen = setkeymsg_plen(p_natt_oar);
1188*2fa1b861SKonstantin Belousov 		setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1189*2fa1b861SKonstantin Belousov 		    sizeof(m_addr), (caddr_t)sa, salen);
1190*2fa1b861SKonstantin Belousov 
1191*2fa1b861SKonstantin Belousov 		len = sizeof(m_natt_port);
1192*2fa1b861SKonstantin Belousov 		memset(&m_natt_port, 0, sizeof(m_natt_port));
1193*2fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1194*2fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
1195*2fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_port = htons(p_natt_dport);
1196*2fa1b861SKonstantin Belousov 		memcpy(buf + l, &m_natt_port, len);
1197*2fa1b861SKonstantin Belousov 		l += len;
1198*2fa1b861SKonstantin Belousov 
1199*2fa1b861SKonstantin Belousov 		if (p_natt_fraglen != -1) {
1200*2fa1b861SKonstantin Belousov 			len = sizeof(m_natt_frag);
1201*2fa1b861SKonstantin Belousov 			memset(&m_natt_port, 0, sizeof(m_natt_frag));
1202*2fa1b861SKonstantin Belousov 			m_natt_frag.sadb_x_nat_t_frag_len = PFKEY_UNIT64(len);
1203*2fa1b861SKonstantin Belousov 			m_natt_frag.sadb_x_nat_t_frag_exttype =
1204*2fa1b861SKonstantin Belousov 			    SADB_X_EXT_NAT_T_FRAG;
1205*2fa1b861SKonstantin Belousov 			m_natt_frag.sadb_x_nat_t_frag_fraglen = p_natt_fraglen;
1206*2fa1b861SKonstantin Belousov 			memcpy(buf + l, &m_natt_frag, len);
1207*2fa1b861SKonstantin Belousov 			l += len;
1208*2fa1b861SKonstantin Belousov 		}
1209*2fa1b861SKonstantin Belousov 	}
1210*2fa1b861SKonstantin Belousov 
1211cf43a054SHajimu UMEMOTO 	l0 = l;
1212cf43a054SHajimu UMEMOTO 	n = 0;
1213cf43a054SHajimu UMEMOTO 
1214cf43a054SHajimu UMEMOTO 	/* do it for all src/dst pairs */
1215cf43a054SHajimu UMEMOTO 	for (s = srcs; s; s = s->ai_next) {
1216cf43a054SHajimu UMEMOTO 		for (d = dsts; d; d = d->ai_next) {
1217cf43a054SHajimu UMEMOTO 			/* rewind pointer */
1218cf43a054SHajimu UMEMOTO 			l = l0;
1219cf43a054SHajimu UMEMOTO 
1220cf43a054SHajimu UMEMOTO 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1221cf43a054SHajimu UMEMOTO 				continue;
12222c1296a3SKonstantin Belousov 			plen = setkeymsg_plen(s);
12232c1296a3SKonstantin Belousov 			if (plen == -1)
1224cf43a054SHajimu UMEMOTO 				continue;
12259a4365d0SYoshinobu Inoue 
12269a4365d0SYoshinobu Inoue 			/* set src */
1227cf43a054SHajimu UMEMOTO 			sa = s->ai_addr;
1228cf43a054SHajimu UMEMOTO 			salen = s->ai_addr->sa_len;
1229cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1230cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
12319a4365d0SYoshinobu Inoue 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1232cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1233cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen = plen;
12349a4365d0SYoshinobu Inoue 			m_addr.sadb_address_reserved = 0;
12359a4365d0SYoshinobu Inoue 
1236cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1237cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
12389a4365d0SYoshinobu Inoue 
12399a4365d0SYoshinobu Inoue 			/* set dst */
1240cf43a054SHajimu UMEMOTO 			sa = d->ai_addr;
1241cf43a054SHajimu UMEMOTO 			salen = d->ai_addr->sa_len;
1242cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1243cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
12449a4365d0SYoshinobu Inoue 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1245cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1246cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen = plen;
12479a4365d0SYoshinobu Inoue 			m_addr.sadb_address_reserved = 0;
12489a4365d0SYoshinobu Inoue 
1249cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1250cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
1251cf43a054SHajimu UMEMOTO 
1252cf43a054SHajimu UMEMOTO 			msg->sadb_msg_len = PFKEY_UNIT64(l);
1253cf43a054SHajimu UMEMOTO 
1254cf43a054SHajimu UMEMOTO 			sendkeymsg(buf, l);
1255cf43a054SHajimu UMEMOTO 
1256cf43a054SHajimu UMEMOTO 			n++;
12579a4365d0SYoshinobu Inoue 		}
12589a4365d0SYoshinobu Inoue 	}
12599a4365d0SYoshinobu Inoue 
1260cf43a054SHajimu UMEMOTO 	if (n == 0)
1261cf43a054SHajimu UMEMOTO 		return -1;
1262cf43a054SHajimu UMEMOTO 	else
12639a4365d0SYoshinobu Inoue 		return 0;
12649a4365d0SYoshinobu Inoue }
12659a4365d0SYoshinobu Inoue 
12663c62e87aSJun-ichiro itojun Hagino static struct addrinfo *
1267bef81bc0SKonstantin Belousov parse_addr(char *host, char *port)
12683c62e87aSJun-ichiro itojun Hagino {
12693c62e87aSJun-ichiro itojun Hagino 	struct addrinfo hints, *res = NULL;
12703c62e87aSJun-ichiro itojun Hagino 	int error;
12713c62e87aSJun-ichiro itojun Hagino 
12723c62e87aSJun-ichiro itojun Hagino 	memset(&hints, 0, sizeof(hints));
1273cf43a054SHajimu UMEMOTO 	hints.ai_family = p_aifamily;
1274cf43a054SHajimu UMEMOTO 	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
1275cf43a054SHajimu UMEMOTO 	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
1276cf43a054SHajimu UMEMOTO 	hints.ai_flags = p_aiflags;
12773c62e87aSJun-ichiro itojun Hagino 	error = getaddrinfo(host, port, &hints, &res);
12783c62e87aSJun-ichiro itojun Hagino 	if (error != 0) {
12793c62e87aSJun-ichiro itojun Hagino 		yyerror(gai_strerror(error));
12803c62e87aSJun-ichiro itojun Hagino 		return NULL;
12813c62e87aSJun-ichiro itojun Hagino 	}
12823c62e87aSJun-ichiro itojun Hagino 	return res;
12833c62e87aSJun-ichiro itojun Hagino }
12843c62e87aSJun-ichiro itojun Hagino 
12859a4365d0SYoshinobu Inoue static int
1286bef81bc0SKonstantin Belousov fix_portstr(vchar_t *spec, vchar_t *sport, vchar_t *dport)
12879a4365d0SYoshinobu Inoue {
1288cf43a054SHajimu UMEMOTO 	char *p, *p2;
1289cf43a054SHajimu UMEMOTO 	u_int l;
1290cf43a054SHajimu UMEMOTO 
1291cf43a054SHajimu UMEMOTO 	l = 0;
1292cf43a054SHajimu UMEMOTO 	for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++)
1293cf43a054SHajimu UMEMOTO 		;
1294cf43a054SHajimu UMEMOTO 	if (*p == '\0') {
1295cf43a054SHajimu UMEMOTO 		p2 = "0";
1296cf43a054SHajimu UMEMOTO 	} else {
1297cf43a054SHajimu UMEMOTO 		if (*p == ',') {
1298cf43a054SHajimu UMEMOTO 			*p = '\0';
1299cf43a054SHajimu UMEMOTO 			p2 = ++p;
1300cf43a054SHajimu UMEMOTO 		}
1301cf43a054SHajimu UMEMOTO 		for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1302cf43a054SHajimu UMEMOTO 			;
1303cf43a054SHajimu UMEMOTO 		if (*p != '\0' || *p2 == '\0') {
1304cf43a054SHajimu UMEMOTO 			yyerror("invalid an upper layer protocol spec");
1305cf43a054SHajimu UMEMOTO 			return -1;
1306cf43a054SHajimu UMEMOTO 		}
1307cf43a054SHajimu UMEMOTO 	}
1308cf43a054SHajimu UMEMOTO 
1309cf43a054SHajimu UMEMOTO 	sport->buf = strdup(spec->buf);
1310cf43a054SHajimu UMEMOTO 	if (!sport->buf) {
1311cf43a054SHajimu UMEMOTO 		yyerror("insufficient memory");
1312cf43a054SHajimu UMEMOTO 		return -1;
1313cf43a054SHajimu UMEMOTO 	}
1314cf43a054SHajimu UMEMOTO 	sport->len = strlen(sport->buf);
1315cf43a054SHajimu UMEMOTO 	dport->buf = strdup(p2);
1316cf43a054SHajimu UMEMOTO 	if (!dport->buf) {
1317cf43a054SHajimu UMEMOTO 		yyerror("insufficient memory");
1318cf43a054SHajimu UMEMOTO 		return -1;
1319cf43a054SHajimu UMEMOTO 	}
1320cf43a054SHajimu UMEMOTO 	dport->len = strlen(dport->buf);
1321cf43a054SHajimu UMEMOTO 
1322cf43a054SHajimu UMEMOTO 	return 0;
1323cf43a054SHajimu UMEMOTO }
1324cf43a054SHajimu UMEMOTO 
1325cf43a054SHajimu UMEMOTO static int
1326bef81bc0SKonstantin Belousov setvarbuf(char *buf, int *off, struct sadb_ext *ebuf, int elen, caddr_t vbuf,
1327bef81bc0SKonstantin Belousov     int vlen)
1328cf43a054SHajimu UMEMOTO {
1329cf43a054SHajimu UMEMOTO 	memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1330cf43a054SHajimu UMEMOTO 	memcpy(buf + *off, (caddr_t)ebuf, elen);
1331cf43a054SHajimu UMEMOTO 	memcpy(buf + *off + elen, vbuf, vlen);
13329a4365d0SYoshinobu Inoue 	(*off) += PFKEY_ALIGN8(elen + vlen);
13339a4365d0SYoshinobu Inoue 
13349a4365d0SYoshinobu Inoue 	return 0;
13359a4365d0SYoshinobu Inoue }
13369a4365d0SYoshinobu Inoue 
13379a4365d0SYoshinobu Inoue void
1338bef81bc0SKonstantin Belousov parse_init(void)
13399a4365d0SYoshinobu Inoue {
13409a4365d0SYoshinobu Inoue 	p_spi = 0;
13419a4365d0SYoshinobu Inoue 
13423c62e87aSJun-ichiro itojun Hagino 	p_ext = SADB_X_EXT_CYCSEQ;
13439a4365d0SYoshinobu Inoue 	p_alg_enc = SADB_EALG_NONE;
13449a4365d0SYoshinobu Inoue 	p_alg_auth = SADB_AALG_NONE;
13459a4365d0SYoshinobu Inoue 	p_mode = IPSEC_MODE_ANY;
13463c62e87aSJun-ichiro itojun Hagino 	p_reqid = 0;
13473c62e87aSJun-ichiro itojun Hagino 	p_replay = 0;
13489a4365d0SYoshinobu Inoue 	p_key_enc_len = p_key_auth_len = 0;
13499a4365d0SYoshinobu Inoue 	p_key_enc = p_key_auth = 0;
13509a4365d0SYoshinobu Inoue 	p_lt_hard = p_lt_soft = 0;
13519a4365d0SYoshinobu Inoue 
1352cf43a054SHajimu UMEMOTO 	p_aiflags = 0;
1353cf43a054SHajimu UMEMOTO 	p_aifamily = PF_UNSPEC;
1354*2fa1b861SKonstantin Belousov 
1355*2fa1b861SKonstantin Belousov 	p_natt_type = 0;
1356*2fa1b861SKonstantin Belousov 	p_natt_oai = p_natt_oar = NULL;
1357*2fa1b861SKonstantin Belousov 	p_natt_sport = p_natt_dport = 0;
1358*2fa1b861SKonstantin Belousov 	p_natt_fraglen = -1;
13599a4365d0SYoshinobu Inoue }
13609a4365d0SYoshinobu Inoue 
13619a4365d0SYoshinobu Inoue void
1362bef81bc0SKonstantin Belousov free_buffer(void)
13639a4365d0SYoshinobu Inoue {
1364cf43a054SHajimu UMEMOTO 	/* we got tons of memory leaks in the parser anyways, leave them */
13659a4365d0SYoshinobu Inoue }
1366