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