userland - Port TCP-MD5 (RFC 2385) implementation.
[dragonfly.git] / usr.sbin / setkey / parse.y
CommitLineData
984263bc 1/* $FreeBSD: src/usr.sbin/setkey/parse.y,v 1.1.2.2 2001/07/03 11:02:17 ume Exp $ */
25389281 2/* $DragonFly: src/usr.sbin/setkey/parse.y,v 1.4 2004/03/24 18:23:46 cpressey Exp $ */
984263bc
MD
3/* $KAME: kame/kame/kame/setkey/parse.y,v 1.36 2001/06/07 15:53:12 sakane Exp $ */
4
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 <netkey/key_var.h>
43#include <netinet6/ipsec.h>
44#include <arpa/inet.h>
45
46#include <string.h>
47#include <unistd.h>
48#include <stdio.h>
49#include <netdb.h>
50#include <ctype.h>
51#include <errno.h>
52
53#include "libpfkey.h"
54#include "vchar.h"
55
56#define ATOX(c) \
57 (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) ))
58
59u_int p_type;
60u_int32_t p_spi;
61int p_no_spi;
62struct sockaddr *p_src, *p_dst;
63u_int p_prefs, p_prefd, p_upper;
64u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
65u_int32_t p_reqid;
66u_int p_key_enc_len, p_key_auth_len;
67caddr_t p_key_enc, p_key_auth;
68time_t p_lt_hard, p_lt_soft;
69
70u_int p_policy_len;
71char *p_policy;
72
73/* temporary buffer */
74static struct sockaddr *pp_addr;
75static u_int pp_prefix;
76static u_int pp_port;
77static caddr_t pp_key;
78
79extern u_char m_buf[BUFSIZ];
80extern int m_len;
81extern char cmdarg[8192];
82extern int f_debug;
83
2d8a3be7
EN
84static struct addrinfo *parse_addr(char *, char *, int);
85static int setvarbuf(int *, struct sadb_ext *, int, caddr_t, int);
86void parse_init(void);
87void free_buffer(void);
984263bc 88
2d8a3be7
EN
89extern int setkeymsg(void);
90extern int sendkeymsg(void);
984263bc 91
2d8a3be7
EN
92extern int yylex(void);
93extern void yyfatal(const char *);
94extern void yyerror(const char *);
984263bc
MD
95%}
96
97%union {
98 unsigned long num;
99 vchar_t val;
100}
101
102%token EOT
27815e47 103%token ADD GET DELETE DELETEALL FLUSH DUMP
984263bc 104%token ADDRESS PREFIX PORT PORTANY
51006084 105%token UP_PROTO PR_ESP PR_AH PR_IPCOMP PR_TCP
984263bc
MD
106%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
107%token F_MODE MODE F_REQID
108%token F_EXT EXTENSION NOCYCLICSEQ
109%token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
110%token F_LIFETIME_HARD F_LIFETIME_SOFT
111%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
112 /* SPD management */
113%token SPDADD SPDDELETE SPDDUMP SPDFLUSH
114%token F_POLICY PL_REQUESTS
115
116%type <num> PORT PREFIX EXTENSION MODE
51006084 117%type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP PR_TCP
984263bc
MD
118%type <num> ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
119%type <num> DECSTRING
120%type <val> ADDRESS PL_REQUESTS
121%type <val> key_string policy_requests
122%type <val> QUOTEDSTRING HEXSTRING STRING
123
124%%
125commands
126 : /*NOTHING*/
127 | commands command
128 {
129 if (f_debug) {
130 printf("cmdarg:\n%s\n", cmdarg);
131 } else {
132 setkeymsg();
133 sendkeymsg();
134 }
135 free_buffer();
136 parse_init();
137 }
138 ;
139
140command
141 : add_command
142 | get_command
143 | delete_command
144 | deleteall_command
145 | flush_command
146 | dump_command
147 | spdadd_command
148 | spddelete_command
149 | spddump_command
150 | spdflush_command
151 ;
152 /* commands concerned with management, there is in tail of this file. */
153
154 /* add command */
155add_command
156 : ADD { p_type = SADB_ADD; }
157 sa_selector_spec extension_spec algorithm_spec EOT
158 ;
159
160 /* delete */
161delete_command
162 : DELETE { p_type = SADB_DELETE; }
163 sa_selector_spec extension_spec
164 {
165 if (p_mode != IPSEC_MODE_ANY)
166 yyerror("WARNING: mode is obsoleted.");
167 }
168 EOT
169 ;
170
171 /* deleteall command */
172deleteall_command
173 : DELETEALL { p_type = SADB_DELETE; }
174 ipaddress { p_src = pp_addr; }
175 ipaddress { p_dst = pp_addr; }
176 protocol_spec
177 { p_no_spi = 1; }
178 EOT
179 ;
180
181 /* get command */
182get_command
183 : GET { p_type = SADB_GET; }
184 sa_selector_spec extension_spec
185 {
186 if (p_mode != IPSEC_MODE_ANY)
187 yyerror("WARNING: mode is obsoleted.");
188 }
189 EOT
190 ;
191
192 /* flush */
193flush_command
194 : FLUSH { p_type = SADB_FLUSH; }
195 protocol_spec EOT
196 ;
197
198 /* dump */
199dump_command
200 : DUMP { p_type = SADB_DUMP; }
201 protocol_spec EOT
202 ;
203
204 /* sa_selector_spec */
205sa_selector_spec
206 : ipaddress { p_src = pp_addr; }
207 ipaddress { p_dst = pp_addr; }
208 protocol_spec spi
209 ;
210
211protocol_spec
212 : /*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; }
213 | PR_ESP
214 {
215 p_satype = SADB_SATYPE_ESP;
216 if ($1 == 1)
217 p_ext |= SADB_X_EXT_OLD;
218 else
219 p_ext &= ~SADB_X_EXT_OLD;
220 }
221 | PR_AH
222 {
223 p_satype = SADB_SATYPE_AH;
224 if ($1 == 1)
225 p_ext |= SADB_X_EXT_OLD;
226 else
227 p_ext &= ~SADB_X_EXT_OLD;
228 }
229 | PR_IPCOMP
230 {
231 p_satype = SADB_X_SATYPE_IPCOMP;
232 }
51006084
MD
233 | PR_TCP
234 {
235 p_satype = SADB_X_SATYPE_TCPSIGNATURE;
236 }
984263bc
MD
237 ;
238
239spi
240 : DECSTRING { p_spi = $1; }
241 | HEXSTRING
242 {
243 caddr_t bp;
244 caddr_t yp = $1.buf;
245 char buf0[4], buf[4];
246 int i, j;
247
248 /* sanity check */
249 if ($1.len > 4) {
250 yyerror("SPI too big.");
251 free($1.buf);
252 return -1;
253 }
254
255 bp = buf0;
256 while (*yp) {
257 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
258 yp += 2, bp++;
259 }
260
261 /* initialize */
262 for (i = 0; i < 4; i++) buf[i] = 0;
263
264 for (j = $1.len - 1, i = 3; j >= 0; j--, i--)
265 buf[i] = buf0[j];
266
267 /* XXX: endian */
268 p_spi = ntohl(*(u_int32_t *)buf);
269
270 free($1.buf);
271 }
272 ;
273
274algorithm_spec
275 : esp_spec
276 | ah_spec
277 | ipcomp_spec
278 ;
279
280esp_spec
281 : F_ENC enc_alg enc_key F_AUTH auth_alg auth_key
282 | F_ENC enc_alg enc_key
283 ;
284
285ah_spec
286 : F_AUTH auth_alg auth_key
287 ;
288
289ipcomp_spec
290 : F_COMP ALG_COMP { p_alg_enc = $2; }
291 | F_COMP ALG_COMP { p_alg_enc = $2; }
292 F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; }
293 ;
294
295enc_alg
296 : ALG_ENC { p_alg_enc = $1; }
297 | ALG_ENC_DESDERIV
298 {
299 p_alg_enc = $1;
300 if (p_ext & SADB_X_EXT_OLD) {
301 yyerror("algorithm mismatched.");
302 return -1;
303 }
304 p_ext |= SADB_X_EXT_DERIV;
305 }
306 | ALG_ENC_DES32IV
307 {
308 p_alg_enc = $1;
309 if (!(p_ext & SADB_X_EXT_OLD)) {
310 yyerror("algorithm mismatched.");
311 return -1;
312 }
313 p_ext |= SADB_X_EXT_IV4B;
314 }
315 ;
316
317enc_key
318 : /*NOTHING*/
319 {
320 if (p_alg_enc != SADB_EALG_NULL) {
321 yyerror("no key found.");
322 return -1;
323 }
324 }
325 | key_string
326 {
327 p_key_enc_len = $1.len;
328 p_key_enc = pp_key;
329
330 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
331 p_alg_enc,
332 PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
333 yyerror(ipsec_strerror());
334 return -1;
335 }
336 }
337 ;
338
339auth_alg
340 : ALG_AUTH { p_alg_auth = $1; }
341 ;
342
343auth_key
344 : /*NOTHING*/
345 {
346 if (p_alg_auth != SADB_X_AALG_NULL) {
347 yyerror("no key found.");
348 return -1;
349 }
350 }
351 | key_string
352 {
353 p_key_auth_len = $1.len;
354 p_key_auth = pp_key;
355
51006084
MD
356 if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
357 if ((p_key_auth_len < 1) || (p_key_auth_len >
358 80))
359 return -1;
360 } else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
984263bc
MD
361 p_alg_auth,
362 PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
363 yyerror(ipsec_strerror());
364 return -1;
365 }
366 }
367 ;
368
369key_string
370 : QUOTEDSTRING
371 {
372 pp_key = $1.buf;
373 /* free pp_key later */
374 }
375 | HEXSTRING
376 {
377 caddr_t bp;
378 caddr_t yp = $1.buf;
379
380 if ((pp_key = malloc($1.len)) == 0) {
381 free($1.buf);
382 yyerror("not enough core");
383 return -1;
384 }
385 memset(pp_key, 0, $1.len);
386
387 bp = pp_key;
388 while (*yp) {
389 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
390 yp += 2, bp++;
391 }
392
393 free($1.buf);
394 }
395 ;
396
397extension_spec
398 : /*NOTHING*/
399 | extension_spec extension
400 ;
401
402extension
403 : F_EXT EXTENSION { p_ext |= $2; }
404 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
405 | F_MODE MODE { p_mode = $2; }
406 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
407 | F_REQID DECSTRING { p_reqid = $2; }
408 | F_REPLAY DECSTRING
409 {
410 if (p_ext & SADB_X_EXT_OLD) {
411 yyerror("replay prevention "
412 "only use on new spec.");
413 return -1;
414 }
415 p_replay = $2;
416 }
417 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
418 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
419 ;
420
421 /* definition about command for SPD management */
422 /* spdadd */
423spdadd_command
424 : SPDADD
425 {
426 p_type = SADB_X_SPDADD;
427 p_satype = SADB_SATYPE_UNSPEC;
428 }
429 sp_selector_spec policy_spec EOT
430 ;
431
432spddelete_command:
433 SPDDELETE
434 {
435 p_type = SADB_X_SPDDELETE;
436 p_satype = SADB_SATYPE_UNSPEC;
437 }
438 sp_selector_spec policy_spec EOT
439 ;
440
441spddump_command:
442 SPDDUMP
443 {
444 p_type = SADB_X_SPDDUMP;
445 p_satype = SADB_SATYPE_UNSPEC;
446 }
447 EOT
448 ;
449
450spdflush_command:
451 SPDFLUSH
452 {
453 p_type = SADB_X_SPDFLUSH;
454 p_satype = SADB_SATYPE_UNSPEC;
455 }
456 EOT
457 ;
458
459 /* sp_selector_spec */
460sp_selector_spec
461 : ipaddress { p_src = pp_addr; }
462 prefix { p_prefs = pp_prefix; }
463 port
464 {
465 switch (p_src->sa_family) {
466 case AF_INET:
467 ((struct sockaddr_in *)p_src)->sin_port =
468 htons(pp_port);
469 break;
470#ifdef INET6
471 case AF_INET6:
472 ((struct sockaddr_in6 *)p_src)->sin6_port =
473 htons(pp_port);
474 break;
475#endif
476 default:
477 exit(1); /*XXX*/
478 }
479 }
480 ipaddress { p_dst = pp_addr; }
481 prefix { p_prefd = pp_prefix; }
482 port
483 {
484 switch (p_dst->sa_family) {
485 case AF_INET:
486 ((struct sockaddr_in *)p_dst)->sin_port =
487 htons(pp_port);
488 break;
489#ifdef INET6
490 case AF_INET6:
491 ((struct sockaddr_in6 *)p_dst)->sin6_port =
492 htons(pp_port);
493 break;
494#endif
495 default:
496 exit(1); /*XXX*/
497 }
498 }
499 upper_spec
500 {
501 /* XXX is it something userland should check? */
502#if 0
503 switch (p_upper) {
504 case IPPROTO_ICMP:
505 case IPPROTO_ICMPV6:
506 if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY
507 || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) {
508 yyerror("port number must be \"any\".");
509 return -1;
510 }
511 if ((pp_addr->sa_family == AF_INET6
512 && p_upper == IPPROTO_ICMP)
513 || (pp_addr->sa_family == AF_INET
514 && p_upper == IPPROTO_ICMPV6)) {
515 yyerror("upper layer protocol "
516 "mismatched.\n");
517 return -1;
518 }
519 break;
520 default:
521 break;
522 }
523#endif
524 }
525 ;
526
527ipaddress
528 : ADDRESS
529 {
530 struct addrinfo *res;
531
532 res = parse_addr($1.buf, NULL, AI_NUMERICHOST);
533 if (res == NULL) {
534 free($1.buf);
535 return -1;
536 }
537 pp_addr = (struct sockaddr *)malloc(res->ai_addrlen);
538 if (!pp_addr) {
539 yyerror("not enough core");
540 goto end;
541 }
542
543 memcpy(pp_addr, res->ai_addr, res->ai_addrlen);
544 end:
545 freeaddrinfo(res);
546 free($1.buf);
547 }
548 ;
549
550prefix
551 : /*NOTHING*/ { pp_prefix = ~0; }
552 | PREFIX { pp_prefix = $1; }
553 ;
554
555port
556 : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; }
557 | PORT { pp_port = $1; }
558 | PORTANY { pp_port = IPSEC_PORT_ANY; }
559 ;
560
561upper_spec
562 : DECSTRING { p_upper = $1; }
563 | UP_PROTO { p_upper = $1; }
564 | ANY { p_upper = IPSEC_ULPROTO_ANY; }
565 | STRING
566 {
567 struct protoent *ent;
568
569 ent = getprotobyname($1.buf);
570 if (ent)
571 p_upper = ent->p_proto;
572 else {
573 if (strcmp("icmp6", $1.buf) == 0) {
574 p_upper = IPPROTO_ICMPV6;
575 } else if(strcmp("ip4", $1.buf) == 0) {
576 p_upper = IPPROTO_IPV4;
577 } else {
578 yyerror("invalid upper layer protocol");
579 free($1.buf);
580 return -1;
581 }
582 }
583 free($1.buf);
584 }
585 ;
586
587policy_spec
588 : F_POLICY policy_requests
589 {
590 p_policy = ipsec_set_policy($2.buf, $2.len);
591 if (p_policy == NULL) {
592 free($2.buf);
593 p_policy = NULL;
594 yyerror(ipsec_strerror());
595 return -1;
596 }
597
598 p_policy_len = ipsec_get_policylen(p_policy);
599
600 free($2.buf);
601 }
602 ;
603
604policy_requests
605 : PL_REQUESTS { $$ = $1; }
606 ;
607
608%%
609
610int
25389281 611setkeymsg(void)
984263bc
MD
612{
613 struct sadb_msg m_msg;
614
615 m_msg.sadb_msg_version = PF_KEY_V2;
616 m_msg.sadb_msg_type = p_type;
617 m_msg.sadb_msg_errno = 0;
618 m_msg.sadb_msg_satype = p_satype;
619 m_msg.sadb_msg_reserved = 0;
620 m_msg.sadb_msg_seq = 0;
621 m_msg.sadb_msg_pid = getpid();
622
623 m_len = sizeof(struct sadb_msg);
624 memcpy(m_buf, &m_msg, m_len);
625
626 switch (p_type) {
627 case SADB_FLUSH:
628 case SADB_DUMP:
629 break;
630
631 case SADB_ADD:
632 /* set encryption algorithm, if present. */
633 if (p_satype != SADB_X_SATYPE_IPCOMP && p_alg_enc != SADB_EALG_NONE) {
634 struct sadb_key m_key;
635
636 m_key.sadb_key_len =
637 PFKEY_UNIT64(sizeof(m_key)
638 + PFKEY_ALIGN8(p_key_enc_len));
639 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
640 m_key.sadb_key_bits = p_key_enc_len * 8;
641 m_key.sadb_key_reserved = 0;
642
643 setvarbuf(&m_len,
644 (struct sadb_ext *)&m_key, sizeof(m_key),
645 (caddr_t)p_key_enc, p_key_enc_len);
646 }
647
648 /* set authentication algorithm, if present. */
649 if (p_alg_auth != SADB_AALG_NONE) {
650 struct sadb_key m_key;
651
652 m_key.sadb_key_len =
653 PFKEY_UNIT64(sizeof(m_key)
654 + PFKEY_ALIGN8(p_key_auth_len));
655 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
656 m_key.sadb_key_bits = p_key_auth_len * 8;
657 m_key.sadb_key_reserved = 0;
658
659 setvarbuf(&m_len,
660 (struct sadb_ext *)&m_key, sizeof(m_key),
661 (caddr_t)p_key_auth, p_key_auth_len);
662 }
663
664 /* set lifetime for HARD */
665 if (p_lt_hard != 0) {
666 struct sadb_lifetime m_lt;
667 u_int len = sizeof(struct sadb_lifetime);
668
669 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len);
670 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
671 m_lt.sadb_lifetime_allocations = 0;
672 m_lt.sadb_lifetime_bytes = 0;
673 m_lt.sadb_lifetime_addtime = p_lt_hard;
674 m_lt.sadb_lifetime_usetime = 0;
675
676 memcpy(m_buf + m_len, &m_lt, len);
677 m_len += len;
678 }
679
680 /* set lifetime for SOFT */
681 if (p_lt_soft != 0) {
682 struct sadb_lifetime m_lt;
683 u_int len = sizeof(struct sadb_lifetime);
684
685 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len);
686 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
687 m_lt.sadb_lifetime_allocations = 0;
688 m_lt.sadb_lifetime_bytes = 0;
689 m_lt.sadb_lifetime_addtime = p_lt_soft;
690 m_lt.sadb_lifetime_usetime = 0;
691
692 memcpy(m_buf + m_len, &m_lt, len);
693 m_len += len;
694 }
695 /* FALLTHROUGH */
696
697 case SADB_DELETE:
698 case SADB_GET:
699 {
700 struct sadb_sa m_sa;
701 struct sadb_x_sa2 m_sa2;
702 struct sadb_address m_addr;
703 u_int len;
704
705 if (p_no_spi == 0) {
706 len = sizeof(struct sadb_sa);
707 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
708 m_sa.sadb_sa_exttype = SADB_EXT_SA;
709 m_sa.sadb_sa_spi = htonl(p_spi);
710 m_sa.sadb_sa_replay = p_replay;
711 m_sa.sadb_sa_state = 0;
712 m_sa.sadb_sa_auth = p_alg_auth;
713 m_sa.sadb_sa_encrypt = p_alg_enc;
714 m_sa.sadb_sa_flags = p_ext;
715
716 memcpy(m_buf + m_len, &m_sa, len);
717 m_len += len;
718
719 len = sizeof(struct sadb_x_sa2);
720 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
721 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
722 m_sa2.sadb_x_sa2_mode = p_mode;
723 m_sa2.sadb_x_sa2_reqid = p_reqid;
724
725 memcpy(m_buf + m_len, &m_sa2, len);
726 m_len += len;
727 }
728
729 /* set src */
730 m_addr.sadb_address_len =
731 PFKEY_UNIT64(sizeof(m_addr)
732 + PFKEY_ALIGN8(p_src->sa_len));
733 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
734 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
735 switch (p_src->sa_family) {
736 case AF_INET:
737 m_addr.sadb_address_prefixlen =
738 sizeof(struct in_addr) << 3;
739 break;
740#ifdef INET6
741 case AF_INET6:
742 m_addr.sadb_address_prefixlen =
743 sizeof(struct in6_addr) << 3;
744 break;
745#endif
746 default:
747 yyerror("unsupported address family");
748 exit(1); /*XXX*/
749 }
750 m_addr.sadb_address_reserved = 0;
751
752 setvarbuf(&m_len,
753 (struct sadb_ext *)&m_addr, sizeof(m_addr),
754 (caddr_t)p_src, p_src->sa_len);
755
756 /* set dst */
757 m_addr.sadb_address_len =
758 PFKEY_UNIT64(sizeof(m_addr)
759 + PFKEY_ALIGN8(p_dst->sa_len));
760 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
761 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
762 switch (p_dst->sa_family) {
763 case AF_INET:
764 m_addr.sadb_address_prefixlen =
765 sizeof(struct in_addr) << 3;
766 break;
767#ifdef INET6
768 case AF_INET6:
769 m_addr.sadb_address_prefixlen =
770 sizeof(struct in6_addr) << 3;
771 break;
772#endif
773 default:
774 yyerror("unsupported address family");
775 exit(1); /*XXX*/
776 }
777 m_addr.sadb_address_reserved = 0;
778
779 setvarbuf(&m_len,
780 (struct sadb_ext *)&m_addr, sizeof(m_addr),
781 (caddr_t)p_dst, p_dst->sa_len);
782 }
783 break;
784
785 /* for SPD management */
786 case SADB_X_SPDFLUSH:
787 case SADB_X_SPDDUMP:
788 break;
789
790 case SADB_X_SPDADD:
791 case SADB_X_SPDDELETE:
792 {
793 struct sadb_address m_addr;
794 u_int8_t plen;
795
796 memcpy(m_buf + m_len, p_policy, p_policy_len);
797 m_len += p_policy_len;
798 free(p_policy);
799 p_policy = NULL;
800
801 /* set src */
802 m_addr.sadb_address_len =
803 PFKEY_UNIT64(sizeof(m_addr)
804 + PFKEY_ALIGN8(p_src->sa_len));
805 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
806 m_addr.sadb_address_proto = p_upper;
807 switch (p_src->sa_family) {
808 case AF_INET:
809 plen = sizeof(struct in_addr) << 3;
810 break;
811#ifdef INET6
812 case AF_INET6:
813 plen = sizeof(struct in6_addr) << 3;
814 break;
815#endif
816 default:
817 yyerror("unsupported address family");
818 exit(1); /*XXX*/
819 }
820 m_addr.sadb_address_prefixlen =
821 (p_prefs != ~0 ? p_prefs : plen);
822 m_addr.sadb_address_reserved = 0;
823
824 setvarbuf(&m_len,
825 (struct sadb_ext *)&m_addr, sizeof(m_addr),
826 (caddr_t)p_src, p_src->sa_len);
827
828 /* set dst */
829 m_addr.sadb_address_len =
830 PFKEY_UNIT64(sizeof(m_addr)
831 + PFKEY_ALIGN8(p_dst->sa_len));
832 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
833 m_addr.sadb_address_proto = p_upper;
834 switch (p_dst->sa_family) {
835 case AF_INET:
836 plen = sizeof(struct in_addr) << 3;
837 break;
838#ifdef INET6
839 case AF_INET6:
840 plen = sizeof(struct in6_addr) << 3;
841 break;
842#endif
843 default:
844 yyerror("unsupported address family");
845 exit(1); /*XXX*/
846 }
847 m_addr.sadb_address_prefixlen =
848 (p_prefd != ~0 ? p_prefd : plen);
849 m_addr.sadb_address_reserved = 0;
850
851 setvarbuf(&m_len,
852 (struct sadb_ext *)&m_addr, sizeof(m_addr),
853 (caddr_t)p_dst, p_dst->sa_len);
854 }
855 break;
856 }
857
858 ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len);
859
860 return 0;
861}
862
863static struct addrinfo *
25389281 864parse_addr(char *host, char *port, int flag)
984263bc
MD
865{
866 struct addrinfo hints, *res = NULL;
867 int error;
868
869 memset(&hints, 0, sizeof(hints));
870 hints.ai_family = PF_UNSPEC;
871 hints.ai_socktype = SOCK_DGRAM;
872 hints.ai_flags = flag;
873 error = getaddrinfo(host, port, &hints, &res);
874 if (error != 0) {
875 yyerror(gai_strerror(error));
876 return NULL;
877 }
878 if (res->ai_next != NULL) {
879 yyerror(gai_strerror(error));
880 }
881 return res;
882}
883
884static int
25389281 885setvarbuf(int *off, struct sadb_ext *ebuf, int elen, caddr_t vbuf, int vlen)
984263bc
MD
886{
887 memset(m_buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
888 memcpy(m_buf + *off, (caddr_t)ebuf, elen);
889 memcpy(m_buf + *off + elen, vbuf, vlen);
890 (*off) += PFKEY_ALIGN8(elen + vlen);
891
892 return 0;
893}
894
895void
25389281 896parse_init(void)
984263bc
MD
897{
898 p_type = 0;
899 p_spi = 0;
900 p_no_spi = 0;
901
902 p_src = 0, p_dst = 0;
903 pp_prefix = p_prefs = p_prefd = ~0;
904 pp_port = IPSEC_PORT_ANY;
905 p_upper = 0;
906
907 p_satype = 0;
908 p_ext = SADB_X_EXT_CYCSEQ;
909 p_alg_enc = SADB_EALG_NONE;
910 p_alg_auth = SADB_AALG_NONE;
911 p_mode = IPSEC_MODE_ANY;
912 p_reqid = 0;
913 p_replay = 0;
914 p_key_enc_len = p_key_auth_len = 0;
915 p_key_enc = p_key_auth = 0;
916 p_lt_hard = p_lt_soft = 0;
917
918 p_policy_len = 0;
919 p_policy = NULL;
920
921 memset(cmdarg, 0, sizeof(cmdarg));
922
923 return;
924}
925
926void
25389281 927free_buffer(void)
984263bc
MD
928{
929 if (p_src) free(p_src);
930 if (p_dst) free(p_dst);
931 if (p_key_enc) free(p_key_enc);
932 if (p_key_auth) free(p_key_auth);
933
934 return;
935}
936