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