kernel: Disable TCP_SIGNATURE in preparation for removing IPSEC.
[dragonfly.git] / usr.sbin / setkey / parse.y
blobe48b2f9771e95c303cf70e6a73f94f7e1cd02235
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 <stdlib.h>
50 #include <netdb.h>
51 #include <ctype.h>
52 #include <errno.h>
54 #include "libpfkey.h"
55 #include "vchar.h"
57 #define ATOX(c) \
58 (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) ))
60 u_int p_type;
61 u_int32_t p_spi;
62 int p_no_spi;
63 struct sockaddr *p_src, *p_dst;
64 u_int p_prefs, p_prefd, p_upper;
65 u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
66 u_int32_t p_reqid;
67 u_int p_key_enc_len, p_key_auth_len;
68 caddr_t p_key_enc, p_key_auth;
69 time_t p_lt_hard, p_lt_soft;
71 u_int p_policy_len;
72 char *p_policy;
74 /* temporary buffer */
75 static struct sockaddr *pp_addr;
76 static u_int pp_prefix;
77 static u_int pp_port;
78 static caddr_t pp_key;
80 extern u_char m_buf[BUFSIZ];
81 extern u_int m_len;
82 extern char cmdarg[8192];
83 extern int f_debug;
85 static struct addrinfo *parse_addr(char *, char *, int);
86 static int setvarbuf(int *, struct sadb_ext *, int, caddr_t, int);
87 void parse_init(void);
88 void free_buffer(void);
90 extern int setkeymsg(void);
91 extern int sendkeymsg(void);
93 extern int yylex(void);
94 extern void yyfatal(const char *);
95 extern void yyerror(const char *);
98 %union {
99 unsigned long num;
100 vchar_t val;
103 %token EOT
104 %token ADD GET DELETE DELETEALL FLUSH DUMP
105 %token ADDRESS PREFIX PORT PORTANY
106 %token UP_PROTO PR_ESP PR_AH PR_IPCOMP PR_TCP
107 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
108 %token F_MODE MODE F_REQID
109 %token F_EXT EXTENSION NOCYCLICSEQ
110 %token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
111 %token F_LIFETIME_HARD F_LIFETIME_SOFT
112 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
113 /* SPD management */
114 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
115 %token F_POLICY PL_REQUESTS
117 %type <num> PORT PREFIX EXTENSION MODE
118 %type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP PR_TCP
119 %type <num> ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
120 %type <num> DECSTRING
121 %type <val> ADDRESS PL_REQUESTS
122 %type <val> key_string policy_requests
123 %type <val> QUOTEDSTRING HEXSTRING STRING
126 commands
127 : /*NOTHING*/
128 | commands command
130 if (f_debug) {
131 printf("cmdarg:\n%s\n", cmdarg);
132 } else {
133 setkeymsg();
134 sendkeymsg();
136 free_buffer();
137 parse_init();
141 command
142 : add_command
143 | get_command
144 | delete_command
145 | deleteall_command
146 | flush_command
147 | dump_command
148 | spdadd_command
149 | spddelete_command
150 | spddump_command
151 | spdflush_command
153 /* commands concerned with management, there is in tail of this file. */
155 /* add command */
156 add_command
157 : ADD { p_type = SADB_ADD; }
158 sa_selector_spec extension_spec algorithm_spec EOT
161 /* delete */
162 delete_command
163 : DELETE { p_type = SADB_DELETE; }
164 sa_selector_spec extension_spec
166 if (p_mode != IPSEC_MODE_ANY)
167 yyerror("WARNING: mode is obsoleted.");
172 /* deleteall command */
173 deleteall_command
174 : DELETEALL { p_type = SADB_DELETE; }
175 ipaddress { p_src = pp_addr; }
176 ipaddress { p_dst = pp_addr; }
177 protocol_spec
178 { p_no_spi = 1; }
182 /* get command */
183 get_command
184 : GET { p_type = SADB_GET; }
185 sa_selector_spec extension_spec
187 if (p_mode != IPSEC_MODE_ANY)
188 yyerror("WARNING: mode is obsoleted.");
193 /* flush */
194 flush_command
195 : FLUSH { p_type = SADB_FLUSH; }
196 protocol_spec EOT
199 /* dump */
200 dump_command
201 : DUMP { p_type = SADB_DUMP; }
202 protocol_spec EOT
205 /* sa_selector_spec */
206 sa_selector_spec
207 : ipaddress { p_src = pp_addr; }
208 ipaddress { p_dst = pp_addr; }
209 protocol_spec spi
212 protocol_spec
213 : /*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; }
214 | PR_ESP
216 p_satype = SADB_SATYPE_ESP;
217 if ($1 == 1)
218 p_ext |= SADB_X_EXT_OLD;
219 else
220 p_ext &= ~SADB_X_EXT_OLD;
222 | PR_AH
224 p_satype = SADB_SATYPE_AH;
225 if ($1 == 1)
226 p_ext |= SADB_X_EXT_OLD;
227 else
228 p_ext &= ~SADB_X_EXT_OLD;
230 | PR_IPCOMP
232 p_satype = SADB_X_SATYPE_IPCOMP;
234 | PR_TCP
236 p_satype = SADB_X_SATYPE_TCPSIGNATURE;
241 : DECSTRING { p_spi = $1; }
242 | HEXSTRING
244 caddr_t bp;
245 caddr_t yp = $1.buf;
246 char buf0[4], buf[4];
247 int i, j;
249 /* sanity check */
250 if ($1.len > 4) {
251 yyerror("SPI too big.");
252 free($1.buf);
253 return -1;
256 bp = buf0;
257 while (*yp) {
258 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
259 yp += 2, bp++;
262 /* initialize */
263 for (i = 0; i < 4; i++) buf[i] = 0;
265 for (j = $1.len - 1, i = 3; j >= 0; j--, i--)
266 buf[i] = buf0[j];
268 /* XXX: endian */
269 p_spi = ntohl(*(u_int32_t *)buf);
271 free($1.buf);
275 algorithm_spec
276 : esp_spec
277 | ah_spec
278 | ipcomp_spec
281 esp_spec
282 : F_ENC enc_alg enc_key F_AUTH auth_alg auth_key
283 | F_ENC enc_alg enc_key
286 ah_spec
287 : F_AUTH auth_alg auth_key
290 ipcomp_spec
291 : F_COMP ALG_COMP { p_alg_enc = $2; }
292 | F_COMP ALG_COMP { p_alg_enc = $2; }
293 F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; }
296 enc_alg
297 : ALG_ENC { p_alg_enc = $1; }
298 | ALG_ENC_DESDERIV
300 p_alg_enc = $1;
301 if (p_ext & SADB_X_EXT_OLD) {
302 yyerror("algorithm mismatched.");
303 return -1;
305 p_ext |= SADB_X_EXT_DERIV;
307 | ALG_ENC_DES32IV
309 p_alg_enc = $1;
310 if (!(p_ext & SADB_X_EXT_OLD)) {
311 yyerror("algorithm mismatched.");
312 return -1;
314 p_ext |= SADB_X_EXT_IV4B;
318 enc_key
319 : /*NOTHING*/
321 if (p_alg_enc != SADB_EALG_NULL) {
322 yyerror("no key found.");
323 return -1;
326 | key_string
328 p_key_enc_len = $1.len;
329 p_key_enc = pp_key;
331 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
332 p_alg_enc,
333 PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
334 yyerror(ipsec_strerror());
335 return -1;
340 auth_alg
341 : ALG_AUTH { p_alg_auth = $1; }
344 auth_key
345 : /*NOTHING*/
347 if (p_alg_auth != SADB_X_AALG_NULL) {
348 yyerror("no key found.");
349 return -1;
352 | key_string
354 p_key_auth_len = $1.len;
355 p_key_auth = pp_key;
357 if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
358 if ((p_key_auth_len < 1) || (p_key_auth_len >
359 80))
360 return -1;
361 } else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
362 p_alg_auth,
363 PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
364 yyerror(ipsec_strerror());
365 return -1;
370 key_string
371 : QUOTEDSTRING
373 pp_key = $1.buf;
374 /* free pp_key later */
376 | HEXSTRING
378 caddr_t bp;
379 caddr_t yp = $1.buf;
381 if ((pp_key = malloc($1.len)) == 0) {
382 free($1.buf);
383 yyerror("not enough core");
384 return -1;
386 memset(pp_key, 0, $1.len);
388 bp = pp_key;
389 while (*yp) {
390 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
391 yp += 2, bp++;
394 free($1.buf);
398 extension_spec
399 : /*NOTHING*/
400 | extension_spec extension
403 extension
404 : F_EXT EXTENSION { p_ext |= $2; }
405 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
406 | F_MODE MODE { p_mode = $2; }
407 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
408 | F_REQID DECSTRING { p_reqid = $2; }
409 | F_REPLAY DECSTRING
411 if (p_ext & SADB_X_EXT_OLD) {
412 yyerror("replay prevention "
413 "only use on new spec.");
414 return -1;
416 p_replay = $2;
418 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
419 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
422 /* definition about command for SPD management */
423 /* spdadd */
424 spdadd_command
425 : SPDADD
427 p_type = SADB_X_SPDADD;
428 p_satype = SADB_SATYPE_UNSPEC;
430 sp_selector_spec policy_spec EOT
433 spddelete_command:
434 SPDDELETE
436 p_type = SADB_X_SPDDELETE;
437 p_satype = SADB_SATYPE_UNSPEC;
439 sp_selector_spec policy_spec EOT
442 spddump_command:
443 SPDDUMP
445 p_type = SADB_X_SPDDUMP;
446 p_satype = SADB_SATYPE_UNSPEC;
451 spdflush_command:
452 SPDFLUSH
454 p_type = SADB_X_SPDFLUSH;
455 p_satype = SADB_SATYPE_UNSPEC;
460 /* sp_selector_spec */
461 sp_selector_spec
462 : ipaddress { p_src = pp_addr; }
463 prefix { p_prefs = pp_prefix; }
464 port
466 switch (p_src->sa_family) {
467 case AF_INET:
468 ((struct sockaddr_in *)p_src)->sin_port =
469 htons(pp_port);
470 break;
471 #ifdef INET6
472 case AF_INET6:
473 ((struct sockaddr_in6 *)p_src)->sin6_port =
474 htons(pp_port);
475 break;
476 #endif
477 default:
478 exit(1); /*XXX*/
481 ipaddress { p_dst = pp_addr; }
482 prefix { p_prefd = pp_prefix; }
483 port
485 switch (p_dst->sa_family) {
486 case AF_INET:
487 ((struct sockaddr_in *)p_dst)->sin_port =
488 htons(pp_port);
489 break;
490 #ifdef INET6
491 case AF_INET6:
492 ((struct sockaddr_in6 *)p_dst)->sin6_port =
493 htons(pp_port);
494 break;
495 #endif
496 default:
497 exit(1); /*XXX*/
500 upper_spec
502 /* XXX is it something userland should check? */
503 #if 0
504 switch (p_upper) {
505 case IPPROTO_ICMP:
506 case IPPROTO_ICMPV6:
507 if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY
508 || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) {
509 yyerror("port number must be \"any\".");
510 return -1;
512 if ((pp_addr->sa_family == AF_INET6
513 && p_upper == IPPROTO_ICMP)
514 || (pp_addr->sa_family == AF_INET
515 && p_upper == IPPROTO_ICMPV6)) {
516 yyerror("upper layer protocol "
517 "mismatched.\n");
518 return -1;
520 break;
521 default:
522 break;
524 #endif
528 ipaddress
529 : ADDRESS
531 struct addrinfo *res;
533 res = parse_addr($1.buf, NULL, AI_NUMERICHOST);
534 if (res == NULL) {
535 free($1.buf);
536 return -1;
538 pp_addr = (struct sockaddr *)malloc(res->ai_addrlen);
539 if (!pp_addr) {
540 yyerror("not enough core");
541 goto end;
544 memcpy(pp_addr, res->ai_addr, res->ai_addrlen);
545 end:
546 freeaddrinfo(res);
547 free($1.buf);
551 prefix
552 : /*NOTHING*/ { pp_prefix = ~0; }
553 | PREFIX { pp_prefix = $1; }
556 port
557 : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; }
558 | PORT { pp_port = $1; }
559 | PORTANY { pp_port = IPSEC_PORT_ANY; }
562 upper_spec
563 : DECSTRING { p_upper = $1; }
564 | UP_PROTO { p_upper = $1; }
565 | ANY { p_upper = IPSEC_ULPROTO_ANY; }
566 | STRING
568 struct protoent *ent;
570 ent = getprotobyname($1.buf);
571 if (ent)
572 p_upper = ent->p_proto;
573 else {
574 if (strcmp("icmp6", $1.buf) == 0) {
575 p_upper = IPPROTO_ICMPV6;
576 } else if(strcmp("ip4", $1.buf) == 0) {
577 p_upper = IPPROTO_IPV4;
578 } else {
579 yyerror("invalid upper layer protocol");
580 free($1.buf);
581 return -1;
584 free($1.buf);
588 policy_spec
589 : F_POLICY policy_requests
591 p_policy = ipsec_set_policy($2.buf, $2.len);
592 if (p_policy == NULL) {
593 free($2.buf);
594 p_policy = NULL;
595 yyerror(ipsec_strerror());
596 return -1;
599 p_policy_len = ipsec_get_policylen(p_policy);
601 free($2.buf);
605 policy_requests
606 : PL_REQUESTS { $$ = $1; }
612 setkeymsg(void)
614 struct sadb_msg m_msg;
616 m_msg.sadb_msg_version = PF_KEY_V2;
617 m_msg.sadb_msg_type = p_type;
618 m_msg.sadb_msg_errno = 0;
619 m_msg.sadb_msg_satype = p_satype;
620 m_msg.sadb_msg_reserved = 0;
621 m_msg.sadb_msg_seq = 0;
622 m_msg.sadb_msg_pid = getpid();
624 m_len = sizeof(struct sadb_msg);
625 memcpy(m_buf, &m_msg, m_len);
627 switch (p_type) {
628 case SADB_FLUSH:
629 case SADB_DUMP:
630 break;
632 case SADB_ADD:
633 /* set encryption algorithm, if present. */
634 if (p_satype != SADB_X_SATYPE_IPCOMP && p_alg_enc != SADB_EALG_NONE) {
635 struct sadb_key m_key;
637 m_key.sadb_key_len =
638 PFKEY_UNIT64(sizeof(m_key)
639 + PFKEY_ALIGN8(p_key_enc_len));
640 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
641 m_key.sadb_key_bits = p_key_enc_len * 8;
642 m_key.sadb_key_reserved = 0;
644 setvarbuf(&m_len,
645 (struct sadb_ext *)&m_key, sizeof(m_key),
646 (caddr_t)p_key_enc, p_key_enc_len);
649 /* set authentication algorithm, if present. */
650 if (p_alg_auth != SADB_AALG_NONE) {
651 struct sadb_key m_key;
653 m_key.sadb_key_len =
654 PFKEY_UNIT64(sizeof(m_key)
655 + PFKEY_ALIGN8(p_key_auth_len));
656 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
657 m_key.sadb_key_bits = p_key_auth_len * 8;
658 m_key.sadb_key_reserved = 0;
660 setvarbuf(&m_len,
661 (struct sadb_ext *)&m_key, sizeof(m_key),
662 (caddr_t)p_key_auth, p_key_auth_len);
665 /* set lifetime for HARD */
666 if (p_lt_hard != 0) {
667 struct sadb_lifetime m_lt;
668 u_int len = sizeof(struct sadb_lifetime);
670 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len);
671 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
672 m_lt.sadb_lifetime_allocations = 0;
673 m_lt.sadb_lifetime_bytes = 0;
674 m_lt.sadb_lifetime_addtime = p_lt_hard;
675 m_lt.sadb_lifetime_usetime = 0;
677 memcpy(m_buf + m_len, &m_lt, len);
678 m_len += len;
681 /* set lifetime for SOFT */
682 if (p_lt_soft != 0) {
683 struct sadb_lifetime m_lt;
684 u_int len = sizeof(struct sadb_lifetime);
686 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len);
687 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
688 m_lt.sadb_lifetime_allocations = 0;
689 m_lt.sadb_lifetime_bytes = 0;
690 m_lt.sadb_lifetime_addtime = p_lt_soft;
691 m_lt.sadb_lifetime_usetime = 0;
693 memcpy(m_buf + m_len, &m_lt, len);
694 m_len += len;
696 /* FALLTHROUGH */
698 case SADB_DELETE:
699 case SADB_GET:
701 struct sadb_sa m_sa;
702 struct sadb_x_sa2 m_sa2;
703 struct sadb_address m_addr;
704 u_int len;
706 if (p_no_spi == 0) {
707 len = sizeof(struct sadb_sa);
708 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
709 m_sa.sadb_sa_exttype = SADB_EXT_SA;
710 m_sa.sadb_sa_spi = htonl(p_spi);
711 m_sa.sadb_sa_replay = p_replay;
712 m_sa.sadb_sa_state = 0;
713 m_sa.sadb_sa_auth = p_alg_auth;
714 m_sa.sadb_sa_encrypt = p_alg_enc;
715 m_sa.sadb_sa_flags = p_ext;
717 memcpy(m_buf + m_len, &m_sa, len);
718 m_len += len;
720 len = sizeof(struct sadb_x_sa2);
721 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
722 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
723 m_sa2.sadb_x_sa2_mode = p_mode;
724 m_sa2.sadb_x_sa2_reqid = p_reqid;
726 memcpy(m_buf + m_len, &m_sa2, len);
727 m_len += len;
730 /* set src */
731 m_addr.sadb_address_len =
732 PFKEY_UNIT64(sizeof(m_addr)
733 + PFKEY_ALIGN8(p_src->sa_len));
734 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
735 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
736 switch (p_src->sa_family) {
737 case AF_INET:
738 m_addr.sadb_address_prefixlen =
739 sizeof(struct in_addr) << 3;
740 break;
741 #ifdef INET6
742 case AF_INET6:
743 m_addr.sadb_address_prefixlen =
744 sizeof(struct in6_addr) << 3;
745 break;
746 #endif
747 default:
748 yyerror("unsupported address family");
749 exit(1); /*XXX*/
751 m_addr.sadb_address_reserved = 0;
753 setvarbuf(&m_len,
754 (struct sadb_ext *)&m_addr, sizeof(m_addr),
755 (caddr_t)p_src, p_src->sa_len);
757 /* set dst */
758 m_addr.sadb_address_len =
759 PFKEY_UNIT64(sizeof(m_addr)
760 + PFKEY_ALIGN8(p_dst->sa_len));
761 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
762 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
763 switch (p_dst->sa_family) {
764 case AF_INET:
765 m_addr.sadb_address_prefixlen =
766 sizeof(struct in_addr) << 3;
767 break;
768 #ifdef INET6
769 case AF_INET6:
770 m_addr.sadb_address_prefixlen =
771 sizeof(struct in6_addr) << 3;
772 break;
773 #endif
774 default:
775 yyerror("unsupported address family");
776 exit(1); /*XXX*/
778 m_addr.sadb_address_reserved = 0;
780 setvarbuf(&m_len,
781 (struct sadb_ext *)&m_addr, sizeof(m_addr),
782 (caddr_t)p_dst, p_dst->sa_len);
784 break;
786 /* for SPD management */
787 case SADB_X_SPDFLUSH:
788 case SADB_X_SPDDUMP:
789 break;
791 case SADB_X_SPDADD:
792 case SADB_X_SPDDELETE:
794 struct sadb_address m_addr;
795 u_int8_t plen;
797 memcpy(m_buf + m_len, p_policy, p_policy_len);
798 m_len += p_policy_len;
799 free(p_policy);
800 p_policy = NULL;
802 /* set src */
803 m_addr.sadb_address_len =
804 PFKEY_UNIT64(sizeof(m_addr)
805 + PFKEY_ALIGN8(p_src->sa_len));
806 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
807 m_addr.sadb_address_proto = p_upper;
808 switch (p_src->sa_family) {
809 case AF_INET:
810 plen = sizeof(struct in_addr) << 3;
811 break;
812 #ifdef INET6
813 case AF_INET6:
814 plen = sizeof(struct in6_addr) << 3;
815 break;
816 #endif
817 default:
818 yyerror("unsupported address family");
819 exit(1); /*XXX*/
821 m_addr.sadb_address_prefixlen =
822 (p_prefs != ~0 ? p_prefs : plen);
823 m_addr.sadb_address_reserved = 0;
825 setvarbuf(&m_len,
826 (struct sadb_ext *)&m_addr, sizeof(m_addr),
827 (caddr_t)p_src, p_src->sa_len);
829 /* set dst */
830 m_addr.sadb_address_len =
831 PFKEY_UNIT64(sizeof(m_addr)
832 + PFKEY_ALIGN8(p_dst->sa_len));
833 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
834 m_addr.sadb_address_proto = p_upper;
835 switch (p_dst->sa_family) {
836 case AF_INET:
837 plen = sizeof(struct in_addr) << 3;
838 break;
839 #ifdef INET6
840 case AF_INET6:
841 plen = sizeof(struct in6_addr) << 3;
842 break;
843 #endif
844 default:
845 yyerror("unsupported address family");
846 exit(1); /*XXX*/
848 m_addr.sadb_address_prefixlen =
849 (p_prefd != ~0 ? p_prefd : plen);
850 m_addr.sadb_address_reserved = 0;
852 setvarbuf(&m_len,
853 (struct sadb_ext *)&m_addr, sizeof(m_addr),
854 (caddr_t)p_dst, p_dst->sa_len);
856 break;
859 ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len);
861 return 0;
864 static struct addrinfo *
865 parse_addr(char *host, char *port, int flag)
867 struct addrinfo hints, *res = NULL;
868 int error;
870 memset(&hints, 0, sizeof(hints));
871 hints.ai_family = PF_UNSPEC;
872 hints.ai_socktype = SOCK_DGRAM;
873 hints.ai_flags = flag;
874 error = getaddrinfo(host, port, &hints, &res);
875 if (error != 0) {
876 yyerror(gai_strerror(error));
877 return NULL;
879 if (res->ai_next != NULL) {
880 yyerror(gai_strerror(error));
882 return res;
885 static int
886 setvarbuf(int *off, struct sadb_ext *ebuf, int elen, caddr_t vbuf, int vlen)
888 memset(m_buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
889 memcpy(m_buf + *off, (caddr_t)ebuf, elen);
890 memcpy(m_buf + *off + elen, vbuf, vlen);
891 (*off) += PFKEY_ALIGN8(elen + vlen);
893 return 0;
896 void
897 parse_init(void)
899 p_type = 0;
900 p_spi = 0;
901 p_no_spi = 0;
903 p_src = 0, p_dst = 0;
904 pp_prefix = p_prefs = p_prefd = ~0;
905 pp_port = IPSEC_PORT_ANY;
906 p_upper = 0;
908 p_satype = 0;
909 p_ext = SADB_X_EXT_CYCSEQ;
910 p_alg_enc = SADB_EALG_NONE;
911 p_alg_auth = SADB_AALG_NONE;
912 p_mode = IPSEC_MODE_ANY;
913 p_reqid = 0;
914 p_replay = 0;
915 p_key_enc_len = p_key_auth_len = 0;
916 p_key_enc = p_key_auth = 0;
917 p_lt_hard = p_lt_soft = 0;
919 p_policy_len = 0;
920 p_policy = NULL;
922 memset(cmdarg, 0, sizeof(cmdarg));
924 return;
927 void
928 free_buffer(void)
930 if (p_src) free(p_src);
931 if (p_dst) free(p_dst);
932 if (p_key_enc) free(p_key_enc);
933 if (p_key_auth) free(p_key_auth);
935 return;