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