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