xref: /freebsd/sbin/setkey/parse.y (revision 83418c878b75fafd5f9bfc44baf049487ce99a86)
1d02b24bcSHajimu UMEMOTO /*	$KAME: parse.y,v 1.83 2004/05/18 08:48:23 sakane Exp $	*/
23c62e87aSJun-ichiro itojun Hagino 
38a16b7a1SPedro F. Giffuni /*-
48a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
58a16b7a1SPedro F. Giffuni  *
69a4365d0SYoshinobu Inoue  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
79a4365d0SYoshinobu Inoue  * All rights reserved.
89a4365d0SYoshinobu Inoue  *
99a4365d0SYoshinobu Inoue  * Redistribution and use in source and binary forms, with or without
109a4365d0SYoshinobu Inoue  * modification, are permitted provided that the following conditions
119a4365d0SYoshinobu Inoue  * are met:
129a4365d0SYoshinobu Inoue  * 1. Redistributions of source code must retain the above copyright
139a4365d0SYoshinobu Inoue  *    notice, this list of conditions and the following disclaimer.
149a4365d0SYoshinobu Inoue  * 2. Redistributions in binary form must reproduce the above copyright
159a4365d0SYoshinobu Inoue  *    notice, this list of conditions and the following disclaimer in the
169a4365d0SYoshinobu Inoue  *    documentation and/or other materials provided with the distribution.
179a4365d0SYoshinobu Inoue  * 3. Neither the name of the project nor the names of its contributors
189a4365d0SYoshinobu Inoue  *    may be used to endorse or promote products derived from this software
199a4365d0SYoshinobu Inoue  *    without specific prior written permission.
209a4365d0SYoshinobu Inoue  *
219a4365d0SYoshinobu Inoue  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
229a4365d0SYoshinobu Inoue  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
239a4365d0SYoshinobu Inoue  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
249a4365d0SYoshinobu Inoue  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
259a4365d0SYoshinobu Inoue  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
269a4365d0SYoshinobu Inoue  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
279a4365d0SYoshinobu Inoue  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
289a4365d0SYoshinobu Inoue  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
299a4365d0SYoshinobu Inoue  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
309a4365d0SYoshinobu Inoue  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
319a4365d0SYoshinobu Inoue  * SUCH DAMAGE.
329a4365d0SYoshinobu Inoue  */
339a4365d0SYoshinobu Inoue 
349a4365d0SYoshinobu Inoue %{
359a4365d0SYoshinobu Inoue #include <sys/types.h>
369a4365d0SYoshinobu Inoue #include <sys/param.h>
379a4365d0SYoshinobu Inoue #include <sys/socket.h>
389a4365d0SYoshinobu Inoue 
399a4365d0SYoshinobu Inoue #include <net/route.h>
409a4365d0SYoshinobu Inoue #include <netinet/in.h>
419a4365d0SYoshinobu Inoue #include <net/pfkeyv2.h>
428409aedfSGeorge V. Neville-Neil #include <netipsec/key_var.h>
438409aedfSGeorge V. Neville-Neil #include <netipsec/ipsec.h>
449a4365d0SYoshinobu Inoue #include <arpa/inet.h>
452fa1b861SKonstantin Belousov #include <netinet/udp.h>
469a4365d0SYoshinobu Inoue 
479a4365d0SYoshinobu Inoue #include <string.h>
489a4365d0SYoshinobu Inoue #include <unistd.h>
499b93b2d8SKonstantin Belousov #include <stdbool.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;
682fa1b861SKonstantin Belousov u_int p_natt_type;
692fa1b861SKonstantin Belousov struct addrinfo *p_natt_oai, *p_natt_oar;
702fa1b861SKonstantin Belousov int p_natt_sport, p_natt_dport;
712fa1b861SKonstantin Belousov int p_natt_fraglen;
729b93b2d8SKonstantin Belousov bool esn;
73*83418c87SKonstantin Belousov vchar_t p_hwif;
749a4365d0SYoshinobu Inoue 
75cf43a054SHajimu UMEMOTO static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
769a4365d0SYoshinobu Inoue 
77784bddbcSKevin Lo static struct addrinfo *parse_addr(char *, char *);
78784bddbcSKevin Lo static int fix_portstr(vchar_t *, vchar_t *, vchar_t *);
79784bddbcSKevin Lo static int setvarbuf(char *, int *, struct sadb_ext *, int, caddr_t, int);
80784bddbcSKevin Lo void parse_init(void);
81784bddbcSKevin Lo void free_buffer(void);
829a4365d0SYoshinobu Inoue 
83784bddbcSKevin Lo int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t);
84784bddbcSKevin Lo static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *,
85784bddbcSKevin Lo 	struct addrinfo *, int, struct addrinfo *, int);
86784bddbcSKevin Lo static int setkeymsg_addr(unsigned int, unsigned int,
87784bddbcSKevin Lo 	struct addrinfo *, struct addrinfo *, int);
88784bddbcSKevin Lo static int setkeymsg_add(unsigned int, unsigned int,
89784bddbcSKevin Lo 	struct addrinfo *, struct addrinfo *);
90784bddbcSKevin Lo extern int setkeymsg(char *, size_t *);
91784bddbcSKevin Lo extern int sendkeymsg(char *, size_t);
929a4365d0SYoshinobu Inoue 
93784bddbcSKevin Lo extern int yylex(void);
94784bddbcSKevin Lo extern void yyfatal(const char *);
95784bddbcSKevin Lo extern void yyerror(const char *);
969a4365d0SYoshinobu Inoue %}
979a4365d0SYoshinobu Inoue 
989a4365d0SYoshinobu Inoue %union {
99cf43a054SHajimu UMEMOTO 	int num;
100cf43a054SHajimu UMEMOTO 	unsigned long ulnum;
1019a4365d0SYoshinobu Inoue 	vchar_t val;
102cf43a054SHajimu UMEMOTO 	struct addrinfo *res;
1039a4365d0SYoshinobu Inoue }
1049a4365d0SYoshinobu Inoue 
105cf43a054SHajimu UMEMOTO %token EOT SLASH BLCL ELCL
106cf43a054SHajimu UMEMOTO %token ADD GET DELETE DELETEALL FLUSH DUMP
1071922fd12SBruce M Simpson %token PR_ESP PR_AH PR_IPCOMP PR_TCP
1089a4365d0SYoshinobu Inoue %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
1093c62e87aSJun-ichiro itojun Hagino %token F_MODE MODE F_REQID
1103c62e87aSJun-ichiro itojun Hagino %token F_EXT EXTENSION NOCYCLICSEQ
111cf43a054SHajimu UMEMOTO %token ALG_AUTH ALG_AUTH_NOKEY
112cf43a054SHajimu UMEMOTO %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
113afd010c1SGeorge V. Neville-Neil %token ALG_ENC_SALT
114cf43a054SHajimu UMEMOTO %token ALG_COMP
1159a4365d0SYoshinobu Inoue %token F_LIFETIME_HARD F_LIFETIME_SOFT
11633841545SHajimu UMEMOTO %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
1179a4365d0SYoshinobu Inoue 	/* SPD management */
1189a4365d0SYoshinobu Inoue %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
1199a4365d0SYoshinobu Inoue %token F_POLICY PL_REQUESTS
1202fa1b861SKonstantin Belousov %token F_AIFLAGS F_NATT F_NATT_MTU
121*83418c87SKonstantin Belousov %token F_ESN F_HWIF
122cf43a054SHajimu UMEMOTO %token TAGGED
1239a4365d0SYoshinobu Inoue 
124cf43a054SHajimu UMEMOTO %type <num> prefix protocol_spec upper_spec
125cf43a054SHajimu UMEMOTO %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
126afd010c1SGeorge V. Neville-Neil %type <num> ALG_ENC_SALT
127cf43a054SHajimu UMEMOTO %type <num> ALG_AUTH ALG_AUTH_NOKEY
128cf43a054SHajimu UMEMOTO %type <num> ALG_COMP
1291922fd12SBruce M Simpson %type <num> PR_ESP PR_AH PR_IPCOMP PR_TCP
130cf43a054SHajimu UMEMOTO %type <num> EXTENSION MODE
131cf43a054SHajimu UMEMOTO %type <ulnum> DECSTRING
132cf43a054SHajimu UMEMOTO %type <val> PL_REQUESTS portstr key_string
133cf43a054SHajimu UMEMOTO %type <val> policy_requests
13433841545SHajimu UMEMOTO %type <val> QUOTEDSTRING HEXSTRING STRING
135cf43a054SHajimu UMEMOTO %type <val> F_AIFLAGS
136cf43a054SHajimu UMEMOTO %type <val> upper_misc_spec policy_spec
137cf43a054SHajimu UMEMOTO %type <res> ipaddr
1383c62e87aSJun-ichiro itojun Hagino 
1399a4365d0SYoshinobu Inoue %%
1409a4365d0SYoshinobu Inoue commands
1419a4365d0SYoshinobu Inoue 	:	/*NOTHING*/
1429a4365d0SYoshinobu Inoue 	|	commands command
1439a4365d0SYoshinobu Inoue 		{
1449a4365d0SYoshinobu Inoue 			free_buffer();
1459a4365d0SYoshinobu Inoue 			parse_init();
1469a4365d0SYoshinobu Inoue 		}
1479a4365d0SYoshinobu Inoue 	;
1489a4365d0SYoshinobu Inoue 
1499a4365d0SYoshinobu Inoue command
1509a4365d0SYoshinobu Inoue 	:	add_command
1519a4365d0SYoshinobu Inoue 	|	get_command
1529a4365d0SYoshinobu Inoue 	|	delete_command
15333841545SHajimu UMEMOTO 	|	deleteall_command
1549a4365d0SYoshinobu Inoue 	|	flush_command
1559a4365d0SYoshinobu Inoue 	|	dump_command
1569a4365d0SYoshinobu Inoue 	|	spdadd_command
1579a4365d0SYoshinobu Inoue 	|	spddelete_command
1589a4365d0SYoshinobu Inoue 	|	spddump_command
1599a4365d0SYoshinobu Inoue 	|	spdflush_command
1609a4365d0SYoshinobu Inoue 	;
1619a4365d0SYoshinobu Inoue 	/* commands concerned with management, there is in tail of this file. */
1629a4365d0SYoshinobu Inoue 
1639a4365d0SYoshinobu Inoue 	/* add command */
1649a4365d0SYoshinobu Inoue add_command
165cf43a054SHajimu UMEMOTO 	:	ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT
166cf43a054SHajimu UMEMOTO 		{
167cf43a054SHajimu UMEMOTO 			int status;
168cf43a054SHajimu UMEMOTO 
169cf43a054SHajimu UMEMOTO 			status = setkeymsg_add(SADB_ADD, $5, $3, $4);
170cf43a054SHajimu UMEMOTO 			if (status < 0)
171cf43a054SHajimu UMEMOTO 				return -1;
172cf43a054SHajimu UMEMOTO 		}
1739a4365d0SYoshinobu Inoue 	;
1749a4365d0SYoshinobu Inoue 
1759a4365d0SYoshinobu Inoue 	/* delete */
1769a4365d0SYoshinobu Inoue delete_command
177cf43a054SHajimu UMEMOTO 	:	DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
1783c62e87aSJun-ichiro itojun Hagino 		{
179cf43a054SHajimu UMEMOTO 			int status;
180cf43a054SHajimu UMEMOTO 
181cf43a054SHajimu UMEMOTO 			if ($3->ai_next || $4->ai_next) {
182cf43a054SHajimu UMEMOTO 				yyerror("multiple address specified");
183cf43a054SHajimu UMEMOTO 				return -1;
1843c62e87aSJun-ichiro itojun Hagino 			}
185cf43a054SHajimu UMEMOTO 			if (p_mode != IPSEC_MODE_ANY)
186cf43a054SHajimu UMEMOTO 				yyerror("WARNING: mode is obsolete");
187cf43a054SHajimu UMEMOTO 
188cf43a054SHajimu UMEMOTO 			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
189cf43a054SHajimu UMEMOTO 			if (status < 0)
190cf43a054SHajimu UMEMOTO 				return -1;
191cf43a054SHajimu UMEMOTO 		}
1929a4365d0SYoshinobu Inoue 	;
1939a4365d0SYoshinobu Inoue 
19433841545SHajimu UMEMOTO 	/* deleteall command */
19533841545SHajimu UMEMOTO deleteall_command
196cf43a054SHajimu UMEMOTO 	:	DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
197cf43a054SHajimu UMEMOTO 		{
198cf43a054SHajimu UMEMOTO 			int status;
199cf43a054SHajimu UMEMOTO 
200cf43a054SHajimu UMEMOTO 			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
201cf43a054SHajimu UMEMOTO 			if (status < 0)
202cf43a054SHajimu UMEMOTO 				return -1;
203cf43a054SHajimu UMEMOTO 		}
20433841545SHajimu UMEMOTO 	;
20533841545SHajimu UMEMOTO 
2069a4365d0SYoshinobu Inoue 	/* get command */
2079a4365d0SYoshinobu Inoue get_command
208cf43a054SHajimu UMEMOTO 	:	GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
2093c62e87aSJun-ichiro itojun Hagino 		{
210cf43a054SHajimu UMEMOTO 			int status;
211cf43a054SHajimu UMEMOTO 
2123c62e87aSJun-ichiro itojun Hagino 			if (p_mode != IPSEC_MODE_ANY)
213cf43a054SHajimu UMEMOTO 				yyerror("WARNING: mode is obsolete");
214cf43a054SHajimu UMEMOTO 
215cf43a054SHajimu UMEMOTO 			status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
216cf43a054SHajimu UMEMOTO 			if (status < 0)
217cf43a054SHajimu UMEMOTO 				return -1;
2183c62e87aSJun-ichiro itojun Hagino 		}
2199a4365d0SYoshinobu Inoue 	;
2209a4365d0SYoshinobu Inoue 
2219a4365d0SYoshinobu Inoue 	/* flush */
2229a4365d0SYoshinobu Inoue flush_command
223cf43a054SHajimu UMEMOTO 	:	FLUSH protocol_spec EOT
224cf43a054SHajimu UMEMOTO 		{
225cf43a054SHajimu UMEMOTO 			struct sadb_msg msg;
226cf43a054SHajimu UMEMOTO 			setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
227cf43a054SHajimu UMEMOTO 			sendkeymsg((char *)&msg, sizeof(msg));
228cf43a054SHajimu UMEMOTO 		}
2299a4365d0SYoshinobu Inoue 	;
2309a4365d0SYoshinobu Inoue 
2319a4365d0SYoshinobu Inoue 	/* dump */
2329a4365d0SYoshinobu Inoue dump_command
233cf43a054SHajimu UMEMOTO 	:	DUMP protocol_spec EOT
234cf43a054SHajimu UMEMOTO 		{
235cf43a054SHajimu UMEMOTO 			struct sadb_msg msg;
236cf43a054SHajimu UMEMOTO 			setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
237cf43a054SHajimu UMEMOTO 			sendkeymsg((char *)&msg, sizeof(msg));
238cf43a054SHajimu UMEMOTO 		}
2399a4365d0SYoshinobu Inoue 	;
2409a4365d0SYoshinobu Inoue 
2419a4365d0SYoshinobu Inoue protocol_spec
242cf43a054SHajimu UMEMOTO 	:	/*NOTHING*/
243cf43a054SHajimu UMEMOTO 		{
244cf43a054SHajimu UMEMOTO 			$$ = SADB_SATYPE_UNSPEC;
245cf43a054SHajimu UMEMOTO 		}
2469a4365d0SYoshinobu Inoue 	|	PR_ESP
2479a4365d0SYoshinobu Inoue 		{
248cf43a054SHajimu UMEMOTO 			$$ = SADB_SATYPE_ESP;
2493c62e87aSJun-ichiro itojun Hagino 			if ($1 == 1)
2509a4365d0SYoshinobu Inoue 				p_ext |= SADB_X_EXT_OLD;
2519a4365d0SYoshinobu Inoue 			else
2529a4365d0SYoshinobu Inoue 				p_ext &= ~SADB_X_EXT_OLD;
2539a4365d0SYoshinobu Inoue 		}
2549a4365d0SYoshinobu Inoue 	|	PR_AH
2559a4365d0SYoshinobu Inoue 		{
256cf43a054SHajimu UMEMOTO 			$$ = SADB_SATYPE_AH;
2573c62e87aSJun-ichiro itojun Hagino 			if ($1 == 1)
2589a4365d0SYoshinobu Inoue 				p_ext |= SADB_X_EXT_OLD;
2599a4365d0SYoshinobu Inoue 			else
2609a4365d0SYoshinobu Inoue 				p_ext &= ~SADB_X_EXT_OLD;
2619a4365d0SYoshinobu Inoue 		}
2629a4365d0SYoshinobu Inoue 	|	PR_IPCOMP
2639a4365d0SYoshinobu Inoue 		{
264cf43a054SHajimu UMEMOTO 			$$ = SADB_X_SATYPE_IPCOMP;
2659a4365d0SYoshinobu Inoue 		}
2661922fd12SBruce M Simpson 	|	PR_TCP
2671922fd12SBruce M Simpson 		{
2681922fd12SBruce M Simpson 			$$ = SADB_X_SATYPE_TCPSIGNATURE;
2691922fd12SBruce M Simpson 		}
2709a4365d0SYoshinobu Inoue 	;
2719a4365d0SYoshinobu Inoue 
2729a4365d0SYoshinobu Inoue spi
2733c62e87aSJun-ichiro itojun Hagino 	:	DECSTRING { p_spi = $1; }
2749a4365d0SYoshinobu Inoue 	|	HEXSTRING
2759a4365d0SYoshinobu Inoue 		{
276cf43a054SHajimu UMEMOTO 			char *ep;
277cf43a054SHajimu UMEMOTO 			unsigned long v;
2789a4365d0SYoshinobu Inoue 
279cf43a054SHajimu UMEMOTO 			ep = NULL;
280cf43a054SHajimu UMEMOTO 			v = strtoul($1.buf, &ep, 16);
281cf43a054SHajimu UMEMOTO 			if (!ep || *ep) {
282cf43a054SHajimu UMEMOTO 				yyerror("invalid SPI");
283cf43a054SHajimu UMEMOTO 				return -1;
284cf43a054SHajimu UMEMOTO 			}
285cf43a054SHajimu UMEMOTO 			if (v & ~0xffffffff) {
2869a4365d0SYoshinobu Inoue 				yyerror("SPI too big.");
2879a4365d0SYoshinobu Inoue 				return -1;
2889a4365d0SYoshinobu Inoue 			}
2899a4365d0SYoshinobu Inoue 
290cf43a054SHajimu UMEMOTO 			p_spi = v;
2919a4365d0SYoshinobu Inoue 		}
2929a4365d0SYoshinobu Inoue 	;
2939a4365d0SYoshinobu Inoue 
2949a4365d0SYoshinobu Inoue algorithm_spec
2959a4365d0SYoshinobu Inoue 	:	esp_spec
2969a4365d0SYoshinobu Inoue 	|	ah_spec
2979a4365d0SYoshinobu Inoue 	|	ipcomp_spec
2989a4365d0SYoshinobu Inoue 	;
2999a4365d0SYoshinobu Inoue 
3009a4365d0SYoshinobu Inoue esp_spec
301cf43a054SHajimu UMEMOTO 	:	F_ENC enc_alg F_AUTH auth_alg
302cf43a054SHajimu UMEMOTO 	|	F_ENC enc_alg
3039a4365d0SYoshinobu Inoue 	;
3049a4365d0SYoshinobu Inoue 
3059a4365d0SYoshinobu Inoue ah_spec
306cf43a054SHajimu UMEMOTO 	:	F_AUTH auth_alg
3079a4365d0SYoshinobu Inoue 	;
3089a4365d0SYoshinobu Inoue 
3099a4365d0SYoshinobu Inoue ipcomp_spec
310cf43a054SHajimu UMEMOTO 	:	F_COMP ALG_COMP
311cf43a054SHajimu UMEMOTO 		{
312cf43a054SHajimu UMEMOTO 			if ($2 < 0) {
313cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
314cf43a054SHajimu UMEMOTO 				return -1;
315cf43a054SHajimu UMEMOTO 			}
316cf43a054SHajimu UMEMOTO 			p_alg_enc = $2;
317cf43a054SHajimu UMEMOTO 		}
318cf43a054SHajimu UMEMOTO 	|	F_COMP ALG_COMP F_RAWCPI
319cf43a054SHajimu UMEMOTO 		{
320cf43a054SHajimu UMEMOTO 			if ($2 < 0) {
321cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
322cf43a054SHajimu UMEMOTO 				return -1;
323cf43a054SHajimu UMEMOTO 			}
324cf43a054SHajimu UMEMOTO 			p_alg_enc = $2;
325cf43a054SHajimu UMEMOTO 			p_ext |= SADB_X_EXT_RAWCPI;
326cf43a054SHajimu UMEMOTO 		}
3279a4365d0SYoshinobu Inoue 	;
3289a4365d0SYoshinobu Inoue 
3299a4365d0SYoshinobu Inoue enc_alg
330cf43a054SHajimu UMEMOTO 	:	ALG_ENC_NOKEY {
331cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
332cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
333cf43a054SHajimu UMEMOTO 				return -1;
334cf43a054SHajimu UMEMOTO 			}
335cf43a054SHajimu UMEMOTO 			p_alg_enc = $1;
336cf43a054SHajimu UMEMOTO 
337cf43a054SHajimu UMEMOTO 			p_key_enc_len = 0;
338cf43a054SHajimu UMEMOTO 			p_key_enc = NULL;
3398b205f5eSHajimu UMEMOTO 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
3408b205f5eSHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
3418b205f5eSHajimu UMEMOTO 				yyerror(ipsec_strerror());
3428b205f5eSHajimu UMEMOTO 				return -1;
3438b205f5eSHajimu UMEMOTO 			}
344cf43a054SHajimu UMEMOTO 		}
345cf43a054SHajimu UMEMOTO 	|	ALG_ENC key_string {
346cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
347cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
348cf43a054SHajimu UMEMOTO 				return -1;
349cf43a054SHajimu UMEMOTO 			}
350cf43a054SHajimu UMEMOTO 			p_alg_enc = $1;
351cf43a054SHajimu UMEMOTO 
352cf43a054SHajimu UMEMOTO 			p_key_enc_len = $2.len;
353cf43a054SHajimu UMEMOTO 			p_key_enc = $2.buf;
354cf43a054SHajimu UMEMOTO 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
355cf43a054SHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
356cf43a054SHajimu UMEMOTO 				yyerror(ipsec_strerror());
357cf43a054SHajimu UMEMOTO 				return -1;
358cf43a054SHajimu UMEMOTO 			}
359cf43a054SHajimu UMEMOTO 		}
360cf43a054SHajimu UMEMOTO 	|	ALG_ENC_OLD {
361cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
362cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
363cf43a054SHajimu UMEMOTO 				return -1;
364cf43a054SHajimu UMEMOTO 			}
365cf43a054SHajimu UMEMOTO 			yyerror("WARNING: obsolete algorithm");
366cf43a054SHajimu UMEMOTO 			p_alg_enc = $1;
367cf43a054SHajimu UMEMOTO 
368cf43a054SHajimu UMEMOTO 			p_key_enc_len = 0;
369cf43a054SHajimu UMEMOTO 			p_key_enc = NULL;
3708b205f5eSHajimu UMEMOTO 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
3718b205f5eSHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
3728b205f5eSHajimu UMEMOTO 				yyerror(ipsec_strerror());
3738b205f5eSHajimu UMEMOTO 				return -1;
3748b205f5eSHajimu UMEMOTO 			}
375cf43a054SHajimu UMEMOTO 		}
376cf43a054SHajimu UMEMOTO 	|	ALG_ENC_DESDERIV key_string
3779a4365d0SYoshinobu Inoue 		{
378cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
379cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
380cf43a054SHajimu UMEMOTO 				return -1;
381cf43a054SHajimu UMEMOTO 			}
3823c62e87aSJun-ichiro itojun Hagino 			p_alg_enc = $1;
3839a4365d0SYoshinobu Inoue 			if (p_ext & SADB_X_EXT_OLD) {
384cf43a054SHajimu UMEMOTO 				yyerror("algorithm mismatched");
3859a4365d0SYoshinobu Inoue 				return -1;
3869a4365d0SYoshinobu Inoue 			}
3879a4365d0SYoshinobu Inoue 			p_ext |= SADB_X_EXT_DERIV;
388cf43a054SHajimu UMEMOTO 
389cf43a054SHajimu UMEMOTO 			p_key_enc_len = $2.len;
390cf43a054SHajimu UMEMOTO 			p_key_enc = $2.buf;
391cf43a054SHajimu UMEMOTO 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
392cf43a054SHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
393cf43a054SHajimu UMEMOTO 				yyerror(ipsec_strerror());
394cf43a054SHajimu UMEMOTO 				return -1;
3959a4365d0SYoshinobu Inoue 			}
396cf43a054SHajimu UMEMOTO 		}
397cf43a054SHajimu UMEMOTO 	|	ALG_ENC_DES32IV key_string
3989a4365d0SYoshinobu Inoue 		{
399cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
400cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
401cf43a054SHajimu UMEMOTO 				return -1;
402cf43a054SHajimu UMEMOTO 			}
4033c62e87aSJun-ichiro itojun Hagino 			p_alg_enc = $1;
4049a4365d0SYoshinobu Inoue 			if (!(p_ext & SADB_X_EXT_OLD)) {
405cf43a054SHajimu UMEMOTO 				yyerror("algorithm mismatched");
4069a4365d0SYoshinobu Inoue 				return -1;
4079a4365d0SYoshinobu Inoue 			}
4089a4365d0SYoshinobu Inoue 			p_ext |= SADB_X_EXT_IV4B;
4099a4365d0SYoshinobu Inoue 
410cf43a054SHajimu UMEMOTO 			p_key_enc_len = $2.len;
411cf43a054SHajimu UMEMOTO 			p_key_enc = $2.buf;
4129a4365d0SYoshinobu Inoue 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
413cf43a054SHajimu UMEMOTO 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
4149a4365d0SYoshinobu Inoue 				yyerror(ipsec_strerror());
4159a4365d0SYoshinobu Inoue 				return -1;
4169a4365d0SYoshinobu Inoue 			}
4179a4365d0SYoshinobu Inoue 		}
418afd010c1SGeorge V. Neville-Neil 	|	ALG_ENC_SALT key_string
419afd010c1SGeorge V. Neville-Neil 		{
420afd010c1SGeorge V. Neville-Neil 			if ($1 < 0) {
421afd010c1SGeorge V. Neville-Neil 				yyerror("unsupported algorithm");
422afd010c1SGeorge V. Neville-Neil 				return -1;
423afd010c1SGeorge V. Neville-Neil 			}
424afd010c1SGeorge V. Neville-Neil 			p_alg_enc = $1;
425afd010c1SGeorge V. Neville-Neil 
426afd010c1SGeorge V. Neville-Neil 			p_key_enc_len = $2.len;
427afd010c1SGeorge V. Neville-Neil 
428afd010c1SGeorge V. Neville-Neil 			p_key_enc = $2.buf;
429afd010c1SGeorge V. Neville-Neil 			/*
430afd010c1SGeorge V. Neville-Neil 			 * Salted keys include a 4 byte value that is
431afd010c1SGeorge V. Neville-Neil 			 * not part of the key.
432afd010c1SGeorge V. Neville-Neil 			 */
433afd010c1SGeorge V. Neville-Neil 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
434afd010c1SGeorge V. Neville-Neil 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len - 4)) < 0) {
435afd010c1SGeorge V. Neville-Neil 				yyerror(ipsec_strerror());
436afd010c1SGeorge V. Neville-Neil 				return -1;
437afd010c1SGeorge V. Neville-Neil 			}
438afd010c1SGeorge V. Neville-Neil 		}
4399a4365d0SYoshinobu Inoue 	;
4409a4365d0SYoshinobu Inoue 
4419a4365d0SYoshinobu Inoue auth_alg
442cf43a054SHajimu UMEMOTO 	:	ALG_AUTH key_string {
443cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
444cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
4459a4365d0SYoshinobu Inoue 				return -1;
4469a4365d0SYoshinobu Inoue 			}
447cf43a054SHajimu UMEMOTO 			p_alg_auth = $1;
4489a4365d0SYoshinobu Inoue 
449cf43a054SHajimu UMEMOTO 			p_key_auth_len = $2.len;
450cf43a054SHajimu UMEMOTO 			p_key_auth = $2.buf;
4511922fd12SBruce M Simpson 
4521922fd12SBruce M Simpson 			if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
4531922fd12SBruce M Simpson 				if ((p_key_auth_len < 1) || (p_key_auth_len >
4541922fd12SBruce M Simpson 				    80))
4551922fd12SBruce M Simpson 					return -1;
4561922fd12SBruce M Simpson 			} else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
457cf43a054SHajimu UMEMOTO 			    p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
4589a4365d0SYoshinobu Inoue 				yyerror(ipsec_strerror());
4599a4365d0SYoshinobu Inoue 				return -1;
4609a4365d0SYoshinobu Inoue 			}
4619a4365d0SYoshinobu Inoue 		}
462cf43a054SHajimu UMEMOTO 	|	ALG_AUTH_NOKEY {
463cf43a054SHajimu UMEMOTO 			if ($1 < 0) {
464cf43a054SHajimu UMEMOTO 				yyerror("unsupported algorithm");
465cf43a054SHajimu UMEMOTO 				return -1;
466cf43a054SHajimu UMEMOTO 			}
467cf43a054SHajimu UMEMOTO 			p_alg_auth = $1;
468cf43a054SHajimu UMEMOTO 
469cf43a054SHajimu UMEMOTO 			p_key_auth_len = 0;
470cf43a054SHajimu UMEMOTO 			p_key_auth = NULL;
471cf43a054SHajimu UMEMOTO 		}
4729a4365d0SYoshinobu Inoue 	;
4739a4365d0SYoshinobu Inoue 
4749a4365d0SYoshinobu Inoue key_string
4759a4365d0SYoshinobu Inoue 	:	QUOTEDSTRING
4769a4365d0SYoshinobu Inoue 		{
477cf43a054SHajimu UMEMOTO 			$$ = $1;
4789a4365d0SYoshinobu Inoue 		}
4799a4365d0SYoshinobu Inoue 	|	HEXSTRING
4809a4365d0SYoshinobu Inoue 		{
481cf43a054SHajimu UMEMOTO 			caddr_t pp_key;
4829a4365d0SYoshinobu Inoue 			caddr_t bp;
4833c62e87aSJun-ichiro itojun Hagino 			caddr_t yp = $1.buf;
484cf43a054SHajimu UMEMOTO 			int l;
4859a4365d0SYoshinobu Inoue 
486cf43a054SHajimu UMEMOTO 			l = strlen(yp) % 2 + strlen(yp) / 2;
487cf43a054SHajimu UMEMOTO 			if ((pp_key = malloc(l)) == 0) {
4883c62e87aSJun-ichiro itojun Hagino 				yyerror("not enough core");
4899a4365d0SYoshinobu Inoue 				return -1;
4909a4365d0SYoshinobu Inoue 			}
491cf43a054SHajimu UMEMOTO 			memset(pp_key, 0, l);
4929a4365d0SYoshinobu Inoue 
4939a4365d0SYoshinobu Inoue 			bp = pp_key;
494cf43a054SHajimu UMEMOTO 			if (strlen(yp) % 2) {
495cf43a054SHajimu UMEMOTO 				*bp = ATOX(yp[0]);
496cf43a054SHajimu UMEMOTO 				yp++, bp++;
497cf43a054SHajimu UMEMOTO 			}
4989a4365d0SYoshinobu Inoue 			while (*yp) {
4999a4365d0SYoshinobu Inoue 				*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
5009a4365d0SYoshinobu Inoue 				yp += 2, bp++;
5019a4365d0SYoshinobu Inoue 			}
5029a4365d0SYoshinobu Inoue 
503cf43a054SHajimu UMEMOTO 			$$.len = l;
504cf43a054SHajimu UMEMOTO 			$$.buf = pp_key;
5059a4365d0SYoshinobu Inoue 		}
5069a4365d0SYoshinobu Inoue 	;
5079a4365d0SYoshinobu Inoue 
5089a4365d0SYoshinobu Inoue extension_spec
5099a4365d0SYoshinobu Inoue 	:	/*NOTHING*/
5109a4365d0SYoshinobu Inoue 	|	extension_spec extension
5119a4365d0SYoshinobu Inoue 	;
5129a4365d0SYoshinobu Inoue 
5139a4365d0SYoshinobu Inoue extension
5143c62e87aSJun-ichiro itojun Hagino 	:	F_EXT EXTENSION { p_ext |= $2; }
5153c62e87aSJun-ichiro itojun Hagino 	|	F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
5163c62e87aSJun-ichiro itojun Hagino 	|	F_MODE MODE { p_mode = $2; }
5179a4365d0SYoshinobu Inoue 	|	F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
5183c62e87aSJun-ichiro itojun Hagino 	|	F_REQID DECSTRING { p_reqid = $2; }
5199a4365d0SYoshinobu Inoue 	|	F_REPLAY DECSTRING
5209a4365d0SYoshinobu Inoue 		{
521cf43a054SHajimu UMEMOTO 			if ((p_ext & SADB_X_EXT_OLD) != 0) {
522cf43a054SHajimu UMEMOTO 				yyerror("replay prevention cannot be used with "
523cf43a054SHajimu UMEMOTO 				    "ah/esp-old");
5249a4365d0SYoshinobu Inoue 				return -1;
5259a4365d0SYoshinobu Inoue 			}
5263c62e87aSJun-ichiro itojun Hagino 			p_replay = $2;
5274e0e8f31SAndrey V. Elsukov 			if (p_replay > (UINT32_MAX - 32) >> 3)
5284e0e8f31SAndrey V. Elsukov 				yyerror("replay window is too large");
5299a4365d0SYoshinobu Inoue 		}
5303c62e87aSJun-ichiro itojun Hagino 	|	F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
5313c62e87aSJun-ichiro itojun Hagino 	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
5322fa1b861SKonstantin Belousov 	|	F_NATT ipaddr BLCL DECSTRING ELCL ipaddr BLCL DECSTRING ELCL
5332fa1b861SKonstantin Belousov 		{
5342fa1b861SKonstantin Belousov 			p_natt_type = UDP_ENCAP_ESPINUDP;
5352fa1b861SKonstantin Belousov 			p_natt_oai = $2;
5362fa1b861SKonstantin Belousov 			p_natt_oar = $6;
5372fa1b861SKonstantin Belousov 			if (p_natt_oai == NULL || p_natt_oar == NULL)
5382fa1b861SKonstantin Belousov 				return (-1);
5392fa1b861SKonstantin Belousov 			p_natt_sport = $4;
5402fa1b861SKonstantin Belousov 			p_natt_dport = $8;
5412fa1b861SKonstantin Belousov 		}
5422fa1b861SKonstantin Belousov 	|	F_NATT_MTU DECSTRING
5432fa1b861SKonstantin Belousov 		{
5442fa1b861SKonstantin Belousov 			p_natt_fraglen = $2;
5452fa1b861SKonstantin Belousov 		}
5469b93b2d8SKonstantin Belousov 	|	F_ESN
5479b93b2d8SKonstantin Belousov 		{
5489b93b2d8SKonstantin Belousov 			esn = true;
5499b93b2d8SKonstantin Belousov 			p_ext |= SADB_X_SAFLAGS_ESN;
5509b93b2d8SKonstantin Belousov 		}
551*83418c87SKonstantin Belousov 	|	F_HWIF STRING
552*83418c87SKonstantin Belousov 		{
553*83418c87SKonstantin Belousov 			p_hwif = $2;
554*83418c87SKonstantin Belousov 		}
5559a4365d0SYoshinobu Inoue 	;
5569a4365d0SYoshinobu Inoue 
5579a4365d0SYoshinobu Inoue 	/* definition about command for SPD management */
5589a4365d0SYoshinobu Inoue 	/* spdadd */
5599a4365d0SYoshinobu Inoue spdadd_command
560*83418c87SKonstantin Belousov 	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec spd_hwif EOT
5619a4365d0SYoshinobu Inoue 		{
562cf43a054SHajimu UMEMOTO 			int status;
563cf43a054SHajimu UMEMOTO 			struct addrinfo *src, *dst;
564cf43a054SHajimu UMEMOTO 
565cf43a054SHajimu UMEMOTO 			/* fixed port fields if ulp is icmpv6 */
566cf43a054SHajimu UMEMOTO 			if ($10.buf != NULL) {
567cf43a054SHajimu UMEMOTO 				if ($9 != IPPROTO_ICMPV6)
568cf43a054SHajimu UMEMOTO 					return -1;
569cf43a054SHajimu UMEMOTO 				free($5.buf);
570cf43a054SHajimu UMEMOTO 				free($8.buf);
571cf43a054SHajimu UMEMOTO 				if (fix_portstr(&$10, &$5, &$8))
572cf43a054SHajimu UMEMOTO 					return -1;
5739a4365d0SYoshinobu Inoue 			}
574cf43a054SHajimu UMEMOTO 
575cf43a054SHajimu UMEMOTO 			src = parse_addr($3.buf, $5.buf);
576cf43a054SHajimu UMEMOTO 			dst = parse_addr($6.buf, $8.buf);
577cf43a054SHajimu UMEMOTO 			if (!src || !dst) {
578cf43a054SHajimu UMEMOTO 				/* yyerror is already called */
579cf43a054SHajimu UMEMOTO 				return -1;
580cf43a054SHajimu UMEMOTO 			}
581cf43a054SHajimu UMEMOTO 			if (src->ai_next || dst->ai_next) {
582cf43a054SHajimu UMEMOTO 				yyerror("multiple address specified");
583cf43a054SHajimu UMEMOTO 				freeaddrinfo(src);
584cf43a054SHajimu UMEMOTO 				freeaddrinfo(dst);
585cf43a054SHajimu UMEMOTO 				return -1;
586cf43a054SHajimu UMEMOTO 			}
587cf43a054SHajimu UMEMOTO 
588cf43a054SHajimu UMEMOTO 			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
589cf43a054SHajimu UMEMOTO 			    src, $4, dst, $7);
590cf43a054SHajimu UMEMOTO 			freeaddrinfo(src);
591cf43a054SHajimu UMEMOTO 			freeaddrinfo(dst);
592cf43a054SHajimu UMEMOTO 			if (status < 0)
593cf43a054SHajimu UMEMOTO 				return -1;
594cf43a054SHajimu UMEMOTO 		}
595cf43a054SHajimu UMEMOTO 	|	SPDADD TAGGED QUOTEDSTRING policy_spec EOT
596cf43a054SHajimu UMEMOTO 		{
597cf43a054SHajimu UMEMOTO 			return -1;
598cf43a054SHajimu UMEMOTO 		}
5999a4365d0SYoshinobu Inoue 	;
6009a4365d0SYoshinobu Inoue 
601cf43a054SHajimu UMEMOTO spddelete_command
602cf43a054SHajimu UMEMOTO 	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
6039a4365d0SYoshinobu Inoue 		{
604cf43a054SHajimu UMEMOTO 			int status;
605cf43a054SHajimu UMEMOTO 			struct addrinfo *src, *dst;
606cf43a054SHajimu UMEMOTO 
607cf43a054SHajimu UMEMOTO 			/* fixed port fields if ulp is icmpv6 */
608cf43a054SHajimu UMEMOTO 			if ($10.buf != NULL) {
609cf43a054SHajimu UMEMOTO 				if ($9 != IPPROTO_ICMPV6)
610cf43a054SHajimu UMEMOTO 					return -1;
611cf43a054SHajimu UMEMOTO 				free($5.buf);
612cf43a054SHajimu UMEMOTO 				free($8.buf);
613cf43a054SHajimu UMEMOTO 				if (fix_portstr(&$10, &$5, &$8))
614cf43a054SHajimu UMEMOTO 					return -1;
6159a4365d0SYoshinobu Inoue 			}
616cf43a054SHajimu UMEMOTO 
617cf43a054SHajimu UMEMOTO 			src = parse_addr($3.buf, $5.buf);
618cf43a054SHajimu UMEMOTO 			dst = parse_addr($6.buf, $8.buf);
619cf43a054SHajimu UMEMOTO 			if (!src || !dst) {
620cf43a054SHajimu UMEMOTO 				/* yyerror is already called */
621cf43a054SHajimu UMEMOTO 				return -1;
622cf43a054SHajimu UMEMOTO 			}
623cf43a054SHajimu UMEMOTO 			if (src->ai_next || dst->ai_next) {
624cf43a054SHajimu UMEMOTO 				yyerror("multiple address specified");
625cf43a054SHajimu UMEMOTO 				freeaddrinfo(src);
626cf43a054SHajimu UMEMOTO 				freeaddrinfo(dst);
627cf43a054SHajimu UMEMOTO 				return -1;
628cf43a054SHajimu UMEMOTO 			}
629cf43a054SHajimu UMEMOTO 
630cf43a054SHajimu UMEMOTO 			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
631cf43a054SHajimu UMEMOTO 			    src, $4, dst, $7);
632cf43a054SHajimu UMEMOTO 			freeaddrinfo(src);
633cf43a054SHajimu UMEMOTO 			freeaddrinfo(dst);
634cf43a054SHajimu UMEMOTO 			if (status < 0)
635cf43a054SHajimu UMEMOTO 				return -1;
636cf43a054SHajimu UMEMOTO 		}
6379a4365d0SYoshinobu Inoue 	;
6389a4365d0SYoshinobu Inoue 
6399a4365d0SYoshinobu Inoue spddump_command:
640cf43a054SHajimu UMEMOTO 		SPDDUMP EOT
6419a4365d0SYoshinobu Inoue 		{
642cf43a054SHajimu UMEMOTO 			struct sadb_msg msg;
643cf43a054SHajimu UMEMOTO 			setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
644cf43a054SHajimu UMEMOTO 			    sizeof(msg));
645cf43a054SHajimu UMEMOTO 			sendkeymsg((char *)&msg, sizeof(msg));
6469a4365d0SYoshinobu Inoue 		}
6479a4365d0SYoshinobu Inoue 	;
6489a4365d0SYoshinobu Inoue 
6499a4365d0SYoshinobu Inoue spdflush_command:
650cf43a054SHajimu UMEMOTO 		SPDFLUSH EOT
6519a4365d0SYoshinobu Inoue 		{
652cf43a054SHajimu UMEMOTO 			struct sadb_msg msg;
653cf43a054SHajimu UMEMOTO 			setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
654cf43a054SHajimu UMEMOTO 			    sizeof(msg));
655cf43a054SHajimu UMEMOTO 			sendkeymsg((char *)&msg, sizeof(msg));
6563c62e87aSJun-ichiro itojun Hagino 		}
6579a4365d0SYoshinobu Inoue 	;
6589a4365d0SYoshinobu Inoue 
659cf43a054SHajimu UMEMOTO ipaddropts
660cf43a054SHajimu UMEMOTO 	:	/* nothing */
661cf43a054SHajimu UMEMOTO 	|	ipaddropts ipaddropt
662cf43a054SHajimu UMEMOTO 	;
6639a4365d0SYoshinobu Inoue 
664*83418c87SKonstantin Belousov spd_hwif
665*83418c87SKonstantin Belousov 	:
666*83418c87SKonstantin Belousov 	|	F_HWIF STRING
667*83418c87SKonstantin Belousov 		{
668*83418c87SKonstantin Belousov 			p_hwif = $2;
669*83418c87SKonstantin Belousov 		}
670*83418c87SKonstantin Belousov 	;
671*83418c87SKonstantin Belousov 
672cf43a054SHajimu UMEMOTO ipaddropt
673cf43a054SHajimu UMEMOTO 	:	F_AIFLAGS
674cf43a054SHajimu UMEMOTO 		{
675cf43a054SHajimu UMEMOTO 			char *p;
676cf43a054SHajimu UMEMOTO 
677cf43a054SHajimu UMEMOTO 			for (p = $1.buf + 1; *p; p++)
678cf43a054SHajimu UMEMOTO 				switch (*p) {
679cf43a054SHajimu UMEMOTO 				case '4':
680cf43a054SHajimu UMEMOTO 					p_aifamily = AF_INET;
681cf43a054SHajimu UMEMOTO 					break;
682cf43a054SHajimu UMEMOTO #ifdef INET6
683cf43a054SHajimu UMEMOTO 				case '6':
684cf43a054SHajimu UMEMOTO 					p_aifamily = AF_INET6;
685cf43a054SHajimu UMEMOTO 					break;
686cf43a054SHajimu UMEMOTO #endif
687cf43a054SHajimu UMEMOTO 				case 'n':
688cf43a054SHajimu UMEMOTO 					p_aiflags = AI_NUMERICHOST;
689cf43a054SHajimu UMEMOTO 					break;
690cf43a054SHajimu UMEMOTO 				default:
691cf43a054SHajimu UMEMOTO 					yyerror("invalid flag");
6929a4365d0SYoshinobu Inoue 					return -1;
6939a4365d0SYoshinobu Inoue 				}
6949a4365d0SYoshinobu Inoue 		}
695cf43a054SHajimu UMEMOTO 	;
6969a4365d0SYoshinobu Inoue 
697cf43a054SHajimu UMEMOTO ipaddr
698cf43a054SHajimu UMEMOTO 	:	STRING
699cf43a054SHajimu UMEMOTO 		{
700cf43a054SHajimu UMEMOTO 			$$ = parse_addr($1.buf, NULL);
701cf43a054SHajimu UMEMOTO 			if ($$ == NULL) {
702cf43a054SHajimu UMEMOTO 				/* yyerror already called by parse_addr */
703cf43a054SHajimu UMEMOTO 				return -1;
704cf43a054SHajimu UMEMOTO 			}
7059a4365d0SYoshinobu Inoue 		}
7069a4365d0SYoshinobu Inoue 	;
7079a4365d0SYoshinobu Inoue 
7089a4365d0SYoshinobu Inoue prefix
709cf43a054SHajimu UMEMOTO 	:	/*NOTHING*/ { $$ = -1; }
710cf43a054SHajimu UMEMOTO 	|	SLASH DECSTRING { $$ = $2; }
7119a4365d0SYoshinobu Inoue 	;
7129a4365d0SYoshinobu Inoue 
713cf43a054SHajimu UMEMOTO portstr
714cf43a054SHajimu UMEMOTO 	:	/*NOTHING*/
715cf43a054SHajimu UMEMOTO 		{
716cf43a054SHajimu UMEMOTO 			$$.buf = strdup("0");
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 ANY ELCL
724cf43a054SHajimu UMEMOTO 		{
725cf43a054SHajimu UMEMOTO 			$$.buf = strdup("0");
726cf43a054SHajimu UMEMOTO 			if (!$$.buf) {
727cf43a054SHajimu UMEMOTO 				yyerror("insufficient memory");
728cf43a054SHajimu UMEMOTO 				return -1;
729cf43a054SHajimu UMEMOTO 			}
730cf43a054SHajimu UMEMOTO 			$$.len = strlen($$.buf);
731cf43a054SHajimu UMEMOTO 		}
732cf43a054SHajimu UMEMOTO 	|	BLCL DECSTRING ELCL
733cf43a054SHajimu UMEMOTO 		{
734cf43a054SHajimu UMEMOTO 			char buf[20];
735cf43a054SHajimu UMEMOTO 			snprintf(buf, sizeof(buf), "%lu", $2);
736cf43a054SHajimu UMEMOTO 			$$.buf = strdup(buf);
737cf43a054SHajimu UMEMOTO 			if (!$$.buf) {
738cf43a054SHajimu UMEMOTO 				yyerror("insufficient memory");
739cf43a054SHajimu UMEMOTO 				return -1;
740cf43a054SHajimu UMEMOTO 			}
741cf43a054SHajimu UMEMOTO 			$$.len = strlen($$.buf);
742cf43a054SHajimu UMEMOTO 		}
743cf43a054SHajimu UMEMOTO 	|	BLCL STRING ELCL
744cf43a054SHajimu UMEMOTO 		{
745cf43a054SHajimu UMEMOTO 			$$ = $2;
746cf43a054SHajimu UMEMOTO 		}
7479a4365d0SYoshinobu Inoue 	;
7489a4365d0SYoshinobu Inoue 
7499a4365d0SYoshinobu Inoue upper_spec
750cf43a054SHajimu UMEMOTO 	:	DECSTRING { $$ = $1; }
751cf43a054SHajimu UMEMOTO 	|	ANY { $$ = IPSEC_ULPROTO_ANY; }
7521ba19fe8SBruce M Simpson 	|	PR_TCP { $$ = IPPROTO_TCP; }
753b40114f7SMaxim Konovalov 	|	PR_ESP { $$ = IPPROTO_ESP; }
75433841545SHajimu UMEMOTO 	|	STRING
75533841545SHajimu UMEMOTO 		{
75633841545SHajimu UMEMOTO 			struct protoent *ent;
75733841545SHajimu UMEMOTO 
75833841545SHajimu UMEMOTO 			ent = getprotobyname($1.buf);
75933841545SHajimu UMEMOTO 			if (ent)
760cf43a054SHajimu UMEMOTO 				$$ = ent->p_proto;
76133841545SHajimu UMEMOTO 			else {
76233841545SHajimu UMEMOTO 				if (strcmp("icmp6", $1.buf) == 0) {
763cf43a054SHajimu UMEMOTO 					$$ = IPPROTO_ICMPV6;
76433841545SHajimu UMEMOTO 				} else if(strcmp("ip4", $1.buf) == 0) {
765cf43a054SHajimu UMEMOTO 					$$ = IPPROTO_IPV4;
76633841545SHajimu UMEMOTO 				} else {
76733841545SHajimu UMEMOTO 					yyerror("invalid upper layer protocol");
76833841545SHajimu UMEMOTO 					return -1;
76933841545SHajimu UMEMOTO 				}
77033841545SHajimu UMEMOTO 			}
771cf43a054SHajimu UMEMOTO 			endprotoent();
772cf43a054SHajimu UMEMOTO 		}
773cf43a054SHajimu UMEMOTO 	;
774cf43a054SHajimu UMEMOTO 
775cf43a054SHajimu UMEMOTO upper_misc_spec
776cf43a054SHajimu UMEMOTO 	:	/*NOTHING*/
777cf43a054SHajimu UMEMOTO 		{
778cf43a054SHajimu UMEMOTO 			$$.buf = NULL;
779cf43a054SHajimu UMEMOTO 			$$.len = 0;
780cf43a054SHajimu UMEMOTO 		}
781cf43a054SHajimu UMEMOTO 	|	STRING
782cf43a054SHajimu UMEMOTO 		{
783cf43a054SHajimu UMEMOTO 			$$.buf = strdup($1.buf);
784cf43a054SHajimu UMEMOTO 			if (!$$.buf) {
785cf43a054SHajimu UMEMOTO 				yyerror("insufficient memory");
786cf43a054SHajimu UMEMOTO 				return -1;
787cf43a054SHajimu UMEMOTO 			}
788cf43a054SHajimu UMEMOTO 			$$.len = strlen($$.buf);
78933841545SHajimu UMEMOTO 		}
7909a4365d0SYoshinobu Inoue 	;
7919a4365d0SYoshinobu Inoue 
7929a4365d0SYoshinobu Inoue policy_spec
7939a4365d0SYoshinobu Inoue 	:	F_POLICY policy_requests
7949a4365d0SYoshinobu Inoue 		{
795cf43a054SHajimu UMEMOTO 			char *policy;
796cf43a054SHajimu UMEMOTO 
797cf43a054SHajimu UMEMOTO 			policy = ipsec_set_policy($2.buf, $2.len);
798cf43a054SHajimu UMEMOTO 			if (policy == NULL) {
7999a4365d0SYoshinobu Inoue 				yyerror(ipsec_strerror());
8009a4365d0SYoshinobu Inoue 				return -1;
8019a4365d0SYoshinobu Inoue 			}
8029a4365d0SYoshinobu Inoue 
803cf43a054SHajimu UMEMOTO 			$$.buf = policy;
804cf43a054SHajimu UMEMOTO 			$$.len = ipsec_get_policylen(policy);
8059a4365d0SYoshinobu Inoue 		}
8069a4365d0SYoshinobu Inoue 	;
8079a4365d0SYoshinobu Inoue 
8083c62e87aSJun-ichiro itojun Hagino policy_requests
8093c62e87aSJun-ichiro itojun Hagino 	:	PL_REQUESTS { $$ = $1; }
8109a4365d0SYoshinobu Inoue 	;
8119a4365d0SYoshinobu Inoue 
8129a4365d0SYoshinobu Inoue %%
8139a4365d0SYoshinobu Inoue 
8149a4365d0SYoshinobu Inoue int
815bef81bc0SKonstantin Belousov setkeymsg0(struct sadb_msg *msg, unsigned type, unsigned satype, size_t l)
8169a4365d0SYoshinobu Inoue {
8179a4365d0SYoshinobu Inoue 
818cf43a054SHajimu UMEMOTO 	msg->sadb_msg_version = PF_KEY_V2;
819cf43a054SHajimu UMEMOTO 	msg->sadb_msg_type = type;
820cf43a054SHajimu UMEMOTO 	msg->sadb_msg_errno = 0;
821cf43a054SHajimu UMEMOTO 	msg->sadb_msg_satype = satype;
822cf43a054SHajimu UMEMOTO 	msg->sadb_msg_reserved = 0;
823cf43a054SHajimu UMEMOTO 	msg->sadb_msg_seq = 0;
824cf43a054SHajimu UMEMOTO 	msg->sadb_msg_pid = getpid();
825cf43a054SHajimu UMEMOTO 	msg->sadb_msg_len = PFKEY_UNIT64(l);
826cf43a054SHajimu UMEMOTO 	return 0;
827cf43a054SHajimu UMEMOTO }
8289a4365d0SYoshinobu Inoue 
8292c1296a3SKonstantin Belousov static int
8302c1296a3SKonstantin Belousov setkeymsg_plen(struct addrinfo *s)
8312c1296a3SKonstantin Belousov {
8322c1296a3SKonstantin Belousov 	switch (s->ai_addr->sa_family) {
8332c1296a3SKonstantin Belousov #ifdef INET
8342c1296a3SKonstantin Belousov 	case AF_INET:
8352c1296a3SKonstantin Belousov 		return (sizeof(struct in_addr) << 3);
8362c1296a3SKonstantin Belousov #endif
8372c1296a3SKonstantin Belousov #ifdef INET6
8382c1296a3SKonstantin Belousov 	case AF_INET6:
8392c1296a3SKonstantin Belousov 		return (sizeof(struct in6_addr) << 3);
8402c1296a3SKonstantin Belousov #endif
8412c1296a3SKonstantin Belousov 	default:
8422c1296a3SKonstantin Belousov 		return (-1);
8432c1296a3SKonstantin Belousov 	}
8442c1296a3SKonstantin Belousov }
8452c1296a3SKonstantin Belousov 
846cf43a054SHajimu UMEMOTO /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
847cf43a054SHajimu UMEMOTO static int
848bef81bc0SKonstantin Belousov setkeymsg_spdaddr(unsigned type, unsigned upper, vchar_t *policy,
849bef81bc0SKonstantin Belousov     struct addrinfo *srcs, int splen, struct addrinfo *dsts, int dplen)
850cf43a054SHajimu UMEMOTO {
851cf43a054SHajimu UMEMOTO 	struct sadb_msg *msg;
852cf43a054SHajimu UMEMOTO 	char buf[BUFSIZ];
853cf43a054SHajimu UMEMOTO 	int l, l0;
854cf43a054SHajimu UMEMOTO 	struct sadb_address m_addr;
855*83418c87SKonstantin Belousov 	struct sadb_x_if_hw_offl m_if_hw;
856cf43a054SHajimu UMEMOTO 	struct addrinfo *s, *d;
857cf43a054SHajimu UMEMOTO 	int n;
858cf43a054SHajimu UMEMOTO 	int plen;
859cf43a054SHajimu UMEMOTO 	struct sockaddr *sa;
860cf43a054SHajimu UMEMOTO 	int salen;
8619a4365d0SYoshinobu Inoue 
862cf43a054SHajimu UMEMOTO 	msg = (struct sadb_msg *)buf;
863cf43a054SHajimu UMEMOTO 
864cf43a054SHajimu UMEMOTO 	if (!srcs || !dsts)
865cf43a054SHajimu UMEMOTO 		return -1;
866cf43a054SHajimu UMEMOTO 
867cf43a054SHajimu UMEMOTO 	/* fix up length afterwards */
868cf43a054SHajimu UMEMOTO 	setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
869cf43a054SHajimu UMEMOTO 	l = sizeof(struct sadb_msg);
870cf43a054SHajimu UMEMOTO 
871cf43a054SHajimu UMEMOTO 	memcpy(buf + l, policy->buf, policy->len);
872cf43a054SHajimu UMEMOTO 	l += policy->len;
873cf43a054SHajimu UMEMOTO 
874*83418c87SKonstantin Belousov 	if (p_hwif.len != 0) {
875*83418c87SKonstantin Belousov 		l0 = sizeof(struct sadb_x_if_hw_offl);
876*83418c87SKonstantin Belousov 		m_if_hw.sadb_x_if_hw_offl_len = PFKEY_UNIT64(l0);
877*83418c87SKonstantin Belousov 		m_if_hw.sadb_x_if_hw_offl_exttype = SADB_X_EXT_IF_HW_OFFL;
878*83418c87SKonstantin Belousov 		m_if_hw.sadb_x_if_hw_offl_flags = 0;
879*83418c87SKonstantin Belousov 		memset(&m_if_hw.sadb_x_if_hw_offl_if[0], 0,
880*83418c87SKonstantin Belousov 		    sizeof(m_if_hw.sadb_x_if_hw_offl_if));
881*83418c87SKonstantin Belousov 		strlcpy(&m_if_hw.sadb_x_if_hw_offl_if[0], p_hwif.buf,
882*83418c87SKonstantin Belousov 		    sizeof(m_if_hw.sadb_x_if_hw_offl_if));
883*83418c87SKonstantin Belousov 
884*83418c87SKonstantin Belousov 		memcpy(buf + l, &m_if_hw, l0);
885*83418c87SKonstantin Belousov 		l += l0;
886*83418c87SKonstantin Belousov 	}
887*83418c87SKonstantin Belousov 
888cf43a054SHajimu UMEMOTO 	l0 = l;
889cf43a054SHajimu UMEMOTO 	n = 0;
890cf43a054SHajimu UMEMOTO 
891cf43a054SHajimu UMEMOTO 	/* do it for all src/dst pairs */
892cf43a054SHajimu UMEMOTO 	for (s = srcs; s; s = s->ai_next) {
893cf43a054SHajimu UMEMOTO 		for (d = dsts; d; d = d->ai_next) {
894cf43a054SHajimu UMEMOTO 			/* rewind pointer */
895cf43a054SHajimu UMEMOTO 			l = l0;
896cf43a054SHajimu UMEMOTO 
897cf43a054SHajimu UMEMOTO 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
898cf43a054SHajimu UMEMOTO 				continue;
8992c1296a3SKonstantin Belousov 			plen = setkeymsg_plen(s);
9002c1296a3SKonstantin Belousov 			if (plen == -1)
901cf43a054SHajimu UMEMOTO 				continue;
9029a4365d0SYoshinobu Inoue 
903cf43a054SHajimu UMEMOTO 			/* set src */
904cf43a054SHajimu UMEMOTO 			sa = s->ai_addr;
905cf43a054SHajimu UMEMOTO 			salen = s->ai_addr->sa_len;
906cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
907cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
908cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
909cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_proto = upper;
910cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen =
911cf43a054SHajimu UMEMOTO 			    (splen >= 0 ? splen : plen);
912cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_reserved = 0;
9139a4365d0SYoshinobu Inoue 
914cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
915cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
9169a4365d0SYoshinobu Inoue 
917cf43a054SHajimu UMEMOTO 			/* set dst */
918cf43a054SHajimu UMEMOTO 			sa = d->ai_addr;
919cf43a054SHajimu UMEMOTO 			salen = d->ai_addr->sa_len;
920cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
921cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
922cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
923cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_proto = upper;
924cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen =
925cf43a054SHajimu UMEMOTO 			    (dplen >= 0 ? dplen : plen);
926cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_reserved = 0;
927cf43a054SHajimu UMEMOTO 
928cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
929cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
930cf43a054SHajimu UMEMOTO 
931cf43a054SHajimu UMEMOTO 			msg->sadb_msg_len = PFKEY_UNIT64(l);
932cf43a054SHajimu UMEMOTO 
933cf43a054SHajimu UMEMOTO 			sendkeymsg(buf, l);
934cf43a054SHajimu UMEMOTO 
935cf43a054SHajimu UMEMOTO 			n++;
936cf43a054SHajimu UMEMOTO 		}
9379a4365d0SYoshinobu Inoue 	}
9389a4365d0SYoshinobu Inoue 
939cf43a054SHajimu UMEMOTO 	if (n == 0)
940cf43a054SHajimu UMEMOTO 		return -1;
941cf43a054SHajimu UMEMOTO 	else
942cf43a054SHajimu UMEMOTO 		return 0;
9439a4365d0SYoshinobu Inoue }
9449a4365d0SYoshinobu Inoue 
945cf43a054SHajimu UMEMOTO /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
946cf43a054SHajimu UMEMOTO static int
947bef81bc0SKonstantin Belousov setkeymsg_addr(unsigned type, unsigned satype, struct addrinfo *srcs,
948bef81bc0SKonstantin Belousov     struct addrinfo *dsts, int no_spi)
9499a4365d0SYoshinobu Inoue {
950cf43a054SHajimu UMEMOTO 	struct sadb_msg *msg;
951cf43a054SHajimu UMEMOTO 	char buf[BUFSIZ];
952cf43a054SHajimu UMEMOTO 	int l, l0, len;
9539a4365d0SYoshinobu Inoue 	struct sadb_sa m_sa;
9543c62e87aSJun-ichiro itojun Hagino 	struct sadb_x_sa2 m_sa2;
9554e0e8f31SAndrey V. Elsukov 	struct sadb_x_sa_replay m_replay;
9569a4365d0SYoshinobu Inoue 	struct sadb_address m_addr;
957cf43a054SHajimu UMEMOTO 	struct addrinfo *s, *d;
958cf43a054SHajimu UMEMOTO 	int n;
959cf43a054SHajimu UMEMOTO 	int plen;
960cf43a054SHajimu UMEMOTO 	struct sockaddr *sa;
961cf43a054SHajimu UMEMOTO 	int salen;
9629a4365d0SYoshinobu Inoue 
963cf43a054SHajimu UMEMOTO 	msg = (struct sadb_msg *)buf;
964cf43a054SHajimu UMEMOTO 
965cf43a054SHajimu UMEMOTO 	if (!srcs || !dsts)
966cf43a054SHajimu UMEMOTO 		return -1;
967cf43a054SHajimu UMEMOTO 
968cf43a054SHajimu UMEMOTO 	/* fix up length afterwards */
969cf43a054SHajimu UMEMOTO 	setkeymsg0(msg, type, satype, 0);
970cf43a054SHajimu UMEMOTO 	l = sizeof(struct sadb_msg);
971cf43a054SHajimu UMEMOTO 
972cf43a054SHajimu UMEMOTO 	if (!no_spi) {
9739a4365d0SYoshinobu Inoue 		len = sizeof(struct sadb_sa);
9749a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_len = PFKEY_UNIT64(len);
9759a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_exttype = SADB_EXT_SA;
9769a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_spi = htonl(p_spi);
9774e0e8f31SAndrey V. Elsukov 		m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX:
9784e0e8f31SAndrey V. Elsukov 		    p_replay;
9799a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_state = 0;
9809a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_auth = p_alg_auth;
9819a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_encrypt = p_alg_enc;
9829a4365d0SYoshinobu Inoue 		m_sa.sadb_sa_flags = p_ext;
9839a4365d0SYoshinobu Inoue 
984cf43a054SHajimu UMEMOTO 		memcpy(buf + l, &m_sa, len);
985cf43a054SHajimu UMEMOTO 		l += len;
9869a4365d0SYoshinobu Inoue 
9873c62e87aSJun-ichiro itojun Hagino 		len = sizeof(struct sadb_x_sa2);
9883c62e87aSJun-ichiro itojun Hagino 		m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
9893c62e87aSJun-ichiro itojun Hagino 		m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
9903c62e87aSJun-ichiro itojun Hagino 		m_sa2.sadb_x_sa2_mode = p_mode;
9913c62e87aSJun-ichiro itojun Hagino 		m_sa2.sadb_x_sa2_reqid = p_reqid;
9923c62e87aSJun-ichiro itojun Hagino 
993cf43a054SHajimu UMEMOTO 		memcpy(buf + l, &m_sa2, len);
994cf43a054SHajimu UMEMOTO 		l += len;
9954e0e8f31SAndrey V. Elsukov 
9964e0e8f31SAndrey V. Elsukov 		if (p_replay > UINT8_MAX) {
9974e0e8f31SAndrey V. Elsukov 			len = sizeof(struct sadb_x_sa_replay);
9984e0e8f31SAndrey V. Elsukov 			m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
9994e0e8f31SAndrey V. Elsukov 			m_replay.sadb_x_sa_replay_exttype =
10004e0e8f31SAndrey V. Elsukov 			    SADB_X_EXT_SA_REPLAY;
10014e0e8f31SAndrey V. Elsukov 			m_replay.sadb_x_sa_replay_replay = p_replay << 3;
10024e0e8f31SAndrey V. Elsukov 
10034e0e8f31SAndrey V. Elsukov 			memcpy(buf + l, &m_replay, len);
10044e0e8f31SAndrey V. Elsukov 			l += len;
10054e0e8f31SAndrey V. Elsukov 		}
1006cf43a054SHajimu UMEMOTO 	}
1007cf43a054SHajimu UMEMOTO 
1008cf43a054SHajimu UMEMOTO 	l0 = l;
1009cf43a054SHajimu UMEMOTO 	n = 0;
1010cf43a054SHajimu UMEMOTO 
1011cf43a054SHajimu UMEMOTO 	/* do it for all src/dst pairs */
1012cf43a054SHajimu UMEMOTO 	for (s = srcs; s; s = s->ai_next) {
1013cf43a054SHajimu UMEMOTO 		for (d = dsts; d; d = d->ai_next) {
1014cf43a054SHajimu UMEMOTO 			/* rewind pointer */
1015cf43a054SHajimu UMEMOTO 			l = l0;
1016cf43a054SHajimu UMEMOTO 
1017cf43a054SHajimu UMEMOTO 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1018cf43a054SHajimu UMEMOTO 				continue;
10192c1296a3SKonstantin Belousov 			plen = setkeymsg_plen(s);
10202c1296a3SKonstantin Belousov 			if (plen == -1)
1021cf43a054SHajimu UMEMOTO 				continue;
10223c62e87aSJun-ichiro itojun Hagino 
10239a4365d0SYoshinobu Inoue 			/* set src */
1024cf43a054SHajimu UMEMOTO 			sa = s->ai_addr;
1025cf43a054SHajimu UMEMOTO 			salen = s->ai_addr->sa_len;
1026cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1027cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
10289a4365d0SYoshinobu Inoue 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
10299a4365d0SYoshinobu Inoue 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1030cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen = plen;
10319a4365d0SYoshinobu Inoue 			m_addr.sadb_address_reserved = 0;
10329a4365d0SYoshinobu Inoue 
1033cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1034cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
10359a4365d0SYoshinobu Inoue 
10369a4365d0SYoshinobu Inoue 			/* set dst */
1037cf43a054SHajimu UMEMOTO 			sa = d->ai_addr;
1038cf43a054SHajimu UMEMOTO 			salen = d->ai_addr->sa_len;
1039cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1040cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
10419a4365d0SYoshinobu Inoue 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
10429a4365d0SYoshinobu Inoue 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1043cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen = plen;
10449a4365d0SYoshinobu Inoue 			m_addr.sadb_address_reserved = 0;
10459a4365d0SYoshinobu Inoue 
1046cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1047cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
1048cf43a054SHajimu UMEMOTO 
1049cf43a054SHajimu UMEMOTO 			msg->sadb_msg_len = PFKEY_UNIT64(l);
1050cf43a054SHajimu UMEMOTO 
1051cf43a054SHajimu UMEMOTO 			sendkeymsg(buf, l);
1052cf43a054SHajimu UMEMOTO 
1053cf43a054SHajimu UMEMOTO 			n++;
10549a4365d0SYoshinobu Inoue 		}
1055cf43a054SHajimu UMEMOTO 	}
10569a4365d0SYoshinobu Inoue 
1057cf43a054SHajimu UMEMOTO 	if (n == 0)
1058cf43a054SHajimu UMEMOTO 		return -1;
1059cf43a054SHajimu UMEMOTO 	else
1060cf43a054SHajimu UMEMOTO 		return 0;
1061cf43a054SHajimu UMEMOTO }
10629a4365d0SYoshinobu Inoue 
1063cf43a054SHajimu UMEMOTO /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1064cf43a054SHajimu UMEMOTO static int
1065bef81bc0SKonstantin Belousov setkeymsg_add(unsigned type, unsigned satype, struct addrinfo *srcs,
1066bef81bc0SKonstantin Belousov     struct addrinfo *dsts)
10679a4365d0SYoshinobu Inoue {
1068cf43a054SHajimu UMEMOTO 	struct sadb_msg *msg;
1069cf43a054SHajimu UMEMOTO 	char buf[BUFSIZ];
1070cf43a054SHajimu UMEMOTO 	int l, l0, len;
1071cf43a054SHajimu UMEMOTO 	struct sadb_sa m_sa;
1072cf43a054SHajimu UMEMOTO 	struct sadb_x_sa2 m_sa2;
10733c62e87aSJun-ichiro itojun Hagino 	struct sadb_address m_addr;
10744e0e8f31SAndrey V. Elsukov 	struct sadb_x_sa_replay m_replay;
1075cf43a054SHajimu UMEMOTO 	struct addrinfo *s, *d;
10762fa1b861SKonstantin Belousov 	struct sadb_x_nat_t_type m_natt_type;
10772fa1b861SKonstantin Belousov 	struct sadb_x_nat_t_port m_natt_port;
10782fa1b861SKonstantin Belousov 	struct sadb_x_nat_t_frag m_natt_frag;
1079*83418c87SKonstantin Belousov 	struct sadb_x_if_hw_offl m_if_hw;
1080cf43a054SHajimu UMEMOTO 	int n;
1081cf43a054SHajimu UMEMOTO 	int plen;
1082cf43a054SHajimu UMEMOTO 	struct sockaddr *sa;
1083cf43a054SHajimu UMEMOTO 	int salen;
10843c62e87aSJun-ichiro itojun Hagino 
1085cf43a054SHajimu UMEMOTO 	msg = (struct sadb_msg *)buf;
1086cf43a054SHajimu UMEMOTO 
1087cf43a054SHajimu UMEMOTO 	if (!srcs || !dsts)
1088cf43a054SHajimu UMEMOTO 		return -1;
1089cf43a054SHajimu UMEMOTO 
1090cf43a054SHajimu UMEMOTO 	/* fix up length afterwards */
1091cf43a054SHajimu UMEMOTO 	setkeymsg0(msg, type, satype, 0);
1092cf43a054SHajimu UMEMOTO 	l = sizeof(struct sadb_msg);
1093cf43a054SHajimu UMEMOTO 
1094cf43a054SHajimu UMEMOTO 	/* set encryption algorithm, if present. */
1095cf43a054SHajimu UMEMOTO 	if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1096cf43a054SHajimu UMEMOTO 		struct sadb_key m_key;
1097cf43a054SHajimu UMEMOTO 
1098cf43a054SHajimu UMEMOTO 		m_key.sadb_key_len =
1099cf43a054SHajimu UMEMOTO 			PFKEY_UNIT64(sizeof(m_key)
1100cf43a054SHajimu UMEMOTO 				   + PFKEY_ALIGN8(p_key_enc_len));
1101cf43a054SHajimu UMEMOTO 		m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1102cf43a054SHajimu UMEMOTO 		m_key.sadb_key_bits = p_key_enc_len * 8;
1103cf43a054SHajimu UMEMOTO 		m_key.sadb_key_reserved = 0;
1104cf43a054SHajimu UMEMOTO 
1105cf43a054SHajimu UMEMOTO 		setvarbuf(buf, &l,
1106cf43a054SHajimu UMEMOTO 			(struct sadb_ext *)&m_key, sizeof(m_key),
1107cf43a054SHajimu UMEMOTO 			(caddr_t)p_key_enc, p_key_enc_len);
1108cf43a054SHajimu UMEMOTO 	}
1109cf43a054SHajimu UMEMOTO 
1110cf43a054SHajimu UMEMOTO 	/* set authentication algorithm, if present. */
1111cf43a054SHajimu UMEMOTO 	if (p_key_auth) {
1112cf43a054SHajimu UMEMOTO 		struct sadb_key m_key;
1113cf43a054SHajimu UMEMOTO 
1114cf43a054SHajimu UMEMOTO 		m_key.sadb_key_len =
1115cf43a054SHajimu UMEMOTO 			PFKEY_UNIT64(sizeof(m_key)
1116cf43a054SHajimu UMEMOTO 				   + PFKEY_ALIGN8(p_key_auth_len));
1117cf43a054SHajimu UMEMOTO 		m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1118cf43a054SHajimu UMEMOTO 		m_key.sadb_key_bits = p_key_auth_len * 8;
1119cf43a054SHajimu UMEMOTO 		m_key.sadb_key_reserved = 0;
1120cf43a054SHajimu UMEMOTO 
1121cf43a054SHajimu UMEMOTO 		setvarbuf(buf, &l,
1122cf43a054SHajimu UMEMOTO 			(struct sadb_ext *)&m_key, sizeof(m_key),
1123cf43a054SHajimu UMEMOTO 			(caddr_t)p_key_auth, p_key_auth_len);
1124cf43a054SHajimu UMEMOTO 	}
1125cf43a054SHajimu UMEMOTO 
1126cf43a054SHajimu UMEMOTO 	/* set lifetime for HARD */
1127cf43a054SHajimu UMEMOTO 	if (p_lt_hard != 0) {
1128cf43a054SHajimu UMEMOTO 		struct sadb_lifetime m_lt;
1129cf43a054SHajimu UMEMOTO 		u_int slen = sizeof(struct sadb_lifetime);
1130cf43a054SHajimu UMEMOTO 
1131cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1132cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1133cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_allocations = 0;
1134cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_bytes = 0;
1135cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_addtime = p_lt_hard;
1136cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_usetime = 0;
1137cf43a054SHajimu UMEMOTO 
1138cf43a054SHajimu UMEMOTO 		memcpy(buf + l, &m_lt, slen);
1139d02b24bcSHajimu UMEMOTO 		l += slen;
1140cf43a054SHajimu UMEMOTO 	}
1141cf43a054SHajimu UMEMOTO 
1142cf43a054SHajimu UMEMOTO 	/* set lifetime for SOFT */
1143cf43a054SHajimu UMEMOTO 	if (p_lt_soft != 0) {
1144cf43a054SHajimu UMEMOTO 		struct sadb_lifetime m_lt;
1145cf43a054SHajimu UMEMOTO 		u_int slen = sizeof(struct sadb_lifetime);
1146cf43a054SHajimu UMEMOTO 
1147cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1148cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1149cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_allocations = 0;
1150cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_bytes = 0;
1151cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_addtime = p_lt_soft;
1152cf43a054SHajimu UMEMOTO 		m_lt.sadb_lifetime_usetime = 0;
1153cf43a054SHajimu UMEMOTO 
1154cf43a054SHajimu UMEMOTO 		memcpy(buf + l, &m_lt, slen);
1155d02b24bcSHajimu UMEMOTO 		l += slen;
1156cf43a054SHajimu UMEMOTO 	}
1157cf43a054SHajimu UMEMOTO 
1158cf43a054SHajimu UMEMOTO 	len = sizeof(struct sadb_sa);
1159cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1160cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_exttype = SADB_EXT_SA;
1161cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_spi = htonl(p_spi);
11624e0e8f31SAndrey V. Elsukov 	m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX: p_replay;
1163cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_state = 0;
1164cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_auth = p_alg_auth;
1165cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_encrypt = p_alg_enc;
1166cf43a054SHajimu UMEMOTO 	m_sa.sadb_sa_flags = p_ext;
1167cf43a054SHajimu UMEMOTO 
1168cf43a054SHajimu UMEMOTO 	memcpy(buf + l, &m_sa, len);
1169cf43a054SHajimu UMEMOTO 	l += len;
1170cf43a054SHajimu UMEMOTO 
1171cf43a054SHajimu UMEMOTO 	len = sizeof(struct sadb_x_sa2);
1172cf43a054SHajimu UMEMOTO 	m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1173cf43a054SHajimu UMEMOTO 	m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1174cf43a054SHajimu UMEMOTO 	m_sa2.sadb_x_sa2_mode = p_mode;
1175cf43a054SHajimu UMEMOTO 	m_sa2.sadb_x_sa2_reqid = p_reqid;
1176cf43a054SHajimu UMEMOTO 
1177cf43a054SHajimu UMEMOTO 	memcpy(buf + l, &m_sa2, len);
1178cf43a054SHajimu UMEMOTO 	l += len;
1179cf43a054SHajimu UMEMOTO 
11804e0e8f31SAndrey V. Elsukov 	if (p_replay > UINT8_MAX) {
11814e0e8f31SAndrey V. Elsukov 		len = sizeof(struct sadb_x_sa_replay);
11824e0e8f31SAndrey V. Elsukov 		m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
11834e0e8f31SAndrey V. Elsukov 		m_replay.sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY;
11844e0e8f31SAndrey V. Elsukov 		m_replay.sadb_x_sa_replay_replay = p_replay << 3;
11854e0e8f31SAndrey V. Elsukov 
11864e0e8f31SAndrey V. Elsukov 		memcpy(buf + l, &m_replay, len);
11874e0e8f31SAndrey V. Elsukov 		l += len;
11884e0e8f31SAndrey V. Elsukov 	}
11892fa1b861SKonstantin Belousov 
11902fa1b861SKonstantin Belousov 	if (p_natt_type != 0) {
11912fa1b861SKonstantin Belousov 		len = sizeof(m_natt_type);
11922fa1b861SKonstantin Belousov 		memset(&m_natt_type, 0, sizeof(m_natt_type));
11932fa1b861SKonstantin Belousov 		m_natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
11942fa1b861SKonstantin Belousov 		m_natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
11952fa1b861SKonstantin Belousov 		m_natt_type.sadb_x_nat_t_type_type = p_natt_type;
11962fa1b861SKonstantin Belousov 		memcpy(buf + l, &m_natt_type, len);
11972fa1b861SKonstantin Belousov 		l += len;
11982fa1b861SKonstantin Belousov 
11992fa1b861SKonstantin Belousov 		memset(&m_addr, 0, sizeof(m_addr));
12002fa1b861SKonstantin Belousov 		m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OAI;
12012fa1b861SKonstantin Belousov 		sa = p_natt_oai->ai_addr;
12022fa1b861SKonstantin Belousov 		salen = p_natt_oai->ai_addr->sa_len;
12032fa1b861SKonstantin Belousov 		m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
12042fa1b861SKonstantin Belousov 		    PFKEY_ALIGN8(salen));
12052fa1b861SKonstantin Belousov 		m_addr.sadb_address_prefixlen = setkeymsg_plen(p_natt_oai);
12062fa1b861SKonstantin Belousov 		setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
12072fa1b861SKonstantin Belousov 		    sizeof(m_addr), (caddr_t)sa, salen);
12082fa1b861SKonstantin Belousov 
12092fa1b861SKonstantin Belousov 		len = sizeof(m_natt_port);
12102fa1b861SKonstantin Belousov 		memset(&m_natt_port, 0, sizeof(m_natt_port));
12112fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
12122fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
12132fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_port = htons(p_natt_sport);
12142fa1b861SKonstantin Belousov 		memcpy(buf + l, &m_natt_port, len);
12152fa1b861SKonstantin Belousov 		l += len;
12162fa1b861SKonstantin Belousov 
12172fa1b861SKonstantin Belousov 		memset(&m_addr, 0, sizeof(m_addr));
12182fa1b861SKonstantin Belousov 		m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OAR;
12192fa1b861SKonstantin Belousov 		sa = p_natt_oar->ai_addr;
12202fa1b861SKonstantin Belousov 		salen = p_natt_oar->ai_addr->sa_len;
12212fa1b861SKonstantin Belousov 		m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
12222fa1b861SKonstantin Belousov 		    PFKEY_ALIGN8(salen));
12232fa1b861SKonstantin Belousov 		m_addr.sadb_address_prefixlen = setkeymsg_plen(p_natt_oar);
12242fa1b861SKonstantin Belousov 		setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
12252fa1b861SKonstantin Belousov 		    sizeof(m_addr), (caddr_t)sa, salen);
12262fa1b861SKonstantin Belousov 
12272fa1b861SKonstantin Belousov 		len = sizeof(m_natt_port);
12282fa1b861SKonstantin Belousov 		memset(&m_natt_port, 0, sizeof(m_natt_port));
12292fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
12302fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
12312fa1b861SKonstantin Belousov 		m_natt_port.sadb_x_nat_t_port_port = htons(p_natt_dport);
12322fa1b861SKonstantin Belousov 		memcpy(buf + l, &m_natt_port, len);
12332fa1b861SKonstantin Belousov 		l += len;
12342fa1b861SKonstantin Belousov 
12352fa1b861SKonstantin Belousov 		if (p_natt_fraglen != -1) {
12362fa1b861SKonstantin Belousov 			len = sizeof(m_natt_frag);
12372fa1b861SKonstantin Belousov 			memset(&m_natt_port, 0, sizeof(m_natt_frag));
12382fa1b861SKonstantin Belousov 			m_natt_frag.sadb_x_nat_t_frag_len = PFKEY_UNIT64(len);
12392fa1b861SKonstantin Belousov 			m_natt_frag.sadb_x_nat_t_frag_exttype =
12402fa1b861SKonstantin Belousov 			    SADB_X_EXT_NAT_T_FRAG;
12412fa1b861SKonstantin Belousov 			m_natt_frag.sadb_x_nat_t_frag_fraglen = p_natt_fraglen;
12422fa1b861SKonstantin Belousov 			memcpy(buf + l, &m_natt_frag, len);
12432fa1b861SKonstantin Belousov 			l += len;
12442fa1b861SKonstantin Belousov 		}
12452fa1b861SKonstantin Belousov 	}
12462fa1b861SKonstantin Belousov 
1247cf43a054SHajimu UMEMOTO 	l0 = l;
1248cf43a054SHajimu UMEMOTO 	n = 0;
1249cf43a054SHajimu UMEMOTO 
1250cf43a054SHajimu UMEMOTO 	/* do it for all src/dst pairs */
1251cf43a054SHajimu UMEMOTO 	for (s = srcs; s; s = s->ai_next) {
1252cf43a054SHajimu UMEMOTO 		for (d = dsts; d; d = d->ai_next) {
1253cf43a054SHajimu UMEMOTO 			/* rewind pointer */
1254cf43a054SHajimu UMEMOTO 			l = l0;
1255cf43a054SHajimu UMEMOTO 
1256cf43a054SHajimu UMEMOTO 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1257cf43a054SHajimu UMEMOTO 				continue;
12582c1296a3SKonstantin Belousov 			plen = setkeymsg_plen(s);
12592c1296a3SKonstantin Belousov 			if (plen == -1)
1260cf43a054SHajimu UMEMOTO 				continue;
12619a4365d0SYoshinobu Inoue 
12629a4365d0SYoshinobu Inoue 			/* set src */
1263cf43a054SHajimu UMEMOTO 			sa = s->ai_addr;
1264cf43a054SHajimu UMEMOTO 			salen = s->ai_addr->sa_len;
1265cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1266cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
12679a4365d0SYoshinobu Inoue 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1268cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1269cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen = plen;
12709a4365d0SYoshinobu Inoue 			m_addr.sadb_address_reserved = 0;
12719a4365d0SYoshinobu Inoue 
1272cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1273cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
12749a4365d0SYoshinobu Inoue 
12759a4365d0SYoshinobu Inoue 			/* set dst */
1276cf43a054SHajimu UMEMOTO 			sa = d->ai_addr;
1277cf43a054SHajimu UMEMOTO 			salen = d->ai_addr->sa_len;
1278cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1279cf43a054SHajimu UMEMOTO 			    PFKEY_ALIGN8(salen));
12809a4365d0SYoshinobu Inoue 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1281cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1282cf43a054SHajimu UMEMOTO 			m_addr.sadb_address_prefixlen = plen;
12839a4365d0SYoshinobu Inoue 			m_addr.sadb_address_reserved = 0;
12849a4365d0SYoshinobu Inoue 
1285cf43a054SHajimu UMEMOTO 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1286cf43a054SHajimu UMEMOTO 			    sizeof(m_addr), (caddr_t)sa, salen);
1287cf43a054SHajimu UMEMOTO 
1288cf43a054SHajimu UMEMOTO 			msg->sadb_msg_len = PFKEY_UNIT64(l);
1289cf43a054SHajimu UMEMOTO 
1290cf43a054SHajimu UMEMOTO 			sendkeymsg(buf, l);
1291cf43a054SHajimu UMEMOTO 
1292cf43a054SHajimu UMEMOTO 			n++;
12939a4365d0SYoshinobu Inoue 		}
12949a4365d0SYoshinobu Inoue 	}
12959a4365d0SYoshinobu Inoue 
1296*83418c87SKonstantin Belousov 	if (p_hwif.len != 0) {
1297*83418c87SKonstantin Belousov 		len = sizeof(struct sadb_x_if_hw_offl);
1298*83418c87SKonstantin Belousov 		m_if_hw.sadb_x_if_hw_offl_len = PFKEY_UNIT64(len);
1299*83418c87SKonstantin Belousov 		m_if_hw.sadb_x_if_hw_offl_exttype = SADB_X_EXT_IF_HW_OFFL;
1300*83418c87SKonstantin Belousov 		m_if_hw.sadb_x_if_hw_offl_flags = 0;
1301*83418c87SKonstantin Belousov 		memset(&m_if_hw.sadb_x_if_hw_offl_if[0], 0,
1302*83418c87SKonstantin Belousov 		    sizeof(m_if_hw.sadb_x_if_hw_offl_if));
1303*83418c87SKonstantin Belousov 		strlcpy(&m_if_hw.sadb_x_if_hw_offl_if[0], p_hwif.buf,
1304*83418c87SKonstantin Belousov 		    sizeof(m_if_hw.sadb_x_if_hw_offl_if));
1305*83418c87SKonstantin Belousov 
1306*83418c87SKonstantin Belousov 		memcpy(buf + l, &m_if_hw, len);
1307*83418c87SKonstantin Belousov 		l += len;
1308*83418c87SKonstantin Belousov 	}
1309*83418c87SKonstantin Belousov 
1310cf43a054SHajimu UMEMOTO 	if (n == 0)
1311cf43a054SHajimu UMEMOTO 		return -1;
1312cf43a054SHajimu UMEMOTO 	else
13139a4365d0SYoshinobu Inoue 		return 0;
13149a4365d0SYoshinobu Inoue }
13159a4365d0SYoshinobu Inoue 
13163c62e87aSJun-ichiro itojun Hagino static struct addrinfo *
1317bef81bc0SKonstantin Belousov parse_addr(char *host, char *port)
13183c62e87aSJun-ichiro itojun Hagino {
13193c62e87aSJun-ichiro itojun Hagino 	struct addrinfo hints, *res = NULL;
13203c62e87aSJun-ichiro itojun Hagino 	int error;
13213c62e87aSJun-ichiro itojun Hagino 
13223c62e87aSJun-ichiro itojun Hagino 	memset(&hints, 0, sizeof(hints));
1323cf43a054SHajimu UMEMOTO 	hints.ai_family = p_aifamily;
1324cf43a054SHajimu UMEMOTO 	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
1325cf43a054SHajimu UMEMOTO 	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
1326cf43a054SHajimu UMEMOTO 	hints.ai_flags = p_aiflags;
13273c62e87aSJun-ichiro itojun Hagino 	error = getaddrinfo(host, port, &hints, &res);
13283c62e87aSJun-ichiro itojun Hagino 	if (error != 0) {
13293c62e87aSJun-ichiro itojun Hagino 		yyerror(gai_strerror(error));
13303c62e87aSJun-ichiro itojun Hagino 		return NULL;
13313c62e87aSJun-ichiro itojun Hagino 	}
13323c62e87aSJun-ichiro itojun Hagino 	return res;
13333c62e87aSJun-ichiro itojun Hagino }
13343c62e87aSJun-ichiro itojun Hagino 
13359a4365d0SYoshinobu Inoue static int
1336bef81bc0SKonstantin Belousov fix_portstr(vchar_t *spec, vchar_t *sport, vchar_t *dport)
13379a4365d0SYoshinobu Inoue {
1338cf43a054SHajimu UMEMOTO 	char *p, *p2;
1339cf43a054SHajimu UMEMOTO 	u_int l;
1340cf43a054SHajimu UMEMOTO 
1341cf43a054SHajimu UMEMOTO 	l = 0;
1342cf43a054SHajimu UMEMOTO 	for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++)
1343cf43a054SHajimu UMEMOTO 		;
1344cf43a054SHajimu UMEMOTO 	if (*p == '\0') {
1345cf43a054SHajimu UMEMOTO 		p2 = "0";
1346cf43a054SHajimu UMEMOTO 	} else {
1347cf43a054SHajimu UMEMOTO 		if (*p == ',') {
1348cf43a054SHajimu UMEMOTO 			*p = '\0';
1349cf43a054SHajimu UMEMOTO 			p2 = ++p;
1350cf43a054SHajimu UMEMOTO 		}
1351cf43a054SHajimu UMEMOTO 		for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1352cf43a054SHajimu UMEMOTO 			;
1353cf43a054SHajimu UMEMOTO 		if (*p != '\0' || *p2 == '\0') {
1354cf43a054SHajimu UMEMOTO 			yyerror("invalid an upper layer protocol spec");
1355cf43a054SHajimu UMEMOTO 			return -1;
1356cf43a054SHajimu UMEMOTO 		}
1357cf43a054SHajimu UMEMOTO 	}
1358cf43a054SHajimu UMEMOTO 
1359cf43a054SHajimu UMEMOTO 	sport->buf = strdup(spec->buf);
1360cf43a054SHajimu UMEMOTO 	if (!sport->buf) {
1361cf43a054SHajimu UMEMOTO 		yyerror("insufficient memory");
1362cf43a054SHajimu UMEMOTO 		return -1;
1363cf43a054SHajimu UMEMOTO 	}
1364cf43a054SHajimu UMEMOTO 	sport->len = strlen(sport->buf);
1365cf43a054SHajimu UMEMOTO 	dport->buf = strdup(p2);
1366cf43a054SHajimu UMEMOTO 	if (!dport->buf) {
1367cf43a054SHajimu UMEMOTO 		yyerror("insufficient memory");
1368cf43a054SHajimu UMEMOTO 		return -1;
1369cf43a054SHajimu UMEMOTO 	}
1370cf43a054SHajimu UMEMOTO 	dport->len = strlen(dport->buf);
1371cf43a054SHajimu UMEMOTO 
1372cf43a054SHajimu UMEMOTO 	return 0;
1373cf43a054SHajimu UMEMOTO }
1374cf43a054SHajimu UMEMOTO 
1375cf43a054SHajimu UMEMOTO static int
1376bef81bc0SKonstantin Belousov setvarbuf(char *buf, int *off, struct sadb_ext *ebuf, int elen, caddr_t vbuf,
1377bef81bc0SKonstantin Belousov     int vlen)
1378cf43a054SHajimu UMEMOTO {
1379cf43a054SHajimu UMEMOTO 	memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1380cf43a054SHajimu UMEMOTO 	memcpy(buf + *off, (caddr_t)ebuf, elen);
1381cf43a054SHajimu UMEMOTO 	memcpy(buf + *off + elen, vbuf, vlen);
13829a4365d0SYoshinobu Inoue 	(*off) += PFKEY_ALIGN8(elen + vlen);
13839a4365d0SYoshinobu Inoue 
13849a4365d0SYoshinobu Inoue 	return 0;
13859a4365d0SYoshinobu Inoue }
13869a4365d0SYoshinobu Inoue 
13879a4365d0SYoshinobu Inoue void
1388bef81bc0SKonstantin Belousov parse_init(void)
13899a4365d0SYoshinobu Inoue {
13909a4365d0SYoshinobu Inoue 	p_spi = 0;
13919a4365d0SYoshinobu Inoue 
13923c62e87aSJun-ichiro itojun Hagino 	p_ext = SADB_X_EXT_CYCSEQ;
13939a4365d0SYoshinobu Inoue 	p_alg_enc = SADB_EALG_NONE;
13949a4365d0SYoshinobu Inoue 	p_alg_auth = SADB_AALG_NONE;
13959a4365d0SYoshinobu Inoue 	p_mode = IPSEC_MODE_ANY;
13963c62e87aSJun-ichiro itojun Hagino 	p_reqid = 0;
13973c62e87aSJun-ichiro itojun Hagino 	p_replay = 0;
13989a4365d0SYoshinobu Inoue 	p_key_enc_len = p_key_auth_len = 0;
13999a4365d0SYoshinobu Inoue 	p_key_enc = p_key_auth = 0;
14009a4365d0SYoshinobu Inoue 	p_lt_hard = p_lt_soft = 0;
14019a4365d0SYoshinobu Inoue 
1402cf43a054SHajimu UMEMOTO 	p_aiflags = 0;
1403cf43a054SHajimu UMEMOTO 	p_aifamily = PF_UNSPEC;
14042fa1b861SKonstantin Belousov 
14052fa1b861SKonstantin Belousov 	p_natt_type = 0;
14062fa1b861SKonstantin Belousov 	p_natt_oai = p_natt_oar = NULL;
14072fa1b861SKonstantin Belousov 	p_natt_sport = p_natt_dport = 0;
14082fa1b861SKonstantin Belousov 	p_natt_fraglen = -1;
14099b93b2d8SKonstantin Belousov 
14109b93b2d8SKonstantin Belousov 	esn = false;
1411*83418c87SKonstantin Belousov 	p_hwif.len = 0;
1412*83418c87SKonstantin Belousov 	p_hwif.buf = NULL;
14139a4365d0SYoshinobu Inoue }
14149a4365d0SYoshinobu Inoue 
14159a4365d0SYoshinobu Inoue void
1416bef81bc0SKonstantin Belousov free_buffer(void)
14179a4365d0SYoshinobu Inoue {
1418cf43a054SHajimu UMEMOTO 	/* we got tons of memory leaks in the parser anyways, leave them */
14199a4365d0SYoshinobu Inoue }
1420