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