Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / crypto / dist / ipsec-tools / src / setkey / parse.y
blob70ec3246c6265163b5354ded6d5d0d5272657432
1 /* $NetBSD: parse.y,v 1.11 2008/12/29 12:54:33 mlelstv Exp $ */
3 /* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun 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 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <net/pfkeyv2.h>
45 #include PATH_IPSEC_H
46 #include <arpa/inet.h>
48 #include <string.h>
49 #include <unistd.h>
50 #include <stdio.h>
51 #include <netdb.h>
52 #include <ctype.h>
53 #include <errno.h>
54 #include <stdlib.h>
56 #include "libpfkey.h"
57 #include "vchar.h"
58 #include "extern.h"
60 #ifndef IPPROTO_MH
61 #define IPPROTO_MH 135
62 #endif
64 #define DEFAULT_NATT_PORT 4500
66 #ifndef UDP_ENCAP_ESPINUDP
67 #define UDP_ENCAP_ESPINUDP 2
68 #endif
70 #define ATOX(c) \
71 (isdigit((int)c) ? (c - '0') : \
72 (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10)))
74 u_int32_t p_spi;
75 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
76 u_int32_t p_reqid;
77 u_int p_key_enc_len, p_key_auth_len;
78 const char *p_key_enc;
79 const char *p_key_auth;
80 time_t p_lt_hard, p_lt_soft;
81 size_t p_lb_hard, p_lb_soft;
83 struct security_ctx {
84 u_int8_t doi;
85 u_int8_t alg;
86 u_int16_t len;
87 char *buf;
90 struct security_ctx sec_ctx;
92 static u_int p_natt_type;
93 static struct addrinfo * p_natt_oa = NULL;
95 static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
97 static struct addrinfo *parse_addr __P((char *, char *));
98 static int fix_portstr __P((vchar_t *, vchar_t *, vchar_t *));
99 static int setvarbuf __P((char *, int *, struct sadb_ext *, int,
100 const void *, int));
101 void parse_init __P((void));
102 void free_buffer __P((void));
104 int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t));
105 static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *,
106 struct addrinfo *, int, struct addrinfo *, int));
107 static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *));
108 static int setkeymsg_addr __P((unsigned int, unsigned int,
109 struct addrinfo *, struct addrinfo *, int));
110 static int setkeymsg_add __P((unsigned int, unsigned int,
111 struct addrinfo *, struct addrinfo *));
114 %union {
115 int num;
116 unsigned long ulnum;
117 vchar_t val;
118 struct addrinfo *res;
121 %token EOT SLASH BLCL ELCL
122 %token ADD GET DELETE DELETEALL FLUSH DUMP EXIT
123 %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
124 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
125 %token F_MODE MODE F_REQID
126 %token F_EXT EXTENSION NOCYCLICSEQ
127 %token ALG_AUTH ALG_AUTH_NOKEY
128 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
129 %token ALG_COMP
130 %token F_LIFETIME_HARD F_LIFETIME_SOFT
131 %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT
132 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
133 /* SPD management */
134 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
135 %token F_POLICY PL_REQUESTS
136 %token F_AIFLAGS
137 %token TAGGED
138 %token SECURITY_CTX
140 %type <num> prefix protocol_spec upper_spec
141 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
142 %type <num> ALG_AUTH ALG_AUTH_NOKEY
143 %type <num> ALG_COMP
144 %type <num> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
145 %type <num> EXTENSION MODE
146 %type <ulnum> DECSTRING
147 %type <val> PL_REQUESTS portstr key_string
148 %type <val> policy_requests
149 %type <val> QUOTEDSTRING HEXSTRING STRING
150 %type <val> F_AIFLAGS
151 %type <val> upper_misc_spec policy_spec
152 %type <res> ipaddr ipandport
155 commands
156 : /*NOTHING*/
157 | commands command
159 free_buffer();
160 parse_init();
164 command
165 : add_command
166 | get_command
167 | delete_command
168 | deleteall_command
169 | flush_command
170 | dump_command
171 | exit_command
172 | spdadd_command
173 | spddelete_command
174 | spddump_command
175 | spdflush_command
177 /* commands concerned with management, there is in tail of this file. */
179 /* add command */
180 add_command
181 : ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
183 int status;
185 status = setkeymsg_add(SADB_ADD, $5, $3, $4);
186 if (status < 0)
187 return -1;
191 /* delete */
192 delete_command
193 : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
195 int status;
197 if ($3->ai_next || $4->ai_next) {
198 yyerror("multiple address specified");
199 return -1;
201 if (p_mode != IPSEC_MODE_ANY)
202 yyerror("WARNING: mode is obsolete");
204 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
205 if (status < 0)
206 return -1;
210 /* deleteall command */
211 deleteall_command
212 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
214 #ifndef __linux__
215 if (setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1) < 0)
216 return -1;
217 #else /* __linux__ */
218 /* linux strictly adheres to RFC2367, and returns
219 * an error if we send an SADB_DELETE request without
220 * an SPI. Therefore, we must first retrieve a list
221 * of SPIs for all matching SADB entries, and then
222 * delete each one separately. */
223 u_int32_t *spi;
224 int i, n;
226 spi = sendkeymsg_spigrep($5, $3, $4, &n);
227 for (i = 0; i < n; i++) {
228 p_spi = spi[i];
229 if (setkeymsg_addr(SADB_DELETE,
230 $5, $3, $4, 0) < 0)
231 return -1;
233 free(spi);
234 #endif /* __linux__ */
238 /* get command */
239 get_command
240 : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
242 int status;
244 if (p_mode != IPSEC_MODE_ANY)
245 yyerror("WARNING: mode is obsolete");
247 status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
248 if (status < 0)
249 return -1;
253 /* flush */
254 flush_command
255 : FLUSH protocol_spec EOT
257 struct sadb_msg msg;
258 setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
259 sendkeymsg((char *)&msg, sizeof(msg));
263 /* dump */
264 dump_command
265 : DUMP protocol_spec EOT
267 struct sadb_msg msg;
268 setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
269 sendkeymsg((char *)&msg, sizeof(msg));
273 protocol_spec
274 : /*NOTHING*/
276 $$ = SADB_SATYPE_UNSPEC;
278 | PR_ESP
280 $$ = SADB_SATYPE_ESP;
281 if ($1 == 1)
282 p_ext |= SADB_X_EXT_OLD;
283 else
284 p_ext &= ~SADB_X_EXT_OLD;
286 | PR_AH
288 $$ = SADB_SATYPE_AH;
289 if ($1 == 1)
290 p_ext |= SADB_X_EXT_OLD;
291 else
292 p_ext &= ~SADB_X_EXT_OLD;
294 | PR_IPCOMP
296 $$ = SADB_X_SATYPE_IPCOMP;
298 | PR_ESPUDP
300 $$ = SADB_SATYPE_ESP;
301 p_ext &= ~SADB_X_EXT_OLD;
302 p_natt_oa = 0;
303 p_natt_type = UDP_ENCAP_ESPINUDP;
305 | PR_ESPUDP ipaddr
307 $$ = SADB_SATYPE_ESP;
308 p_ext &= ~SADB_X_EXT_OLD;
309 p_natt_oa = $2;
310 p_natt_type = UDP_ENCAP_ESPINUDP;
312 | PR_TCP
314 #ifdef SADB_X_SATYPE_TCPSIGNATURE
315 $$ = SADB_X_SATYPE_TCPSIGNATURE;
316 #endif
321 : DECSTRING { p_spi = $1; }
322 | HEXSTRING
324 char *ep;
325 unsigned long v;
327 ep = NULL;
328 v = strtoul($1.buf, &ep, 16);
329 if (!ep || *ep) {
330 yyerror("invalid SPI");
331 return -1;
333 if (v & ~0xffffffff) {
334 yyerror("SPI too big.");
335 return -1;
338 p_spi = v;
342 algorithm_spec
343 : esp_spec
344 | ah_spec
345 | ipcomp_spec
348 esp_spec
349 : F_ENC enc_alg F_AUTH auth_alg
350 | F_ENC enc_alg
353 ah_spec
354 : F_AUTH auth_alg
357 ipcomp_spec
358 : F_COMP ALG_COMP
360 if ($2 < 0) {
361 yyerror("unsupported algorithm");
362 return -1;
364 p_alg_enc = $2;
366 | F_COMP ALG_COMP F_RAWCPI
368 if ($2 < 0) {
369 yyerror("unsupported algorithm");
370 return -1;
372 p_alg_enc = $2;
373 p_ext |= SADB_X_EXT_RAWCPI;
377 enc_alg
378 : ALG_ENC_NOKEY {
379 if ($1 < 0) {
380 yyerror("unsupported algorithm");
381 return -1;
383 p_alg_enc = $1;
385 p_key_enc_len = 0;
386 p_key_enc = "";
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;
393 | ALG_ENC key_string {
394 if ($1 < 0) {
395 yyerror("unsupported algorithm");
396 return -1;
398 p_alg_enc = $1;
400 p_key_enc_len = $2.len;
401 p_key_enc = $2.buf;
402 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
403 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
404 yyerror(ipsec_strerror());
405 return -1;
408 | ALG_ENC_OLD {
409 if ($1 < 0) {
410 yyerror("unsupported algorithm");
411 return -1;
413 yyerror("WARNING: obsolete algorithm");
414 p_alg_enc = $1;
416 p_key_enc_len = 0;
417 p_key_enc = "";
418 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
419 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
420 yyerror(ipsec_strerror());
421 return -1;
424 | ALG_ENC_DESDERIV key_string
426 if ($1 < 0) {
427 yyerror("unsupported algorithm");
428 return -1;
430 p_alg_enc = $1;
431 if (p_ext & SADB_X_EXT_OLD) {
432 yyerror("algorithm mismatched");
433 return -1;
435 p_ext |= SADB_X_EXT_DERIV;
437 p_key_enc_len = $2.len;
438 p_key_enc = $2.buf;
439 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
440 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
441 yyerror(ipsec_strerror());
442 return -1;
445 | ALG_ENC_DES32IV key_string
447 if ($1 < 0) {
448 yyerror("unsupported algorithm");
449 return -1;
451 p_alg_enc = $1;
452 if (!(p_ext & SADB_X_EXT_OLD)) {
453 yyerror("algorithm mismatched");
454 return -1;
456 p_ext |= SADB_X_EXT_IV4B;
458 p_key_enc_len = $2.len;
459 p_key_enc = $2.buf;
460 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
461 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
462 yyerror(ipsec_strerror());
463 return -1;
468 auth_alg
469 : ALG_AUTH key_string {
470 if ($1 < 0) {
471 yyerror("unsupported algorithm");
472 return -1;
474 p_alg_auth = $1;
476 p_key_auth_len = $2.len;
477 p_key_auth = $2.buf;
478 #ifdef SADB_X_AALG_TCP_MD5
479 if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
480 if ((p_key_auth_len < 1) ||
481 (p_key_auth_len > 80))
482 return -1;
483 } else
484 #endif
486 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
487 p_alg_auth,
488 PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
489 yyerror(ipsec_strerror());
490 return -1;
494 | ALG_AUTH_NOKEY {
495 if ($1 < 0) {
496 yyerror("unsupported algorithm");
497 return -1;
499 p_alg_auth = $1;
501 p_key_auth_len = 0;
502 p_key_auth = NULL;
506 key_string
507 : QUOTEDSTRING
509 $$ = $1;
511 | HEXSTRING
513 caddr_t pp_key;
514 caddr_t bp;
515 caddr_t yp = $1.buf;
516 int l;
518 l = strlen(yp) % 2 + strlen(yp) / 2;
519 if ((pp_key = malloc(l)) == 0) {
520 yyerror("not enough core");
521 return -1;
523 memset(pp_key, 0, l);
525 bp = pp_key;
526 if (strlen(yp) % 2) {
527 *bp = ATOX(yp[0]);
528 yp++, bp++;
530 while (*yp) {
531 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
532 yp += 2, bp++;
535 $$.len = l;
536 $$.buf = pp_key;
540 extension_spec
541 : /*NOTHING*/
542 | extension_spec extension
545 extension
546 : F_EXT EXTENSION { p_ext |= $2; }
547 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
548 | F_MODE MODE { p_mode = $2; }
549 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
550 | F_REQID DECSTRING { p_reqid = $2; }
551 | F_REPLAY DECSTRING
553 if ((p_ext & SADB_X_EXT_OLD) != 0) {
554 yyerror("replay prevention cannot be used with "
555 "ah/esp-old");
556 return -1;
558 p_replay = $2;
560 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
561 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
562 | F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; }
563 | F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; }
564 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
565 sec_ctx.doi = $2;
566 sec_ctx.alg = $3;
567 sec_ctx.len = $4.len+1;
568 sec_ctx.buf = $4.buf;
572 /* definition about command for SPD management */
573 /* spdadd */
574 spdadd_command
575 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
577 int status;
578 struct addrinfo *src, *dst;
580 #ifdef HAVE_PFKEY_POLICY_PRIORITY
581 last_msg_type = SADB_X_SPDADD;
582 #endif
584 /* fixed port fields if ulp is icmp */
585 if ($10.buf != NULL) {
586 if (($9 != IPPROTO_ICMPV6) &&
587 ($9 != IPPROTO_ICMP) &&
588 ($9 != IPPROTO_MH))
589 return -1;
590 free($5.buf);
591 free($8.buf);
592 if (fix_portstr(&$10, &$5, &$8))
593 return -1;
596 src = parse_addr($3.buf, $5.buf);
597 dst = parse_addr($6.buf, $8.buf);
598 if (!src || !dst) {
599 /* yyerror is already called */
600 return -1;
602 if (src->ai_next || dst->ai_next) {
603 yyerror("multiple address specified");
604 freeaddrinfo(src);
605 freeaddrinfo(dst);
606 return -1;
609 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12,
610 src, $4, dst, $7);
611 freeaddrinfo(src);
612 freeaddrinfo(dst);
613 if (status < 0)
614 return -1;
616 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT
618 int status;
620 status = setkeymsg_spdaddr_tag(SADB_X_SPDADD,
621 $3.buf, &$4);
622 if (status < 0)
623 return -1;
627 spddelete_command
628 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
630 int status;
631 struct addrinfo *src, *dst;
633 /* fixed port fields if ulp is icmp */
634 if ($10.buf != NULL) {
635 if (($9 != IPPROTO_ICMPV6) &&
636 ($9 != IPPROTO_ICMP) &&
637 ($9 != IPPROTO_MH))
638 return -1;
639 free($5.buf);
640 free($8.buf);
641 if (fix_portstr(&$10, &$5, &$8))
642 return -1;
645 src = parse_addr($3.buf, $5.buf);
646 dst = parse_addr($6.buf, $8.buf);
647 if (!src || !dst) {
648 /* yyerror is already called */
649 return -1;
651 if (src->ai_next || dst->ai_next) {
652 yyerror("multiple address specified");
653 freeaddrinfo(src);
654 freeaddrinfo(dst);
655 return -1;
658 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12,
659 src, $4, dst, $7);
660 freeaddrinfo(src);
661 freeaddrinfo(dst);
662 if (status < 0)
663 return -1;
667 spddump_command:
668 SPDDUMP EOT
670 struct sadb_msg msg;
671 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
672 sizeof(msg));
673 sendkeymsg((char *)&msg, sizeof(msg));
677 spdflush_command
679 SPDFLUSH EOT
681 struct sadb_msg msg;
682 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
683 sizeof(msg));
684 sendkeymsg((char *)&msg, sizeof(msg));
688 ipaddropts
689 : /* nothing */
690 | ipaddropts ipaddropt
693 ipaddropt
694 : F_AIFLAGS
696 char *p;
698 for (p = $1.buf + 1; *p; p++)
699 switch (*p) {
700 case '4':
701 p_aifamily = AF_INET;
702 break;
703 #ifdef INET6
704 case '6':
705 p_aifamily = AF_INET6;
706 break;
707 #endif
708 case 'n':
709 p_aiflags = AI_NUMERICHOST;
710 break;
711 default:
712 yyerror("invalid flag");
713 return -1;
718 ipaddr
719 : STRING
721 $$ = parse_addr($1.buf, NULL);
722 if ($$ == NULL) {
723 /* yyerror already called by parse_addr */
724 return -1;
729 ipandport
730 : STRING
732 $$ = parse_addr($1.buf, NULL);
733 if ($$ == NULL) {
734 /* yyerror already called by parse_addr */
735 return -1;
738 | STRING portstr
740 $$ = parse_addr($1.buf, $2.buf);
741 if ($$ == NULL) {
742 /* yyerror already called by parse_addr */
743 return -1;
748 prefix
749 : /*NOTHING*/ { $$ = -1; }
750 | SLASH DECSTRING { $$ = $2; }
753 portstr
754 : /*NOTHING*/
756 $$.buf = strdup("0");
757 if (!$$.buf) {
758 yyerror("insufficient memory");
759 return -1;
761 $$.len = strlen($$.buf);
763 | BLCL ANY ELCL
765 $$.buf = strdup("0");
766 if (!$$.buf) {
767 yyerror("insufficient memory");
768 return -1;
770 $$.len = strlen($$.buf);
772 | BLCL DECSTRING ELCL
774 char buf[20];
775 snprintf(buf, sizeof(buf), "%lu", $2);
776 $$.buf = strdup(buf);
777 if (!$$.buf) {
778 yyerror("insufficient memory");
779 return -1;
781 $$.len = strlen($$.buf);
783 | BLCL STRING ELCL
785 $$ = $2;
789 upper_spec
790 : DECSTRING { $$ = $1; }
791 | ANY { $$ = IPSEC_ULPROTO_ANY; }
792 | PR_TCP {
793 $$ = IPPROTO_TCP;
795 | STRING
797 struct protoent *ent;
799 ent = getprotobyname($1.buf);
800 if (ent)
801 $$ = ent->p_proto;
802 else {
803 if (strcmp("icmp6", $1.buf) == 0) {
804 $$ = IPPROTO_ICMPV6;
805 } else if(strcmp("ip4", $1.buf) == 0) {
806 $$ = IPPROTO_IPV4;
807 } else {
808 yyerror("invalid upper layer protocol");
809 return -1;
812 endprotoent();
816 upper_misc_spec
817 : /*NOTHING*/
819 $$.buf = NULL;
820 $$.len = 0;
822 | STRING
824 $$.buf = strdup($1.buf);
825 if (!$$.buf) {
826 yyerror("insufficient memory");
827 return -1;
829 $$.len = strlen($$.buf);
833 context_spec
834 : /* NOTHING */
835 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
836 sec_ctx.doi = $2;
837 sec_ctx.alg = $3;
838 sec_ctx.len = $4.len+1;
839 sec_ctx.buf = $4.buf;
843 policy_spec
844 : F_POLICY policy_requests
846 char *policy;
847 #ifdef HAVE_PFKEY_POLICY_PRIORITY
848 struct sadb_x_policy *xpl;
849 #endif
851 policy = ipsec_set_policy($2.buf, $2.len);
852 if (policy == NULL) {
853 yyerror(ipsec_strerror());
854 return -1;
857 $$.buf = policy;
858 $$.len = ipsec_get_policylen(policy);
860 #ifdef HAVE_PFKEY_POLICY_PRIORITY
861 xpl = (struct sadb_x_policy *) $$.buf;
862 last_priority = xpl->sadb_x_policy_priority;
863 #endif
867 policy_requests
868 : PL_REQUESTS { $$ = $1; }
871 /* exit */
872 exit_command
873 : EXIT EOT
875 exit_now = 1;
876 YYACCEPT;
882 setkeymsg0(msg, type, satype, l)
883 struct sadb_msg *msg;
884 unsigned int type;
885 unsigned int satype;
886 size_t l;
889 msg->sadb_msg_version = PF_KEY_V2;
890 msg->sadb_msg_type = type;
891 msg->sadb_msg_errno = 0;
892 msg->sadb_msg_satype = satype;
893 msg->sadb_msg_reserved = 0;
894 msg->sadb_msg_seq = 0;
895 msg->sadb_msg_pid = getpid();
896 msg->sadb_msg_len = PFKEY_UNIT64(l);
897 return 0;
900 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
901 static int
902 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen)
903 unsigned int type;
904 unsigned int upper;
905 vchar_t *policy;
906 struct addrinfo *srcs;
907 int splen;
908 struct addrinfo *dsts;
909 int dplen;
911 struct sadb_msg *msg;
912 char buf[BUFSIZ];
913 int l, l0;
914 struct sadb_address m_addr;
915 struct addrinfo *s, *d;
916 int n;
917 int plen;
918 struct sockaddr *sa;
919 int salen;
920 struct sadb_x_policy *sp;
921 #ifdef HAVE_POLICY_FWD
922 struct sadb_x_ipsecrequest *ps = NULL;
923 int saved_level, saved_id = 0;
924 #endif
926 msg = (struct sadb_msg *)buf;
928 if (!srcs || !dsts)
929 return -1;
931 /* fix up length afterwards */
932 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
933 l = sizeof(struct sadb_msg);
935 sp = (struct sadb_x_policy*) (buf + l);
936 memcpy(buf + l, policy->buf, policy->len);
937 l += policy->len;
939 l0 = l;
940 n = 0;
942 /* do it for all src/dst pairs */
943 for (s = srcs; s; s = s->ai_next) {
944 for (d = dsts; d; d = d->ai_next) {
945 /* rewind pointer */
946 l = l0;
948 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
949 continue;
950 switch (s->ai_addr->sa_family) {
951 case AF_INET:
952 plen = sizeof(struct in_addr) << 3;
953 break;
954 #ifdef INET6
955 case AF_INET6:
956 plen = sizeof(struct in6_addr) << 3;
957 break;
958 #endif
959 default:
960 continue;
963 /* set src */
964 sa = s->ai_addr;
965 salen = sysdep_sa_len(s->ai_addr);
966 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
967 PFKEY_ALIGN8(salen));
968 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
969 m_addr.sadb_address_proto = upper;
970 m_addr.sadb_address_prefixlen =
971 (splen >= 0 ? splen : plen);
972 m_addr.sadb_address_reserved = 0;
974 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
975 sizeof(m_addr), (caddr_t)sa, salen);
977 /* set dst */
978 sa = d->ai_addr;
979 salen = sysdep_sa_len(d->ai_addr);
980 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
981 PFKEY_ALIGN8(salen));
982 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
983 m_addr.sadb_address_proto = upper;
984 m_addr.sadb_address_prefixlen =
985 (dplen >= 0 ? dplen : plen);
986 m_addr.sadb_address_reserved = 0;
988 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
989 sizeof(m_addr), sa, salen);
990 #ifdef SADB_X_EXT_SEC_CTX
991 /* Add security context label */
992 if (sec_ctx.doi) {
993 struct sadb_x_sec_ctx m_sec_ctx;
994 u_int slen = sizeof(struct sadb_x_sec_ctx);
996 memset(&m_sec_ctx, 0, slen);
998 m_sec_ctx.sadb_x_sec_len =
999 PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len));
1001 m_sec_ctx.sadb_x_sec_exttype =
1002 SADB_X_EXT_SEC_CTX;
1003 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/
1004 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
1005 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
1006 setvarbuf(buf, &l,
1007 (struct sadb_ext *)&m_sec_ctx, slen,
1008 (caddr_t)sec_ctx.buf, sec_ctx.len);
1010 #endif
1011 msg->sadb_msg_len = PFKEY_UNIT64(l);
1013 sendkeymsg(buf, l);
1015 #ifdef HAVE_POLICY_FWD
1016 /* create extra call for FWD policy */
1017 if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) {
1018 sp->sadb_x_policy_dir = IPSEC_DIR_FWD;
1019 ps = (struct sadb_x_ipsecrequest*) (sp+1);
1021 /* if request level is unique, change it to
1022 * require for fwd policy */
1023 /* XXX: currently, only first policy is updated
1024 * only. Update following too... */
1025 saved_level = ps->sadb_x_ipsecrequest_level;
1026 if (saved_level == IPSEC_LEVEL_UNIQUE) {
1027 saved_id = ps->sadb_x_ipsecrequest_reqid;
1028 ps->sadb_x_ipsecrequest_reqid=0;
1029 ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE;
1032 sendkeymsg(buf, l);
1033 /* restoring for next message */
1034 sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
1035 if (saved_level == IPSEC_LEVEL_UNIQUE) {
1036 ps->sadb_x_ipsecrequest_reqid = saved_id;
1037 ps->sadb_x_ipsecrequest_level = saved_level;
1040 #endif
1042 n++;
1046 if (n == 0)
1047 return -1;
1048 else
1049 return 0;
1052 static int
1053 setkeymsg_spdaddr_tag(type, tag, policy)
1054 unsigned int type;
1055 char *tag;
1056 vchar_t *policy;
1058 struct sadb_msg *msg;
1059 char buf[BUFSIZ];
1060 int l, l0;
1061 #ifdef SADB_X_EXT_TAG
1062 struct sadb_x_tag m_tag;
1063 #endif
1064 int n;
1066 msg = (struct sadb_msg *)buf;
1068 /* fix up length afterwards */
1069 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
1070 l = sizeof(struct sadb_msg);
1072 memcpy(buf + l, policy->buf, policy->len);
1073 l += policy->len;
1075 l0 = l;
1076 n = 0;
1078 #ifdef SADB_X_EXT_TAG
1079 memset(&m_tag, 0, sizeof(m_tag));
1080 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag));
1081 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG;
1082 if (strlcpy(m_tag.sadb_x_tag_name, tag,
1083 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name))
1084 return -1;
1085 memcpy(buf + l, &m_tag, sizeof(m_tag));
1086 l += sizeof(m_tag);
1087 #endif
1089 msg->sadb_msg_len = PFKEY_UNIT64(l);
1091 sendkeymsg(buf, l);
1093 return 0;
1096 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1097 static int
1098 setkeymsg_addr(type, satype, srcs, dsts, no_spi)
1099 unsigned int type;
1100 unsigned int satype;
1101 struct addrinfo *srcs;
1102 struct addrinfo *dsts;
1103 int no_spi;
1105 struct sadb_msg *msg;
1106 char buf[BUFSIZ];
1107 int l, l0, len;
1108 struct sadb_sa m_sa;
1109 struct sadb_x_sa2 m_sa2;
1110 struct sadb_address m_addr;
1111 struct addrinfo *s, *d;
1112 int n;
1113 int plen;
1114 struct sockaddr *sa;
1115 int salen;
1117 msg = (struct sadb_msg *)buf;
1119 if (!srcs || !dsts)
1120 return -1;
1122 /* fix up length afterwards */
1123 setkeymsg0(msg, type, satype, 0);
1124 l = sizeof(struct sadb_msg);
1126 if (!no_spi) {
1127 len = sizeof(struct sadb_sa);
1128 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1129 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1130 m_sa.sadb_sa_spi = htonl(p_spi);
1131 m_sa.sadb_sa_replay = p_replay;
1132 m_sa.sadb_sa_state = 0;
1133 m_sa.sadb_sa_auth = p_alg_auth;
1134 m_sa.sadb_sa_encrypt = p_alg_enc;
1135 m_sa.sadb_sa_flags = p_ext;
1137 memcpy(buf + l, &m_sa, len);
1138 l += len;
1140 len = sizeof(struct sadb_x_sa2);
1141 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1142 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1143 m_sa2.sadb_x_sa2_mode = p_mode;
1144 m_sa2.sadb_x_sa2_reqid = p_reqid;
1146 memcpy(buf + l, &m_sa2, len);
1147 l += len;
1150 l0 = l;
1151 n = 0;
1153 /* do it for all src/dst pairs */
1154 for (s = srcs; s; s = s->ai_next) {
1155 for (d = dsts; d; d = d->ai_next) {
1156 /* rewind pointer */
1157 l = l0;
1159 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1160 continue;
1161 switch (s->ai_addr->sa_family) {
1162 case AF_INET:
1163 plen = sizeof(struct in_addr) << 3;
1164 break;
1165 #ifdef INET6
1166 case AF_INET6:
1167 plen = sizeof(struct in6_addr) << 3;
1168 break;
1169 #endif
1170 default:
1171 continue;
1174 /* set src */
1175 sa = s->ai_addr;
1176 salen = sysdep_sa_len(s->ai_addr);
1177 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1178 PFKEY_ALIGN8(salen));
1179 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1180 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1181 m_addr.sadb_address_prefixlen = plen;
1182 m_addr.sadb_address_reserved = 0;
1184 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1185 sizeof(m_addr), sa, salen);
1187 /* set dst */
1188 sa = d->ai_addr;
1189 salen = sysdep_sa_len(d->ai_addr);
1190 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1191 PFKEY_ALIGN8(salen));
1192 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1193 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1194 m_addr.sadb_address_prefixlen = plen;
1195 m_addr.sadb_address_reserved = 0;
1197 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1198 sizeof(m_addr), sa, salen);
1200 msg->sadb_msg_len = PFKEY_UNIT64(l);
1202 sendkeymsg(buf, l);
1204 n++;
1208 if (n == 0)
1209 return -1;
1210 else
1211 return 0;
1214 #ifdef SADB_X_EXT_NAT_T_TYPE
1215 static u_int16_t get_port (struct addrinfo *addr)
1217 struct sockaddr *s = addr->ai_addr;
1218 u_int16_t port = 0;
1220 switch (s->sa_family) {
1221 case AF_INET:
1223 struct sockaddr_in *sin4 = (struct sockaddr_in *)s;
1224 port = ntohs(sin4->sin_port);
1225 break;
1227 case AF_INET6:
1229 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s;
1230 port = ntohs(sin6->sin6_port);
1231 break;
1235 if (port == 0)
1236 port = DEFAULT_NATT_PORT;
1238 return port;
1240 #endif
1242 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1243 static int
1244 setkeymsg_add(type, satype, srcs, dsts)
1245 unsigned int type;
1246 unsigned int satype;
1247 struct addrinfo *srcs;
1248 struct addrinfo *dsts;
1250 struct sadb_msg *msg;
1251 char buf[BUFSIZ];
1252 int l, l0, len;
1253 struct sadb_sa m_sa;
1254 struct sadb_x_sa2 m_sa2;
1255 struct sadb_address m_addr;
1256 struct addrinfo *s, *d;
1257 int n;
1258 int plen;
1259 struct sockaddr *sa;
1260 int salen;
1262 msg = (struct sadb_msg *)buf;
1264 if (!srcs || !dsts)
1265 return -1;
1267 /* fix up length afterwards */
1268 setkeymsg0(msg, type, satype, 0);
1269 l = sizeof(struct sadb_msg);
1271 /* set encryption algorithm, if present. */
1272 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1273 union {
1274 struct sadb_key key;
1275 struct sadb_ext ext;
1276 } m;
1278 m.key.sadb_key_len =
1279 PFKEY_UNIT64(sizeof(m.key)
1280 + PFKEY_ALIGN8(p_key_enc_len));
1281 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1282 m.key.sadb_key_bits = p_key_enc_len * 8;
1283 m.key.sadb_key_reserved = 0;
1285 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1286 p_key_enc, p_key_enc_len);
1289 /* set authentication algorithm, if present. */
1290 if (p_key_auth) {
1291 union {
1292 struct sadb_key key;
1293 struct sadb_ext ext;
1294 } m;
1296 m.key.sadb_key_len =
1297 PFKEY_UNIT64(sizeof(m.key)
1298 + PFKEY_ALIGN8(p_key_auth_len));
1299 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1300 m.key.sadb_key_bits = p_key_auth_len * 8;
1301 m.key.sadb_key_reserved = 0;
1303 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1304 p_key_auth, p_key_auth_len);
1307 /* set lifetime for HARD */
1308 if (p_lt_hard != 0 || p_lb_hard != 0) {
1309 struct sadb_lifetime m_lt;
1310 u_int slen = sizeof(struct sadb_lifetime);
1312 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1313 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1314 m_lt.sadb_lifetime_allocations = 0;
1315 m_lt.sadb_lifetime_bytes = p_lb_hard;
1316 m_lt.sadb_lifetime_addtime = p_lt_hard;
1317 m_lt.sadb_lifetime_usetime = 0;
1319 memcpy(buf + l, &m_lt, slen);
1320 l += slen;
1323 /* set lifetime for SOFT */
1324 if (p_lt_soft != 0 || p_lb_soft != 0) {
1325 struct sadb_lifetime m_lt;
1326 u_int slen = sizeof(struct sadb_lifetime);
1328 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1329 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1330 m_lt.sadb_lifetime_allocations = 0;
1331 m_lt.sadb_lifetime_bytes = p_lb_soft;
1332 m_lt.sadb_lifetime_addtime = p_lt_soft;
1333 m_lt.sadb_lifetime_usetime = 0;
1335 memcpy(buf + l, &m_lt, slen);
1336 l += slen;
1339 #ifdef SADB_X_EXT_SEC_CTX
1340 /* Add security context label */
1341 if (sec_ctx.doi) {
1342 struct sadb_x_sec_ctx m_sec_ctx;
1343 u_int slen = sizeof(struct sadb_x_sec_ctx);
1345 memset(&m_sec_ctx, 0, slen);
1347 m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen +
1348 PFKEY_ALIGN8(sec_ctx.len));
1349 m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
1350 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */
1351 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
1352 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
1353 setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen,
1354 (caddr_t)sec_ctx.buf, sec_ctx.len);
1356 #endif
1358 len = sizeof(struct sadb_sa);
1359 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1360 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1361 m_sa.sadb_sa_spi = htonl(p_spi);
1362 m_sa.sadb_sa_replay = p_replay;
1363 m_sa.sadb_sa_state = 0;
1364 m_sa.sadb_sa_auth = p_alg_auth;
1365 m_sa.sadb_sa_encrypt = p_alg_enc;
1366 m_sa.sadb_sa_flags = p_ext;
1368 memcpy(buf + l, &m_sa, len);
1369 l += len;
1371 len = sizeof(struct sadb_x_sa2);
1372 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1373 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1374 m_sa2.sadb_x_sa2_mode = p_mode;
1375 m_sa2.sadb_x_sa2_reqid = p_reqid;
1377 memcpy(buf + l, &m_sa2, len);
1378 l += len;
1380 #ifdef SADB_X_EXT_NAT_T_TYPE
1381 if (p_natt_type) {
1382 struct sadb_x_nat_t_type natt_type;
1384 len = sizeof(struct sadb_x_nat_t_type);
1385 memset(&natt_type, 0, len);
1386 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1387 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1388 natt_type.sadb_x_nat_t_type_type = p_natt_type;
1390 memcpy(buf + l, &natt_type, len);
1391 l += len;
1393 if (p_natt_oa) {
1394 sa = p_natt_oa->ai_addr;
1395 switch (sa->sa_family) {
1396 case AF_INET:
1397 plen = sizeof(struct in_addr) << 3;
1398 break;
1399 #ifdef INET6
1400 case AF_INET6:
1401 plen = sizeof(struct in6_addr) << 3;
1402 break;
1403 #endif
1404 default:
1405 return -1;
1407 salen = sysdep_sa_len(sa);
1408 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1409 PFKEY_ALIGN8(salen));
1410 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA;
1411 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1412 m_addr.sadb_address_prefixlen = plen;
1413 m_addr.sadb_address_reserved = 0;
1415 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1416 sizeof(m_addr), sa, salen);
1419 #endif
1421 l0 = l;
1422 n = 0;
1424 /* do it for all src/dst pairs */
1425 for (s = srcs; s; s = s->ai_next) {
1426 for (d = dsts; d; d = d->ai_next) {
1427 /* rewind pointer */
1428 l = l0;
1430 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1431 continue;
1432 switch (s->ai_addr->sa_family) {
1433 case AF_INET:
1434 plen = sizeof(struct in_addr) << 3;
1435 break;
1436 #ifdef INET6
1437 case AF_INET6:
1438 plen = sizeof(struct in6_addr) << 3;
1439 break;
1440 #endif
1441 default:
1442 continue;
1445 /* set src */
1446 sa = s->ai_addr;
1447 salen = sysdep_sa_len(s->ai_addr);
1448 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1449 PFKEY_ALIGN8(salen));
1450 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1451 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1452 m_addr.sadb_address_prefixlen = plen;
1453 m_addr.sadb_address_reserved = 0;
1455 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1456 sizeof(m_addr), sa, salen);
1458 /* set dst */
1459 sa = d->ai_addr;
1460 salen = sysdep_sa_len(d->ai_addr);
1461 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1462 PFKEY_ALIGN8(salen));
1463 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1464 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1465 m_addr.sadb_address_prefixlen = plen;
1466 m_addr.sadb_address_reserved = 0;
1468 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1469 sizeof(m_addr), sa, salen);
1471 #ifdef SADB_X_EXT_NAT_T_TYPE
1472 if (p_natt_type) {
1473 struct sadb_x_nat_t_port natt_port;
1475 /* NATT_SPORT */
1476 len = sizeof(struct sadb_x_nat_t_port);
1477 memset(&natt_port, 0, len);
1478 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1479 natt_port.sadb_x_nat_t_port_exttype =
1480 SADB_X_EXT_NAT_T_SPORT;
1481 natt_port.sadb_x_nat_t_port_port = htons(get_port(s));
1483 memcpy(buf + l, &natt_port, len);
1484 l += len;
1486 /* NATT_DPORT */
1487 natt_port.sadb_x_nat_t_port_exttype =
1488 SADB_X_EXT_NAT_T_DPORT;
1489 natt_port.sadb_x_nat_t_port_port = htons(get_port(d));
1491 memcpy(buf + l, &natt_port, len);
1492 l += len;
1494 #endif
1495 msg->sadb_msg_len = PFKEY_UNIT64(l);
1497 sendkeymsg(buf, l);
1499 n++;
1503 if (n == 0)
1504 return -1;
1505 else
1506 return 0;
1509 static struct addrinfo *
1510 parse_addr(host, port)
1511 char *host;
1512 char *port;
1514 struct addrinfo hints, *res = NULL;
1515 int error;
1517 memset(&hints, 0, sizeof(hints));
1518 hints.ai_family = p_aifamily;
1519 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
1520 hints.ai_protocol = IPPROTO_UDP; /*dummy*/
1521 hints.ai_flags = p_aiflags;
1522 error = getaddrinfo(host, port, &hints, &res);
1523 if (error != 0) {
1524 yyerror(gai_strerror(error));
1525 return NULL;
1527 return res;
1530 static int
1531 fix_portstr(spec, sport, dport)
1532 vchar_t *spec, *sport, *dport;
1534 const char *p, *p2 = "0";
1535 char *q;
1536 u_int l;
1538 l = 0;
1539 for (q = spec->buf; *q != ',' && *q != '\0' && l < spec->len; q++, l++)
1541 if (*q != '\0') {
1542 if (*q == ',') {
1543 *q = '\0';
1544 p2 = ++q;
1546 for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1548 if (*p != '\0' || *p2 == '\0') {
1549 yyerror("invalid an upper layer protocol spec");
1550 return -1;
1554 sport->buf = strdup(spec->buf);
1555 if (!sport->buf) {
1556 yyerror("insufficient memory");
1557 return -1;
1559 sport->len = strlen(sport->buf);
1560 dport->buf = strdup(p2);
1561 if (!dport->buf) {
1562 yyerror("insufficient memory");
1563 return -1;
1565 dport->len = strlen(dport->buf);
1567 return 0;
1570 static int
1571 setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
1572 char *buf;
1573 int *off;
1574 struct sadb_ext *ebuf;
1575 int elen;
1576 const void *vbuf;
1577 int vlen;
1579 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1580 memcpy(buf + *off, (caddr_t)ebuf, elen);
1581 memcpy(buf + *off + elen, vbuf, vlen);
1582 (*off) += PFKEY_ALIGN8(elen + vlen);
1584 return 0;
1587 void
1588 parse_init()
1590 p_spi = 0;
1592 p_ext = SADB_X_EXT_CYCSEQ;
1593 p_alg_enc = SADB_EALG_NONE;
1594 p_alg_auth = SADB_AALG_NONE;
1595 p_mode = IPSEC_MODE_ANY;
1596 p_reqid = 0;
1597 p_replay = 0;
1598 p_key_enc_len = p_key_auth_len = 0;
1599 p_key_enc = p_key_auth = 0;
1600 p_lt_hard = p_lt_soft = 0;
1601 p_lb_hard = p_lb_soft = 0;
1603 memset(&sec_ctx, 0, sizeof(struct security_ctx));
1605 p_aiflags = 0;
1606 p_aifamily = PF_UNSPEC;
1608 /* Clear out any natt OA information */
1609 if (p_natt_oa)
1610 freeaddrinfo (p_natt_oa);
1611 p_natt_oa = NULL;
1612 p_natt_type = 0;
1614 return;
1617 void
1618 free_buffer()
1620 /* we got tons of memory leaks in the parser anyways, leave them */
1622 return;