parse.y revision 1.52
1/*	$OpenBSD: parse.y,v 1.52 2006/03/07 00:30:28 reyk Exp $	*/
2
3/*
4 * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
5 * Copyright (c) 2001 Markus Friedl.  All rights reserved.
6 * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
7 * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
8 * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
9 *
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23%{
24#include <sys/types.h>
25#include <sys/ioctl.h>
26#include <sys/queue.h>
27#include <sys/socket.h>
28#include <sys/stat.h>
29#include <net/if.h>
30#include <netinet/in.h>
31#include <netinet/ip_ipsp.h>
32#include <arpa/inet.h>
33
34#include <ctype.h>
35#include <err.h>
36#include <errno.h>
37#include <fcntl.h>
38#include <ifaddrs.h>
39#include <limits.h>
40#include <stdarg.h>
41#include <stdio.h>
42#include <string.h>
43#include <syslog.h>
44#include <unistd.h>
45
46#include "ipsecctl.h"
47
48#define KEYSIZE_LIMIT	1024
49
50static struct ipsecctl	*ipsec = NULL;
51static FILE		*fin = NULL;
52static int		 lineno = 1;
53static int		 errors = 0;
54static int		 debug = 0;
55
56const struct ipsec_xf authxfs[] = {
57	{ "unknown",		AUTHXF_UNKNOWN,		0,	0 },
58	{ "none",		AUTHXF_NONE,		0,	0 },
59	{ "hmac-md5",		AUTHXF_HMAC_MD5,	16,	0 },
60	{ "hmac-ripemd160",	AUTHXF_HMAC_RIPEMD160,	20,	0 },
61	{ "hmac-sha1",		AUTHXF_HMAC_SHA1,	20,	0 },
62	{ "hmac-sha2-256",	AUTHXF_HMAC_SHA2_256,	32,	0 },
63	{ "hmac-sha2-384",	AUTHXF_HMAC_SHA2_384,	48,	0 },
64	{ "hmac-sha2-512",	AUTHXF_HMAC_SHA2_512,	64,	0 },
65	{ NULL,			0,			0,	0 },
66};
67
68const struct ipsec_xf encxfs[] = {
69	{ "unknown",		ENCXF_UNKNOWN,		0,	0 },
70	{ "none",		ENCXF_NONE,		0,	0 },
71	{ "3des-cbc",		ENCXF_3DES_CBC,		24,	24 },
72	{ "des-cbc",		ENCXF_DES_CBC,		8,	8 },
73	{ "aes",		ENCXF_AES,		16,	32 },
74	{ "aesctr",		ENCXF_AESCTR,		16+4,	32+4 },
75	{ "blowfish",		ENCXF_BLOWFISH,		5,	56 },
76	{ "cast128",		ENCXF_CAST128,		5,	16 },
77	{ "null",		ENCXF_NULL,		0,	0 },
78	{ "skipjack",		ENCXF_SKIPJACK,		10,	10 },
79	{ NULL,			0,			0,	0 },
80};
81
82const struct ipsec_xf compxfs[] = {
83	{ "unknown",		COMPXF_UNKNOWN,		0,	0 },
84	{ "deflate",		COMPXF_DEFLATE,		0,	0 },
85	{ "lzs",		COMPXF_LZS,		0,	0 },
86	{ NULL,			0,			0,	0 },
87};
88
89int			 yyerror(const char *, ...);
90int			 yyparse(void);
91int			 kw_cmp(const void *, const void *);
92int			 lookup(char *);
93int			 lgetc(FILE *);
94int			 lungetc(int);
95int			 findeol(void);
96int			 yylex(void);
97
98TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
99struct sym {
100	TAILQ_ENTRY(sym)	 entries;
101	int		 used;
102	int		 persist;
103	char		*nam;
104	char		*val;
105};
106
107int			 symset(const char *, const char *, int);
108int			 cmdline_symset(char *);
109char			*symget(const char *);
110int			 atoul(char *, u_long *);
111int			 atospi(char *, u_int32_t *);
112u_int8_t		 x2i(unsigned char *);
113struct ipsec_key	*parsekey(unsigned char *, size_t);
114struct ipsec_key	*parsekeyfile(char *);
115struct ipsec_addr_wrap	*host(const char *);
116struct ipsec_addr_wrap	*host_v4(const char *, int);
117struct ipsec_addr_wrap	*host_if(const char *, int);
118void			 ifa_load(void);
119int			 ifa_exists(const char *);
120struct ipsec_addr_wrap	*ifa_lookup(const char *ifa_name);
121void			 set_ipmask(struct ipsec_addr_wrap *, u_int8_t);
122struct ipsec_addr_wrap	*copyhost(const struct ipsec_addr_wrap *);
123const struct ipsec_xf	*parse_xf(const char *, const struct ipsec_xf *);
124struct ipsec_transforms *copytransforms(const struct ipsec_transforms *);
125int			 validate_sa(u_int32_t, u_int8_t,
126			     struct ipsec_transforms *, struct ipsec_key *,
127			     struct ipsec_key *, u_int8_t);
128struct ipsec_rule	*create_sa(u_int8_t, u_int8_t, struct ipsec_addr_wrap *,
129			     struct ipsec_addr_wrap *, u_int32_t,
130			     struct ipsec_transforms *, struct ipsec_key *,
131			     struct ipsec_key *);
132struct ipsec_rule	*reverse_sa(struct ipsec_rule *, u_int32_t,
133			     struct ipsec_key *, struct ipsec_key *);
134struct ipsec_rule	*create_flow(u_int8_t, struct ipsec_addr_wrap *, struct
135			     ipsec_addr_wrap *, struct ipsec_addr_wrap *,
136			     u_int8_t, char *, char *, u_int8_t);
137struct ipsec_rule	*reverse_rule(struct ipsec_rule *);
138struct ipsec_rule	*create_ike(struct ipsec_addr_wrap *, struct
139			     ipsec_addr_wrap *, struct ipsec_addr_wrap *,
140			     struct ipsec_transforms *, struct
141			     ipsec_transforms *, u_int8_t, u_int8_t, char *,
142			     char *, struct ike_auth *);
143
144struct ipsec_transforms *ipsec_transforms;
145
146typedef struct {
147	union {
148		u_int32_t	 number;
149		u_int8_t	 ikemode;
150		u_int8_t	 dir;
151		u_int8_t	 protocol;
152		u_int8_t	 tmode;
153		char		*string;
154		struct {
155			struct ipsec_addr_wrap *src;
156			struct ipsec_addr_wrap *dst;
157		} hosts;
158		struct ipsec_addr_wrap *peer;
159		struct ipsec_addr_wrap *host;
160		struct {
161			char *srcid;
162			char *dstid;
163		} ids;
164		char		*id;
165		u_int8_t	 type;
166		struct ike_auth	 ikeauth;
167		struct {
168			u_int32_t	spiout;
169			u_int32_t	spiin;
170		} spis;
171		struct {
172			struct ipsec_key *keyout;
173			struct ipsec_key *keyin;
174		} authkeys;
175		struct {
176			struct ipsec_key *keyout;
177			struct ipsec_key *keyin;
178		} enckeys;
179		struct {
180			struct ipsec_key *keyout;
181			struct ipsec_key *keyin;
182		} keys;
183		struct ipsec_transforms *transforms;
184		struct ipsec_transforms *mmxfs;
185		struct ipsec_transforms *qmxfs;
186	} v;
187	int lineno;
188} YYSTYPE;
189
190%}
191
192%token	FLOW FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK TCPMD5 SPI
193%token	AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK PASSIVE
194%token	ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC
195%token	TYPE DENY BYPASS
196%token	<v.string>		STRING
197%type	<v.dir>			dir
198%type	<v.protocol>		protocol
199%type	<v.tmode>		tmode
200%type	<v.number>		number
201%type	<v.hosts>		hosts
202%type	<v.peer>		peer
203%type	<v.host>		host
204%type	<v.ids>			ids
205%type	<v.id>			id
206%type	<v.spis>		spispec
207%type	<v.authkeys>		authkeyspec
208%type	<v.enckeys>		enckeyspec
209%type	<v.keys>		keyspec
210%type	<v.transforms>		transforms
211%type	<v.mmxfs>		mmxfs
212%type	<v.qmxfs>		qmxfs
213%type	<v.ikemode>		ikemode
214%type	<v.ikeauth>		ikeauth
215%type	<v.type>		type
216%%
217
218grammar		: /* empty */
219		| grammar '\n'
220		| grammar ikerule '\n'
221		| grammar flowrule '\n'
222		| grammar sarule '\n'
223		| grammar tcpmd5rule '\n'
224		| grammar error '\n'		{ errors++; }
225		;
226
227number		: STRING			{
228			unsigned long	ulval;
229
230			if (atoul($1, &ulval) == -1) {
231				yyerror("%s is not a number", $1);
232				free($1);
233				YYERROR;
234			}
235			if (ulval > UINT_MAX) {
236				yyerror("0x%lx out of range", ulval);
237				free($1);
238				YYERROR;
239			}
240			$$ = (u_int32_t)ulval;
241			free($1);
242		}
243		;
244
245tcpmd5rule	: TCPMD5 hosts spispec authkeyspec	{
246			struct ipsec_rule	*r;
247
248			r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, $2.src,
249			    $2.dst, $3.spiout, NULL, $4.keyout, NULL);
250			if (r == NULL)
251				YYERROR;
252			r->nr = ipsec->rule_nr++;
253
254			if (ipsecctl_add_rule(ipsec, r))
255				errx(1, "tcpmd5rule: ipsecctl_add_rule");
256
257			/* Create and add reverse SA rule. */
258			if ($3.spiin != 0 || $4.keyin != NULL) {
259				r = reverse_sa(r, $3.spiin, $4.keyin, NULL);
260				if (r == NULL)
261					YYERROR;
262				r->nr = ipsec->rule_nr++;
263
264				if (ipsecctl_add_rule(ipsec, r))
265					errx(1, "tcpmd5rule: "
266					    "ipsecctl_add_rule");
267			}
268		}
269		;
270
271sarule		: protocol tmode hosts spispec transforms authkeyspec
272		    enckeyspec {
273			struct ipsec_rule	*r;
274
275			r = create_sa($1, $2, $3.src, $3.dst, $4.spiout, $5,
276			    $6.keyout, $7.keyout);
277			if (r == NULL)
278				YYERROR;
279			r->nr = ipsec->rule_nr++;
280
281			if (ipsecctl_add_rule(ipsec, r))
282				errx(1, "sarule: ipsecctl_add_rule");
283
284			/* Create and add reverse SA rule. */
285			if ($4.spiin != 0 || $6.keyin || $7.keyin) {
286				r = reverse_sa(r, $4.spiin, $6.keyin,
287				    $7.keyin);
288				if (r == NULL)
289					YYERROR;
290				r->nr = ipsec->rule_nr++;
291
292				if (ipsecctl_add_rule(ipsec, r))
293					errx(1, "sarule: ipsecctl_add_rule");
294			}
295		}
296		;
297
298flowrule	: FLOW protocol dir hosts peer ids type {
299			struct ipsec_rule	*r;
300
301			r = create_flow($3, $4.src, $4.dst, $5, $2, $6.srcid,
302			    $6.dstid, $7);
303			if (r == NULL)
304				YYERROR;
305			r->nr = ipsec->rule_nr++;
306
307			if (ipsecctl_add_rule(ipsec, r))
308				errx(1, "flowrule: ipsecctl_add_rule");
309
310			/* Create and add reverse flow rule. */
311			if ($7 == TYPE_UNKNOWN && $3 == IPSEC_INOUT) {
312				r = reverse_rule(r);
313				r->nr = ipsec->rule_nr++;
314
315				if (ipsecctl_add_rule(ipsec, r))
316					errx(1, "flowrule: ipsecctl_add_rule");
317			}
318		}
319		;
320
321ikerule		: IKE ikemode protocol hosts peer mmxfs qmxfs ids ikeauth {
322			struct ipsec_rule	*r;
323
324			r = create_ike($4.src, $4.dst, $5, $6, $7, $3, $2,
325			    $8.srcid, $8.dstid, &$9);
326			if (r == NULL)
327				YYERROR;
328			r->nr = ipsec->rule_nr++;
329
330			if (ipsecctl_add_rule(ipsec, r))
331				errx(1, "ikerule: ipsecctl_add_rule");
332		}
333		;
334
335protocol	: /* empty */			{ $$ = IPSEC_ESP; }
336		| ESP				{ $$ = IPSEC_ESP; }
337		| AH				{ $$ = IPSEC_AH; }
338		| IPCOMP			{ $$ = IPSEC_IPCOMP; }
339		| IPIP				{ $$ = IPSEC_IPIP; }
340		;
341
342tmode		: /* empty */			{ $$ = IPSEC_TUNNEL; }
343		| TUNNEL			{ $$ = IPSEC_TUNNEL; }
344		| TRANSPORT			{ $$ = IPSEC_TRANSPORT; }
345		;
346
347dir		: /* empty */			{ $$ = IPSEC_INOUT; }
348		| IN				{ $$ = IPSEC_IN; }
349		| OUT				{ $$ = IPSEC_OUT; }
350		;
351
352hosts		: FROM host TO host		{
353			$$.src = $2;
354			$$.dst = $4;
355		}
356		| TO host FROM host		{
357			$$.src = $4;
358			$$.dst = $2;
359		}
360		;
361
362peer		: /* empty */			{ $$ = NULL; }
363		| PEER STRING			{
364			if (($$ = host($2)) == NULL) {
365				free($2);
366				yyerror("could not parse host specification");
367				YYERROR;
368			}
369			free($2);
370		}
371		;
372
373host		: STRING			{
374			if (($$ = host($1)) == NULL) {
375				free($1);
376				yyerror("could not parse host specification");
377				YYERROR;
378			}
379			free($1);
380		}
381		| STRING '/' number		{
382			char	*buf;
383
384			if (asprintf(&buf, "%s/%u", $1, $3) == -1)
385				err(1, "host: asprintf");
386			free($1);
387			if (($$ = host(buf)) == NULL)	{
388				free(buf);
389				yyerror("could not parse host specification");
390				YYERROR;
391			}
392			free(buf);
393		}
394		| ANY				{
395			struct ipsec_addr_wrap	*ipa;
396
397			ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
398			if (ipa == NULL)
399				err(1, "host: calloc");
400
401			ipa->af = AF_INET;
402			ipa->netaddress = 1;
403			if ((ipa->name = strdup("0.0.0.0/0")) == NULL)
404				err(1, "host: strdup");
405			$$ = ipa;
406		}
407		;
408
409ids		: /* empty */			{
410			$$.srcid = NULL;
411			$$.dstid = NULL;
412		}
413		| SRCID id DSTID id		{
414			$$.srcid = $2;
415			$$.dstid = $4;
416		}
417		| SRCID id			{
418			$$.srcid = $2;
419			$$.dstid = NULL;
420		}
421		| DSTID id			{
422			$$.srcid = NULL;
423			$$.dstid = $2;
424		}
425		;
426
427type		: /* empty */			{
428			$$ = TYPE_UNKNOWN;
429		}
430		| TYPE DENY			{
431			$$ = TYPE_DENY;
432		}
433		| TYPE BYPASS			{
434			$$ = TYPE_BYPASS;
435		}
436		;
437
438id		: STRING			{ $$ = $1; }
439		;
440
441spispec		: SPI STRING			{
442			u_int32_t	 spi;
443			char		*p = strchr($2, ':');
444
445			if (p != NULL) {
446				*p++ = 0;
447
448				if (atospi(p, &spi) == -1) {
449					yyerror("%s is not a valid spi", p);
450					free($2);
451					YYERROR;
452				}
453				$$.spiin = spi;
454			}
455			if (atospi($2, &spi) == -1) {
456				yyerror("%s is not a valid spi", $2);
457				free($2);
458				YYERROR;
459			}
460			$$.spiout = spi;
461
462
463			free($2);
464		}
465		;
466
467transforms	:					{
468			if ((ipsec_transforms = calloc(1,
469			    sizeof(struct ipsec_transforms))) == NULL)
470				err(1, "transforms: calloc");
471		}
472		    transforms_l			{ $$ = ipsec_transforms; }
473		| /* empty */				{
474			if (($$ = calloc(1,
475			    sizeof(struct ipsec_transforms))) == NULL)
476				err(1, "transforms: calloc");
477		}
478		;
479
480transforms_l	: transforms_l transform
481		| transform
482		;
483
484transform	: AUTHXF STRING			{
485			if (ipsec_transforms->authxf)
486				yyerror("auth already set");
487			else {
488				ipsec_transforms->authxf = parse_xf($2,
489				    authxfs);
490				if (!ipsec_transforms->authxf)
491					yyerror("%s not a valid transform", $2);
492			}
493		}
494		| ENCXF STRING			{
495			if (ipsec_transforms->encxf)
496				yyerror("enc already set");
497			else {
498				ipsec_transforms->encxf = parse_xf($2, encxfs);
499				if (!ipsec_transforms->encxf)
500					yyerror("%s not a valid transform", $2);
501			}
502		}
503		| COMPXF STRING			{
504			if (ipsec_transforms->compxf)
505				yyerror("comp already set");
506			else {
507				ipsec_transforms->compxf = parse_xf($2,
508				    compxfs);
509				if (!ipsec_transforms->compxf)
510					yyerror("%s not a valid transform", $2);
511			}
512		}
513		;
514
515mmxfs		: /* empty */			{
516			struct ipsec_transforms *xfs;
517
518			/* We create just an empty transform */
519			if ((xfs = calloc(1, sizeof(struct ipsec_transforms)))
520			    == NULL)
521				err(1, "mmxfs: calloc");
522			$$ = xfs;
523		}
524		| MAIN transforms		{ $$ = $2; }
525		;
526
527qmxfs		: /* empty */			{
528			struct ipsec_transforms *xfs;
529
530			/* We create just an empty transform */
531			if ((xfs = calloc(1, sizeof(struct ipsec_transforms)))
532			    == NULL)
533				err(1, "qmxfs: calloc");
534			$$ = xfs;
535		}
536		| QUICK transforms		{ $$ = $2; }
537		;
538
539authkeyspec	: /* empty */			{
540			$$.keyout = NULL;
541			$$.keyin = NULL;
542		}
543		| AUTHKEY keyspec		{
544			$$.keyout = $2.keyout;
545			$$.keyin = $2.keyin;
546		}
547		;
548
549enckeyspec	: /* empty */			{
550			$$.keyout = NULL;
551			$$.keyin = NULL;
552		}
553		| ENCKEY keyspec		{
554			$$.keyout = $2.keyout;
555			$$.keyin = $2.keyin;
556		}
557		;
558
559keyspec		: STRING			{
560			unsigned char	*hex;
561			unsigned char	*p = strchr($1, ':');
562
563			if (p != NULL ) {
564				*p++ = 0;
565
566				if (!strncmp(p, "0x", 2))
567					p += 2;
568				$$.keyin = parsekey(p, strlen(p));
569			}
570
571			hex = $1;
572			if (!strncmp(hex, "0x", 2))
573				hex += 2;
574			$$.keyout = parsekey(hex, strlen(hex));
575
576			free($1);
577		}
578		| FILENAME STRING		{
579			unsigned char	*p = strchr($2, ':');
580
581			if (p != NULL) {
582				*p++ = 0;
583				$$.keyin = parsekeyfile(p);
584			}
585			$$.keyout = parsekeyfile($2);
586			free($2);
587		}
588		;
589
590ikemode		: /* empty */			{ $$ = IKE_ACTIVE; }
591		| PASSIVE			{ $$ = IKE_PASSIVE; }
592		| DYNAMIC			{ $$ = IKE_DYNAMIC; }
593		| ACTIVE			{ $$ = IKE_ACTIVE; }
594		;
595
596ikeauth		: /* empty */			{
597			$$.type = IKE_AUTH_RSA;
598			$$.string = NULL;
599		}
600		| RSA				{
601			$$.type = IKE_AUTH_RSA;
602			$$.string = NULL;
603		}
604		| PSK STRING			{
605			$$.type = IKE_AUTH_PSK;
606			if (($$.string = strdup($2)) == NULL)
607				err(1, "ikeauth: strdup");
608		}
609		;
610
611%%
612
613struct keywords {
614	const char	*k_name;
615	int		 k_val;
616};
617
618int
619yyerror(const char *fmt, ...)
620{
621	va_list		 ap;
622	extern char	*infile;
623
624	errors = 1;
625	va_start(ap, fmt);
626	fprintf(stderr, "%s: %d: ", infile, yyval.lineno);
627	vfprintf(stderr, fmt, ap);
628	fprintf(stderr, "\n");
629	va_end(ap);
630	return (0);
631}
632
633int
634kw_cmp(const void *k, const void *e)
635{
636	return (strcmp(k, ((const struct keywords *)e)->k_name));
637}
638
639int
640lookup(char *s)
641{
642	/* this has to be sorted always */
643	static const struct keywords keywords[] = {
644		{ "active",		ACTIVE },
645		{ "ah",			AH },
646		{ "any",		ANY },
647		{ "auth",		AUTHXF },
648		{ "authkey",		AUTHKEY },
649		{ "bypass",		BYPASS },
650		{ "comp",		COMPXF },
651		{ "deny",		DENY },
652		{ "dstid",		DSTID },
653		{ "dynamic",		DYNAMIC },
654		{ "enc",		ENCXF },
655		{ "enckey",		ENCKEY },
656		{ "esp",		ESP },
657		{ "file",		FILENAME },
658		{ "flow",		FLOW },
659		{ "from",		FROM },
660		{ "ike",		IKE },
661		{ "in",			IN },
662		{ "ipcomp",		IPCOMP },
663		{ "ipip",		IPIP },
664		{ "main",		MAIN },
665		{ "out",		OUT },
666		{ "passive",		PASSIVE },
667		{ "peer",		PEER },
668		{ "psk",		PSK },
669		{ "quick",		QUICK },
670		{ "rsa",		RSA },
671		{ "spi",		SPI },
672		{ "srcid",		SRCID },
673		{ "tcpmd5",		TCPMD5 },
674		{ "to",			TO },
675		{ "transport",		TRANSPORT },
676		{ "tunnel",		TUNNEL },
677		{ "type",		TYPE },
678	};
679	const struct keywords	*p;
680
681	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
682	    sizeof(keywords[0]), kw_cmp);
683
684	if (p) {
685		if (debug > 1)
686			fprintf(stderr, "%s: %d\n", s, p->k_val);
687		return (p->k_val);
688	} else {
689		if (debug > 1)
690			fprintf(stderr, "string: %s\n", s);
691		return (STRING);
692	}
693}
694
695#define MAXPUSHBACK	128
696
697char	*parsebuf;
698int	 parseindex;
699char	 pushback_buffer[MAXPUSHBACK];
700int	 pushback_index = 0;
701
702int
703lgetc(FILE *f)
704{
705	int	c, next;
706
707	if (parsebuf) {
708		/* Read character from the parsebuffer instead of input. */
709		if (parseindex >= 0) {
710			c = parsebuf[parseindex++];
711			if (c != '\0')
712				return (c);
713			parsebuf = NULL;
714		} else
715			parseindex++;
716	}
717
718	if (pushback_index)
719		return (pushback_buffer[--pushback_index]);
720
721	while ((c = getc(f)) == '\\') {
722		next = getc(f);
723		if (next != '\n') {
724			if (isspace(next))
725				yyerror("whitespace after \\");
726			ungetc(next, f);
727			break;
728		}
729		yylval.lineno = lineno;
730		lineno++;
731	}
732	if (c == '\t' || c == ' ') {
733		/* Compress blanks to a single space. */
734		do {
735			c = getc(f);
736		} while (c == '\t' || c == ' ');
737		ungetc(c, f);
738		c = ' ';
739	}
740
741	return (c);
742}
743
744int
745lungetc(int c)
746{
747	if (c == EOF)
748		return (EOF);
749	if (parsebuf) {
750		parseindex--;
751		if (parseindex >= 0)
752			return (c);
753	}
754	if (pushback_index < MAXPUSHBACK-1)
755		return (pushback_buffer[pushback_index++] = c);
756	else
757		return (EOF);
758}
759
760int
761findeol(void)
762{
763	int	c;
764
765	parsebuf = NULL;
766	pushback_index = 0;
767
768	/* skip to either EOF or the first real EOL */
769	while (1) {
770		c = lgetc(fin);
771		if (c == '\n') {
772			lineno++;
773			break;
774		}
775		if (c == EOF)
776			break;
777	}
778	return (ERROR);
779}
780
781int
782yylex(void)
783{
784	char	 buf[8096];
785	char	*p, *val;
786	int	 endc, c;
787	int	 token;
788
789top:
790	p = buf;
791	while ((c = lgetc(fin)) == ' ')
792		; /* nothing */
793
794	yylval.lineno = lineno;
795	if (c == '#')
796		while ((c = lgetc(fin)) != '\n' && c != EOF)
797			; /* nothing */
798	if (c == '$' && parsebuf == NULL) {
799		while (1) {
800			if ((c = lgetc(fin)) == EOF)
801				return (0);
802
803			if (p + 1 >= buf + sizeof(buf) - 1) {
804				yyerror("string too long");
805				return (findeol());
806			}
807			if (isalnum(c) || c == '_') {
808				*p++ = (char)c;
809				continue;
810			}
811			*p = '\0';
812			lungetc(c);
813			break;
814		}
815		val = symget(buf);
816		if (val == NULL) {
817			yyerror("macro \"%s\" not defined", buf);
818			return (findeol());
819		}
820		parsebuf = val;
821		parseindex = 0;
822		goto top;
823	}
824
825	switch (c) {
826	case '\'':
827	case '"':
828		endc = c;
829		while (1) {
830			if ((c = lgetc(fin)) == EOF)
831				return (0);
832			if (c == endc) {
833				*p = '\0';
834				break;
835			}
836			if (c == '\n') {
837				lineno++;
838				continue;
839			}
840			if (p + 1 >= buf + sizeof(buf) - 1) {
841				yyerror("string too long");
842				return (findeol());
843			}
844			*p++ = (char)c;
845		}
846		yylval.v.string = strdup(buf);
847		if (yylval.v.string == NULL)
848			err(1, "yylex: strdup");
849		return (STRING);
850	}
851
852#define allowed_in_string(x) \
853	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
854	x != '{' && x != '}' && x != '<' && x != '>' && \
855	x != '!' && x != '=' && x != '/' && x != '#' && \
856	x != ','))
857
858	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
859		do {
860			*p++ = c;
861			if ((unsigned)(p-buf) >= sizeof(buf)) {
862				yyerror("string too long");
863				return (findeol());
864			}
865		} while ((c = lgetc(fin)) != EOF && (allowed_in_string(c)));
866		lungetc(c);
867		*p = '\0';
868		if ((token = lookup(buf)) == STRING)
869			if ((yylval.v.string = strdup(buf)) == NULL)
870				err(1, "yylex: strdup");
871		return (token);
872	}
873	if (c == '\n') {
874		yylval.lineno = lineno;
875		lineno++;
876	}
877	if (c == EOF)
878		return (0);
879	return (c);
880}
881
882int
883parse_rules(FILE *input, struct ipsecctl *ipsecx)
884{
885	struct sym	*sym;
886
887	ipsec = ipsecx;
888	fin = input;
889	lineno = 1;
890	errors = 0;
891
892	yyparse();
893
894	/* Free macros and check which have not been used. */
895	while ((sym = TAILQ_FIRST(&symhead))) {
896		TAILQ_REMOVE(&symhead, sym, entries);
897		free(sym->nam);
898		free(sym->val);
899		free(sym);
900	}
901
902	return (errors ? -1 : 0);
903}
904
905int
906symset(const char *nam, const char *val, int persist)
907{
908	struct sym	*sym;
909
910	for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
911	    sym = TAILQ_NEXT(sym, entries))
912		;	/* nothing */
913
914	if (sym != NULL) {
915		if (sym->persist == 1)
916			return (0);
917		else {
918			TAILQ_REMOVE(&symhead, sym, entries);
919			free(sym->nam);
920			free(sym->val);
921			free(sym);
922		}
923	}
924	if ((sym = calloc(1, sizeof(*sym))) == NULL)
925		return (-1);
926
927	sym->nam = strdup(nam);
928	if (sym->nam == NULL) {
929		free(sym);
930		return (-1);
931	}
932	sym->val = strdup(val);
933	if (sym->val == NULL) {
934		free(sym->nam);
935		free(sym);
936		return (-1);
937	}
938	sym->used = 0;
939	sym->persist = persist;
940	TAILQ_INSERT_TAIL(&symhead, sym, entries);
941	return (0);
942}
943
944int
945cmdline_symset(char *s)
946{
947	char	*sym, *val;
948	int	ret;
949	size_t	len;
950
951	if ((val = strrchr(s, '=')) == NULL)
952		return (-1);
953
954	len = strlen(s) - strlen(val) + 1;
955	if ((sym = malloc(len)) == NULL)
956		err(1, "cmdline_symset: malloc");
957
958	strlcpy(sym, s, len);
959
960	ret = symset(sym, val + 1, 1);
961	free(sym);
962
963	return (ret);
964}
965
966char *
967symget(const char *nam)
968{
969	struct sym	*sym;
970
971	TAILQ_FOREACH(sym, &symhead, entries)
972		if (strcmp(nam, sym->nam) == 0) {
973			sym->used = 1;
974			return (sym->val);
975		}
976	return (NULL);
977}
978
979int
980atoul(char *s, u_long *ulvalp)
981{
982	u_long	 ulval;
983	char	*ep;
984
985	errno = 0;
986	ulval = strtoul(s, &ep, 0);
987	if (s[0] == '\0' || *ep != '\0')
988		return (-1);
989	if (errno == ERANGE && ulval == ULONG_MAX)
990		return (-1);
991	*ulvalp = ulval;
992	return (0);
993}
994
995int
996atospi(char *s, u_int32_t *spivalp)
997{
998	unsigned long	ulval;
999
1000	if (atoul(s, &ulval) == -1)
1001		return (-1);
1002	if (ulval >= SPI_RESERVED_MIN && ulval <= SPI_RESERVED_MAX) {
1003		yyerror("illegal SPI value");
1004		return (-1);
1005	}
1006	*spivalp = ulval;
1007	return (0);
1008}
1009
1010u_int8_t
1011x2i(unsigned char *s)
1012{
1013	char	ss[3];
1014
1015	ss[0] = s[0];
1016	ss[1] = s[1];
1017	ss[2] = 0;
1018
1019	if (!isxdigit(s[0]) || !isxdigit(s[1])) {
1020		yyerror("keys need to be specified in hex digits");
1021		return (-1);
1022	}
1023	return ((u_int8_t)strtoul(ss, NULL, 16));
1024}
1025
1026struct ipsec_key *
1027parsekey(unsigned char *hexkey, size_t len)
1028{
1029	struct ipsec_key *key;
1030	int		  i;
1031
1032	key = calloc(1, sizeof(struct ipsec_key));
1033	if (key == NULL)
1034		err(1, "parsekey: calloc");
1035
1036	key->len = len / 2;
1037	key->data = calloc(key->len, sizeof(u_int8_t));
1038	if (key->data == NULL)
1039		err(1, "parsekey: calloc");
1040
1041	for (i = 0; i < (int)key->len; i++)
1042		key->data[i] = x2i(hexkey + 2 * i);
1043
1044	return (key);
1045}
1046
1047struct ipsec_key *
1048parsekeyfile(char *filename)
1049{
1050	struct stat	 sb;
1051	int		 fd;
1052	unsigned char	*hex;
1053
1054	if ((fd = open(filename, O_RDONLY)) < 0)
1055		err(1, "parsekeyfile: open");
1056	if (fstat(fd, &sb) < 0)
1057		err(1, "parsekeyfile: stat %s", filename);
1058	if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0))
1059		errx(1, "parsekeyfile: key too %s", sb.st_size ? "large" :
1060		    "small");
1061	if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL)
1062		err(1, "parsekeyfile: calloc");
1063	if (read(fd, hex, sb.st_size) < sb.st_size)
1064		err(1, "parsekeyfile: read");
1065	close(fd);
1066	return (parsekey(hex, sb.st_size));
1067}
1068
1069struct ipsec_addr_wrap *
1070host(const char *s)
1071{
1072	struct ipsec_addr_wrap	*ipa = NULL;
1073	int			 mask, v4mask, cont = 1;
1074	char			*p, *q, *ps;
1075
1076	if ((p = strrchr(s, '/')) != NULL) {
1077		mask = strtol(p + 1, &q, 0);
1078		if (!q || *q || mask > 32 || q == (p + 1))
1079			errx(1, "host: invalid netmask '%s'", p);
1080		if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL)
1081			err(1, "host: calloc");
1082		strlcpy(ps, s, strlen(s) - strlen(p) + 1);
1083		v4mask = mask;
1084	} else {
1085		if ((ps = strdup(s)) == NULL)
1086			err(1, "host: strdup");
1087		v4mask = 32;
1088		mask = -1;
1089	}
1090
1091	/* Does interface with this name exist? */
1092	if (cont && (ipa = host_if(ps, mask)) != NULL)
1093		cont = 0;
1094
1095	/* IPv4 address? */
1096	if (cont && (ipa = host_v4(s, mask)) != NULL)
1097		cont = 0;
1098
1099#if notyet
1100	/* IPv6 address? */
1101	if (cont && (ipa = host_dns(ps, v4mask, 0)) != NULL)
1102		cont = 0;
1103#endif
1104	free(ps);
1105
1106	if (ipa == NULL || cont == 1) {
1107		fprintf(stderr, "no IP address found for %s\n", s);
1108		return (NULL);
1109	}
1110	return (ipa);
1111}
1112
1113struct ipsec_addr_wrap *
1114host_v4(const char *s, int mask)
1115{
1116	struct ipsec_addr_wrap	*ipa = NULL;
1117	struct in_addr		 ina;
1118	int			 bits = 32;
1119
1120	bzero(&ina, sizeof(struct in_addr));
1121	if (strrchr(s, '/') != NULL) {
1122		if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1)
1123			return (NULL);
1124	} else {
1125		if (inet_pton(AF_INET, s, &ina) != 1)
1126			return (NULL);
1127	}
1128
1129	ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1130	if (ipa == NULL)
1131		err(1, "host_v4: calloc");
1132
1133	ipa->address.v4 = ina;
1134	ipa->name = strdup(s);
1135	if (ipa->name == NULL)
1136		err(1, "host_v4: strdup");
1137	ipa->af = AF_INET;
1138
1139	set_ipmask(ipa, bits);
1140	if (bits != (ipa->af == AF_INET ? 32 : 128))
1141		ipa->netaddress = 1;
1142
1143	return (ipa);
1144}
1145
1146struct ipsec_addr_wrap *
1147host_if(const char *s, int mask)
1148{
1149	struct ipsec_addr_wrap *ipa = NULL;
1150	char			*ps;
1151
1152	if ((ps = strdup(s)) == NULL)
1153		err(1, "host_if: strdup");
1154
1155	if (ifa_exists(ps))
1156		ipa = ifa_lookup(ps);
1157
1158	free(ps);
1159	return (ipa);
1160}
1161
1162/* interface lookup routintes */
1163
1164struct addr_node	*iftab;
1165
1166void
1167ifa_load(void)
1168{
1169	struct ifaddrs		*ifap, *ifa;
1170	struct addr_node	*n = NULL, *h = NULL;
1171
1172	if (getifaddrs(&ifap) < 0)
1173		err(1, "ifa_load: getiffaddrs");
1174
1175	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1176		if (!(ifa->ifa_addr->sa_family == AF_INET ||
1177		    ifa->ifa_addr->sa_family == AF_INET6 ||
1178		    ifa->ifa_addr->sa_family == AF_LINK))
1179			continue;
1180		n = calloc(1, sizeof(struct addr_node));
1181		if (n == NULL)
1182			err(1, "ifa_load: calloc");
1183		n->af = ifa->ifa_addr->sa_family;
1184		if ((n->addr.name = strdup(ifa->ifa_name)) == NULL)
1185			err(1, "ifa_load: strdup");
1186		if (n->af == AF_INET) {
1187			n->addr.af = AF_INET;
1188			memcpy(&n->addr.address.v4, &((struct sockaddr_in *)
1189			    ifa->ifa_addr)->sin_addr.s_addr,
1190			    sizeof(struct in_addr));
1191			memcpy(&n->addr.mask.v4, &((struct sockaddr_in *)
1192			    ifa->ifa_netmask)->sin_addr.s_addr,
1193			    sizeof(struct in_addr));
1194		} else if (n->af == AF_INET6) {
1195			n->addr.af = AF_INET6;
1196			memcpy(&n->addr.address.v6, &((struct sockaddr_in6 *)
1197			    ifa->ifa_addr)->sin6_addr.s6_addr,
1198			    sizeof(struct in6_addr));
1199			memcpy(&n->addr.mask.v6, &((struct sockaddr_in6 *)
1200			    ifa->ifa_netmask)->sin6_addr.s6_addr,
1201			    sizeof(struct in6_addr));
1202		}
1203		if ((n->addr.name = strdup(ifa->ifa_name)) == NULL)
1204			err(1, "ifa_load: strdup");
1205		n->next = NULL;
1206		n->tail = n;
1207		if (h == NULL)
1208			h = n;
1209		else {
1210			h->tail->next = n;
1211			h->tail = n;
1212		}
1213	}
1214
1215	iftab = h;
1216	freeifaddrs(ifap);
1217}
1218
1219int
1220ifa_exists(const char *ifa_name)
1221{
1222	struct addr_node	*n;
1223
1224	if (iftab == NULL)
1225		ifa_load();
1226
1227	for (n = iftab; n; n = n->next) {
1228		if (n->af == AF_LINK && !strncmp(n->addr.name, ifa_name,
1229		    IFNAMSIZ))
1230			return (1);
1231	}
1232
1233	return (0);
1234}
1235
1236struct ipsec_addr_wrap *
1237ifa_lookup(const char *ifa_name)
1238{
1239	struct addr_node	*p = NULL;
1240	struct ipsec_addr_wrap	*ipa = NULL;
1241
1242	if (iftab == NULL)
1243		ifa_load();
1244
1245	for (p = iftab; p; p = p->next) {
1246		if (p->af != AF_INET)
1247			continue;
1248		if (strncmp(p->addr.name, ifa_name, IFNAMSIZ))
1249			continue;
1250		ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1251		if (ipa == NULL)
1252			err(1, "ifa_lookup: calloc");
1253		memcpy(ipa, &p->addr, sizeof(struct ipsec_addr_wrap));
1254		if ((ipa->name = strdup(p->addr.name)) == NULL)
1255			err(1, "ifa_lookup: strdup");
1256		break;
1257	}
1258
1259	return (ipa);
1260}
1261
1262void
1263set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b)
1264{
1265	struct ipsec_addr	*ipa;
1266	int			 i, j = 0;
1267
1268	ipa = &address->mask;
1269	bzero(ipa, sizeof(struct ipsec_addr));
1270
1271	while (b >= 32) {
1272		ipa->addr32[j++] = 0xffffffff;
1273		b -= 32;
1274	}
1275	for (i = 31; i > 31 - b; --i)
1276		ipa->addr32[j] |= (1 << i);
1277	if (b)
1278		ipa->addr32[j] = htonl(ipa->addr32[j]);
1279}
1280
1281struct ipsec_addr_wrap *
1282copyhost(const struct ipsec_addr_wrap *src)
1283{
1284	struct ipsec_addr_wrap *dst;
1285
1286	dst = calloc(1, sizeof(struct ipsec_addr_wrap));
1287	if (dst == NULL)
1288		err(1, "copyhost: calloc");
1289
1290	memcpy(dst, src, sizeof(struct ipsec_addr_wrap));
1291
1292	if ((dst->name = strdup(src->name)) == NULL)
1293		err(1, "copyhost: strdup");
1294
1295	return dst;
1296}
1297
1298const struct ipsec_xf *
1299parse_xf(const char *name, const struct ipsec_xf xfs[])
1300{
1301	int		i;
1302
1303	for (i = 0; xfs[i].name != NULL; i++) {
1304		if (strncmp(name, xfs[i].name, strlen(name)))
1305			continue;
1306		return &xfs[i];
1307	}
1308	return (NULL);
1309}
1310
1311struct ipsec_transforms *
1312copytransforms(const struct ipsec_transforms *xfs)
1313{
1314	struct ipsec_transforms *newxfs;
1315
1316	if (xfs == NULL)
1317		return (NULL);
1318
1319	newxfs = calloc(1, sizeof(struct ipsec_transforms));
1320	if (newxfs == NULL)
1321		err(1, "copytransforms: calloc");
1322
1323	memcpy(newxfs, xfs, sizeof(struct ipsec_transforms));
1324	return (newxfs);
1325}
1326
1327int
1328validate_sa(u_int32_t spi, u_int8_t protocol, struct ipsec_transforms *xfs,
1329    struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode)
1330{
1331	/* Sanity checks */
1332	if (spi == 0) {
1333		yyerror("no SPI specified");
1334		return (0);
1335	}
1336	if (protocol == IPSEC_AH) {
1337		if (!xfs) {
1338			yyerror("no transforms specified");
1339			return (0);
1340		}
1341		if (!xfs->authxf)
1342			xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
1343		if (xfs->encxf) {
1344			yyerror("ah does not provide encryption");
1345			return (0);
1346		}
1347		if (xfs->compxf) {
1348			yyerror("ah does not provide compression");
1349			return (0);
1350		}
1351	}
1352	if (protocol == IPSEC_ESP) {
1353		if (!xfs) {
1354			yyerror("no transforms specified");
1355			return (0);
1356		}
1357		if (xfs->compxf) {
1358			yyerror("esp does not provide compression");
1359			return (0);
1360		}
1361		if (!xfs->authxf)
1362			xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
1363		if (!xfs->encxf)
1364			xfs->encxf = &encxfs[ENCXF_AESCTR];
1365	}
1366	if (protocol == IPSEC_IPCOMP) {
1367		if (!xfs) {
1368			yyerror("no transform specified");
1369			return (0);
1370		}
1371		if (xfs->authxf || xfs->encxf) {
1372			yyerror("no encryption or authenticaion with ipcomp");
1373			return (0);
1374		}
1375		if (!xfs->compxf)
1376			xfs->compxf = &compxfs[COMPXF_DEFLATE];
1377	}
1378	if (protocol == IPSEC_IPIP) {
1379		if (!xfs) {
1380			yyerror("no transform specified");
1381			return (0);
1382		}
1383		if (xfs->authxf || xfs->encxf || xfs->compxf) {
1384			yyerror("no encryption, authenticaion or compression"
1385			    " with ipip");
1386			return (0);
1387		}
1388	}
1389	if (protocol == IPSEC_TCPMD5 && authkey == NULL && tmode !=
1390	    IPSEC_TRANSPORT) {
1391		yyerror("authentication key needed for tcpmd5");
1392		return (0);
1393	}
1394	if (xfs && xfs->authxf) {
1395		if (!authkey) {
1396			yyerror("no authentication key specified");
1397			return (0);
1398		}
1399		if (authkey->len != xfs->authxf->keymin) {
1400			yyerror("wrong authentication key length, needs to be "
1401			    "%d bits", xfs->authxf->keymin * 8);
1402			return (0);
1403		}
1404	}
1405	if (xfs && xfs->encxf) {
1406		if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) {
1407			yyerror("no encryption key specified");
1408			return (0);
1409		}
1410		if (enckey) {
1411			if (enckey->len < xfs->encxf->keymin) {
1412				yyerror("encryption key too short, "
1413				    "minimum %d bits", xfs->encxf->keymin * 8);
1414				return (0);
1415			}
1416			if (xfs->encxf->keymax < enckey->len) {
1417				yyerror("encryption key too long, "
1418				    "maximum %d bits", xfs->encxf->keymax * 8);
1419				return (0);
1420			}
1421		}
1422	}
1423
1424	return 1;
1425}
1426
1427struct ipsec_rule *
1428create_sa(u_int8_t protocol, u_int8_t tmode, struct ipsec_addr_wrap *src, struct
1429    ipsec_addr_wrap *dst, u_int32_t spi, struct ipsec_transforms *xfs,
1430    struct ipsec_key *authkey, struct ipsec_key *enckey)
1431{
1432	struct ipsec_rule *r;
1433
1434	if (validate_sa(spi, protocol, xfs, authkey, enckey, tmode) == 0)
1435		return (NULL);
1436
1437	r = calloc(1, sizeof(struct ipsec_rule));
1438	if (r == NULL)
1439		err(1, "create_sa: calloc");
1440
1441	r->type |= RULE_SA;
1442	r->proto = protocol;
1443	r->tmode = tmode;
1444	r->src = src;
1445	r->dst = dst;
1446	r->spi = spi;
1447	r->xfs = xfs;
1448	r->authkey = authkey;
1449	r->enckey = enckey;
1450
1451	return r;
1452}
1453
1454struct ipsec_rule *
1455reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey,
1456    struct ipsec_key *enckey)
1457{
1458	struct ipsec_rule *reverse;
1459
1460	if (validate_sa(spi, rule->proto, rule->xfs, authkey, enckey,
1461	    rule->tmode) == 0)
1462		return (NULL);
1463
1464	reverse = calloc(1, sizeof(struct ipsec_rule));
1465	if (reverse == NULL)
1466		err(1, "reverse_sa: calloc");
1467
1468	reverse->type |= RULE_SA;
1469	reverse->proto = rule->proto;
1470	reverse->tmode = rule->tmode;
1471	reverse->src = copyhost(rule->dst);
1472	reverse->dst = copyhost(rule->src);
1473	reverse->spi = spi;
1474	reverse->xfs = copytransforms(rule->xfs);
1475	reverse->authkey = authkey;
1476	reverse->enckey = enckey;
1477
1478	return (reverse);
1479}
1480
1481struct ipsec_rule *
1482create_flow(u_int8_t dir, struct ipsec_addr_wrap *src, struct ipsec_addr_wrap
1483    *dst, struct ipsec_addr_wrap *peer, u_int8_t proto, char *srcid, char
1484    *dstid, u_int8_t type)
1485{
1486	struct ipsec_rule *r;
1487
1488	r = calloc(1, sizeof(struct ipsec_rule));
1489	if (r == NULL)
1490		err(1, "create_flow: calloc");
1491
1492	r->type |= RULE_FLOW;
1493
1494	if (dir == IPSEC_INOUT)
1495		r->direction = IPSEC_OUT;
1496	else
1497		r->direction = dir;
1498
1499	r->proto = proto;
1500	r->src = src;
1501	r->dst = dst;
1502
1503	if (type != TYPE_UNKNOWN) {
1504		r->flowtype = type;
1505		return (r);
1506	}
1507
1508	if (r->direction == IPSEC_IN)
1509		r->flowtype = TYPE_USE;
1510	else
1511		r->flowtype = TYPE_REQUIRE;
1512
1513	if (peer == NULL) {
1514		/* Set peer to remote host.  Must be a host address. */
1515		if (r->direction == IPSEC_IN) {
1516			if (r->src->netaddress) {
1517				yyerror("no peer specified");
1518				goto errout;
1519			}
1520			r->peer = copyhost(r->src);
1521		} else {
1522			if (r->dst->netaddress) {
1523				yyerror("no peer specified");
1524				goto errout;
1525			}
1526			r->peer = copyhost(r->dst);
1527		}
1528	} else
1529		r->peer = peer;
1530
1531	r->auth = calloc(1, sizeof(struct ipsec_auth));
1532	if (r->auth == NULL)
1533		err(1, "create_flow: calloc");
1534	r->auth->srcid = srcid;
1535	r->auth->dstid = dstid;
1536	r->auth->idtype = ID_FQDN;	/* XXX For now only FQDN. */
1537
1538	return r;
1539
1540errout:
1541	free(r);
1542	if (srcid)
1543		free(srcid);
1544	if (dstid)
1545		free(dstid);
1546	free(src);
1547	free(dst);
1548
1549	return NULL;
1550}
1551
1552struct ipsec_rule *
1553reverse_rule(struct ipsec_rule *rule)
1554{
1555	struct ipsec_rule *reverse;
1556
1557	reverse = calloc(1, sizeof(struct ipsec_rule));
1558	if (reverse == NULL)
1559		err(1, "reverse_rule: calloc");
1560
1561	reverse->type |= RULE_FLOW;
1562
1563	if (rule->direction == (u_int8_t)IPSEC_OUT) {
1564		reverse->direction = (u_int8_t)IPSEC_IN;
1565		reverse->flowtype = TYPE_USE;
1566	} else {
1567		reverse->direction = (u_int8_t)IPSEC_OUT;
1568		reverse->flowtype = TYPE_REQUIRE;
1569	}
1570
1571	reverse->src = copyhost(rule->dst);
1572	reverse->dst = copyhost(rule->src);
1573	reverse->peer = copyhost(rule->peer);
1574	reverse->proto = (u_int8_t)rule->proto;
1575
1576	reverse->auth = calloc(1, sizeof(struct ipsec_auth));
1577	if (reverse->auth == NULL)
1578		err(1, "reverse_rule: calloc");
1579	if (rule->auth->dstid && (reverse->auth->dstid =
1580	    strdup(rule->auth->dstid)) == NULL)
1581		err(1, "reverse_rule: strdup");
1582	if (rule->auth->srcid && (reverse->auth->srcid =
1583	    strdup(rule->auth->srcid)) == NULL)
1584		err(1, "reverse_rule: strdup");
1585	reverse->auth->idtype = rule->auth->idtype;
1586	reverse->auth->type = rule->auth->type;
1587
1588	return reverse;
1589}
1590
1591struct ipsec_rule *
1592create_ike(struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst, struct
1593    ipsec_addr_wrap * peer, struct ipsec_transforms *mmxfs, struct
1594    ipsec_transforms *qmxfs, u_int8_t proto, u_int8_t mode, char *srcid, char
1595    *dstid, struct ike_auth *authtype)
1596{
1597	struct ipsec_rule *r;
1598
1599	r = calloc(1, sizeof(struct ipsec_rule));
1600	if (r == NULL)
1601		err(1, "create_ike: calloc");
1602
1603	r->type = RULE_IKE;
1604
1605	r->src = src;
1606	r->dst = dst;
1607
1608	if (peer == NULL) {
1609		/* Set peer to remote host.  Must be a host address. */
1610		if (r->direction == IPSEC_IN) {
1611			if (r->src->netaddress) {
1612				yyerror("no peer specified");
1613				goto errout;
1614			}
1615			r->peer = copyhost(r->src);
1616		} else {
1617			if (r->dst->netaddress) {
1618				yyerror("no peer specified");
1619				goto errout;
1620			}
1621			r->peer = copyhost(r->dst);
1622		}
1623	} else
1624		r->peer = peer;
1625
1626	r->proto = proto;
1627	r->ikemode = mode;
1628	r->mmxfs = mmxfs;
1629	r->qmxfs = qmxfs;
1630	r->auth = calloc(1, sizeof(struct ipsec_auth));
1631	if (r->auth == NULL)
1632		err(1, "create_ike: calloc");
1633	r->auth->srcid = srcid;
1634	r->auth->dstid = dstid;
1635	r->auth->idtype = ID_FQDN;	/* XXX For now only FQDN. */
1636	r->ikeauth = calloc(1, sizeof(struct ike_auth));
1637	if (r->ikeauth == NULL)
1638		err(1, "create_ike: calloc");
1639	r->ikeauth->type = authtype->type;
1640	r->ikeauth->string = authtype->string;
1641
1642	return (r);
1643
1644errout:
1645	free(r);
1646	if (srcid)
1647		free(srcid);
1648	if (dstid)
1649		free(dstid);
1650	free(src);
1651	free(dst);
1652	if (authtype->string)
1653		free(authtype->string);
1654
1655	return (NULL);
1656}
1657