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