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