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