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