parse.y revision 286143
1/*	$FreeBSD: head/sbin/setkey/parse.y 286143 2015-07-31 23:40:18Z gnn $	*/
2/*	$KAME: parse.y,v 1.83 2004/05/18 08:48:23 sakane Exp $	*/
3
4/*
5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33%{
34#include <sys/types.h>
35#include <sys/param.h>
36#include <sys/socket.h>
37
38#include <net/route.h>
39#include <netinet/in.h>
40#include <net/pfkeyv2.h>
41#include <netipsec/key_var.h>
42#include <netipsec/ipsec.h>
43#include <arpa/inet.h>
44
45#include <string.h>
46#include <unistd.h>
47#include <stdio.h>
48#include <netdb.h>
49#include <ctype.h>
50#include <errno.h>
51
52#include "libpfkey.h"
53#include "vchar.h"
54
55#define ATOX(c) \
56  (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10)))
57
58u_int32_t p_spi;
59u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
60u_int32_t p_reqid;
61u_int p_key_enc_len, p_key_auth_len;
62caddr_t p_key_enc, p_key_auth;
63time_t p_lt_hard, p_lt_soft;
64
65static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
66
67static struct addrinfo *parse_addr(char *, char *);
68static int fix_portstr(vchar_t *, vchar_t *, vchar_t *);
69static int setvarbuf(char *, int *, struct sadb_ext *, int, caddr_t, int);
70void parse_init(void);
71void free_buffer(void);
72
73int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t);
74static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *,
75	struct addrinfo *, int, struct addrinfo *, int);
76static int setkeymsg_addr(unsigned int, unsigned int,
77	struct addrinfo *, struct addrinfo *, int);
78static int setkeymsg_add(unsigned int, unsigned int,
79	struct addrinfo *, struct addrinfo *);
80extern int setkeymsg(char *, size_t *);
81extern int sendkeymsg(char *, size_t);
82
83extern int yylex(void);
84extern void yyfatal(const char *);
85extern void yyerror(const char *);
86%}
87
88%union {
89	int num;
90	unsigned long ulnum;
91	vchar_t val;
92	struct addrinfo *res;
93}
94
95%token EOT SLASH BLCL ELCL
96%token ADD GET DELETE DELETEALL FLUSH DUMP
97%token PR_ESP PR_AH PR_IPCOMP PR_TCP
98%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
99%token F_MODE MODE F_REQID
100%token F_EXT EXTENSION NOCYCLICSEQ
101%token ALG_AUTH ALG_AUTH_NOKEY
102%token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
103%token ALG_ENC_SALT
104%token ALG_COMP
105%token F_LIFETIME_HARD F_LIFETIME_SOFT
106%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
107	/* SPD management */
108%token SPDADD SPDDELETE SPDDUMP SPDFLUSH
109%token F_POLICY PL_REQUESTS
110%token F_AIFLAGS
111%token TAGGED
112
113%type <num> prefix protocol_spec upper_spec
114%type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
115%type <num> ALG_ENC_SALT
116%type <num> ALG_AUTH ALG_AUTH_NOKEY
117%type <num> ALG_COMP
118%type <num> PR_ESP PR_AH PR_IPCOMP PR_TCP
119%type <num> EXTENSION MODE
120%type <ulnum> DECSTRING
121%type <val> PL_REQUESTS portstr key_string
122%type <val> policy_requests
123%type <val> QUOTEDSTRING HEXSTRING STRING
124%type <val> F_AIFLAGS
125%type <val> upper_misc_spec policy_spec
126%type <res> ipaddr
127
128%%
129commands
130	:	/*NOTHING*/
131	|	commands command
132		{
133			free_buffer();
134			parse_init();
135		}
136	;
137
138command
139	:	add_command
140	|	get_command
141	|	delete_command
142	|	deleteall_command
143	|	flush_command
144	|	dump_command
145	|	spdadd_command
146	|	spddelete_command
147	|	spddump_command
148	|	spdflush_command
149	;
150	/* commands concerned with management, there is in tail of this file. */
151
152	/* add command */
153add_command
154	:	ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT
155		{
156			int status;
157
158			status = setkeymsg_add(SADB_ADD, $5, $3, $4);
159			if (status < 0)
160				return -1;
161		}
162	;
163
164	/* delete */
165delete_command
166	:	DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
167		{
168			int status;
169
170			if ($3->ai_next || $4->ai_next) {
171				yyerror("multiple address specified");
172				return -1;
173			}
174			if (p_mode != IPSEC_MODE_ANY)
175				yyerror("WARNING: mode is obsolete");
176
177			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
178			if (status < 0)
179				return -1;
180		}
181	;
182
183	/* deleteall command */
184deleteall_command
185	:	DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
186		{
187			int status;
188
189			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
190			if (status < 0)
191				return -1;
192		}
193	;
194
195	/* get command */
196get_command
197	:	GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
198		{
199			int status;
200
201			if (p_mode != IPSEC_MODE_ANY)
202				yyerror("WARNING: mode is obsolete");
203
204			status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
205			if (status < 0)
206				return -1;
207		}
208	;
209
210	/* flush */
211flush_command
212	:	FLUSH protocol_spec EOT
213		{
214			struct sadb_msg msg;
215			setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
216			sendkeymsg((char *)&msg, sizeof(msg));
217		}
218	;
219
220	/* dump */
221dump_command
222	:	DUMP protocol_spec EOT
223		{
224			struct sadb_msg msg;
225			setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
226			sendkeymsg((char *)&msg, sizeof(msg));
227		}
228	;
229
230protocol_spec
231	:	/*NOTHING*/
232		{
233			$$ = SADB_SATYPE_UNSPEC;
234		}
235	|	PR_ESP
236		{
237			$$ = SADB_SATYPE_ESP;
238			if ($1 == 1)
239				p_ext |= SADB_X_EXT_OLD;
240			else
241				p_ext &= ~SADB_X_EXT_OLD;
242		}
243	|	PR_AH
244		{
245			$$ = SADB_SATYPE_AH;
246			if ($1 == 1)
247				p_ext |= SADB_X_EXT_OLD;
248			else
249				p_ext &= ~SADB_X_EXT_OLD;
250		}
251	|	PR_IPCOMP
252		{
253			$$ = SADB_X_SATYPE_IPCOMP;
254		}
255	|	PR_TCP
256		{
257			$$ = SADB_X_SATYPE_TCPSIGNATURE;
258		}
259	;
260
261spi
262	:	DECSTRING { p_spi = $1; }
263	|	HEXSTRING
264		{
265			char *ep;
266			unsigned long v;
267
268			ep = NULL;
269			v = strtoul($1.buf, &ep, 16);
270			if (!ep || *ep) {
271				yyerror("invalid SPI");
272				return -1;
273			}
274			if (v & ~0xffffffff) {
275				yyerror("SPI too big.");
276				return -1;
277			}
278
279			p_spi = v;
280		}
281	;
282
283algorithm_spec
284	:	esp_spec
285	|	ah_spec
286	|	ipcomp_spec
287	;
288
289esp_spec
290	:	F_ENC enc_alg F_AUTH auth_alg
291	|	F_ENC enc_alg
292	;
293
294ah_spec
295	:	F_AUTH auth_alg
296	;
297
298ipcomp_spec
299	:	F_COMP ALG_COMP
300		{
301			if ($2 < 0) {
302				yyerror("unsupported algorithm");
303				return -1;
304			}
305			p_alg_enc = $2;
306		}
307	|	F_COMP ALG_COMP F_RAWCPI
308		{
309			if ($2 < 0) {
310				yyerror("unsupported algorithm");
311				return -1;
312			}
313			p_alg_enc = $2;
314			p_ext |= SADB_X_EXT_RAWCPI;
315		}
316	;
317
318enc_alg
319	:	ALG_ENC_NOKEY {
320			if ($1 < 0) {
321				yyerror("unsupported algorithm");
322				return -1;
323			}
324			p_alg_enc = $1;
325
326			p_key_enc_len = 0;
327			p_key_enc = NULL;
328			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
329			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
330				yyerror(ipsec_strerror());
331				return -1;
332			}
333		}
334	|	ALG_ENC key_string {
335			if ($1 < 0) {
336				yyerror("unsupported algorithm");
337				return -1;
338			}
339			p_alg_enc = $1;
340
341			p_key_enc_len = $2.len;
342			p_key_enc = $2.buf;
343			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
344			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
345				yyerror(ipsec_strerror());
346				return -1;
347			}
348		}
349	|	ALG_ENC_OLD {
350			if ($1 < 0) {
351				yyerror("unsupported algorithm");
352				return -1;
353			}
354			yyerror("WARNING: obsolete algorithm");
355			p_alg_enc = $1;
356
357			p_key_enc_len = 0;
358			p_key_enc = NULL;
359			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
360			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
361				yyerror(ipsec_strerror());
362				return -1;
363			}
364		}
365	|	ALG_ENC_DESDERIV key_string
366		{
367			if ($1 < 0) {
368				yyerror("unsupported algorithm");
369				return -1;
370			}
371			p_alg_enc = $1;
372			if (p_ext & SADB_X_EXT_OLD) {
373				yyerror("algorithm mismatched");
374				return -1;
375			}
376			p_ext |= SADB_X_EXT_DERIV;
377
378			p_key_enc_len = $2.len;
379			p_key_enc = $2.buf;
380			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
381			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
382				yyerror(ipsec_strerror());
383				return -1;
384			}
385		}
386	|	ALG_ENC_DES32IV key_string
387		{
388			if ($1 < 0) {
389				yyerror("unsupported algorithm");
390				return -1;
391			}
392			p_alg_enc = $1;
393			if (!(p_ext & SADB_X_EXT_OLD)) {
394				yyerror("algorithm mismatched");
395				return -1;
396			}
397			p_ext |= SADB_X_EXT_IV4B;
398
399			p_key_enc_len = $2.len;
400			p_key_enc = $2.buf;
401			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
402			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
403				yyerror(ipsec_strerror());
404				return -1;
405			}
406		}
407	|	ALG_ENC_SALT key_string
408		{
409			if ($1 < 0) {
410				yyerror("unsupported algorithm");
411				return -1;
412			}
413			p_alg_enc = $1;
414
415			p_key_enc_len = $2.len;
416
417			p_key_enc = $2.buf;
418			/*
419			 * Salted keys include a 4 byte value that is
420			 * not part of the key.
421			 */
422			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
423			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len - 4)) < 0) {
424				yyerror(ipsec_strerror());
425				return -1;
426			}
427		}
428	;
429
430auth_alg
431	:	ALG_AUTH key_string {
432			if ($1 < 0) {
433				yyerror("unsupported algorithm");
434				return -1;
435			}
436			p_alg_auth = $1;
437
438			p_key_auth_len = $2.len;
439			p_key_auth = $2.buf;
440
441			if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
442				if ((p_key_auth_len < 1) || (p_key_auth_len >
443				    80))
444					return -1;
445			} else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
446			    p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
447				yyerror(ipsec_strerror());
448				return -1;
449			}
450		}
451	|	ALG_AUTH_NOKEY {
452			if ($1 < 0) {
453				yyerror("unsupported algorithm");
454				return -1;
455			}
456			p_alg_auth = $1;
457
458			p_key_auth_len = 0;
459			p_key_auth = NULL;
460		}
461	;
462
463key_string
464	:	QUOTEDSTRING
465		{
466			$$ = $1;
467		}
468	|	HEXSTRING
469		{
470			caddr_t pp_key;
471			caddr_t bp;
472			caddr_t yp = $1.buf;
473			int l;
474
475			l = strlen(yp) % 2 + strlen(yp) / 2;
476			if ((pp_key = malloc(l)) == 0) {
477				yyerror("not enough core");
478				return -1;
479			}
480			memset(pp_key, 0, l);
481
482			bp = pp_key;
483			if (strlen(yp) % 2) {
484				*bp = ATOX(yp[0]);
485				yp++, bp++;
486			}
487			while (*yp) {
488				*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
489				yp += 2, bp++;
490			}
491
492			$$.len = l;
493			$$.buf = pp_key;
494		}
495	;
496
497extension_spec
498	:	/*NOTHING*/
499	|	extension_spec extension
500	;
501
502extension
503	:	F_EXT EXTENSION { p_ext |= $2; }
504	|	F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
505	|	F_MODE MODE { p_mode = $2; }
506	|	F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
507	|	F_REQID DECSTRING { p_reqid = $2; }
508	|	F_REPLAY DECSTRING
509		{
510			if ((p_ext & SADB_X_EXT_OLD) != 0) {
511				yyerror("replay prevention cannot be used with "
512				    "ah/esp-old");
513				return -1;
514			}
515			p_replay = $2;
516		}
517	|	F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
518	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
519	;
520
521	/* definition about command for SPD management */
522	/* spdadd */
523spdadd_command
524	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
525		{
526			int status;
527			struct addrinfo *src, *dst;
528
529			/* fixed port fields if ulp is icmpv6 */
530			if ($10.buf != NULL) {
531				if ($9 != IPPROTO_ICMPV6)
532					return -1;
533				free($5.buf);
534				free($8.buf);
535				if (fix_portstr(&$10, &$5, &$8))
536					return -1;
537			}
538
539			src = parse_addr($3.buf, $5.buf);
540			dst = parse_addr($6.buf, $8.buf);
541			if (!src || !dst) {
542				/* yyerror is already called */
543				return -1;
544			}
545			if (src->ai_next || dst->ai_next) {
546				yyerror("multiple address specified");
547				freeaddrinfo(src);
548				freeaddrinfo(dst);
549				return -1;
550			}
551
552			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
553			    src, $4, dst, $7);
554			freeaddrinfo(src);
555			freeaddrinfo(dst);
556			if (status < 0)
557				return -1;
558		}
559	|	SPDADD TAGGED QUOTEDSTRING policy_spec EOT
560		{
561			return -1;
562		}
563	;
564
565spddelete_command
566	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
567		{
568			int status;
569			struct addrinfo *src, *dst;
570
571			/* fixed port fields if ulp is icmpv6 */
572			if ($10.buf != NULL) {
573				if ($9 != IPPROTO_ICMPV6)
574					return -1;
575				free($5.buf);
576				free($8.buf);
577				if (fix_portstr(&$10, &$5, &$8))
578					return -1;
579			}
580
581			src = parse_addr($3.buf, $5.buf);
582			dst = parse_addr($6.buf, $8.buf);
583			if (!src || !dst) {
584				/* yyerror is already called */
585				return -1;
586			}
587			if (src->ai_next || dst->ai_next) {
588				yyerror("multiple address specified");
589				freeaddrinfo(src);
590				freeaddrinfo(dst);
591				return -1;
592			}
593
594			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
595			    src, $4, dst, $7);
596			freeaddrinfo(src);
597			freeaddrinfo(dst);
598			if (status < 0)
599				return -1;
600		}
601	;
602
603spddump_command:
604		SPDDUMP EOT
605		{
606			struct sadb_msg msg;
607			setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
608			    sizeof(msg));
609			sendkeymsg((char *)&msg, sizeof(msg));
610		}
611	;
612
613spdflush_command:
614		SPDFLUSH EOT
615		{
616			struct sadb_msg msg;
617			setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
618			    sizeof(msg));
619			sendkeymsg((char *)&msg, sizeof(msg));
620		}
621	;
622
623ipaddropts
624	:	/* nothing */
625	|	ipaddropts ipaddropt
626	;
627
628ipaddropt
629	:	F_AIFLAGS
630		{
631			char *p;
632
633			for (p = $1.buf + 1; *p; p++)
634				switch (*p) {
635				case '4':
636					p_aifamily = AF_INET;
637					break;
638#ifdef INET6
639				case '6':
640					p_aifamily = AF_INET6;
641					break;
642#endif
643				case 'n':
644					p_aiflags = AI_NUMERICHOST;
645					break;
646				default:
647					yyerror("invalid flag");
648					return -1;
649				}
650		}
651	;
652
653ipaddr
654	:	STRING
655		{
656			$$ = parse_addr($1.buf, NULL);
657			if ($$ == NULL) {
658				/* yyerror already called by parse_addr */
659				return -1;
660			}
661		}
662	;
663
664prefix
665	:	/*NOTHING*/ { $$ = -1; }
666	|	SLASH DECSTRING { $$ = $2; }
667	;
668
669portstr
670	:	/*NOTHING*/
671		{
672			$$.buf = strdup("0");
673			if (!$$.buf) {
674				yyerror("insufficient memory");
675				return -1;
676			}
677			$$.len = strlen($$.buf);
678		}
679	|	BLCL ANY ELCL
680		{
681			$$.buf = strdup("0");
682			if (!$$.buf) {
683				yyerror("insufficient memory");
684				return -1;
685			}
686			$$.len = strlen($$.buf);
687		}
688	|	BLCL DECSTRING ELCL
689		{
690			char buf[20];
691			snprintf(buf, sizeof(buf), "%lu", $2);
692			$$.buf = strdup(buf);
693			if (!$$.buf) {
694				yyerror("insufficient memory");
695				return -1;
696			}
697			$$.len = strlen($$.buf);
698		}
699	|	BLCL STRING ELCL
700		{
701			$$ = $2;
702		}
703	;
704
705upper_spec
706	:	DECSTRING { $$ = $1; }
707	|	ANY { $$ = IPSEC_ULPROTO_ANY; }
708	|	PR_TCP { $$ = IPPROTO_TCP; }
709	|	PR_ESP { $$ = IPPROTO_ESP; }
710	|	STRING
711		{
712			struct protoent *ent;
713
714			ent = getprotobyname($1.buf);
715			if (ent)
716				$$ = ent->p_proto;
717			else {
718				if (strcmp("icmp6", $1.buf) == 0) {
719					$$ = IPPROTO_ICMPV6;
720				} else if(strcmp("ip4", $1.buf) == 0) {
721					$$ = IPPROTO_IPV4;
722				} else {
723					yyerror("invalid upper layer protocol");
724					return -1;
725				}
726			}
727			endprotoent();
728		}
729	;
730
731upper_misc_spec
732	:	/*NOTHING*/
733		{
734			$$.buf = NULL;
735			$$.len = 0;
736		}
737	|	STRING
738		{
739			$$.buf = strdup($1.buf);
740			if (!$$.buf) {
741				yyerror("insufficient memory");
742				return -1;
743			}
744			$$.len = strlen($$.buf);
745		}
746	;
747
748policy_spec
749	:	F_POLICY policy_requests
750		{
751			char *policy;
752
753			policy = ipsec_set_policy($2.buf, $2.len);
754			if (policy == NULL) {
755				yyerror(ipsec_strerror());
756				return -1;
757			}
758
759			$$.buf = policy;
760			$$.len = ipsec_get_policylen(policy);
761		}
762	;
763
764policy_requests
765	:	PL_REQUESTS { $$ = $1; }
766	;
767
768%%
769
770int
771setkeymsg0(msg, type, satype, l)
772	struct sadb_msg *msg;
773	unsigned int type;
774	unsigned int satype;
775	size_t l;
776{
777
778	msg->sadb_msg_version = PF_KEY_V2;
779	msg->sadb_msg_type = type;
780	msg->sadb_msg_errno = 0;
781	msg->sadb_msg_satype = satype;
782	msg->sadb_msg_reserved = 0;
783	msg->sadb_msg_seq = 0;
784	msg->sadb_msg_pid = getpid();
785	msg->sadb_msg_len = PFKEY_UNIT64(l);
786	return 0;
787}
788
789/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
790static int
791setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen)
792	unsigned int type;
793	unsigned int upper;
794	vchar_t *policy;
795	struct addrinfo *srcs;
796	int splen;
797	struct addrinfo *dsts;
798	int dplen;
799{
800	struct sadb_msg *msg;
801	char buf[BUFSIZ];
802	int l, l0;
803	struct sadb_address m_addr;
804	struct addrinfo *s, *d;
805	int n;
806	int plen;
807	struct sockaddr *sa;
808	int salen;
809
810	msg = (struct sadb_msg *)buf;
811
812	if (!srcs || !dsts)
813		return -1;
814
815	/* fix up length afterwards */
816	setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
817	l = sizeof(struct sadb_msg);
818
819	memcpy(buf + l, policy->buf, policy->len);
820	l += policy->len;
821
822	l0 = l;
823	n = 0;
824
825	/* do it for all src/dst pairs */
826	for (s = srcs; s; s = s->ai_next) {
827		for (d = dsts; d; d = d->ai_next) {
828			/* rewind pointer */
829			l = l0;
830
831			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
832				continue;
833			switch (s->ai_addr->sa_family) {
834			case AF_INET:
835				plen = sizeof(struct in_addr) << 3;
836				break;
837#ifdef INET6
838			case AF_INET6:
839				plen = sizeof(struct in6_addr) << 3;
840				break;
841#endif
842			default:
843				continue;
844			}
845
846			/* set src */
847			sa = s->ai_addr;
848			salen = s->ai_addr->sa_len;
849			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
850			    PFKEY_ALIGN8(salen));
851			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
852			m_addr.sadb_address_proto = upper;
853			m_addr.sadb_address_prefixlen =
854			    (splen >= 0 ? splen : plen);
855			m_addr.sadb_address_reserved = 0;
856
857			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
858			    sizeof(m_addr), (caddr_t)sa, salen);
859
860			/* set dst */
861			sa = d->ai_addr;
862			salen = d->ai_addr->sa_len;
863			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
864			    PFKEY_ALIGN8(salen));
865			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
866			m_addr.sadb_address_proto = upper;
867			m_addr.sadb_address_prefixlen =
868			    (dplen >= 0 ? dplen : plen);
869			m_addr.sadb_address_reserved = 0;
870
871			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
872			    sizeof(m_addr), (caddr_t)sa, salen);
873
874			msg->sadb_msg_len = PFKEY_UNIT64(l);
875
876			sendkeymsg(buf, l);
877
878			n++;
879		}
880	}
881
882	if (n == 0)
883		return -1;
884	else
885		return 0;
886}
887
888/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
889static int
890setkeymsg_addr(type, satype, srcs, dsts, no_spi)
891	unsigned int type;
892	unsigned int satype;
893	struct addrinfo *srcs;
894	struct addrinfo *dsts;
895	int no_spi;
896{
897	struct sadb_msg *msg;
898	char buf[BUFSIZ];
899	int l, l0, len;
900	struct sadb_sa m_sa;
901	struct sadb_x_sa2 m_sa2;
902	struct sadb_address m_addr;
903	struct addrinfo *s, *d;
904	int n;
905	int plen;
906	struct sockaddr *sa;
907	int salen;
908
909	msg = (struct sadb_msg *)buf;
910
911	if (!srcs || !dsts)
912		return -1;
913
914	/* fix up length afterwards */
915	setkeymsg0(msg, type, satype, 0);
916	l = sizeof(struct sadb_msg);
917
918	if (!no_spi) {
919		len = sizeof(struct sadb_sa);
920		m_sa.sadb_sa_len = PFKEY_UNIT64(len);
921		m_sa.sadb_sa_exttype = SADB_EXT_SA;
922		m_sa.sadb_sa_spi = htonl(p_spi);
923		m_sa.sadb_sa_replay = p_replay;
924		m_sa.sadb_sa_state = 0;
925		m_sa.sadb_sa_auth = p_alg_auth;
926		m_sa.sadb_sa_encrypt = p_alg_enc;
927		m_sa.sadb_sa_flags = p_ext;
928
929		memcpy(buf + l, &m_sa, len);
930		l += len;
931
932		len = sizeof(struct sadb_x_sa2);
933		m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
934		m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
935		m_sa2.sadb_x_sa2_mode = p_mode;
936		m_sa2.sadb_x_sa2_reqid = p_reqid;
937
938		memcpy(buf + l, &m_sa2, len);
939		l += len;
940	}
941
942	l0 = l;
943	n = 0;
944
945	/* do it for all src/dst pairs */
946	for (s = srcs; s; s = s->ai_next) {
947		for (d = dsts; d; d = d->ai_next) {
948			/* rewind pointer */
949			l = l0;
950
951			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
952				continue;
953			switch (s->ai_addr->sa_family) {
954			case AF_INET:
955				plen = sizeof(struct in_addr) << 3;
956				break;
957#ifdef INET6
958			case AF_INET6:
959				plen = sizeof(struct in6_addr) << 3;
960				break;
961#endif
962			default:
963				continue;
964			}
965
966			/* set src */
967			sa = s->ai_addr;
968			salen = s->ai_addr->sa_len;
969			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
970			    PFKEY_ALIGN8(salen));
971			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
972			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
973			m_addr.sadb_address_prefixlen = plen;
974			m_addr.sadb_address_reserved = 0;
975
976			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
977			    sizeof(m_addr), (caddr_t)sa, salen);
978
979			/* set dst */
980			sa = d->ai_addr;
981			salen = d->ai_addr->sa_len;
982			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
983			    PFKEY_ALIGN8(salen));
984			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
985			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
986			m_addr.sadb_address_prefixlen = plen;
987			m_addr.sadb_address_reserved = 0;
988
989			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
990			    sizeof(m_addr), (caddr_t)sa, salen);
991
992			msg->sadb_msg_len = PFKEY_UNIT64(l);
993
994			sendkeymsg(buf, l);
995
996			n++;
997		}
998	}
999
1000	if (n == 0)
1001		return -1;
1002	else
1003		return 0;
1004}
1005
1006/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1007static int
1008setkeymsg_add(type, satype, srcs, dsts)
1009	unsigned int type;
1010	unsigned int satype;
1011	struct addrinfo *srcs;
1012	struct addrinfo *dsts;
1013{
1014	struct sadb_msg *msg;
1015	char buf[BUFSIZ];
1016	int l, l0, len;
1017	struct sadb_sa m_sa;
1018	struct sadb_x_sa2 m_sa2;
1019	struct sadb_address m_addr;
1020	struct addrinfo *s, *d;
1021	int n;
1022	int plen;
1023	struct sockaddr *sa;
1024	int salen;
1025
1026	msg = (struct sadb_msg *)buf;
1027
1028	if (!srcs || !dsts)
1029		return -1;
1030
1031	/* fix up length afterwards */
1032	setkeymsg0(msg, type, satype, 0);
1033	l = sizeof(struct sadb_msg);
1034
1035	/* set encryption algorithm, if present. */
1036	if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1037		struct sadb_key m_key;
1038
1039		m_key.sadb_key_len =
1040			PFKEY_UNIT64(sizeof(m_key)
1041				   + PFKEY_ALIGN8(p_key_enc_len));
1042		m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1043		m_key.sadb_key_bits = p_key_enc_len * 8;
1044		m_key.sadb_key_reserved = 0;
1045
1046		setvarbuf(buf, &l,
1047			(struct sadb_ext *)&m_key, sizeof(m_key),
1048			(caddr_t)p_key_enc, p_key_enc_len);
1049	}
1050
1051	/* set authentication algorithm, if present. */
1052	if (p_key_auth) {
1053		struct sadb_key m_key;
1054
1055		m_key.sadb_key_len =
1056			PFKEY_UNIT64(sizeof(m_key)
1057				   + PFKEY_ALIGN8(p_key_auth_len));
1058		m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1059		m_key.sadb_key_bits = p_key_auth_len * 8;
1060		m_key.sadb_key_reserved = 0;
1061
1062		setvarbuf(buf, &l,
1063			(struct sadb_ext *)&m_key, sizeof(m_key),
1064			(caddr_t)p_key_auth, p_key_auth_len);
1065	}
1066
1067	/* set lifetime for HARD */
1068	if (p_lt_hard != 0) {
1069		struct sadb_lifetime m_lt;
1070		u_int slen = sizeof(struct sadb_lifetime);
1071
1072		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1073		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1074		m_lt.sadb_lifetime_allocations = 0;
1075		m_lt.sadb_lifetime_bytes = 0;
1076		m_lt.sadb_lifetime_addtime = p_lt_hard;
1077		m_lt.sadb_lifetime_usetime = 0;
1078
1079		memcpy(buf + l, &m_lt, slen);
1080		l += slen;
1081	}
1082
1083	/* set lifetime for SOFT */
1084	if (p_lt_soft != 0) {
1085		struct sadb_lifetime m_lt;
1086		u_int slen = sizeof(struct sadb_lifetime);
1087
1088		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1089		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1090		m_lt.sadb_lifetime_allocations = 0;
1091		m_lt.sadb_lifetime_bytes = 0;
1092		m_lt.sadb_lifetime_addtime = p_lt_soft;
1093		m_lt.sadb_lifetime_usetime = 0;
1094
1095		memcpy(buf + l, &m_lt, slen);
1096		l += slen;
1097	}
1098
1099	len = sizeof(struct sadb_sa);
1100	m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1101	m_sa.sadb_sa_exttype = SADB_EXT_SA;
1102	m_sa.sadb_sa_spi = htonl(p_spi);
1103	m_sa.sadb_sa_replay = p_replay;
1104	m_sa.sadb_sa_state = 0;
1105	m_sa.sadb_sa_auth = p_alg_auth;
1106	m_sa.sadb_sa_encrypt = p_alg_enc;
1107	m_sa.sadb_sa_flags = p_ext;
1108
1109	memcpy(buf + l, &m_sa, len);
1110	l += len;
1111
1112	len = sizeof(struct sadb_x_sa2);
1113	m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1114	m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1115	m_sa2.sadb_x_sa2_mode = p_mode;
1116	m_sa2.sadb_x_sa2_reqid = p_reqid;
1117
1118	memcpy(buf + l, &m_sa2, len);
1119	l += len;
1120
1121	l0 = l;
1122	n = 0;
1123
1124	/* do it for all src/dst pairs */
1125	for (s = srcs; s; s = s->ai_next) {
1126		for (d = dsts; d; d = d->ai_next) {
1127			/* rewind pointer */
1128			l = l0;
1129
1130			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1131				continue;
1132			switch (s->ai_addr->sa_family) {
1133			case AF_INET:
1134				plen = sizeof(struct in_addr) << 3;
1135				break;
1136#ifdef INET6
1137			case AF_INET6:
1138				plen = sizeof(struct in6_addr) << 3;
1139				break;
1140#endif
1141			default:
1142				continue;
1143			}
1144
1145			/* set src */
1146			sa = s->ai_addr;
1147			salen = s->ai_addr->sa_len;
1148			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1149			    PFKEY_ALIGN8(salen));
1150			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1151			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1152			m_addr.sadb_address_prefixlen = plen;
1153			m_addr.sadb_address_reserved = 0;
1154
1155			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1156			    sizeof(m_addr), (caddr_t)sa, salen);
1157
1158			/* set dst */
1159			sa = d->ai_addr;
1160			salen = d->ai_addr->sa_len;
1161			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1162			    PFKEY_ALIGN8(salen));
1163			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1164			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1165			m_addr.sadb_address_prefixlen = plen;
1166			m_addr.sadb_address_reserved = 0;
1167
1168			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1169			    sizeof(m_addr), (caddr_t)sa, salen);
1170
1171			msg->sadb_msg_len = PFKEY_UNIT64(l);
1172
1173			sendkeymsg(buf, l);
1174
1175			n++;
1176		}
1177	}
1178
1179	if (n == 0)
1180		return -1;
1181	else
1182		return 0;
1183}
1184
1185static struct addrinfo *
1186parse_addr(host, port)
1187	char *host;
1188	char *port;
1189{
1190	struct addrinfo hints, *res = NULL;
1191	int error;
1192
1193	memset(&hints, 0, sizeof(hints));
1194	hints.ai_family = p_aifamily;
1195	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
1196	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
1197	hints.ai_flags = p_aiflags;
1198	error = getaddrinfo(host, port, &hints, &res);
1199	if (error != 0) {
1200		yyerror(gai_strerror(error));
1201		return NULL;
1202	}
1203	return res;
1204}
1205
1206static int
1207fix_portstr(spec, sport, dport)
1208	vchar_t *spec, *sport, *dport;
1209{
1210	char *p, *p2;
1211	u_int l;
1212
1213	l = 0;
1214	for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++)
1215		;
1216	if (*p == '\0') {
1217		p2 = "0";
1218	} else {
1219		if (*p == ',') {
1220			*p = '\0';
1221			p2 = ++p;
1222		}
1223		for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1224			;
1225		if (*p != '\0' || *p2 == '\0') {
1226			yyerror("invalid an upper layer protocol spec");
1227			return -1;
1228		}
1229	}
1230
1231	sport->buf = strdup(spec->buf);
1232	if (!sport->buf) {
1233		yyerror("insufficient memory");
1234		return -1;
1235	}
1236	sport->len = strlen(sport->buf);
1237	dport->buf = strdup(p2);
1238	if (!dport->buf) {
1239		yyerror("insufficient memory");
1240		return -1;
1241	}
1242	dport->len = strlen(dport->buf);
1243
1244	return 0;
1245}
1246
1247static int
1248setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
1249	char *buf;
1250	int *off;
1251	struct sadb_ext *ebuf;
1252	int elen;
1253	caddr_t vbuf;
1254	int vlen;
1255{
1256	memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1257	memcpy(buf + *off, (caddr_t)ebuf, elen);
1258	memcpy(buf + *off + elen, vbuf, vlen);
1259	(*off) += PFKEY_ALIGN8(elen + vlen);
1260
1261	return 0;
1262}
1263
1264void
1265parse_init()
1266{
1267	p_spi = 0;
1268
1269	p_ext = SADB_X_EXT_CYCSEQ;
1270	p_alg_enc = SADB_EALG_NONE;
1271	p_alg_auth = SADB_AALG_NONE;
1272	p_mode = IPSEC_MODE_ANY;
1273	p_reqid = 0;
1274	p_replay = 0;
1275	p_key_enc_len = p_key_auth_len = 0;
1276	p_key_enc = p_key_auth = 0;
1277	p_lt_hard = p_lt_soft = 0;
1278
1279	p_aiflags = 0;
1280	p_aifamily = PF_UNSPEC;
1281
1282	return;
1283}
1284
1285void
1286free_buffer()
1287{
1288	/* we got tons of memory leaks in the parser anyways, leave them */
1289
1290	return;
1291}
1292