parse.y revision 55505
1/*
2 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/sbin/setkey/parse.y 55505 2000-01-06 12:40:54Z shin $
30 */
31/* KAME $Id: parse.y,v 1.7 1999/10/27 17:08:57 sakane Exp $ */
32
33%{
34#include <sys/types.h>
35#include <sys/param.h>
36#include <sys/socket.h>
37
38#include <net/route.h>
39#include <netinet/in.h>
40#include <net/pfkeyv2.h>
41#include <netkey/key_var.h>
42#include <netinet6/ipsec.h>
43#include <arpa/inet.h>
44
45#include <string.h>
46#include <unistd.h>
47#include <stdio.h>
48#include <ctype.h>
49#include <errno.h>
50#include <netdb.h>
51
52#include "vchar.h"
53
54#define ATOX(c) \
55  (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) ))
56
57u_int	p_type;
58u_int32_t	p_spi;
59struct	sockaddr *p_src, *p_dst;
60u_int	p_prefs, p_prefd, p_upper;
61u_int	p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
62u_int	p_key_enc_len, p_key_auth_len;
63caddr_t	p_key_enc, p_key_auth;
64time_t	p_lt_hard, p_lt_soft;
65
66u_int	p_policy_len;
67char	*p_policy;
68
69/* temporary buffer */
70static struct	sockaddr *pp_addr;
71static u_int	pp_prefix;
72static u_int	pp_port;
73static caddr_t	pp_key;
74
75extern u_char	m_buf[BUFSIZ];
76extern int	m_len;
77extern char	cmdarg[8192];
78extern int	f_debug;
79
80int	setkeymsg __P((void));
81static int	setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int));
82void	parse_init __P((void));
83void	free_buffer __P((void));
84
85extern int	setkeymsg __P((void));
86extern int	sendkeymsg __P((void));
87
88extern int	yylex __P((void));
89extern void	yyerror __P((char *));
90%}
91
92%union {
93	unsigned long num;
94	vchar_t val;
95}
96
97%token EOT
98%token ADD GET DELETE FLUSH DUMP
99%token IP4_ADDRESS IP6_ADDRESS PREFIX PORT PORTANY
100%token UP_PROTO PR_ESP PR_AH PR_IPCOMP
101%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
102%token F_MODE MODE
103%token F_EXT EXTENSION
104%token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
105%token F_LIFETIME_HARD F_LIFETIME_SOFT
106%token DECSTRING QUOTEDSTRING HEXSTRING ANY
107	/* SPD management */
108%token SPDADD SPDDELETE SPDDUMP SPDFLUSH
109%token F_POLICY PL_REQUESTS
110
111%%
112commands
113	:	/*NOTHING*/
114	|	commands command
115		{
116			if (f_debug) {
117				printf("cmdarg:\n%s\n", cmdarg);
118			} else {
119				setkeymsg();
120				sendkeymsg();
121			}
122			free_buffer();
123			parse_init();
124		}
125	;
126
127command
128	:	add_command
129	|	get_command
130	|	delete_command
131	|	flush_command
132	|	dump_command
133	|	spdadd_command
134	|	spddelete_command
135	|	spddump_command
136	|	spdflush_command
137	;
138	/* commands concerned with management, there is in tail of this file. */
139
140	/* add command */
141add_command
142	:	ADD { p_type = SADB_ADD; }
143		sa_selector_spec extension_spec algorithm_spec EOT
144	;
145
146	/* delete */
147delete_command
148	:	DELETE { p_type = SADB_DELETE; }
149		sa_selector_spec extension_spec EOT
150	;
151
152	/* get command */
153get_command
154	:	GET { p_type = SADB_GET; }
155		sa_selector_spec extension_spec EOT
156	;
157
158	/* flush */
159flush_command
160	:	FLUSH { p_type = SADB_FLUSH; }
161		protocol_spec EOT
162	;
163
164	/* dump */
165dump_command
166	:	DUMP { p_type = SADB_DUMP; }
167		protocol_spec EOT
168	;
169
170	/* sa_selector_spec */
171sa_selector_spec
172	:	ipaddress { p_src = pp_addr; }
173		ipaddress { p_dst = pp_addr; }
174		protocol_spec spi
175	;
176
177protocol_spec
178	:	/*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; }
179	|	PR_ESP
180		{
181			p_satype = SADB_SATYPE_ESP;
182			if ($1.num == 1)
183				p_ext |= SADB_X_EXT_OLD;
184			else
185				p_ext &= ~SADB_X_EXT_OLD;
186		}
187	|	PR_AH
188		{
189			p_satype = SADB_SATYPE_AH;
190			if ($1.num == 1)
191				p_ext |= SADB_X_EXT_OLD;
192			else
193				p_ext &= ~SADB_X_EXT_OLD;
194		}
195	|	PR_IPCOMP
196		{
197			p_satype = SADB_X_SATYPE_IPCOMP;
198		}
199	;
200
201spi
202	:	DECSTRING { p_spi = $1.num; }
203	|	HEXSTRING
204		{
205			caddr_t bp;
206			caddr_t yp = $1.val.buf;
207			char buf0[4], buf[4];
208			int i, j;
209
210			/* sanity check */
211			if ($1.val.len > 4) {
212				yyerror("SPI too big.");
213				free($1.val.buf);
214				return -1;
215			}
216
217			bp = buf0;
218			while (*yp) {
219				*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
220				yp += 2, bp++;
221			}
222
223			/* initialize */
224			for (i = 0; i < 4; i++) buf[i] = 0;
225
226			for (j = $1.val.len - 1, i = 3; j >= 0; j--, i--)
227				buf[i] = buf0[j];
228
229			/* XXX: endian */
230			p_spi = ntohl(*(u_int32_t *)buf);
231
232			free($1.val.buf);
233		}
234	;
235
236algorithm_spec
237	:	esp_spec
238	|	ah_spec
239	|	ipcomp_spec
240	;
241
242esp_spec
243	:	F_ENC enc_alg enc_key F_AUTH auth_alg auth_key
244	|	F_ENC enc_alg enc_key
245	;
246
247ah_spec
248	:	F_AUTH auth_alg auth_key
249	;
250
251ipcomp_spec
252	:	F_COMP ALG_COMP { p_alg_enc = $2.num; }
253	|	F_COMP ALG_COMP { p_alg_enc = $2.num; }
254		F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; }
255	;
256
257enc_alg
258	:	ALG_ENC { p_alg_enc = $1.num; }
259	|	ALG_ENC_DESDERIV
260		{
261			p_alg_enc = $1.num;
262			if (p_ext & SADB_X_EXT_OLD) {
263				yyerror("algorithm mismatched.");
264				return -1;
265			}
266			p_ext |= SADB_X_EXT_DERIV;
267		}
268	|	ALG_ENC_DES32IV
269		{
270			p_alg_enc = $1.num;
271			if (!(p_ext & SADB_X_EXT_OLD)) {
272				yyerror("algorithm mismatched.");
273				return -1;
274			}
275			p_ext |= SADB_X_EXT_IV4B;
276		}
277	;
278
279enc_key
280	:	/*NOTHING*/
281		{
282			if (p_alg_enc != SADB_EALG_NULL) {
283				yyerror("no key found.");
284				return -1;
285			}
286		}
287	|	key_string
288		{
289			p_key_enc_len = $1.val.len;
290			p_key_enc = pp_key;
291
292			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
293					p_alg_enc,
294					PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
295				yyerror(ipsec_strerror());
296				return -1;
297			}
298		}
299	;
300
301auth_alg
302	:	ALG_AUTH { p_alg_auth = $1.num; }
303	;
304
305auth_key
306	:	/*NOTHING*/
307		{
308			if (p_alg_auth != SADB_AALG_NULL) {
309				yyerror("no key found.");
310				return -1;
311			}
312		}
313	|	key_string
314		{
315			p_key_auth_len = $1.val.len;
316			p_key_auth = pp_key;
317
318			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
319					p_alg_auth,
320					PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
321				yyerror(ipsec_strerror());
322				return -1;
323			}
324		}
325	;
326
327key_string
328	:	QUOTEDSTRING
329		{
330			pp_key = $1.val.buf;
331			/* free pp_key later */
332		}
333	|	HEXSTRING
334		{
335			caddr_t bp;
336			caddr_t yp = $1.val.buf;
337
338			if ((pp_key = malloc($1.val.len)) == 0) {
339				free($1.val.buf);
340				yyerror(strerror(errno));
341				return -1;
342			}
343			memset(pp_key, 0, $1.val.len);
344
345			bp = pp_key;
346			while (*yp) {
347				*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
348				yp += 2, bp++;
349			}
350
351			free($1.val.buf);
352		}
353	;
354
355extension_spec
356	:	/*NOTHING*/
357	|	extension_spec extension
358	;
359
360extension
361	:	F_EXT EXTENSION { p_ext |= $1.num; }
362	|	F_MODE MODE { p_mode = $2.num; }
363	|	F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
364	|	F_REPLAY DECSTRING
365		{
366			if (p_ext & SADB_X_EXT_OLD) {
367				yyerror("replay prevention "
368				        "only use on new spec.");
369				return -1;
370			}
371			p_replay = $2.num;
372		}
373	|	F_LIFETIME_HARD DECSTRING { p_lt_hard = $2.num; }
374	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2.num; }
375	;
376
377	/* definition about command for SPD management */
378	/* spdadd */
379spdadd_command
380	:	SPDADD
381		{
382			p_type = SADB_X_SPDADD;
383			p_satype = SADB_SATYPE_UNSPEC;
384		}
385		sp_selector_spec policy_spec EOT
386	;
387
388spddelete_command:
389		SPDDELETE
390		{
391			p_type = SADB_X_SPDDELETE;
392			p_satype = SADB_SATYPE_UNSPEC;
393		}
394		sp_selector_spec EOT
395	;
396
397spddump_command:
398		SPDDUMP
399		{
400			p_type = SADB_X_SPDDUMP;
401			p_satype = SADB_SATYPE_UNSPEC;
402		}
403		EOT
404	;
405
406spdflush_command:
407		SPDFLUSH
408		{
409			p_type = SADB_X_SPDFLUSH;
410			p_satype = SADB_SATYPE_UNSPEC;
411		}
412		EOT
413	;
414
415	/* sp_selector_spec */
416sp_selector_spec
417	:	ipaddress { p_src = pp_addr; }
418		prefix { p_prefs = pp_prefix; }
419		port { _INPORTBYSA(p_src) = htons(pp_port); }
420		ipaddress { p_dst = pp_addr; }
421		prefix { p_prefd = pp_prefix; }
422		port { _INPORTBYSA(p_dst) = htons(pp_port); }
423		upper_spec
424	;
425
426ipaddress
427	:	IP4_ADDRESS
428		{
429			struct sockaddr_in *in;
430			u_int sa_len = $1.val.len;
431
432			if ((in = (struct sockaddr_in *)malloc(sa_len)) == 0) {
433				yyerror(strerror(errno));
434				free($1.val.buf);
435				return -1;
436			}
437			memset((caddr_t)in, 0, sa_len);
438
439			in->sin_family = PF_INET;
440			in->sin_len = sa_len;
441			in->sin_port = IPSEC_PORT_ANY;
442			(void)inet_pton(PF_INET, $1.val.buf, &in->sin_addr);
443
444			pp_addr = (struct sockaddr *)in;
445			free($1.val.buf);
446		}
447	|	IP6_ADDRESS
448		{
449#ifdef INET6
450			struct sockaddr_in6 *in6;
451			u_int sa_len = $1.val.len;
452			struct addrinfo hints, *res;
453			int ret_gai;
454
455			if ((in6 = (struct sockaddr_in6 *)malloc(sa_len)) == 0) {
456				free($1.val.buf);
457				yyerror(strerror(errno));
458				return -1;
459			}
460			memset((caddr_t)in6, 0, sa_len);
461
462			bzero(&hints, sizeof(struct addrinfo));
463			hints.ai_flags = AI_NUMERICHOST;
464			hints.ai_family = AF_INET6;
465			ret_gai = getaddrinfo($1.val.buf, NULL, &hints, &res);
466			if (ret_gai) {
467				free($1.val.buf);
468				free(in6);
469				yyerror(gai_strerror(ret_gai));
470				if (ret_gai == EAI_SYSTEM)
471					yyerror(strerror(errno));
472				return -1;
473			}
474			(void)memcpy(in6, res->ai_addr, res->ai_addrlen);
475
476			/*
477			 * XXX: If the scope of the destination is link-local,
478			 * embed the scope-id(in this case, interface index)
479			 * into the address.
480			 */
481			if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr) &&
482			    in6->sin6_scope_id != 0)
483				*(u_short *)&in6->sin6_addr.s6_addr[2] =
484					htons(in6->sin6_scope_id & 0xffff);
485
486			freeaddrinfo(res);
487
488			pp_addr = (struct sockaddr *)in6;
489#else
490			yyerror("IPv6 address not supported");
491#endif
492			free($1.val.buf);
493		}
494	;
495
496prefix
497	:	/*NOTHING*/ { pp_prefix = ~0; }
498	|	PREFIX { pp_prefix = $1.num; }
499	;
500
501port
502	:	/*NOTHING*/ { pp_port = IPSEC_PORT_ANY; }
503	|	PORT { pp_port = $1.num; }
504	|	PORTANY { pp_port = IPSEC_PORT_ANY; }
505	;
506
507upper_spec
508	:	DECSTRING { p_upper = $1.num; }
509	|	UP_PROTO { p_upper = $1.num; }
510	|	PR_ESP { p_upper = IPPROTO_ESP; };
511	|	PR_AH { p_upper = IPPROTO_AH; };
512	|	PR_IPCOMP { p_upper = IPPROTO_IPCOMP; };
513	|	ANY { p_upper = IPSEC_ULPROTO_ANY; }
514	;
515
516policy_spec
517	:	F_POLICY policy_requests
518		{
519			p_policy = ipsec_set_policy($2.val.buf, $2.val.len);
520			if (p_policy == NULL) {
521				free($2.val.buf);
522				p_policy = NULL;
523				yyerror(ipsec_strerror());
524				return -1;
525			}
526
527			p_policy_len = ipsec_get_policylen(p_policy);
528
529			free($2.val.buf);
530		}
531	;
532
533policy_requests:
534		/*NOTHING*/
535	|	PL_REQUESTS { $$ = $1; }
536	;
537
538%%
539
540int
541setkeymsg()
542{
543	struct sadb_msg m_msg;
544
545	m_msg.sadb_msg_version = PF_KEY_V2;
546	m_msg.sadb_msg_type = p_type;
547	m_msg.sadb_msg_errno = 0;
548	m_msg.sadb_msg_satype = p_satype;
549	m_msg.sadb_msg_mode = p_mode;
550	m_msg.sadb_msg_reserved = 0;
551	m_msg.sadb_msg_seq = 0;
552	m_msg.sadb_msg_pid = getpid();
553
554	m_len = sizeof(struct sadb_msg);
555	memcpy(m_buf, &m_msg, m_len);
556
557	switch (p_type) {
558	case SADB_FLUSH:
559	case SADB_DUMP:
560		break;
561
562	case SADB_ADD:
563		/* set encryption algorithm, if present. */
564		if (p_satype != SADB_X_SATYPE_IPCOMP && p_alg_enc != SADB_EALG_NONE) {
565			struct sadb_key m_key;
566
567			m_key.sadb_key_len =
568				PFKEY_UNIT64(sizeof(m_key)
569				           + PFKEY_ALIGN8(p_key_enc_len));
570			m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
571			m_key.sadb_key_bits = p_key_enc_len * 8;
572			m_key.sadb_key_reserved = 0;
573
574			setvarbuf(&m_len,
575				(struct sadb_ext *)&m_key, sizeof(m_key),
576				(caddr_t)p_key_enc, p_key_enc_len);
577		}
578
579		/* set authentication algorithm, if present. */
580		if (p_alg_auth != SADB_AALG_NONE) {
581			struct sadb_key m_key;
582
583			m_key.sadb_key_len =
584				PFKEY_UNIT64(sizeof(m_key)
585				           + PFKEY_ALIGN8(p_key_auth_len));
586			m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
587			m_key.sadb_key_bits = p_key_auth_len * 8;
588			m_key.sadb_key_reserved = 0;
589
590			setvarbuf(&m_len,
591				(struct sadb_ext *)&m_key, sizeof(m_key),
592				(caddr_t)p_key_auth, p_key_auth_len);
593		}
594
595		/* set lifetime for HARD */
596		if (p_lt_hard != 0) {
597			struct sadb_lifetime m_lt;
598			u_int len = sizeof(struct sadb_lifetime);
599
600			m_lt.sadb_lifetime_len = PFKEY_UNIT64(len);
601			m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
602			m_lt.sadb_lifetime_allocations = 0;
603			m_lt.sadb_lifetime_bytes = 0;
604			m_lt.sadb_lifetime_addtime = p_lt_hard;
605			m_lt.sadb_lifetime_usetime = 0;
606
607			memcpy(m_buf + m_len, &m_lt, len);
608			m_len += len;
609		}
610
611		/* set lifetime for SOFT */
612		if (p_lt_soft != 0) {
613			struct sadb_lifetime m_lt;
614			u_int len = sizeof(struct sadb_lifetime);
615
616			m_lt.sadb_lifetime_len = PFKEY_UNIT64(len);
617			m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
618			m_lt.sadb_lifetime_allocations = 0;
619			m_lt.sadb_lifetime_bytes = 0;
620			m_lt.sadb_lifetime_addtime = p_lt_soft;
621			m_lt.sadb_lifetime_usetime = 0;
622
623			memcpy(m_buf + m_len, &m_lt, len);
624			m_len += len;
625		}
626		/* FALLTHROUGH */
627
628	case SADB_DELETE:
629	case SADB_GET:
630	    {
631		struct sadb_sa m_sa;
632		struct sadb_address m_addr;
633		u_int len;
634
635		len = sizeof(struct sadb_sa);
636		m_sa.sadb_sa_len = PFKEY_UNIT64(len);
637		m_sa.sadb_sa_exttype = SADB_EXT_SA;
638		m_sa.sadb_sa_spi = htonl(p_spi);
639		m_sa.sadb_sa_replay = p_replay;
640		m_sa.sadb_sa_state = 0;
641		m_sa.sadb_sa_auth = p_alg_auth;
642		m_sa.sadb_sa_encrypt = p_alg_enc;
643		m_sa.sadb_sa_flags = p_ext;
644
645		memcpy(m_buf + m_len, &m_sa, len);
646		m_len += len;
647
648		/* set src */
649		m_addr.sadb_address_len =
650			PFKEY_UNIT64(sizeof(m_addr)
651			           + PFKEY_ALIGN8(p_src->sa_len));
652		m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
653		m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
654		m_addr.sadb_address_prefixlen =
655			_INALENBYAF(p_src->sa_family) << 3;
656		m_addr.sadb_address_reserved = 0;
657
658		setvarbuf(&m_len,
659			(struct sadb_ext *)&m_addr, sizeof(m_addr),
660			(caddr_t)p_src, p_src->sa_len);
661
662		/* set dst */
663		m_addr.sadb_address_len =
664			PFKEY_UNIT64(sizeof(m_addr)
665			           + PFKEY_ALIGN8(p_dst->sa_len));
666		m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
667		m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
668		m_addr.sadb_address_prefixlen =
669			_INALENBYAF(p_dst->sa_family) << 3;
670		m_addr.sadb_address_reserved = 0;
671
672		setvarbuf(&m_len,
673			(struct sadb_ext *)&m_addr, sizeof(m_addr),
674			(caddr_t)p_dst, p_dst->sa_len);
675	    }
676		break;
677
678	/* for SPD management */
679	case SADB_X_SPDFLUSH:
680	case SADB_X_SPDDUMP:
681		break;
682
683	case SADB_X_SPDADD:
684	    {
685		memcpy(m_buf + m_len, p_policy, p_policy_len);
686		m_len += p_policy_len;
687		free(p_policy);
688		p_policy = NULL;
689	    }
690		/* FALLTHROUGH */
691
692	case SADB_X_SPDDELETE:
693	    {
694		struct sadb_address m_addr;
695
696		/* set src */
697		m_addr.sadb_address_len =
698			PFKEY_UNIT64(sizeof(m_addr)
699			           + PFKEY_ALIGN8(p_src->sa_len));
700		m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
701		m_addr.sadb_address_proto = p_upper;
702		m_addr.sadb_address_prefixlen =
703		    (p_prefs != ~0 ? p_prefs :
704		                     _INALENBYAF(p_src->sa_family) << 3);
705		m_addr.sadb_address_reserved = 0;
706
707		setvarbuf(&m_len,
708			(struct sadb_ext *)&m_addr, sizeof(m_addr),
709			(caddr_t)p_src, p_src->sa_len);
710
711		/* set dst */
712		m_addr.sadb_address_len =
713			PFKEY_UNIT64(sizeof(m_addr)
714			           + PFKEY_ALIGN8(p_dst->sa_len));
715		m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
716		m_addr.sadb_address_proto = p_upper;
717		m_addr.sadb_address_prefixlen =
718		    (p_prefd != ~0 ? p_prefd :
719		                     _INALENBYAF(p_dst->sa_family) << 3);
720		m_addr.sadb_address_reserved = 0;
721
722		setvarbuf(&m_len,
723			(struct sadb_ext *)&m_addr, sizeof(m_addr),
724			(caddr_t)p_dst, p_dst->sa_len);
725	    }
726		break;
727	}
728
729	((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len);
730
731	return 0;
732}
733
734static int
735setvarbuf(off, ebuf, elen, vbuf, vlen)
736	caddr_t vbuf;
737	struct sadb_ext *ebuf;
738	int *off, elen, vlen;
739{
740	memset(m_buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
741	memcpy(m_buf + *off, (caddr_t)ebuf, elen);
742	memcpy(m_buf + *off + elen, vbuf, vlen);
743	(*off) += PFKEY_ALIGN8(elen + vlen);
744
745	return 0;
746}
747
748void
749parse_init()
750{
751	p_type = 0;
752	p_spi = 0;
753
754	p_src = 0, p_dst = 0;
755	pp_prefix = p_prefs = p_prefd = ~0;
756	pp_port = IPSEC_PORT_ANY;
757	p_upper = 0;
758
759	p_satype = 0;
760	p_ext = SADB_X_EXT_NONE;
761	p_alg_enc = SADB_EALG_NONE;
762	p_alg_auth = SADB_AALG_NONE;
763	p_mode = IPSEC_MODE_ANY;
764	p_replay = 4;
765	p_key_enc_len = p_key_auth_len = 0;
766	p_key_enc = p_key_auth = 0;
767	p_lt_hard = p_lt_soft = 0;
768
769	p_policy_len = 0;
770	p_policy = NULL;
771
772	memset(cmdarg, 0, sizeof(cmdarg));
773
774	return;
775}
776
777void
778free_buffer()
779{
780	if (p_src) free(p_src);
781	if (p_dst) free(p_dst);
782	if (p_key_enc) free(p_key_enc);
783	if (p_key_auth) free(p_key_auth);
784
785	return;
786}
787
788