Make the code we're running under total signal mask as short as possible.
[dragonfly.git] / usr.sbin / setkey / parse.y
blob77c5ad6a07781f7cc2709705c2ac2a8218b47956
1 /* $FreeBSD: src/usr.sbin/setkey/parse.y,v 1.1.2.2 2001/07/03 11:02:17 ume Exp $ */
2 /* $DragonFly: src/usr.sbin/setkey/parse.y,v 1.4 2004/03/24 18:23:46 cpressey Exp $ */
3 /* $KAME: kame/kame/kame/setkey/parse.y,v 1.36 2001/06/07 15:53:12 sakane Exp $ */
5 /*
6 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * All rights reserved.
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.
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.
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/socket.h>
39 #include <net/route.h>
40 #include <netinet/in.h>
41 #include <net/pfkeyv2.h>
42 #include <netkey/key_var.h>
43 #include <netinet6/ipsec.h>
44 #include <arpa/inet.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <stdio.h>
49 #include <netdb.h>
50 #include <ctype.h>
51 #include <errno.h>
53 #include "libpfkey.h"
54 #include "vchar.h"
56 #define ATOX(c) \
57 (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) ))
59 u_int p_type;
60 u_int32_t p_spi;
61 int p_no_spi;
62 struct sockaddr *p_src, *p_dst;
63 u_int p_prefs, p_prefd, p_upper;
64 u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
65 u_int32_t p_reqid;
66 u_int p_key_enc_len, p_key_auth_len;
67 caddr_t p_key_enc, p_key_auth;
68 time_t p_lt_hard, p_lt_soft;
70 u_int p_policy_len;
71 char *p_policy;
73 /* temporary buffer */
74 static struct sockaddr *pp_addr;
75 static u_int pp_prefix;
76 static u_int pp_port;
77 static caddr_t pp_key;
79 extern u_char m_buf[BUFSIZ];
80 extern int m_len;
81 extern char cmdarg[8192];
82 extern int f_debug;
84 static struct addrinfo *parse_addr(char *, char *, int);
85 static int setvarbuf(int *, struct sadb_ext *, int, caddr_t, int);
86 void parse_init(void);
87 void free_buffer(void);
89 extern int setkeymsg(void);
90 extern int sendkeymsg(void);
92 extern int yylex(void);
93 extern void yyfatal(const char *);
94 extern void yyerror(const char *);
97 %union {
98 unsigned long num;
99 vchar_t val;
102 %token EOT
103 %token ADD GET DELETE FLUSH DUMP
104 %token ADDRESS PREFIX PORT PORTANY
105 %token UP_PROTO PR_ESP PR_AH PR_IPCOMP
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_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
110 %token F_LIFETIME_HARD F_LIFETIME_SOFT
111 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
112 /* SPD management */
113 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
114 %token F_POLICY PL_REQUESTS
116 %type <num> PORT PREFIX EXTENSION MODE
117 %type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP
118 %type <num> ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
119 %type <num> DECSTRING
120 %type <val> ADDRESS PL_REQUESTS
121 %type <val> key_string policy_requests
122 %type <val> QUOTEDSTRING HEXSTRING STRING
125 commands
126 : /*NOTHING*/
127 | commands command
129 if (f_debug) {
130 printf("cmdarg:\n%s\n", cmdarg);
131 } else {
132 setkeymsg();
133 sendkeymsg();
135 free_buffer();
136 parse_init();
140 command
141 : add_command
142 | get_command
143 | delete_command
144 | deleteall_command
145 | flush_command
146 | dump_command
147 | spdadd_command
148 | spddelete_command
149 | spddump_command
150 | spdflush_command
152 /* commands concerned with management, there is in tail of this file. */
154 /* add command */
155 add_command
156 : ADD { p_type = SADB_ADD; }
157 sa_selector_spec extension_spec algorithm_spec EOT
160 /* delete */
161 delete_command
162 : DELETE { p_type = SADB_DELETE; }
163 sa_selector_spec extension_spec
165 if (p_mode != IPSEC_MODE_ANY)
166 yyerror("WARNING: mode is obsoleted.");
171 /* deleteall command */
172 deleteall_command
173 : DELETEALL { p_type = SADB_DELETE; }
174 ipaddress { p_src = pp_addr; }
175 ipaddress { p_dst = pp_addr; }
176 protocol_spec
177 { p_no_spi = 1; }
181 /* get command */
182 get_command
183 : GET { p_type = SADB_GET; }
184 sa_selector_spec extension_spec
186 if (p_mode != IPSEC_MODE_ANY)
187 yyerror("WARNING: mode is obsoleted.");
192 /* flush */
193 flush_command
194 : FLUSH { p_type = SADB_FLUSH; }
195 protocol_spec EOT
198 /* dump */
199 dump_command
200 : DUMP { p_type = SADB_DUMP; }
201 protocol_spec EOT
204 /* sa_selector_spec */
205 sa_selector_spec
206 : ipaddress { p_src = pp_addr; }
207 ipaddress { p_dst = pp_addr; }
208 protocol_spec spi
211 protocol_spec
212 : /*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; }
213 | PR_ESP
215 p_satype = SADB_SATYPE_ESP;
216 if ($1 == 1)
217 p_ext |= SADB_X_EXT_OLD;
218 else
219 p_ext &= ~SADB_X_EXT_OLD;
221 | PR_AH
223 p_satype = SADB_SATYPE_AH;
224 if ($1 == 1)
225 p_ext |= SADB_X_EXT_OLD;
226 else
227 p_ext &= ~SADB_X_EXT_OLD;
229 | PR_IPCOMP
231 p_satype = SADB_X_SATYPE_IPCOMP;
236 : DECSTRING { p_spi = $1; }
237 | HEXSTRING
239 caddr_t bp;
240 caddr_t yp = $1.buf;
241 char buf0[4], buf[4];
242 int i, j;
244 /* sanity check */
245 if ($1.len > 4) {
246 yyerror("SPI too big.");
247 free($1.buf);
248 return -1;
251 bp = buf0;
252 while (*yp) {
253 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
254 yp += 2, bp++;
257 /* initialize */
258 for (i = 0; i < 4; i++) buf[i] = 0;
260 for (j = $1.len - 1, i = 3; j >= 0; j--, i--)
261 buf[i] = buf0[j];
263 /* XXX: endian */
264 p_spi = ntohl(*(u_int32_t *)buf);
266 free($1.buf);
270 algorithm_spec
271 : esp_spec
272 | ah_spec
273 | ipcomp_spec
276 esp_spec
277 : F_ENC enc_alg enc_key F_AUTH auth_alg auth_key
278 | F_ENC enc_alg enc_key
281 ah_spec
282 : F_AUTH auth_alg auth_key
285 ipcomp_spec
286 : F_COMP ALG_COMP { p_alg_enc = $2; }
287 | F_COMP ALG_COMP { p_alg_enc = $2; }
288 F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; }
291 enc_alg
292 : ALG_ENC { p_alg_enc = $1; }
293 | ALG_ENC_DESDERIV
295 p_alg_enc = $1;
296 if (p_ext & SADB_X_EXT_OLD) {
297 yyerror("algorithm mismatched.");
298 return -1;
300 p_ext |= SADB_X_EXT_DERIV;
302 | ALG_ENC_DES32IV
304 p_alg_enc = $1;
305 if (!(p_ext & SADB_X_EXT_OLD)) {
306 yyerror("algorithm mismatched.");
307 return -1;
309 p_ext |= SADB_X_EXT_IV4B;
313 enc_key
314 : /*NOTHING*/
316 if (p_alg_enc != SADB_EALG_NULL) {
317 yyerror("no key found.");
318 return -1;
321 | key_string
323 p_key_enc_len = $1.len;
324 p_key_enc = pp_key;
326 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
327 p_alg_enc,
328 PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
329 yyerror(ipsec_strerror());
330 return -1;
335 auth_alg
336 : ALG_AUTH { p_alg_auth = $1; }
339 auth_key
340 : /*NOTHING*/
342 if (p_alg_auth != SADB_X_AALG_NULL) {
343 yyerror("no key found.");
344 return -1;
347 | key_string
349 p_key_auth_len = $1.len;
350 p_key_auth = pp_key;
352 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
353 p_alg_auth,
354 PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
355 yyerror(ipsec_strerror());
356 return -1;
361 key_string
362 : QUOTEDSTRING
364 pp_key = $1.buf;
365 /* free pp_key later */
367 | HEXSTRING
369 caddr_t bp;
370 caddr_t yp = $1.buf;
372 if ((pp_key = malloc($1.len)) == 0) {
373 free($1.buf);
374 yyerror("not enough core");
375 return -1;
377 memset(pp_key, 0, $1.len);
379 bp = pp_key;
380 while (*yp) {
381 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
382 yp += 2, bp++;
385 free($1.buf);
389 extension_spec
390 : /*NOTHING*/
391 | extension_spec extension
394 extension
395 : F_EXT EXTENSION { p_ext |= $2; }
396 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
397 | F_MODE MODE { p_mode = $2; }
398 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
399 | F_REQID DECSTRING { p_reqid = $2; }
400 | F_REPLAY DECSTRING
402 if (p_ext & SADB_X_EXT_OLD) {
403 yyerror("replay prevention "
404 "only use on new spec.");
405 return -1;
407 p_replay = $2;
409 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
410 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
413 /* definition about command for SPD management */
414 /* spdadd */
415 spdadd_command
416 : SPDADD
418 p_type = SADB_X_SPDADD;
419 p_satype = SADB_SATYPE_UNSPEC;
421 sp_selector_spec policy_spec EOT
424 spddelete_command:
425 SPDDELETE
427 p_type = SADB_X_SPDDELETE;
428 p_satype = SADB_SATYPE_UNSPEC;
430 sp_selector_spec policy_spec EOT
433 spddump_command:
434 SPDDUMP
436 p_type = SADB_X_SPDDUMP;
437 p_satype = SADB_SATYPE_UNSPEC;
442 spdflush_command:
443 SPDFLUSH
445 p_type = SADB_X_SPDFLUSH;
446 p_satype = SADB_SATYPE_UNSPEC;
451 /* sp_selector_spec */
452 sp_selector_spec
453 : ipaddress { p_src = pp_addr; }
454 prefix { p_prefs = pp_prefix; }
455 port
457 switch (p_src->sa_family) {
458 case AF_INET:
459 ((struct sockaddr_in *)p_src)->sin_port =
460 htons(pp_port);
461 break;
462 #ifdef INET6
463 case AF_INET6:
464 ((struct sockaddr_in6 *)p_src)->sin6_port =
465 htons(pp_port);
466 break;
467 #endif
468 default:
469 exit(1); /*XXX*/
472 ipaddress { p_dst = pp_addr; }
473 prefix { p_prefd = pp_prefix; }
474 port
476 switch (p_dst->sa_family) {
477 case AF_INET:
478 ((struct sockaddr_in *)p_dst)->sin_port =
479 htons(pp_port);
480 break;
481 #ifdef INET6
482 case AF_INET6:
483 ((struct sockaddr_in6 *)p_dst)->sin6_port =
484 htons(pp_port);
485 break;
486 #endif
487 default:
488 exit(1); /*XXX*/
491 upper_spec
493 /* XXX is it something userland should check? */
494 #if 0
495 switch (p_upper) {
496 case IPPROTO_ICMP:
497 case IPPROTO_ICMPV6:
498 if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY
499 || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) {
500 yyerror("port number must be \"any\".");
501 return -1;
503 if ((pp_addr->sa_family == AF_INET6
504 && p_upper == IPPROTO_ICMP)
505 || (pp_addr->sa_family == AF_INET
506 && p_upper == IPPROTO_ICMPV6)) {
507 yyerror("upper layer protocol "
508 "mismatched.\n");
509 return -1;
511 break;
512 default:
513 break;
515 #endif
519 ipaddress
520 : ADDRESS
522 struct addrinfo *res;
524 res = parse_addr($1.buf, NULL, AI_NUMERICHOST);
525 if (res == NULL) {
526 free($1.buf);
527 return -1;
529 pp_addr = (struct sockaddr *)malloc(res->ai_addrlen);
530 if (!pp_addr) {
531 yyerror("not enough core");
532 goto end;
535 memcpy(pp_addr, res->ai_addr, res->ai_addrlen);
536 end:
537 freeaddrinfo(res);
538 free($1.buf);
542 prefix
543 : /*NOTHING*/ { pp_prefix = ~0; }
544 | PREFIX { pp_prefix = $1; }
547 port
548 : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; }
549 | PORT { pp_port = $1; }
550 | PORTANY { pp_port = IPSEC_PORT_ANY; }
553 upper_spec
554 : DECSTRING { p_upper = $1; }
555 | UP_PROTO { p_upper = $1; }
556 | ANY { p_upper = IPSEC_ULPROTO_ANY; }
557 | STRING
559 struct protoent *ent;
561 ent = getprotobyname($1.buf);
562 if (ent)
563 p_upper = ent->p_proto;
564 else {
565 if (strcmp("icmp6", $1.buf) == 0) {
566 p_upper = IPPROTO_ICMPV6;
567 } else if(strcmp("ip4", $1.buf) == 0) {
568 p_upper = IPPROTO_IPV4;
569 } else {
570 yyerror("invalid upper layer protocol");
571 free($1.buf);
572 return -1;
575 free($1.buf);
579 policy_spec
580 : F_POLICY policy_requests
582 p_policy = ipsec_set_policy($2.buf, $2.len);
583 if (p_policy == NULL) {
584 free($2.buf);
585 p_policy = NULL;
586 yyerror(ipsec_strerror());
587 return -1;
590 p_policy_len = ipsec_get_policylen(p_policy);
592 free($2.buf);
596 policy_requests
597 : PL_REQUESTS { $$ = $1; }
603 setkeymsg(void)
605 struct sadb_msg m_msg;
607 m_msg.sadb_msg_version = PF_KEY_V2;
608 m_msg.sadb_msg_type = p_type;
609 m_msg.sadb_msg_errno = 0;
610 m_msg.sadb_msg_satype = p_satype;
611 m_msg.sadb_msg_reserved = 0;
612 m_msg.sadb_msg_seq = 0;
613 m_msg.sadb_msg_pid = getpid();
615 m_len = sizeof(struct sadb_msg);
616 memcpy(m_buf, &m_msg, m_len);
618 switch (p_type) {
619 case SADB_FLUSH:
620 case SADB_DUMP:
621 break;
623 case SADB_ADD:
624 /* set encryption algorithm, if present. */
625 if (p_satype != SADB_X_SATYPE_IPCOMP && p_alg_enc != SADB_EALG_NONE) {
626 struct sadb_key m_key;
628 m_key.sadb_key_len =
629 PFKEY_UNIT64(sizeof(m_key)
630 + PFKEY_ALIGN8(p_key_enc_len));
631 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
632 m_key.sadb_key_bits = p_key_enc_len * 8;
633 m_key.sadb_key_reserved = 0;
635 setvarbuf(&m_len,
636 (struct sadb_ext *)&m_key, sizeof(m_key),
637 (caddr_t)p_key_enc, p_key_enc_len);
640 /* set authentication algorithm, if present. */
641 if (p_alg_auth != SADB_AALG_NONE) {
642 struct sadb_key m_key;
644 m_key.sadb_key_len =
645 PFKEY_UNIT64(sizeof(m_key)
646 + PFKEY_ALIGN8(p_key_auth_len));
647 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
648 m_key.sadb_key_bits = p_key_auth_len * 8;
649 m_key.sadb_key_reserved = 0;
651 setvarbuf(&m_len,
652 (struct sadb_ext *)&m_key, sizeof(m_key),
653 (caddr_t)p_key_auth, p_key_auth_len);
656 /* set lifetime for HARD */
657 if (p_lt_hard != 0) {
658 struct sadb_lifetime m_lt;
659 u_int len = sizeof(struct sadb_lifetime);
661 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len);
662 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
663 m_lt.sadb_lifetime_allocations = 0;
664 m_lt.sadb_lifetime_bytes = 0;
665 m_lt.sadb_lifetime_addtime = p_lt_hard;
666 m_lt.sadb_lifetime_usetime = 0;
668 memcpy(m_buf + m_len, &m_lt, len);
669 m_len += len;
672 /* set lifetime for SOFT */
673 if (p_lt_soft != 0) {
674 struct sadb_lifetime m_lt;
675 u_int len = sizeof(struct sadb_lifetime);
677 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len);
678 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
679 m_lt.sadb_lifetime_allocations = 0;
680 m_lt.sadb_lifetime_bytes = 0;
681 m_lt.sadb_lifetime_addtime = p_lt_soft;
682 m_lt.sadb_lifetime_usetime = 0;
684 memcpy(m_buf + m_len, &m_lt, len);
685 m_len += len;
687 /* FALLTHROUGH */
689 case SADB_DELETE:
690 case SADB_GET:
692 struct sadb_sa m_sa;
693 struct sadb_x_sa2 m_sa2;
694 struct sadb_address m_addr;
695 u_int len;
697 if (p_no_spi == 0) {
698 len = sizeof(struct sadb_sa);
699 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
700 m_sa.sadb_sa_exttype = SADB_EXT_SA;
701 m_sa.sadb_sa_spi = htonl(p_spi);
702 m_sa.sadb_sa_replay = p_replay;
703 m_sa.sadb_sa_state = 0;
704 m_sa.sadb_sa_auth = p_alg_auth;
705 m_sa.sadb_sa_encrypt = p_alg_enc;
706 m_sa.sadb_sa_flags = p_ext;
708 memcpy(m_buf + m_len, &m_sa, len);
709 m_len += len;
711 len = sizeof(struct sadb_x_sa2);
712 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
713 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
714 m_sa2.sadb_x_sa2_mode = p_mode;
715 m_sa2.sadb_x_sa2_reqid = p_reqid;
717 memcpy(m_buf + m_len, &m_sa2, len);
718 m_len += len;
721 /* set src */
722 m_addr.sadb_address_len =
723 PFKEY_UNIT64(sizeof(m_addr)
724 + PFKEY_ALIGN8(p_src->sa_len));
725 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
726 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
727 switch (p_src->sa_family) {
728 case AF_INET:
729 m_addr.sadb_address_prefixlen =
730 sizeof(struct in_addr) << 3;
731 break;
732 #ifdef INET6
733 case AF_INET6:
734 m_addr.sadb_address_prefixlen =
735 sizeof(struct in6_addr) << 3;
736 break;
737 #endif
738 default:
739 yyerror("unsupported address family");
740 exit(1); /*XXX*/
742 m_addr.sadb_address_reserved = 0;
744 setvarbuf(&m_len,
745 (struct sadb_ext *)&m_addr, sizeof(m_addr),
746 (caddr_t)p_src, p_src->sa_len);
748 /* set dst */
749 m_addr.sadb_address_len =
750 PFKEY_UNIT64(sizeof(m_addr)
751 + PFKEY_ALIGN8(p_dst->sa_len));
752 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
753 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
754 switch (p_dst->sa_family) {
755 case AF_INET:
756 m_addr.sadb_address_prefixlen =
757 sizeof(struct in_addr) << 3;
758 break;
759 #ifdef INET6
760 case AF_INET6:
761 m_addr.sadb_address_prefixlen =
762 sizeof(struct in6_addr) << 3;
763 break;
764 #endif
765 default:
766 yyerror("unsupported address family");
767 exit(1); /*XXX*/
769 m_addr.sadb_address_reserved = 0;
771 setvarbuf(&m_len,
772 (struct sadb_ext *)&m_addr, sizeof(m_addr),
773 (caddr_t)p_dst, p_dst->sa_len);
775 break;
777 /* for SPD management */
778 case SADB_X_SPDFLUSH:
779 case SADB_X_SPDDUMP:
780 break;
782 case SADB_X_SPDADD:
783 case SADB_X_SPDDELETE:
785 struct sadb_address m_addr;
786 u_int8_t plen;
788 memcpy(m_buf + m_len, p_policy, p_policy_len);
789 m_len += p_policy_len;
790 free(p_policy);
791 p_policy = NULL;
793 /* set src */
794 m_addr.sadb_address_len =
795 PFKEY_UNIT64(sizeof(m_addr)
796 + PFKEY_ALIGN8(p_src->sa_len));
797 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
798 m_addr.sadb_address_proto = p_upper;
799 switch (p_src->sa_family) {
800 case AF_INET:
801 plen = sizeof(struct in_addr) << 3;
802 break;
803 #ifdef INET6
804 case AF_INET6:
805 plen = sizeof(struct in6_addr) << 3;
806 break;
807 #endif
808 default:
809 yyerror("unsupported address family");
810 exit(1); /*XXX*/
812 m_addr.sadb_address_prefixlen =
813 (p_prefs != ~0 ? p_prefs : plen);
814 m_addr.sadb_address_reserved = 0;
816 setvarbuf(&m_len,
817 (struct sadb_ext *)&m_addr, sizeof(m_addr),
818 (caddr_t)p_src, p_src->sa_len);
820 /* set dst */
821 m_addr.sadb_address_len =
822 PFKEY_UNIT64(sizeof(m_addr)
823 + PFKEY_ALIGN8(p_dst->sa_len));
824 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
825 m_addr.sadb_address_proto = p_upper;
826 switch (p_dst->sa_family) {
827 case AF_INET:
828 plen = sizeof(struct in_addr) << 3;
829 break;
830 #ifdef INET6
831 case AF_INET6:
832 plen = sizeof(struct in6_addr) << 3;
833 break;
834 #endif
835 default:
836 yyerror("unsupported address family");
837 exit(1); /*XXX*/
839 m_addr.sadb_address_prefixlen =
840 (p_prefd != ~0 ? p_prefd : plen);
841 m_addr.sadb_address_reserved = 0;
843 setvarbuf(&m_len,
844 (struct sadb_ext *)&m_addr, sizeof(m_addr),
845 (caddr_t)p_dst, p_dst->sa_len);
847 break;
850 ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len);
852 return 0;
855 static struct addrinfo *
856 parse_addr(char *host, char *port, int flag)
858 struct addrinfo hints, *res = NULL;
859 int error;
861 memset(&hints, 0, sizeof(hints));
862 hints.ai_family = PF_UNSPEC;
863 hints.ai_socktype = SOCK_DGRAM;
864 hints.ai_flags = flag;
865 error = getaddrinfo(host, port, &hints, &res);
866 if (error != 0) {
867 yyerror(gai_strerror(error));
868 return NULL;
870 if (res->ai_next != NULL) {
871 yyerror(gai_strerror(error));
873 return res;
876 static int
877 setvarbuf(int *off, struct sadb_ext *ebuf, int elen, caddr_t vbuf, int vlen)
879 memset(m_buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
880 memcpy(m_buf + *off, (caddr_t)ebuf, elen);
881 memcpy(m_buf + *off + elen, vbuf, vlen);
882 (*off) += PFKEY_ALIGN8(elen + vlen);
884 return 0;
887 void
888 parse_init(void)
890 p_type = 0;
891 p_spi = 0;
892 p_no_spi = 0;
894 p_src = 0, p_dst = 0;
895 pp_prefix = p_prefs = p_prefd = ~0;
896 pp_port = IPSEC_PORT_ANY;
897 p_upper = 0;
899 p_satype = 0;
900 p_ext = SADB_X_EXT_CYCSEQ;
901 p_alg_enc = SADB_EALG_NONE;
902 p_alg_auth = SADB_AALG_NONE;
903 p_mode = IPSEC_MODE_ANY;
904 p_reqid = 0;
905 p_replay = 0;
906 p_key_enc_len = p_key_auth_len = 0;
907 p_key_enc = p_key_auth = 0;
908 p_lt_hard = p_lt_soft = 0;
910 p_policy_len = 0;
911 p_policy = NULL;
913 memset(cmdarg, 0, sizeof(cmdarg));
915 return;
918 void
919 free_buffer(void)
921 if (p_src) free(p_src);
922 if (p_dst) free(p_dst);
923 if (p_key_enc) free(p_key_enc);
924 if (p_key_auth) free(p_key_auth);
926 return;