parse.y revision 1.97
1/*	$OpenBSD: parse.y,v 1.97 2006/06/02 15:43:37 naddy 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 <netdb.h>
41#include <stdarg.h>
42#include <stdio.h>
43#include <string.h>
44#include <syslog.h>
45#include <unistd.h>
46#include <netdb.h>
47
48#include "ipsecctl.h"
49
50#define KEYSIZE_LIMIT	1024
51
52static struct ipsecctl	*ipsec = NULL;
53static FILE		*fin = NULL;
54static int		 lineno = 1;
55static int		 errors = 0;
56static int		 debug = 0;
57
58const struct ipsec_xf authxfs[] = {
59	{ "unknown",		AUTHXF_UNKNOWN,		0,	0 },
60	{ "none",		AUTHXF_NONE,		0,	0 },
61	{ "hmac-md5",		AUTHXF_HMAC_MD5,	16,	0 },
62	{ "hmac-ripemd160",	AUTHXF_HMAC_RIPEMD160,	20,	0 },
63	{ "hmac-sha1",		AUTHXF_HMAC_SHA1,	20,	0 },
64	{ "hmac-sha2-256",	AUTHXF_HMAC_SHA2_256,	32,	0 },
65	{ "hmac-sha2-384",	AUTHXF_HMAC_SHA2_384,	48,	0 },
66	{ "hmac-sha2-512",	AUTHXF_HMAC_SHA2_512,	64,	0 },
67	{ NULL,			0,			0,	0 },
68};
69
70const struct ipsec_xf encxfs[] = {
71	{ "unknown",		ENCXF_UNKNOWN,		0,	0 },
72	{ "none",		ENCXF_NONE,		0,	0 },
73	{ "3des-cbc",		ENCXF_3DES_CBC,		24,	24 },
74	{ "des-cbc",		ENCXF_DES_CBC,		8,	8 },
75	{ "aes",		ENCXF_AES,		16,	32 },
76	{ "aesctr",		ENCXF_AESCTR,		16+4,	32+4 },
77	{ "blowfish",		ENCXF_BLOWFISH,		5,	56 },
78	{ "cast128",		ENCXF_CAST128,		5,	16 },
79	{ "null",		ENCXF_NULL,		0,	0 },
80	{ "skipjack",		ENCXF_SKIPJACK,		10,	10 },
81	{ NULL,			0,			0,	0 },
82};
83
84const struct ipsec_xf compxfs[] = {
85	{ "unknown",		COMPXF_UNKNOWN,		0,	0 },
86	{ "deflate",		COMPXF_DEFLATE,		0,	0 },
87	{ "lzs",		COMPXF_LZS,		0,	0 },
88	{ NULL,			0,			0,	0 },
89};
90
91const struct ipsec_xf groupxfs[] = {
92	{ "unknown",		GROUPXF_UNKNOWN,	0,	0 },
93	{ "modp768",		GROUPXF_768,		768,	0 },
94	{ "grp1",		GROUPXF_768,		768,	0 },
95	{ "modp1024",		GROUPXF_1024,		1024,	0 },
96	{ "grp2",		GROUPXF_1024,		1024,	0 },
97	{ "modp1536",		GROUPXF_1536,		1536,	0 },
98	{ "grp5",		GROUPXF_1536,		1536,	0 },
99	{ "modp2048",		GROUPXF_2048,		2048,	0 },
100	{ "grp14",		GROUPXF_2048,		2048,	0 },
101	{ "modp3072",		GROUPXF_3072,		3072,	0 },
102	{ "grp15",		GROUPXF_3072,		3072,	0 },
103	{ "modp4096",		GROUPXF_4096,		4096,	0 },
104	{ "grp16",		GROUPXF_4096,		4096,	0 },
105	{ "modp6144",		GROUPXF_6144,		6144,	0 },
106	{ "grp18",		GROUPXF_6144,		6144,	0 },
107	{ "modp8192",		GROUPXF_8192,		8192,	0 },
108	{ "grp18",		GROUPXF_8192,		8192,	0 },
109	{ NULL,			0,			0,	0 },
110};
111
112int			 yyerror(const char *, ...);
113int			 yyparse(void);
114int			 kw_cmp(const void *, const void *);
115int			 lookup(char *);
116int			 lgetc(FILE *);
117int			 lungetc(int);
118int			 findeol(void);
119int			 yylex(void);
120
121TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
122struct sym {
123	TAILQ_ENTRY(sym)	 entries;
124	int		 used;
125	int		 persist;
126	char		*nam;
127	char		*val;
128};
129
130int			 symset(const char *, const char *, int);
131int			 cmdline_symset(char *);
132char			*symget(const char *);
133int			 atoul(char *, u_long *);
134int			 atospi(char *, u_int32_t *);
135u_int8_t		 x2i(unsigned char *);
136struct ipsec_key	*parsekey(unsigned char *, size_t);
137struct ipsec_key	*parsekeyfile(char *);
138struct ipsec_addr_wrap	*host(const char *);
139struct ipsec_addr_wrap	*host_v6(const char *, int);
140struct ipsec_addr_wrap	*host_v4(const char *, int);
141struct ipsec_addr_wrap	*host_dns(const char *, int, int);
142struct ipsec_addr_wrap	*host_if(const char *, int);
143void			 ifa_load(void);
144int			 ifa_exists(const char *);
145struct ipsec_addr_wrap	*ifa_lookup(const char *ifa_name);
146struct ipsec_addr_wrap	*ifa_grouplookup(const char *);
147void			 set_ipmask(struct ipsec_addr_wrap *, u_int8_t);
148const struct ipsec_xf	*parse_xf(const char *, const struct ipsec_xf *);
149struct ipsec_life	*parse_life(int);
150struct ipsec_transforms *copytransforms(const struct ipsec_transforms *);
151struct ipsec_life	*copylife(const struct ipsec_life *);
152struct ipsec_auth	*copyipsecauth(const struct ipsec_auth *);
153struct ike_auth		*copyikeauth(const struct ike_auth *);
154struct ipsec_key	*copykey(struct ipsec_key *);
155struct ipsec_addr_wrap	*copyhost(const struct ipsec_addr_wrap *);
156struct ipsec_rule	*copyrule(struct ipsec_rule *);
157int			 validate_sa(u_int32_t, u_int8_t,
158			     struct ipsec_transforms *, struct ipsec_key *,
159			     struct ipsec_key *, u_int8_t);
160int			 validate_af(struct ipsec_addr_wrap *,
161				struct ipsec_addr_wrap *);
162struct ipsec_rule	*create_sa(u_int8_t, u_int8_t, struct ipsec_hosts *,
163			     u_int32_t, struct ipsec_transforms *,
164			     struct ipsec_key *, struct ipsec_key *);
165struct ipsec_rule	*reverse_sa(struct ipsec_rule *, u_int32_t,
166			     struct ipsec_key *, struct ipsec_key *);
167struct ipsec_rule	*create_sagroup(struct ipsec_addr_wrap *, u_int8_t,
168			     u_int32_t, struct ipsec_addr_wrap *, u_int8_t,
169			     u_int32_t);
170struct ipsec_rule	*create_flow(u_int8_t, u_int8_t, struct ipsec_hosts *,
171			     struct ipsec_hosts *, u_int8_t, char *, char *,
172			     u_int8_t);
173int			 expand_rule(struct ipsec_rule *, u_int8_t, u_int32_t,
174			     struct ipsec_key *, struct ipsec_key *, int);
175struct ipsec_rule	*reverse_rule(struct ipsec_rule *);
176struct ipsec_rule	*create_ike(u_int8_t, struct ipsec_hosts *,
177			     struct ipsec_hosts *, struct ike_mode *,
178			     struct ike_mode *, u_int8_t, u_int8_t, char *,
179			     char *, struct ike_auth *);
180int			 add_sagroup(struct ipsec_rule *);
181
182struct ipsec_transforms *ipsec_transforms;
183
184typedef struct {
185	union {
186		u_int32_t	 number;
187		u_int8_t	 ikemode;
188		u_int8_t	 dir;
189		u_int8_t	 satype;	/* encapsulating prococol */
190		u_int8_t	 proto;		/* encapsulated protocol */
191		u_int8_t	 tmode;
192		char		*string;
193		u_int16_t	 port;
194		struct ipsec_hosts hosts;
195		struct ipsec_hosts peers;
196		struct ipsec_addr_wrap *singlehost;
197		struct ipsec_addr_wrap *host;
198		struct {
199			char *srcid;
200			char *dstid;
201		} ids;
202		char		*id;
203		u_int8_t	 type;
204		struct ike_auth	 ikeauth;
205		struct {
206			u_int32_t	spiout;
207			u_int32_t	spiin;
208		} spis;
209		struct {
210			struct ipsec_key *keyout;
211			struct ipsec_key *keyin;
212		} authkeys;
213		struct {
214			struct ipsec_key *keyout;
215			struct ipsec_key *keyin;
216		} enckeys;
217		struct {
218			struct ipsec_key *keyout;
219			struct ipsec_key *keyin;
220		} keys;
221		struct ipsec_transforms *transforms;
222		struct ipsec_life	*life;
223		struct ike_mode		*mainmode;
224		struct ike_mode		*quickmode;
225	} v;
226	int lineno;
227} YYSTYPE;
228
229%}
230
231%token	FLOW FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK TCPMD5 SPI
232%token	AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK PASSIVE
233%token	ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC LIFE
234%token	TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT
235%token	<v.string>		STRING
236%type	<v.string>		string
237%type	<v.dir>			dir
238%type	<v.satype>		satype
239%type	<v.proto>		proto
240%type	<v.tmode>		tmode
241%type	<v.number>		number
242%type	<v.hosts>		hosts
243%type	<v.port>		port
244%type	<v.peers>		peers
245%type	<v.singlehost>		singlehost
246%type	<v.host>		host host_list
247%type	<v.ids>			ids
248%type	<v.id>			id
249%type	<v.spis>		spispec
250%type	<v.authkeys>		authkeyspec
251%type	<v.enckeys>		enckeyspec
252%type	<v.keys>		keyspec
253%type	<v.transforms>		transforms
254%type	<v.ikemode>		ikemode
255%type	<v.ikeauth>		ikeauth
256%type	<v.type>		type
257%type	<v.life>		life
258%type	<v.mainmode>		mainmode
259%type	<v.quickmode>		quickmode
260%%
261
262grammar		: /* empty */
263		| grammar '\n'
264		| grammar ikerule '\n'
265		| grammar flowrule '\n'
266		| grammar sarule '\n'
267		| grammar tcpmd5rule '\n'
268		| grammar varset '\n'
269		| grammar error '\n'		{ errors++; }
270		;
271
272number		: STRING			{
273			unsigned long	ulval;
274
275			if (atoul($1, &ulval) == -1) {
276				yyerror("%s is not a number", $1);
277				free($1);
278				YYERROR;
279			}
280			if (ulval > UINT_MAX) {
281				yyerror("0x%lx out of range", ulval);
282				free($1);
283				YYERROR;
284			}
285			$$ = (u_int32_t)ulval;
286			free($1);
287		}
288		;
289
290comma		: ','
291		| /* empty */
292		;
293
294tcpmd5rule	: TCPMD5 hosts spispec authkeyspec	{
295			struct ipsec_rule	*r;
296
297			r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, &$2,
298			    $3.spiout, NULL, $4.keyout, NULL);
299			if (r == NULL)
300				YYERROR;
301			r->nr = ipsec->rule_nr++;
302
303			if (expand_rule(r, 0, $3.spiin, $4.keyin, NULL, 0))
304				errx(1, "tcpmd5rule: expand_rule");
305		}
306		;
307
308sarule		: satype tmode hosts spispec transforms authkeyspec
309		    enckeyspec {
310			struct ipsec_rule	*r;
311
312			r = create_sa($1, $2, &$3, $4.spiout, $5, $6.keyout,
313			    $7.keyout);
314			if (r == NULL)
315				YYERROR;
316			r->nr = ipsec->rule_nr++;
317
318			if (expand_rule(r, 0, $4.spiin, $6.keyin, $7.keyin, 1))
319				errx(1, "sarule: expand_rule");
320		}
321		;
322
323flowrule	: FLOW satype dir proto hosts peers ids type {
324			struct ipsec_rule	*r;
325
326			r = create_flow($3, $4, &$5, &$6, $2, $7.srcid,
327			    $7.dstid, $8);
328			if (r == NULL)
329				YYERROR;
330
331			if (expand_rule(r, $3, 0, NULL, NULL, 0))
332				errx(1, "flowrule: expand_rule");
333		}
334		;
335
336ikerule		: IKE ikemode satype proto hosts peers mainmode quickmode
337		      ids ikeauth {
338			struct ipsec_rule	*r;
339
340			r = create_ike($4, &$5, &$6, $7, $8, $3, $2, $9.srcid,
341			    $9.dstid, &$10);
342			if (r == NULL)
343				YYERROR;
344			r->nr = ipsec->rule_nr++;
345
346			if (expand_rule(r, 0, 0, NULL, NULL, 0))
347				errx(1, "ikerule: expand_rule");
348		}
349		;
350
351satype		: /* empty */			{ $$ = IPSEC_ESP; }
352		| ESP				{ $$ = IPSEC_ESP; }
353		| AH				{ $$ = IPSEC_AH; }
354		| IPCOMP			{ $$ = IPSEC_IPCOMP; }
355		| IPIP				{ $$ = IPSEC_IPIP; }
356		;
357
358proto		: /* empty */			{ $$ = 0; }
359		| PROTO STRING			{
360			struct protoent *p;
361			const char *errstr;
362			int proto;
363
364			if ((p = getprotobyname($2)) != NULL) {
365				$$ = p->p_proto;
366			} else {
367				errstr = NULL;
368				proto = strtonum($2, 0, 255, &errstr);
369				if (errstr)
370					errx(1, "unknown protocol: %s", $2);
371				$$ = proto;
372			}
373
374		}
375		;
376
377tmode		: /* empty */			{ $$ = IPSEC_TUNNEL; }
378		| TUNNEL			{ $$ = IPSEC_TUNNEL; }
379		| TRANSPORT			{ $$ = IPSEC_TRANSPORT; }
380		;
381
382dir		: /* empty */			{ $$ = IPSEC_INOUT; }
383		| IN				{ $$ = IPSEC_IN; }
384		| OUT				{ $$ = IPSEC_OUT; }
385		;
386
387hosts		: FROM host port TO host port		{
388			$$.src = $2;
389			$$.sport = $3;
390			$$.dst = $5;
391			$$.dport = $6;
392		}
393		| TO host port FROM host port		{
394			$$.src = $5;
395			$$.sport = $6;
396			$$.dst = $2;
397			$$.dport = $3;
398		}
399		;
400
401port		: /* empty */				{ $$ = 0; }
402		| PORT STRING				{
403			struct servent *s;
404			const char *errstr;
405			int port;
406
407			if ((s = getservbyname($2, "tcp")) != NULL ||
408			    (s = getservbyname($2, "udp")) != NULL) {
409				$$ = s->s_port;
410			} else {
411				errstr = NULL;
412				port = strtonum($2, 0, USHRT_MAX, &errstr);
413				if (errstr) {
414					yyerror("unknown port: %s", $2);
415					YYERROR;
416				}
417				$$ = htons(port);
418			}
419		}
420		;
421
422peers		: /* empty */				{
423			$$.dst = NULL;
424			$$.src = NULL;
425		}
426		| PEER singlehost LOCAL singlehost	{
427			$$.dst = $2;
428			$$.src = $4;
429		}
430		| LOCAL singlehost PEER singlehost	{
431			$$.dst = $4;
432			$$.src = $2;
433		}
434		| PEER singlehost			{
435			$$.dst = $2;
436			$$.src = NULL;
437		}
438		| LOCAL singlehost			{
439			$$.dst = NULL;
440			$$.src = $2;
441		}
442		;
443
444singlehost	: /* empty */			{ $$ = NULL; }
445		| STRING			{
446			if (($$ = host($1)) == NULL) {
447				free($1);
448				yyerror("could not parse host specification");
449				YYERROR;
450			}
451			free($1);
452		}
453		;
454
455host_list	: host				{ $$ = $1; }
456		| host_list comma host		{
457			if ($3 == NULL)
458				$$ = $1;
459			else if ($1 == NULL)
460				$$ = $3;
461			else {
462				$1->tail->next = $3;
463				$1->tail = $3->tail;
464				$$ = $1;
465			}
466		}
467		;
468
469host		: STRING			{
470			if (($$ = host($1)) == NULL) {
471				free($1);
472				yyerror("could not parse host specification");
473				YYERROR;
474			}
475			free($1);
476		}
477		| STRING '/' number		{
478			char	*buf;
479
480			if (asprintf(&buf, "%s/%u", $1, $3) == -1)
481				err(1, "host: asprintf");
482			free($1);
483			if (($$ = host(buf)) == NULL)	{
484				free(buf);
485				yyerror("could not parse host specification");
486				YYERROR;
487			}
488			free(buf);
489		}
490		| ANY				{
491			struct ipsec_addr_wrap	*ipa;
492
493			ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
494			if (ipa == NULL)
495				err(1, "host: calloc");
496
497			ipa->af = AF_INET;
498			ipa->netaddress = 1;
499			if ((ipa->name = strdup("0.0.0.0/0")) == NULL)
500				err(1, "host: strdup");
501
502			ipa->next = calloc(1, sizeof(struct ipsec_addr_wrap));
503			if (ipa->next == NULL)
504				err(1, "host: calloc");
505
506			ipa->next->af = AF_INET6;
507			ipa->next->netaddress = 1;
508			if ((ipa->next->name = strdup("::/0")) == NULL)
509				err(1, "host: strdup");
510
511			$$ = ipa;
512		}
513		| '{' host_list '}'		{ $$ = $2; }
514		;
515
516ids		: /* empty */			{
517			$$.srcid = NULL;
518			$$.dstid = NULL;
519		}
520		| SRCID id DSTID id		{
521			$$.srcid = $2;
522			$$.dstid = $4;
523		}
524		| SRCID id			{
525			$$.srcid = $2;
526			$$.dstid = NULL;
527		}
528		| DSTID id			{
529			$$.srcid = NULL;
530			$$.dstid = $2;
531		}
532		;
533
534type		: /* empty */			{
535			$$ = TYPE_REQUIRE;
536		}
537		| TYPE USE			{
538			$$ = TYPE_USE;
539		}
540		| TYPE ACQUIRE			{
541			$$ = TYPE_ACQUIRE;
542		}
543		| TYPE REQUIRE			{
544			$$ = TYPE_REQUIRE;
545		}
546		| TYPE DENY			{
547			$$ = TYPE_DENY;
548		}
549		| TYPE BYPASS			{
550			$$ = TYPE_BYPASS;
551		}
552		| TYPE DONTACQ			{
553			$$ = TYPE_DONTACQ;
554		}
555		;
556
557id		: STRING			{ $$ = $1; }
558		;
559
560spispec		: SPI STRING			{
561			u_int32_t	 spi;
562			char		*p = strchr($2, ':');
563
564			if (p != NULL) {
565				*p++ = 0;
566
567				if (atospi(p, &spi) == -1) {
568					yyerror("%s is not a valid spi", p);
569					free($2);
570					YYERROR;
571				}
572				$$.spiin = spi;
573			}
574			if (atospi($2, &spi) == -1) {
575				yyerror("%s is not a valid spi", $2);
576				free($2);
577				YYERROR;
578			}
579			$$.spiout = spi;
580
581
582			free($2);
583		}
584		;
585
586transforms	:					{
587			if ((ipsec_transforms = calloc(1,
588			    sizeof(struct ipsec_transforms))) == NULL)
589				err(1, "transforms: calloc");
590		}
591		    transforms_l
592			{ $$ = ipsec_transforms; }
593		| /* empty */				{
594			if (($$ = calloc(1,
595			    sizeof(struct ipsec_transforms))) == NULL)
596				err(1, "transforms: calloc");
597		}
598		;
599
600transforms_l	: transforms_l transform
601		| transform
602		;
603
604transform	: AUTHXF STRING			{
605			if (ipsec_transforms->authxf)
606				yyerror("auth already set");
607			else {
608				ipsec_transforms->authxf = parse_xf($2,
609				    authxfs);
610				if (!ipsec_transforms->authxf)
611					yyerror("%s not a valid transform", $2);
612			}
613		}
614		| ENCXF STRING			{
615			if (ipsec_transforms->encxf)
616				yyerror("enc already set");
617			else {
618				ipsec_transforms->encxf = parse_xf($2, encxfs);
619				if (!ipsec_transforms->encxf)
620					yyerror("%s not a valid transform", $2);
621			}
622		}
623		| COMPXF STRING			{
624			if (ipsec_transforms->compxf)
625				yyerror("comp already set");
626			else {
627				ipsec_transforms->compxf = parse_xf($2,
628				    compxfs);
629				if (!ipsec_transforms->compxf)
630					yyerror("%s not a valid transform", $2);
631			}
632		}
633		| GROUP STRING			{
634			if (ipsec_transforms->groupxf)
635				yyerror("group already set");
636			else {
637				ipsec_transforms->groupxf = parse_xf($2,
638				    groupxfs);
639				if (!ipsec_transforms->groupxf)
640					yyerror("%s not a valid transform", $2);
641			}
642		}
643		;
644
645mainmode	: /* empty */			{
646			struct ike_mode		*mm;
647
648			/* We create just an empty mode */
649			if ((mm = calloc(1, sizeof(struct ike_mode))) == NULL)
650				err(1, "mainmode: calloc");
651			$$ = mm;
652		}
653		| MAIN transforms life		{
654			struct ike_mode	*mm;
655
656			if ((mm = calloc(1, sizeof(struct ike_mode))) == NULL)
657				err(1, "mainmode: calloc");
658			mm->xfs = $2;
659			mm->life = $3;
660			$$ = mm;
661		}
662		;
663
664quickmode	: /* empty */			{
665			struct ike_mode		*qm;
666
667			/* We create just an empty mode */
668			if ((qm = calloc(1, sizeof(struct ike_mode))) == NULL)
669				err(1, "quickmode: calloc");
670			$$ = qm;
671		}
672		| QUICK transforms life		{
673			struct ike_mode	*qm;
674
675			if ((qm = calloc(1, sizeof(struct ike_mode))) == NULL)
676				err(1, "quickmode: calloc");
677			qm->xfs = $2;
678			qm->life = $3;
679			$$ = qm;
680		}
681		;
682
683life		: /* empty */			{
684			struct ipsec_life *life;
685
686			/* We create just an empty transform */
687			if ((life = calloc(1, sizeof(struct ipsec_life)))
688			    == NULL)
689				err(1, "life: calloc");
690			life->lifetime = -1;
691			life->lifevolume = -1;
692			$$ = life;
693		}
694		| LIFE number			{
695			struct ipsec_life *life;
696
697			life = parse_life($2);
698			if (life == NULL)
699				yyerror("%s not a valid lifetime", $2);
700			$$ = life;
701		}
702		;
703
704authkeyspec	: /* empty */			{
705			$$.keyout = NULL;
706			$$.keyin = NULL;
707		}
708		| AUTHKEY keyspec		{
709			$$.keyout = $2.keyout;
710			$$.keyin = $2.keyin;
711		}
712		;
713
714enckeyspec	: /* empty */			{
715			$$.keyout = NULL;
716			$$.keyin = NULL;
717		}
718		| ENCKEY keyspec		{
719			$$.keyout = $2.keyout;
720			$$.keyin = $2.keyin;
721		}
722		;
723
724keyspec		: STRING			{
725			unsigned char	*hex;
726			unsigned char	*p = strchr($1, ':');
727
728			if (p != NULL ) {
729				*p++ = 0;
730
731				if (!strncmp(p, "0x", 2))
732					p += 2;
733				$$.keyin = parsekey(p, strlen(p));
734			}
735
736			hex = $1;
737			if (!strncmp(hex, "0x", 2))
738				hex += 2;
739			$$.keyout = parsekey(hex, strlen(hex));
740
741			free($1);
742		}
743		| FILENAME STRING		{
744			unsigned char	*p = strchr($2, ':');
745
746			if (p != NULL) {
747				*p++ = 0;
748				$$.keyin = parsekeyfile(p);
749			}
750			$$.keyout = parsekeyfile($2);
751			free($2);
752		}
753		;
754
755ikemode		: /* empty */			{ $$ = IKE_ACTIVE; }
756		| PASSIVE			{ $$ = IKE_PASSIVE; }
757		| DYNAMIC			{ $$ = IKE_DYNAMIC; }
758		| ACTIVE			{ $$ = IKE_ACTIVE; }
759		;
760
761ikeauth		: /* empty */			{
762			$$.type = IKE_AUTH_RSA;
763			$$.string = NULL;
764		}
765		| RSA				{
766			$$.type = IKE_AUTH_RSA;
767			$$.string = NULL;
768		}
769		| PSK STRING			{
770			$$.type = IKE_AUTH_PSK;
771			if (($$.string = strdup($2)) == NULL)
772				err(1, "ikeauth: strdup");
773		}
774		;
775
776string		: string STRING
777		{
778			if (asprintf(&$$, "%s %s", $1, $2) == -1)
779				err(1, "string: asprintf");
780			free($1);
781			free($2);
782		}
783		| STRING
784		;
785
786varset		: STRING '=' string
787		{
788			if (ipsec->opts & IPSECCTL_OPT_VERBOSE)
789				printf("%s = \"%s\"\n", $1, $3);
790			if (symset($1, $3, 0) == -1)
791				err(1, "cannot store variable");
792			free($1);
793			free($3);
794		}
795		;
796
797%%
798
799struct keywords {
800	const char	*k_name;
801	int		 k_val;
802};
803
804int
805yyerror(const char *fmt, ...)
806{
807	va_list		 ap;
808	extern const char *infile;
809
810	errors = 1;
811	va_start(ap, fmt);
812	fprintf(stderr, "%s: %d: ", infile, yyval.lineno);
813	vfprintf(stderr, fmt, ap);
814	fprintf(stderr, "\n");
815	va_end(ap);
816	return (0);
817}
818
819int
820kw_cmp(const void *k, const void *e)
821{
822	return (strcmp(k, ((const struct keywords *)e)->k_name));
823}
824
825int
826lookup(char *s)
827{
828	/* this has to be sorted always */
829	static const struct keywords keywords[] = {
830		{ "acquire",		ACQUIRE },
831		{ "active",		ACTIVE },
832		{ "ah",			AH },
833		{ "any",		ANY },
834		{ "auth",		AUTHXF },
835		{ "authkey",		AUTHKEY },
836		{ "bypass",		BYPASS },
837		{ "comp",		COMPXF },
838		{ "deny",		DENY },
839		{ "dontacq",		DONTACQ },
840		{ "dstid",		DSTID },
841		{ "dynamic",		DYNAMIC },
842		{ "enc",		ENCXF },
843		{ "enckey",		ENCKEY },
844		{ "esp",		ESP },
845		{ "file",		FILENAME },
846		{ "flow",		FLOW },
847		{ "from",		FROM },
848		{ "group",		GROUP },
849		{ "ike",		IKE },
850		{ "in",			IN },
851		{ "ipcomp",		IPCOMP },
852		{ "ipip",		IPIP },
853		{ "life",		LIFE },
854		{ "local",		LOCAL },
855		{ "main",		MAIN },
856		{ "out",		OUT },
857		{ "passive",		PASSIVE },
858		{ "peer",		PEER },
859		{ "port",		PORT },
860		{ "proto",		PROTO },
861		{ "psk",		PSK },
862		{ "quick",		QUICK },
863		{ "require",		REQUIRE },
864		{ "rsa",		RSA },
865		{ "spi",		SPI },
866		{ "srcid",		SRCID },
867		{ "tcpmd5",		TCPMD5 },
868		{ "to",			TO },
869		{ "transport",		TRANSPORT },
870		{ "tunnel",		TUNNEL },
871		{ "type",		TYPE },
872		{ "use",		USE }
873	};
874	const struct keywords	*p;
875
876	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
877	    sizeof(keywords[0]), kw_cmp);
878
879	if (p) {
880		if (debug > 1)
881			fprintf(stderr, "%s: %d\n", s, p->k_val);
882		return (p->k_val);
883	} else {
884		if (debug > 1)
885			fprintf(stderr, "string: %s\n", s);
886		return (STRING);
887	}
888}
889
890#define MAXPUSHBACK	128
891
892char	*parsebuf;
893int	 parseindex;
894char	 pushback_buffer[MAXPUSHBACK];
895int	 pushback_index = 0;
896
897int
898lgetc(FILE *f)
899{
900	int	c, next;
901
902	if (parsebuf) {
903		/* Read character from the parsebuffer instead of input. */
904		if (parseindex >= 0) {
905			c = parsebuf[parseindex++];
906			if (c != '\0')
907				return (c);
908			parsebuf = NULL;
909		} else
910			parseindex++;
911	}
912
913	if (pushback_index)
914		return (pushback_buffer[--pushback_index]);
915
916	while ((c = getc(f)) == '\\') {
917		next = getc(f);
918		if (next != '\n') {
919			c = next;
920			break;
921		}
922		yylval.lineno = lineno;
923		lineno++;
924	}
925	if (c == '\t' || c == ' ') {
926		/* Compress blanks to a single space. */
927		do {
928			c = getc(f);
929		} while (c == '\t' || c == ' ');
930		ungetc(c, f);
931		c = ' ';
932	}
933
934	return (c);
935}
936
937int
938lungetc(int c)
939{
940	if (c == EOF)
941		return (EOF);
942	if (parsebuf) {
943		parseindex--;
944		if (parseindex >= 0)
945			return (c);
946	}
947	if (pushback_index < MAXPUSHBACK-1)
948		return (pushback_buffer[pushback_index++] = c);
949	else
950		return (EOF);
951}
952
953int
954findeol(void)
955{
956	int	c;
957
958	parsebuf = NULL;
959	pushback_index = 0;
960
961	/* skip to either EOF or the first real EOL */
962	while (1) {
963		c = lgetc(fin);
964		if (c == '\n') {
965			lineno++;
966			break;
967		}
968		if (c == EOF)
969			break;
970	}
971	return (ERROR);
972}
973
974int
975yylex(void)
976{
977	char	 buf[8096];
978	char	*p, *val;
979	int	 endc, c;
980	int	 token;
981
982top:
983	p = buf;
984	while ((c = lgetc(fin)) == ' ')
985		; /* nothing */
986
987	yylval.lineno = lineno;
988	if (c == '#')
989		while ((c = lgetc(fin)) != '\n' && c != EOF)
990			; /* nothing */
991	if (c == '$' && parsebuf == NULL) {
992		while (1) {
993			if ((c = lgetc(fin)) == EOF)
994				return (0);
995
996			if (p + 1 >= buf + sizeof(buf) - 1) {
997				yyerror("string too long");
998				return (findeol());
999			}
1000			if (isalnum(c) || c == '_') {
1001				*p++ = (char)c;
1002				continue;
1003			}
1004			*p = '\0';
1005			lungetc(c);
1006			break;
1007		}
1008		val = symget(buf);
1009		if (val == NULL) {
1010			yyerror("macro \"%s\" not defined", buf);
1011			return (findeol());
1012		}
1013		parsebuf = val;
1014		parseindex = 0;
1015		goto top;
1016	}
1017
1018	switch (c) {
1019	case '\'':
1020	case '"':
1021		endc = c;
1022		while (1) {
1023			if ((c = lgetc(fin)) == EOF)
1024				return (0);
1025			if (c == endc) {
1026				*p = '\0';
1027				break;
1028			}
1029			if (c == '\n') {
1030				lineno++;
1031				continue;
1032			}
1033			if (p + 1 >= buf + sizeof(buf) - 1) {
1034				yyerror("string too long");
1035				return (findeol());
1036			}
1037			*p++ = (char)c;
1038		}
1039		yylval.v.string = strdup(buf);
1040		if (yylval.v.string == NULL)
1041			err(1, "yylex: strdup");
1042		return (STRING);
1043	}
1044
1045#define allowed_in_string(x) \
1046	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1047	x != '{' && x != '}' && x != '<' && x != '>' && \
1048	x != '!' && x != '=' && x != '/' && x != '#' && \
1049	x != ','))
1050
1051	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1052		do {
1053			*p++ = c;
1054			if ((unsigned)(p-buf) >= sizeof(buf)) {
1055				yyerror("string too long");
1056				return (findeol());
1057			}
1058		} while ((c = lgetc(fin)) != EOF && (allowed_in_string(c)));
1059		lungetc(c);
1060		*p = '\0';
1061		if ((token = lookup(buf)) == STRING)
1062			if ((yylval.v.string = strdup(buf)) == NULL)
1063				err(1, "yylex: strdup");
1064		return (token);
1065	}
1066	if (c == '\n') {
1067		yylval.lineno = lineno;
1068		lineno++;
1069	}
1070	if (c == EOF)
1071		return (0);
1072	return (c);
1073}
1074
1075int
1076parse_rules(FILE *input, struct ipsecctl *ipsecx)
1077{
1078	struct sym	*sym;
1079
1080	ipsec = ipsecx;
1081	fin = input;
1082	lineno = 1;
1083	errors = 0;
1084
1085	yyparse();
1086
1087	/* Free macros and check which have not been used. */
1088	while ((sym = TAILQ_FIRST(&symhead))) {
1089		if ((ipsec->opts & IPSECCTL_OPT_VERBOSE2) && !sym->used)
1090			fprintf(stderr, "warning: macro '%s' not "
1091			    "used\n", sym->nam);
1092		TAILQ_REMOVE(&symhead, sym, entries);
1093		free(sym->nam);
1094		free(sym->val);
1095		free(sym);
1096	}
1097
1098	return (errors ? -1 : 0);
1099}
1100
1101int
1102symset(const char *nam, const char *val, int persist)
1103{
1104	struct sym	*sym;
1105
1106	for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
1107	    sym = TAILQ_NEXT(sym, entries))
1108		;	/* nothing */
1109
1110	if (sym != NULL) {
1111		if (sym->persist == 1)
1112			return (0);
1113		else {
1114			TAILQ_REMOVE(&symhead, sym, entries);
1115			free(sym->nam);
1116			free(sym->val);
1117			free(sym);
1118		}
1119	}
1120	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1121		return (-1);
1122
1123	sym->nam = strdup(nam);
1124	if (sym->nam == NULL) {
1125		free(sym);
1126		return (-1);
1127	}
1128	sym->val = strdup(val);
1129	if (sym->val == NULL) {
1130		free(sym->nam);
1131		free(sym);
1132		return (-1);
1133	}
1134	sym->used = 0;
1135	sym->persist = persist;
1136	TAILQ_INSERT_TAIL(&symhead, sym, entries);
1137	return (0);
1138}
1139
1140int
1141cmdline_symset(char *s)
1142{
1143	char	*sym, *val;
1144	int	ret;
1145	size_t	len;
1146
1147	if ((val = strrchr(s, '=')) == NULL)
1148		return (-1);
1149
1150	len = strlen(s) - strlen(val) + 1;
1151	if ((sym = malloc(len)) == NULL)
1152		err(1, "cmdline_symset: malloc");
1153
1154	strlcpy(sym, s, len);
1155
1156	ret = symset(sym, val + 1, 1);
1157	free(sym);
1158
1159	return (ret);
1160}
1161
1162char *
1163symget(const char *nam)
1164{
1165	struct sym	*sym;
1166
1167	TAILQ_FOREACH(sym, &symhead, entries)
1168		if (strcmp(nam, sym->nam) == 0) {
1169			sym->used = 1;
1170			return (sym->val);
1171		}
1172	return (NULL);
1173}
1174
1175int
1176atoul(char *s, u_long *ulvalp)
1177{
1178	u_long	 ulval;
1179	char	*ep;
1180
1181	errno = 0;
1182	ulval = strtoul(s, &ep, 0);
1183	if (s[0] == '\0' || *ep != '\0')
1184		return (-1);
1185	if (errno == ERANGE && ulval == ULONG_MAX)
1186		return (-1);
1187	*ulvalp = ulval;
1188	return (0);
1189}
1190
1191int
1192atospi(char *s, u_int32_t *spivalp)
1193{
1194	unsigned long	ulval;
1195
1196	if (atoul(s, &ulval) == -1)
1197		return (-1);
1198	if (ulval >= SPI_RESERVED_MIN && ulval <= SPI_RESERVED_MAX) {
1199		yyerror("illegal SPI value");
1200		return (-1);
1201	}
1202	*spivalp = ulval;
1203	return (0);
1204}
1205
1206u_int8_t
1207x2i(unsigned char *s)
1208{
1209	char	ss[3];
1210
1211	ss[0] = s[0];
1212	ss[1] = s[1];
1213	ss[2] = 0;
1214
1215	if (!isxdigit(s[0]) || !isxdigit(s[1])) {
1216		yyerror("keys need to be specified in hex digits");
1217		return (-1);
1218	}
1219	return ((u_int8_t)strtoul(ss, NULL, 16));
1220}
1221
1222struct ipsec_key *
1223parsekey(unsigned char *hexkey, size_t len)
1224{
1225	struct ipsec_key *key;
1226	int		  i;
1227
1228	key = calloc(1, sizeof(struct ipsec_key));
1229	if (key == NULL)
1230		err(1, "parsekey: calloc");
1231
1232	key->len = len / 2;
1233	key->data = calloc(key->len, sizeof(u_int8_t));
1234	if (key->data == NULL)
1235		err(1, "parsekey: calloc");
1236
1237	for (i = 0; i < (int)key->len; i++)
1238		key->data[i] = x2i(hexkey + 2 * i);
1239
1240	return (key);
1241}
1242
1243struct ipsec_key *
1244parsekeyfile(char *filename)
1245{
1246	struct stat	 sb;
1247	int		 fd;
1248	unsigned char	*hex;
1249
1250	if ((fd = open(filename, O_RDONLY)) < 0)
1251		err(1, "parsekeyfile: open");
1252	if (fstat(fd, &sb) < 0)
1253		err(1, "parsekeyfile: stat %s", filename);
1254	if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0))
1255		errx(1, "parsekeyfile: key too %s", sb.st_size ? "large" :
1256		    "small");
1257	if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL)
1258		err(1, "parsekeyfile: calloc");
1259	if (read(fd, hex, sb.st_size) < sb.st_size)
1260		err(1, "parsekeyfile: read");
1261	close(fd);
1262	return (parsekey(hex, sb.st_size));
1263}
1264
1265struct ipsec_addr_wrap *
1266host(const char *s)
1267{
1268	struct ipsec_addr_wrap	*ipa = NULL;
1269	int			 mask, v4mask, cont = 1;
1270	char			*p, *q, *ps;
1271
1272	if ((p = strrchr(s, '/')) != NULL) {
1273		errno = 0;
1274		mask = strtol(p + 1, &q, 0);
1275		if (errno == ERANGE || !q || *q || mask > 128 || q == (p + 1))
1276			errx(1, "host: invalid netmask '%s'", p);
1277		if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL)
1278			err(1, "host: calloc");
1279		strlcpy(ps, s, strlen(s) - strlen(p) + 1);
1280		v4mask = mask;
1281	} else {
1282		if ((ps = strdup(s)) == NULL)
1283			err(1, "host: strdup");
1284		v4mask = 32;
1285		mask = -1;
1286	}
1287
1288	/* Does interface with this name exist? */
1289	if (cont && (ipa = host_if(ps, mask)) != NULL)
1290		cont = 0;
1291
1292	/* IPv4 address? */
1293	if (cont && (ipa = host_v4(s, v4mask)) != NULL)
1294		cont = 0;
1295
1296	/* IPv6 address? */
1297	if (cont && (ipa = host_v6(ps, mask == -1 ? 128 : mask)) != NULL)
1298		cont = 0;
1299
1300	/* dns lookup */
1301	if (cont && (ipa = host_dns(s, v4mask, 0)) != NULL)
1302		cont = 0;
1303	free(ps);
1304
1305	if (ipa == NULL || cont == 1) {
1306		fprintf(stderr, "no IP address found for %s\n", s);
1307		return (NULL);
1308	}
1309	return (ipa);
1310}
1311
1312struct ipsec_addr_wrap *
1313host_v6(const char *s, int prefixlen)
1314{
1315	struct ipsec_addr_wrap	*ipa = NULL;
1316	struct addrinfo		 hints, *res0, *res;
1317	char			 hbuf[NI_MAXHOST];
1318
1319	bzero(&hints, sizeof(struct addrinfo));
1320	hints.ai_family = PF_UNSPEC;
1321	hints.ai_socktype = SOCK_STREAM;
1322	hints.ai_flags = AI_NUMERICHOST;
1323	if (getaddrinfo(s, NULL, &hints, &res0))
1324		return (NULL);
1325
1326	for (res = res0; res; res = res->ai_next) {
1327		if (res->ai_family != AF_INET6)
1328			continue;
1329		break; /* found one */
1330	}
1331	ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1332	if (ipa == NULL)
1333		err(1, "host_addr: calloc");
1334	ipa->af = res->ai_family;
1335	memcpy(&ipa->address.v6,
1336	    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr,
1337	    sizeof(struct in6_addr));
1338	if (prefixlen > 128)
1339		prefixlen = 128;
1340	ipa->next = NULL;
1341	ipa->tail = ipa;
1342
1343	set_ipmask(ipa, prefixlen);
1344	if (getnameinfo(res->ai_addr, res->ai_addrlen,
1345	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
1346		errx(1, "could not get a numeric hostname");
1347	}
1348
1349	if (prefixlen != 128) {
1350		ipa->netaddress = 1;
1351		asprintf(&ipa->name, "%s/%d", hbuf, prefixlen);
1352	} else
1353		ipa->name = strdup(hbuf);
1354	if (ipa->name == NULL)
1355		err(1, "host_dns: strdup");
1356
1357	freeaddrinfo(res0);
1358
1359	return (ipa);
1360}
1361
1362struct ipsec_addr_wrap *
1363host_v4(const char *s, int mask)
1364{
1365	struct ipsec_addr_wrap	*ipa = NULL;
1366	struct in_addr		 ina;
1367	int			 bits = 32;
1368
1369	bzero(&ina, sizeof(struct in_addr));
1370	if (strrchr(s, '/') != NULL) {
1371		if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1)
1372			return (NULL);
1373	} else {
1374		if (inet_pton(AF_INET, s, &ina) != 1)
1375			return (NULL);
1376	}
1377
1378	ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1379	if (ipa == NULL)
1380		err(1, "host_v4: calloc");
1381
1382	ipa->address.v4 = ina;
1383	ipa->name = strdup(s);
1384	if (ipa->name == NULL)
1385		err(1, "host_v4: strdup");
1386	ipa->af = AF_INET;
1387	ipa->next = NULL;
1388	ipa->tail = ipa;
1389
1390	set_ipmask(ipa, bits);
1391	if (bits != (ipa->af == AF_INET ? 32 : 128))
1392		ipa->netaddress = 1;
1393
1394	return (ipa);
1395}
1396
1397struct ipsec_addr_wrap *
1398host_dns(const char *s, int v4mask, int v6mask)
1399{
1400	struct ipsec_addr_wrap	*ipa = NULL;
1401	struct addrinfo		 hints, *res0, *res;
1402	int			 error;
1403	int			 bits = 32;
1404
1405	bzero(&hints, sizeof(struct addrinfo));
1406	hints.ai_family = PF_UNSPEC;
1407	hints.ai_socktype = SOCK_STREAM;
1408	error = getaddrinfo(s, NULL, &hints, &res0);
1409	if (error)
1410		return (NULL);
1411
1412	for (res = res0; res; res = res->ai_next) {
1413		if (res->ai_family != AF_INET)
1414			continue;
1415		ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1416		if (ipa == NULL)
1417			err(1, "host_dns: calloc");
1418		memcpy(&ipa->address.v4,
1419		    &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr,
1420		    sizeof(struct in_addr));
1421		ipa->name = strdup(inet_ntoa(ipa->address.v4));
1422		if (ipa->name == NULL)
1423			err(1, "host_dns: strdup");
1424		ipa->af = AF_INET;
1425		ipa->next = NULL;
1426		ipa->tail = ipa;
1427
1428		set_ipmask(ipa, bits);
1429		if (bits != (ipa->af == AF_INET ? 32 : 128))
1430			ipa->netaddress = 1;
1431		break;
1432	}
1433	freeaddrinfo(res0);
1434
1435	return (ipa);
1436}
1437
1438struct ipsec_addr_wrap *
1439host_if(const char *s, int mask)
1440{
1441	struct ipsec_addr_wrap *ipa = NULL;
1442
1443	if (ifa_exists(s))
1444		ipa = ifa_lookup(s);
1445
1446	return (ipa);
1447}
1448
1449/* interface lookup routintes */
1450
1451struct ipsec_addr_wrap	*iftab;
1452
1453void
1454ifa_load(void)
1455{
1456	struct ifaddrs		*ifap, *ifa;
1457	struct ipsec_addr_wrap	*n = NULL, *h = NULL;
1458
1459	if (getifaddrs(&ifap) < 0)
1460		err(1, "ifa_load: getiffaddrs");
1461
1462	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1463		if (!(ifa->ifa_addr->sa_family == AF_INET ||
1464		    ifa->ifa_addr->sa_family == AF_INET6 ||
1465		    ifa->ifa_addr->sa_family == AF_LINK))
1466			continue;
1467		n = calloc(1, sizeof(struct ipsec_addr_wrap));
1468		if (n == NULL)
1469			err(1, "ifa_load: calloc");
1470		n->af = ifa->ifa_addr->sa_family;
1471		if ((n->name = strdup(ifa->ifa_name)) == NULL)
1472			err(1, "ifa_load: strdup");
1473		if (n->af == AF_INET) {
1474			n->af = AF_INET;
1475			memcpy(&n->address.v4, &((struct sockaddr_in *)
1476			    ifa->ifa_addr)->sin_addr.s_addr,
1477			    sizeof(struct in_addr));
1478			memcpy(&n->mask.v4, &((struct sockaddr_in *)
1479			    ifa->ifa_netmask)->sin_addr.s_addr,
1480			    sizeof(struct in_addr));
1481		} else if (n->af == AF_INET6) {
1482			n->af = AF_INET6;
1483			memcpy(&n->address.v6, &((struct sockaddr_in6 *)
1484			    ifa->ifa_addr)->sin6_addr.s6_addr,
1485			    sizeof(struct in6_addr));
1486			memcpy(&n->mask.v6, &((struct sockaddr_in6 *)
1487			    ifa->ifa_netmask)->sin6_addr.s6_addr,
1488			    sizeof(struct in6_addr));
1489		}
1490		if ((n->name = strdup(ifa->ifa_name)) == NULL)
1491			err(1, "ifa_load: strdup");
1492		n->next = NULL;
1493		n->tail = n;
1494		if (h == NULL)
1495			h = n;
1496		else {
1497			h->tail->next = n;
1498			h->tail = n;
1499		}
1500	}
1501
1502	iftab = h;
1503	freeifaddrs(ifap);
1504}
1505
1506int
1507ifa_exists(const char *ifa_name)
1508{
1509	struct ipsec_addr_wrap	*n;
1510	struct ifgroupreq	 ifgr;
1511	int			 s;
1512
1513	if (iftab == NULL)
1514		ifa_load();
1515
1516	/* check wether this is a group */
1517	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1518		err(1, "ifa_exists: socket");
1519	bzero(&ifgr, sizeof(ifgr));
1520	strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1521	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) {
1522		close(s);
1523		return (1);
1524	}
1525	close(s);
1526
1527	for (n = iftab; n; n = n->next) {
1528		if (n->af == AF_LINK && !strncmp(n->name, ifa_name,
1529		    IFNAMSIZ))
1530			return (1);
1531	}
1532
1533	return (0);
1534}
1535
1536struct ipsec_addr_wrap *
1537ifa_grouplookup(const char *ifa_name)
1538{
1539	struct ifg_req		*ifg;
1540	struct ifgroupreq	 ifgr;
1541	int			 s;
1542	size_t			 len;
1543	struct ipsec_addr_wrap	*n, *h = NULL, *hn;
1544
1545	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1546		err(1, "socket");
1547	bzero(&ifgr, sizeof(ifgr));
1548	strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1549	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
1550		close(s);
1551		return (NULL);
1552	}
1553
1554	len = ifgr.ifgr_len;
1555	if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
1556		err(1, "calloc");
1557	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
1558		err(1, "ioctl");
1559
1560	for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req);
1561	    ifg++) {
1562		len -= sizeof(struct ifg_req);
1563		if ((n = ifa_lookup(ifg->ifgrq_member)) == NULL)
1564			continue;
1565		if (h == NULL)
1566			h = n;
1567		else {
1568			for (hn = h; hn->next != NULL; hn = hn->next)
1569				;	/* nothing */
1570			hn->next = n;
1571			n->tail = hn;
1572		}
1573	}
1574	free(ifgr.ifgr_groups);
1575	close(s);
1576
1577	return (h);
1578}
1579
1580struct ipsec_addr_wrap *
1581ifa_lookup(const char *ifa_name)
1582{
1583	struct ipsec_addr_wrap	*p = NULL, *h = NULL, *n = NULL;
1584
1585	if (iftab == NULL)
1586		ifa_load();
1587
1588	if ((n = ifa_grouplookup(ifa_name)) != NULL)
1589		return (n);
1590
1591	for (p = iftab; p; p = p->next) {
1592		if (p->af != AF_INET && p->af != AF_INET6)
1593			continue;
1594		if (strncmp(p->name, ifa_name, IFNAMSIZ))
1595			continue;
1596		n = calloc(1, sizeof(struct ipsec_addr_wrap));
1597		if (n == NULL)
1598			err(1, "ifa_lookup: calloc");
1599		memcpy(n, p, sizeof(struct ipsec_addr_wrap));
1600		if ((n->name = strdup(p->name)) == NULL)
1601			err(1, "ifa_lookup: strdup");
1602		switch(n->af) {
1603		case AF_INET:
1604			set_ipmask(n, 32);
1605			break;
1606		case AF_INET6:
1607			/* route/show.c and bgpd/util.c give KAME credit */
1608			if (IN6_IS_ADDR_LINKLOCAL(&n->address.v6) ||
1609			    IN6_IS_ADDR_MC_LINKLOCAL(&n->address.v6)) {
1610				u_int16_t tmp16;
1611				/* for now we can not handle link local,
1612				 * therefore bail for now
1613				 */
1614				free(n);
1615				continue;
1616
1617				memcpy(&tmp16, &n->address.v6.s6_addr[2],
1618				    sizeof(tmp16));
1619				/* use this when we support link-local
1620				 * n->??.scopeid = ntohs(tmp16);
1621				 */
1622				n->address.v6.s6_addr[2] = 0;
1623				n->address.v6.s6_addr[3] = 0;
1624			}
1625			set_ipmask(n, 128);
1626			break;
1627		}
1628
1629		n->next = NULL;
1630		n->tail = n;
1631		if (h == NULL)
1632			h = n;
1633		else {
1634			h->tail->next = n;
1635			h->tail = n;
1636		}
1637	}
1638
1639	return (h);
1640}
1641
1642void
1643set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b)
1644{
1645	struct ipsec_addr	*ipa;
1646	int			 i, j = 0;
1647
1648	ipa = &address->mask;
1649	bzero(ipa, sizeof(struct ipsec_addr));
1650
1651	while (b >= 32) {
1652		ipa->addr32[j++] = 0xffffffff;
1653		b -= 32;
1654	}
1655	for (i = 31; i > 31 - b; --i)
1656		ipa->addr32[j] |= (1 << i);
1657	if (b)
1658		ipa->addr32[j] = htonl(ipa->addr32[j]);
1659}
1660
1661const struct ipsec_xf *
1662parse_xf(const char *name, const struct ipsec_xf xfs[])
1663{
1664	int		i;
1665
1666	for (i = 0; xfs[i].name != NULL; i++) {
1667		if (strncmp(name, xfs[i].name, strlen(name)))
1668			continue;
1669		return &xfs[i];
1670	}
1671	return (NULL);
1672}
1673
1674struct ipsec_life *
1675parse_life(int value)
1676{
1677	struct ipsec_life	*life;
1678
1679	life = calloc(1, sizeof(struct ipsec_life));
1680	if (life == NULL)
1681		err(1, "calloc");
1682
1683	life->lifetime = value;
1684
1685	return (life);
1686}
1687
1688struct ipsec_transforms *
1689copytransforms(const struct ipsec_transforms *xfs)
1690{
1691	struct ipsec_transforms *newxfs;
1692
1693	if (xfs == NULL)
1694		return (NULL);
1695
1696	newxfs = calloc(1, sizeof(struct ipsec_transforms));
1697	if (newxfs == NULL)
1698		err(1, "copytransforms: calloc");
1699
1700	memcpy(newxfs, xfs, sizeof(struct ipsec_transforms));
1701	return (newxfs);
1702}
1703
1704struct ipsec_life *
1705copylife(const struct ipsec_life *life)
1706{
1707	struct ipsec_life *newlife;
1708
1709	if (life == NULL)
1710		return (NULL);
1711
1712	newlife = calloc(1, sizeof(struct ipsec_life));
1713	if (newlife == NULL)
1714		err(1, "copylife: calloc");
1715
1716	memcpy(newlife, life, sizeof(struct ipsec_life));
1717	return (newlife);
1718}
1719
1720struct ipsec_auth *
1721copyipsecauth(const struct ipsec_auth *auth)
1722{
1723	struct ipsec_auth	*newauth;
1724
1725	if (auth == NULL)
1726		return (NULL);
1727
1728	if ((newauth = calloc(1, sizeof(struct ipsec_auth))) == NULL)
1729		err(1, "calloc");
1730	if (auth->srcid &&
1731	    asprintf(&newauth->srcid, "%s", auth->srcid) == -1)
1732		err(1, "asprintf");
1733	if (auth->dstid &&
1734	    asprintf(&newauth->dstid, "%s", auth->dstid) == -1)
1735		err(1, "asprintf");
1736
1737	newauth->idtype = auth->idtype;
1738	newauth->type = auth->type;
1739
1740	return (newauth);
1741}
1742
1743struct ike_auth *
1744copyikeauth(const struct ike_auth *auth)
1745{
1746	struct ike_auth	*newauth;
1747
1748	if (auth == NULL)
1749		return (NULL);
1750
1751	if ((newauth = calloc(1, sizeof(struct ike_auth))) == NULL)
1752		err(1, "calloc");
1753	if (auth->string &&
1754	    asprintf(&newauth->string, "%s", auth->string) == -1)
1755		err(1, "asprintf");
1756
1757	newauth->type = auth->type;
1758
1759	return (newauth);
1760}
1761
1762struct ipsec_key *
1763copykey(struct ipsec_key *key)
1764{
1765	struct ipsec_key	*newkey;
1766
1767	if (key == NULL)
1768		return (NULL);
1769
1770	if ((newkey = calloc(1, sizeof(struct ipsec_key))) == NULL)
1771		err(1, "calloc");
1772	if ((newkey->data = calloc(key->len, sizeof(u_int8_t))) == NULL)
1773		err(1, "calloc");
1774	memcpy(newkey->data, key->data, key->len);
1775	newkey->len = key->len;
1776
1777	return (newkey);
1778}
1779
1780struct ipsec_addr_wrap *
1781copyhost(const struct ipsec_addr_wrap *src)
1782{
1783	struct ipsec_addr_wrap *dst;
1784
1785	if (src == NULL)
1786		return (NULL);
1787
1788	dst = calloc(1, sizeof(struct ipsec_addr_wrap));
1789	if (dst == NULL)
1790		err(1, "copyhost: calloc");
1791
1792	memcpy(dst, src, sizeof(struct ipsec_addr_wrap));
1793
1794	if ((dst->name = strdup(src->name)) == NULL)
1795		err(1, "copyhost: strdup");
1796
1797	return dst;
1798}
1799
1800struct ipsec_rule *
1801copyrule(struct ipsec_rule *rule)
1802{
1803	struct ipsec_rule	*r;
1804
1805	if ((r = calloc(1, sizeof(struct ipsec_rule))) == NULL)
1806		err(1, "calloc");
1807
1808	r->src = copyhost(rule->src);
1809	r->dst = copyhost(rule->dst);
1810	r->local = copyhost(rule->local);
1811	r->peer = copyhost(rule->peer);
1812	r->auth = copyipsecauth(rule->auth);
1813	r->ikeauth = copyikeauth(rule->ikeauth);
1814	r->xfs = copytransforms(rule->xfs);
1815	r->mmxfs = copytransforms(rule->mmxfs);
1816	r->qmxfs = copytransforms(rule->qmxfs);
1817	r->mmlife = copylife(rule->mmlife);
1818	r->qmlife = copylife(rule->qmlife);
1819	r->authkey = copykey(rule->authkey);
1820	r->enckey = copykey(rule->enckey);
1821
1822	r->type = rule->type;
1823	r->satype = rule->satype;
1824	r->proto = rule->proto;
1825	r->tmode = rule->tmode;
1826	r->direction = rule->direction;
1827	r->flowtype = rule->flowtype;
1828	r->sport = rule->sport;
1829	r->dport = rule->dport;
1830	r->ikemode = rule->ikemode;
1831	r->spi = rule->spi;
1832	r->nr = rule->nr;
1833
1834	return (r);
1835}
1836
1837int
1838validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs,
1839    struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode)
1840{
1841	/* Sanity checks */
1842	if (spi == 0) {
1843		yyerror("no SPI specified");
1844		return (0);
1845	}
1846	if (satype == IPSEC_AH) {
1847		if (!xfs) {
1848			yyerror("no transforms specified");
1849			return (0);
1850		}
1851		if (!xfs->authxf)
1852			xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
1853		if (xfs->encxf) {
1854			yyerror("ah does not provide encryption");
1855			return (0);
1856		}
1857		if (xfs->compxf) {
1858			yyerror("ah does not provide compression");
1859			return (0);
1860		}
1861	}
1862	if (satype == IPSEC_ESP) {
1863		if (!xfs) {
1864			yyerror("no transforms specified");
1865			return (0);
1866		}
1867		if (xfs->compxf) {
1868			yyerror("esp does not provide compression");
1869			return (0);
1870		}
1871		if (!xfs->authxf)
1872			xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
1873		if (!xfs->encxf)
1874			xfs->encxf = &encxfs[ENCXF_AESCTR];
1875	}
1876	if (satype == IPSEC_IPCOMP) {
1877		if (!xfs) {
1878			yyerror("no transform specified");
1879			return (0);
1880		}
1881		if (xfs->authxf || xfs->encxf) {
1882			yyerror("no encryption or authentication with ipcomp");
1883			return (0);
1884		}
1885		if (!xfs->compxf)
1886			xfs->compxf = &compxfs[COMPXF_DEFLATE];
1887	}
1888	if (satype == IPSEC_IPIP) {
1889		if (!xfs) {
1890			yyerror("no transform specified");
1891			return (0);
1892		}
1893		if (xfs->authxf || xfs->encxf || xfs->compxf) {
1894			yyerror("no encryption, authentication or compression"
1895			    " with ipip");
1896			return (0);
1897		}
1898	}
1899	if (satype == IPSEC_TCPMD5 && authkey == NULL && tmode !=
1900	    IPSEC_TRANSPORT) {
1901		yyerror("authentication key needed for tcpmd5");
1902		return (0);
1903	}
1904	if (xfs && xfs->authxf) {
1905		if (!authkey) {
1906			yyerror("no authentication key specified");
1907			return (0);
1908		}
1909		if (authkey->len != xfs->authxf->keymin) {
1910			yyerror("wrong authentication key length, needs to be "
1911			    "%d bits", xfs->authxf->keymin * 8);
1912			return (0);
1913		}
1914	}
1915	if (xfs && xfs->encxf) {
1916		if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) {
1917			yyerror("no encryption key specified");
1918			return (0);
1919		}
1920		if (enckey) {
1921			if (enckey->len < xfs->encxf->keymin) {
1922				yyerror("encryption key too short (%d bits), "
1923				    "minimum %d bits", enckey->len * 8,
1924				     xfs->encxf->keymin * 8);
1925				return (0);
1926			}
1927			if (xfs->encxf->keymax < enckey->len) {
1928				yyerror("encryption key too long (%d bits), "
1929				    "maximum %d bits", enckey->len * 8,
1930				     xfs->encxf->keymax * 8);
1931				return (0);
1932			}
1933		}
1934	}
1935
1936	return 1;
1937}
1938
1939int
1940add_sagroup(struct ipsec_rule *r)
1941{
1942	struct ipsec_rule	*rp, *last, *group;
1943	int			 found = 0;
1944
1945	TAILQ_FOREACH(rp, &ipsec->group_queue, group_entry) {
1946		if (strcmp(rp->dst->name, r->dst->name) == 0) {
1947			found = 1;
1948			break;
1949		}
1950	}
1951	if (found) {
1952		last = TAILQ_LAST(&rp->dst_group_queue, dst_group_queue);
1953		TAILQ_INSERT_TAIL(&rp->dst_group_queue, r, dst_group_entry);
1954
1955		group = create_sagroup(last->dst, last->satype, last->spi,
1956		    r->dst, r->satype, r->spi);
1957		if (group == NULL)
1958			return (1);
1959		group->nr = ipsec->rule_nr++;
1960		if (ipsecctl_add_rule(ipsec, group))
1961			return (1);
1962	} else {
1963		TAILQ_INSERT_TAIL(&ipsec->group_queue, r, group_entry);
1964		TAILQ_INIT(&r->dst_group_queue);
1965		TAILQ_INSERT_TAIL(&r->dst_group_queue, r, dst_group_entry);
1966	}
1967
1968	return (0);
1969}
1970
1971struct ipsec_rule *
1972create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_hosts *hosts,
1973    u_int32_t spi, struct ipsec_transforms *xfs, struct ipsec_key *authkey,
1974    struct ipsec_key *enckey)
1975{
1976	struct ipsec_rule *r;
1977
1978	if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0)
1979		return (NULL);
1980
1981	r = calloc(1, sizeof(struct ipsec_rule));
1982	if (r == NULL)
1983		err(1, "create_sa: calloc");
1984
1985	r->type |= RULE_SA;
1986	r->satype = satype;
1987	r->tmode = tmode;
1988	r->src = hosts->src;
1989	r->dst = hosts->dst;
1990	r->spi = spi;
1991	r->xfs = xfs;
1992	r->authkey = authkey;
1993	r->enckey = enckey;
1994
1995	return r;
1996}
1997
1998struct ipsec_rule *
1999reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey,
2000    struct ipsec_key *enckey)
2001{
2002	struct ipsec_rule *reverse;
2003
2004	if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey,
2005	    rule->tmode) == 0)
2006		return (NULL);
2007
2008	reverse = calloc(1, sizeof(struct ipsec_rule));
2009	if (reverse == NULL)
2010		err(1, "reverse_sa: calloc");
2011
2012	reverse->type |= RULE_SA;
2013	reverse->satype = rule->satype;
2014	reverse->tmode = rule->tmode;
2015	reverse->src = copyhost(rule->dst);
2016	reverse->dst = copyhost(rule->src);
2017	reverse->spi = spi;
2018	reverse->xfs = copytransforms(rule->xfs);
2019	reverse->authkey = authkey;
2020	reverse->enckey = enckey;
2021
2022	return (reverse);
2023}
2024
2025struct ipsec_rule *
2026create_sagroup(struct ipsec_addr_wrap *dst, u_int8_t proto, u_int32_t spi,
2027    struct ipsec_addr_wrap *dst2, u_int8_t proto2, u_int32_t spi2)
2028{
2029	struct ipsec_rule *r;
2030
2031	r = calloc(1, sizeof(struct ipsec_rule));
2032	if (r == NULL)
2033		err(1, "create_sagroup: calloc");
2034
2035	r->type |= RULE_GROUP;
2036
2037	r->dst = copyhost(dst);
2038	r->dst2 = copyhost(dst2);
2039	r->proto = proto;
2040	r->proto2 = proto2;
2041	r->spi = spi;
2042	r->spi2 = spi2;
2043	r->satype = proto;
2044
2045	return (r);
2046}
2047
2048struct ipsec_rule *
2049create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_hosts *hosts,
2050    struct ipsec_hosts *peers,
2051    u_int8_t satype, char *srcid, char *dstid, u_int8_t type)
2052{
2053	struct ipsec_rule *r;
2054
2055	r = calloc(1, sizeof(struct ipsec_rule));
2056	if (r == NULL)
2057		err(1, "create_flow: calloc");
2058
2059	r->type |= RULE_FLOW;
2060
2061	if (dir == IPSEC_INOUT)
2062		r->direction = IPSEC_OUT;
2063	else
2064		r->direction = dir;
2065
2066	r->satype = satype;
2067	r->proto = proto;
2068	r->src = hosts->src;
2069	r->sport = hosts->sport;
2070	r->dst = hosts->dst;
2071	r->dport = hosts->dport;
2072	if ((hosts->sport != 0 || hosts->dport != 0) &&
2073            (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) {
2074		yyerror("no protocol supplied with source/destination ports");
2075		goto errout;
2076	}
2077
2078	if (type == TYPE_DENY || type == TYPE_BYPASS) {
2079		r->flowtype = type;
2080		return (r);
2081	}
2082
2083	r->flowtype = type;
2084	r->local = peers->src;
2085	if (peers->dst == NULL) {
2086		/* Set peer to remote host.  Must be a host address. */
2087		if (r->direction == IPSEC_IN) {
2088			if (r->src->netaddress) {
2089				yyerror("no peer specified");
2090				goto errout;
2091			}
2092			r->peer = copyhost(r->src);
2093		} else {
2094			if (r->dst->netaddress) {
2095				yyerror("no peer specified");
2096				goto errout;
2097			}
2098			r->peer = copyhost(r->dst);
2099		}
2100	} else
2101		r->peer = peers->dst;
2102
2103	r->auth = calloc(1, sizeof(struct ipsec_auth));
2104	if (r->auth == NULL)
2105		err(1, "create_flow: calloc");
2106	r->auth->srcid = srcid;
2107	r->auth->dstid = dstid;
2108	r->auth->idtype = ID_FQDN;	/* XXX For now only FQDN. */
2109
2110	return r;
2111
2112errout:
2113	free(r);
2114	if (srcid)
2115		free(srcid);
2116	if (dstid)
2117		free(dstid);
2118	free(hosts->src);
2119	free(hosts->dst);
2120
2121	return NULL;
2122}
2123
2124int
2125expand_rule(struct ipsec_rule *rule, u_int8_t direction, u_int32_t spi,
2126    struct ipsec_key *authkey, struct ipsec_key *enckey, int group)
2127{
2128	struct ipsec_rule	*r, *revr;
2129	struct ipsec_addr_wrap	*src, *dst;
2130	int added = 0;
2131
2132	for (src = rule->src; src; src = src->next) {
2133		for (dst = rule->dst; dst; dst = dst->next) {
2134			if (src->af != dst->af)
2135				continue;
2136			r = copyrule(rule);
2137
2138			r->src = copyhost(src);
2139			r->dst = copyhost(dst);
2140
2141			r->nr = ipsec->rule_nr++;
2142			if (ipsecctl_add_rule(ipsec, r))
2143				return (1);
2144			if (group && add_sagroup(r))
2145				return (1);
2146
2147			if (direction == IPSEC_INOUT) {
2148				/* Create and add reverse flow rule. */
2149				revr = reverse_rule(r);
2150				if (revr == NULL)
2151					return (1);
2152
2153				revr->nr = ipsec->rule_nr++;
2154				if (ipsecctl_add_rule(ipsec, revr))
2155					return (1);
2156				if (group && add_sagroup(revr))
2157					return (1);
2158			} else if (spi != 0 || authkey || enckey) {
2159				/* Create and add reverse sa rule. */
2160				revr = reverse_sa(r, spi, authkey, enckey);
2161				if (revr == NULL)
2162					return (1);
2163
2164				revr->nr = ipsec->rule_nr++;
2165				if (ipsecctl_add_rule(ipsec, revr))
2166					return (1);
2167				if (group && add_sagroup(revr))
2168					return (1);
2169			}
2170			added++;
2171		}
2172	}
2173	if (!added)
2174		yyerror("rule expands to no valid combination");
2175	ipsecctl_free_rule(rule);
2176	return (0);
2177}
2178
2179struct ipsec_rule *
2180reverse_rule(struct ipsec_rule *rule)
2181{
2182	struct ipsec_rule *reverse;
2183
2184	reverse = calloc(1, sizeof(struct ipsec_rule));
2185	if (reverse == NULL)
2186		err(1, "reverse_rule: calloc");
2187
2188	reverse->type |= RULE_FLOW;
2189
2190	/* Reverse direction */
2191	if (rule->direction == (u_int8_t)IPSEC_OUT)
2192		reverse->direction = (u_int8_t)IPSEC_IN;
2193	else
2194		reverse->direction = (u_int8_t)IPSEC_OUT;
2195
2196	reverse->flowtype = rule->flowtype;
2197	reverse->src = copyhost(rule->dst);
2198	reverse->dst = copyhost(rule->src);
2199	reverse->sport = rule->dport;
2200	reverse->dport = rule->sport;
2201	if (rule->local)
2202		reverse->local = copyhost(rule->local);
2203	if (rule->peer)
2204		reverse->peer = copyhost(rule->peer);
2205	reverse->satype = rule->satype;
2206	reverse->proto = rule->proto;
2207
2208	if (rule->auth) {
2209		reverse->auth = calloc(1, sizeof(struct ipsec_auth));
2210		if (reverse->auth == NULL)
2211			err(1, "reverse_rule: calloc");
2212		if (rule->auth->dstid && (reverse->auth->dstid =
2213		    strdup(rule->auth->dstid)) == NULL)
2214			err(1, "reverse_rule: strdup");
2215		if (rule->auth->srcid && (reverse->auth->srcid =
2216		    strdup(rule->auth->srcid)) == NULL)
2217			err(1, "reverse_rule: strdup");
2218		reverse->auth->idtype = rule->auth->idtype;
2219		reverse->auth->type = rule->auth->type;
2220	}
2221
2222	return reverse;
2223}
2224
2225struct ipsec_rule *
2226create_ike(u_int8_t proto, struct ipsec_hosts *hosts, struct ipsec_hosts *peers,
2227    struct ike_mode *mainmode, struct ike_mode *quickmode,
2228    u_int8_t satype, u_int8_t mode, char *srcid, char *dstid,
2229    struct ike_auth *authtype)
2230{
2231	struct ipsec_rule *r;
2232
2233	r = calloc(1, sizeof(struct ipsec_rule));
2234	if (r == NULL)
2235		err(1, "create_ike: calloc");
2236
2237	r->type = RULE_IKE;
2238
2239	r->proto = proto;
2240	r->src = hosts->src;
2241	r->sport = hosts->sport;
2242	r->dst = hosts->dst;
2243	r->dport = hosts->dport;
2244	if ((hosts->sport != 0 || hosts->dport != 0) &&
2245            (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) {
2246		yyerror("no protocol supplied with source/destination ports");
2247		free(r);
2248		free(hosts->src);
2249		free(hosts->dst);
2250		if (mainmode) {
2251			free(mainmode->xfs);
2252			free(mainmode->life);
2253		}
2254		if (quickmode) {
2255			free(quickmode->xfs);
2256			free(quickmode->life);
2257		}
2258		if (srcid)
2259			free(srcid);
2260		if (dstid)
2261			free(dstid);
2262		return NULL;
2263	}
2264
2265	if (peers->dst == NULL) {
2266		/* Set peer to remote host.  Must be a host address. */
2267		if (r->direction == IPSEC_IN) {
2268			if (r->src->netaddress)
2269				r->peer = NULL;
2270			else
2271				r->peer = copyhost(r->src);
2272		} else {
2273			if (r->dst->netaddress)
2274				r->peer = NULL;
2275			else
2276				r->peer = copyhost(r->dst);
2277		}
2278	} else
2279		r->peer = peers->dst;
2280
2281	if (peers->src)
2282		r->local = peers->src;
2283
2284	r->satype = satype;
2285	r->ikemode = mode;
2286	if (mainmode) {
2287		r->mmxfs = mainmode->xfs;
2288		r->mmlife = mainmode->life;
2289	}
2290	if (quickmode) {
2291		r->qmxfs = quickmode->xfs;
2292		r->qmlife = quickmode->life;
2293	}
2294	r->auth = calloc(1, sizeof(struct ipsec_auth));
2295	if (r->auth == NULL)
2296		err(1, "create_ike: calloc");
2297	r->auth->srcid = srcid;
2298	r->auth->dstid = dstid;
2299	r->auth->idtype = ID_FQDN;	/* XXX For now only FQDN. */
2300	r->ikeauth = calloc(1, sizeof(struct ike_auth));
2301	if (r->ikeauth == NULL)
2302		err(1, "create_ike: calloc");
2303	r->ikeauth->type = authtype->type;
2304	r->ikeauth->string = authtype->string;
2305
2306	return (r);
2307}
2308