]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/setkey/parse.y
ipsec-146.1.tar.gz
[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 "libpfkey.h"
60 #include "vchar.h"
61 #include "extern.h"
62
63 #define DEFAULT_NATT_PORT 4500
64
65 #ifndef UDP_ENCAP_ESPINUDP
66 #define UDP_ENCAP_ESPINUDP 2
67 #endif
68
69 #define ATOX(c) \
70 (isdigit((int)c) ? (c - '0') : \
71 (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10)))
72
73 u_int32_t p_spi;
74 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
75 u_int32_t p_reqid;
76 u_int p_key_enc_len, p_key_auth_len;
77 const char *p_key_enc;
78 const char *p_key_auth;
79 time_t p_lt_hard, p_lt_soft;
80 size_t p_lb_hard, p_lb_soft;
81
82 static u_int p_natt_type;
83 static struct addrinfo * p_natt_oa = NULL;
84
85 static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
86
87 static struct addrinfo *parse_addr __P((char *, char *));
88 static int fix_portstr __P((vchar_t *, vchar_t *, vchar_t *));
89 static int setvarbuf __P((char *, int *, struct sadb_ext *, int,
90 const void *, int));
91 void parse_init __P((void));
92 void free_buffer __P((void));
93
94 int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t));
95 static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *,
96 struct addrinfo *, int, struct addrinfo *, int));
97 static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *));
98 static int setkeymsg_addr __P((unsigned int, unsigned int,
99 struct addrinfo *, struct addrinfo *, int));
100 static int setkeymsg_add __P((unsigned int, unsigned int,
101 struct addrinfo *, struct addrinfo *));
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 %%
144 commands
145 : /*NOTHING*/
146 | commands command
147 {
148 free_buffer();
149 parse_init();
150 }
151 ;
152
153 command
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 */
169 add_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 */
181 delete_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 */
200 deleteall_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 */
212 get_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 */
227 flush_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 */
237 dump_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
246 protocol_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
293 spi
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
315 algorithm_spec
316 : esp_spec
317 | ah_spec
318 | ipcomp_spec
319 ;
320
321 esp_spec
322 : F_ENC enc_alg F_AUTH auth_alg
323 | F_ENC enc_alg
324 ;
325
326 ah_spec
327 : F_AUTH auth_alg
328 ;
329
330 ipcomp_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
350 enc_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
441 auth_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
479 key_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
513 extension_spec
514 : /*NOTHING*/
515 | extension_spec extension
516 ;
517
518 extension
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 */
541 spdadd_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
592 spddelete_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
630 spddump_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
640 spdflush_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
651 ipaddropts
652 : /* nothing */
653 | ipaddropts ipaddropt
654 ;
655
656 ipaddropt
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
681 ipaddr
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
692 ipandport
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
711 prefix
712 : /*NOTHING*/ { $$ = -1; }
713 | SLASH DECSTRING { $$ = $2; }
714 ;
715
716 portstr
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
752 upper_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
779 upper_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
796 policy_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
820 policy_requests
821 : PL_REQUESTS { $$ = $1; }
822 ;
823
824 /* exit */
825 exit_command
826 : EXIT EOT
827 {
828 exit_now = 1;
829 YYACCEPT;
830 }
831 ;
832 %%
833
834 int
835 setkeymsg0(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! */
854 static int
855 setkeymsg_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;
865 char buf[BUFSIZ];
866 int l, l0;
867 struct sadb_address m_addr;
868 struct addrinfo *s, *d;
869 int n;
870 int plen;
871 struct sockaddr *sa;
872 int salen;
873 struct sadb_x_policy *sp;
874 #ifdef HAVE_POLICY_FWD
875 struct sadb_x_ipsecrequest *ps = NULL;
876 int saved_level, saved_id = 0;
877 #endif
878
879 msg = (struct sadb_msg *)buf;
880
881 if (!srcs || !dsts)
882 return -1;
883
884 /* fix up length afterwards */
885 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
886 l = sizeof(struct sadb_msg);
887
888 sp = (struct sadb_x_policy*) (buf + l);
889 memcpy(buf + l, policy->buf, policy->len);
890 l += policy->len;
891
892 l0 = l;
893 n = 0;
894
895 /* do it for all src/dst pairs */
896 for (s = srcs; s; s = s->ai_next) {
897 for (d = dsts; d; d = d->ai_next) {
898 /* rewind pointer */
899 l = l0;
900
901 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
902 continue;
903 switch (s->ai_addr->sa_family) {
904 case AF_INET:
905 plen = sizeof(struct in_addr) << 3;
906 break;
907 #ifdef INET6
908 case AF_INET6:
909 plen = sizeof(struct in6_addr) << 3;
910 break;
911 #endif
912 default:
913 continue;
914 }
915
916 /* set src */
917 sa = s->ai_addr;
918 salen = sysdep_sa_len(s->ai_addr);
919 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
920 PFKEY_ALIGN8(salen));
921 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
922 m_addr.sadb_address_proto = upper;
923 m_addr.sadb_address_prefixlen =
924 (splen >= 0 ? splen : plen);
925 m_addr.sadb_address_reserved = 0;
926
927 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
928 sizeof(m_addr), (caddr_t)sa, salen);
929
930 /* set dst */
931 sa = d->ai_addr;
932 salen = sysdep_sa_len(d->ai_addr);
933 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
934 PFKEY_ALIGN8(salen));
935 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
936 m_addr.sadb_address_proto = upper;
937 m_addr.sadb_address_prefixlen =
938 (dplen >= 0 ? dplen : plen);
939 m_addr.sadb_address_reserved = 0;
940
941 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
942 sizeof(m_addr), sa, salen);
943
944 msg->sadb_msg_len = PFKEY_UNIT64(l);
945
946 sendkeymsg(buf, l);
947
948 #ifdef HAVE_POLICY_FWD
949 /* create extra call for FWD policy */
950 if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) {
951 sp->sadb_x_policy_dir = IPSEC_DIR_FWD;
952 ps = (struct sadb_x_ipsecrequest*) (sp+1);
953
954 /* if request level is unique, change it to
955 * require for fwd policy */
956 /* XXX: currently, only first policy is updated
957 * only. Update following too... */
958 saved_level = ps->sadb_x_ipsecrequest_level;
959 if (saved_level == IPSEC_LEVEL_UNIQUE) {
960 saved_id = ps->sadb_x_ipsecrequest_reqid;
961 ps->sadb_x_ipsecrequest_reqid=0;
962 ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE;
963 }
964
965 sendkeymsg(buf, l);
966 /* restoring for next message */
967 sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
968 if (saved_level == IPSEC_LEVEL_UNIQUE) {
969 ps->sadb_x_ipsecrequest_reqid = saved_id;
970 ps->sadb_x_ipsecrequest_level = saved_level;
971 }
972 }
973 #endif
974
975 n++;
976 }
977 }
978
979 if (n == 0)
980 return -1;
981 else
982 return 0;
983 }
984
985 static int
986 setkeymsg_spdaddr_tag(type, tag, policy)
987 unsigned int type;
988 char *tag;
989 vchar_t *policy;
990 {
991 struct sadb_msg *msg;
992 char buf[BUFSIZ];
993 int l, l0;
994 #ifdef SADB_X_EXT_TAG
995 struct sadb_x_tag m_tag;
996 #endif
997 int n;
998
999 msg = (struct sadb_msg *)buf;
1000
1001 /* fix up length afterwards */
1002 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
1003 l = sizeof(struct sadb_msg);
1004
1005 memcpy(buf + l, policy->buf, policy->len);
1006 l += policy->len;
1007
1008 l0 = l;
1009 n = 0;
1010
1011 #ifdef SADB_X_EXT_TAG
1012 memset(&m_tag, 0, sizeof(m_tag));
1013 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag));
1014 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG;
1015 if (strlcpy(m_tag.sadb_x_tag_name, tag,
1016 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name))
1017 return -1;
1018 memcpy(buf + l, &m_tag, sizeof(m_tag));
1019 l += sizeof(m_tag);
1020 #endif
1021
1022 msg->sadb_msg_len = PFKEY_UNIT64(l);
1023
1024 sendkeymsg(buf, l);
1025
1026 return 0;
1027 }
1028
1029 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1030 static int
1031 setkeymsg_addr(type, satype, srcs, dsts, no_spi)
1032 unsigned int type;
1033 unsigned int satype;
1034 struct addrinfo *srcs;
1035 struct addrinfo *dsts;
1036 int no_spi;
1037 {
1038 struct sadb_msg *msg;
1039 char buf[BUFSIZ];
1040 int l, l0, len;
1041 struct sadb_sa m_sa;
1042 struct sadb_x_sa2 m_sa2;
1043 struct sadb_address m_addr;
1044 struct addrinfo *s, *d;
1045 int n;
1046 int plen;
1047 struct sockaddr *sa;
1048 int salen;
1049
1050 msg = (struct sadb_msg *)buf;
1051
1052 if (!srcs || !dsts)
1053 return -1;
1054
1055 /* fix up length afterwards */
1056 setkeymsg0(msg, type, satype, 0);
1057 l = sizeof(struct sadb_msg);
1058
1059 if (!no_spi) {
1060 len = sizeof(struct sadb_sa);
1061 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1062 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1063 m_sa.sadb_sa_spi = htonl(p_spi);
1064 m_sa.sadb_sa_replay = p_replay;
1065 m_sa.sadb_sa_state = 0;
1066 m_sa.sadb_sa_auth = p_alg_auth;
1067 m_sa.sadb_sa_encrypt = p_alg_enc;
1068 m_sa.sadb_sa_flags = p_ext;
1069
1070 memcpy(buf + l, &m_sa, len);
1071 l += len;
1072
1073 len = sizeof(struct sadb_x_sa2);
1074 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1075 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1076 m_sa2.sadb_x_sa2_mode = p_mode;
1077 m_sa2.sadb_x_sa2_reqid = p_reqid;
1078
1079 memcpy(buf + l, &m_sa2, len);
1080 l += len;
1081 }
1082
1083 l0 = l;
1084 n = 0;
1085
1086 /* do it for all src/dst pairs */
1087 for (s = srcs; s; s = s->ai_next) {
1088 for (d = dsts; d; d = d->ai_next) {
1089 /* rewind pointer */
1090 l = l0;
1091
1092 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1093 continue;
1094 switch (s->ai_addr->sa_family) {
1095 case AF_INET:
1096 plen = sizeof(struct in_addr) << 3;
1097 break;
1098 #ifdef INET6
1099 case AF_INET6:
1100 plen = sizeof(struct in6_addr) << 3;
1101 break;
1102 #endif
1103 default:
1104 continue;
1105 }
1106
1107 /* set src */
1108 sa = s->ai_addr;
1109 salen = sysdep_sa_len(s->ai_addr);
1110 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1111 PFKEY_ALIGN8(salen));
1112 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1113 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1114 m_addr.sadb_address_prefixlen = plen;
1115 m_addr.sadb_address_reserved = 0;
1116
1117 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1118 sizeof(m_addr), sa, salen);
1119
1120 /* set dst */
1121 sa = d->ai_addr;
1122 salen = sysdep_sa_len(d->ai_addr);
1123 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1124 PFKEY_ALIGN8(salen));
1125 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1126 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1127 m_addr.sadb_address_prefixlen = plen;
1128 m_addr.sadb_address_reserved = 0;
1129
1130 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1131 sizeof(m_addr), sa, salen);
1132
1133 msg->sadb_msg_len = PFKEY_UNIT64(l);
1134
1135 sendkeymsg(buf, l);
1136
1137 n++;
1138 }
1139 }
1140
1141 if (n == 0)
1142 return -1;
1143 else
1144 return 0;
1145 }
1146
1147 #ifdef SADB_X_EXT_NAT_T_TYPE
1148 static u_int16_t get_port (struct addrinfo *addr)
1149 {
1150 struct sockaddr *s = addr->ai_addr;
1151 u_int16_t port = 0;
1152
1153 switch (s->sa_family) {
1154 case AF_INET:
1155 {
1156 struct sockaddr_in *sin4 = (struct sockaddr_in *)s;
1157 port = ntohs(sin4->sin_port);
1158 break;
1159 }
1160 case AF_INET6:
1161 {
1162 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s;
1163 port = ntohs(sin6->sin6_port);
1164 break;
1165 }
1166 }
1167
1168 if (port == 0)
1169 port = DEFAULT_NATT_PORT;
1170
1171 return port;
1172 }
1173 #endif
1174
1175 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1176 static int
1177 setkeymsg_add(type, satype, srcs, dsts)
1178 unsigned int type;
1179 unsigned int satype;
1180 struct addrinfo *srcs;
1181 struct addrinfo *dsts;
1182 {
1183 struct sadb_msg *msg;
1184 char buf[BUFSIZ];
1185 int l, l0, len;
1186 struct sadb_sa m_sa;
1187 struct sadb_x_sa2 m_sa2;
1188 struct sadb_address m_addr;
1189 struct addrinfo *s, *d;
1190 int n;
1191 int plen;
1192 struct sockaddr *sa;
1193 int salen;
1194
1195 msg = (struct sadb_msg *)buf;
1196
1197 if (!srcs || !dsts)
1198 return -1;
1199
1200 /* fix up length afterwards */
1201 setkeymsg0(msg, type, satype, 0);
1202 l = sizeof(struct sadb_msg);
1203
1204 /* set encryption algorithm, if present. */
1205 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1206 union {
1207 struct sadb_key key;
1208 struct sadb_ext ext;
1209 } m;
1210
1211 m.key.sadb_key_len =
1212 PFKEY_UNIT64(sizeof(m.key)
1213 + PFKEY_ALIGN8(p_key_enc_len));
1214 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1215 m.key.sadb_key_bits = p_key_enc_len * 8;
1216 m.key.sadb_key_reserved = 0;
1217
1218 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1219 p_key_enc, p_key_enc_len);
1220 }
1221
1222 /* set authentication algorithm, if present. */
1223 if (p_key_auth) {
1224 union {
1225 struct sadb_key key;
1226 struct sadb_ext ext;
1227 } m;
1228
1229 m.key.sadb_key_len =
1230 PFKEY_UNIT64(sizeof(m.key)
1231 + PFKEY_ALIGN8(p_key_auth_len));
1232 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1233 m.key.sadb_key_bits = p_key_auth_len * 8;
1234 m.key.sadb_key_reserved = 0;
1235
1236 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1237 p_key_auth, p_key_auth_len);
1238 }
1239
1240 /* set lifetime for HARD */
1241 if (p_lt_hard != 0 || p_lb_hard != 0) {
1242 struct sadb_lifetime m_lt;
1243 u_int slen = sizeof(struct sadb_lifetime);
1244
1245 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1246 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1247 m_lt.sadb_lifetime_allocations = 0;
1248 m_lt.sadb_lifetime_bytes = p_lb_hard;
1249 m_lt.sadb_lifetime_addtime = p_lt_hard;
1250 m_lt.sadb_lifetime_usetime = 0;
1251
1252 memcpy(buf + l, &m_lt, slen);
1253 l += slen;
1254 }
1255
1256 /* set lifetime for SOFT */
1257 if (p_lt_soft != 0 || p_lb_soft != 0) {
1258 struct sadb_lifetime m_lt;
1259 u_int slen = sizeof(struct sadb_lifetime);
1260
1261 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1262 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1263 m_lt.sadb_lifetime_allocations = 0;
1264 m_lt.sadb_lifetime_bytes = p_lb_soft;
1265 m_lt.sadb_lifetime_addtime = p_lt_soft;
1266 m_lt.sadb_lifetime_usetime = 0;
1267
1268 memcpy(buf + l, &m_lt, slen);
1269 l += slen;
1270 }
1271
1272 len = sizeof(struct sadb_sa);
1273 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1274 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1275 m_sa.sadb_sa_spi = htonl(p_spi);
1276 m_sa.sadb_sa_replay = p_replay;
1277 m_sa.sadb_sa_state = 0;
1278 m_sa.sadb_sa_auth = p_alg_auth;
1279 m_sa.sadb_sa_encrypt = p_alg_enc;
1280 m_sa.sadb_sa_flags = p_ext;
1281
1282 memcpy(buf + l, &m_sa, len);
1283 l += len;
1284
1285 len = sizeof(struct sadb_x_sa2);
1286 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1287 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1288 m_sa2.sadb_x_sa2_mode = p_mode;
1289 m_sa2.sadb_x_sa2_reqid = p_reqid;
1290
1291 memcpy(buf + l, &m_sa2, len);
1292 l += len;
1293
1294 #ifdef SADB_X_EXT_NAT_T_TYPE
1295 if (p_natt_type) {
1296 struct sadb_x_nat_t_type natt_type;
1297
1298 len = sizeof(struct sadb_x_nat_t_type);
1299 memset(&natt_type, 0, len);
1300 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1301 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1302 natt_type.sadb_x_nat_t_type_type = p_natt_type;
1303
1304 memcpy(buf + l, &natt_type, len);
1305 l += len;
1306
1307 if (p_natt_oa) {
1308 sa = p_natt_oa->ai_addr;
1309 switch (sa->sa_family) {
1310 case AF_INET:
1311 plen = sizeof(struct in_addr) << 3;
1312 break;
1313 #ifdef INET6
1314 case AF_INET6:
1315 plen = sizeof(struct in6_addr) << 3;
1316 break;
1317 #endif
1318 default:
1319 return -1;
1320 }
1321 salen = sysdep_sa_len(sa);
1322 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1323 PFKEY_ALIGN8(salen));
1324 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA;
1325 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1326 m_addr.sadb_address_prefixlen = plen;
1327 m_addr.sadb_address_reserved = 0;
1328
1329 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1330 sizeof(m_addr), sa, salen);
1331 }
1332 }
1333 #endif
1334
1335 l0 = l;
1336 n = 0;
1337
1338 /* do it for all src/dst pairs */
1339 for (s = srcs; s; s = s->ai_next) {
1340 for (d = dsts; d; d = d->ai_next) {
1341 /* rewind pointer */
1342 l = l0;
1343
1344 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1345 continue;
1346 switch (s->ai_addr->sa_family) {
1347 case AF_INET:
1348 plen = sizeof(struct in_addr) << 3;
1349 break;
1350 #ifdef INET6
1351 case AF_INET6:
1352 plen = sizeof(struct in6_addr) << 3;
1353 break;
1354 #endif
1355 default:
1356 continue;
1357 }
1358
1359 /* set src */
1360 sa = s->ai_addr;
1361 salen = sysdep_sa_len(s->ai_addr);
1362 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1363 PFKEY_ALIGN8(salen));
1364 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1365 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1366 m_addr.sadb_address_prefixlen = plen;
1367 m_addr.sadb_address_reserved = 0;
1368
1369 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1370 sizeof(m_addr), sa, salen);
1371
1372 /* set dst */
1373 sa = d->ai_addr;
1374 salen = sysdep_sa_len(d->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_DST;
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(buf, &l, (struct sadb_ext *)&m_addr,
1383 sizeof(m_addr), sa, salen);
1384
1385 #ifdef SADB_X_EXT_NAT_T_TYPE
1386 if (p_natt_type) {
1387 struct sadb_x_nat_t_port natt_port;
1388
1389 /* NATT_SPORT */
1390 len = sizeof(struct sadb_x_nat_t_port);
1391 memset(&natt_port, 0, len);
1392 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1393 natt_port.sadb_x_nat_t_port_exttype =
1394 SADB_X_EXT_NAT_T_SPORT;
1395 natt_port.sadb_x_nat_t_port_port = htons(get_port(s));
1396
1397 memcpy(buf + l, &natt_port, len);
1398 l += len;
1399
1400 /* NATT_DPORT */
1401 natt_port.sadb_x_nat_t_port_exttype =
1402 SADB_X_EXT_NAT_T_DPORT;
1403 natt_port.sadb_x_nat_t_port_port = htons(get_port(d));
1404
1405 memcpy(buf + l, &natt_port, len);
1406 l += len;
1407 }
1408 #endif
1409 msg->sadb_msg_len = PFKEY_UNIT64(l);
1410
1411 sendkeymsg(buf, l);
1412
1413 n++;
1414 }
1415 }
1416
1417 if (n == 0)
1418 return -1;
1419 else
1420 return 0;
1421 }
1422
1423 static struct addrinfo *
1424 parse_addr(host, port)
1425 char *host;
1426 char *port;
1427 {
1428 struct addrinfo hints, *res = NULL;
1429 int error;
1430
1431 memset(&hints, 0, sizeof(hints));
1432 hints.ai_family = p_aifamily;
1433 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
1434 hints.ai_protocol = IPPROTO_UDP; /*dummy*/
1435 hints.ai_flags = p_aiflags;
1436 error = getaddrinfo(host, port, &hints, &res);
1437 if (error != 0) {
1438 yyerror(gai_strerror(error));
1439 return NULL;
1440 }
1441 return res;
1442 }
1443
1444 static int
1445 fix_portstr(spec, sport, dport)
1446 vchar_t *spec, *sport, *dport;
1447 {
1448 const char *p, *p2 = "0";
1449 char *q;
1450 u_int l;
1451
1452 l = 0;
1453 for (q = spec->buf; *q != ',' && *q != '\0' && l < spec->len; q++, l++)
1454 ;
1455 if (*q != '\0') {
1456 if (*q == ',') {
1457 *q = '\0';
1458 p2 = ++q;
1459 }
1460 for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1461 ;
1462 if (*p != '\0' || *p2 == '\0') {
1463 yyerror("invalid an upper layer protocol spec");
1464 return -1;
1465 }
1466 }
1467
1468 sport->buf = strdup(spec->buf);
1469 if (!sport->buf) {
1470 yyerror("insufficient memory");
1471 return -1;
1472 }
1473 sport->len = strlen(sport->buf);
1474 dport->buf = strdup(p2);
1475 if (!dport->buf) {
1476 yyerror("insufficient memory");
1477 return -1;
1478 }
1479 dport->len = strlen(dport->buf);
1480
1481 return 0;
1482 }
1483
1484 static int
1485 setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
1486 char *buf;
1487 int *off;
1488 struct sadb_ext *ebuf;
1489 int elen;
1490 const void *vbuf;
1491 int vlen;
1492 {
1493 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1494 memcpy(buf + *off, (caddr_t)ebuf, elen);
1495 memcpy(buf + *off + elen, vbuf, vlen);
1496 (*off) += PFKEY_ALIGN8(elen + vlen);
1497
1498 return 0;
1499 }
1500
1501 void
1502 parse_init()
1503 {
1504 p_spi = 0;
1505
1506 p_ext = SADB_X_EXT_CYCSEQ;
1507 p_alg_enc = SADB_EALG_NONE;
1508 p_alg_auth = SADB_AALG_NONE;
1509 p_mode = IPSEC_MODE_ANY;
1510 p_reqid = 0;
1511 p_replay = 0;
1512 p_key_enc_len = p_key_auth_len = 0;
1513 p_key_enc = p_key_auth = 0;
1514 p_lt_hard = p_lt_soft = 0;
1515 p_lb_hard = p_lb_soft = 0;
1516
1517 p_aiflags = 0;
1518 p_aifamily = PF_UNSPEC;
1519
1520 /* Clear out any natt OA information */
1521 if (p_natt_oa)
1522 freeaddrinfo (p_natt_oa);
1523 p_natt_oa = NULL;
1524 p_natt_type = 0;
1525
1526 return;
1527 }
1528
1529 void
1530 free_buffer()
1531 {
1532 /* we got tons of memory leaks in the parser anyways, leave them */
1533
1534 return;
1535 }