1 /* $NetBSD: parse.y,v 1.11 2008/12/29 12:54:33 mlelstv Exp $ */
3 /* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */
6 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <net/pfkeyv2.h>
46 #include <arpa/inet.h>
61 #define IPPROTO_MH 135
64 #define DEFAULT_NATT_PORT 4500
66 #ifndef UDP_ENCAP_ESPINUDP
67 #define UDP_ENCAP_ESPINUDP 2
71 (isdigit
((int)c
) ?
(c
- '0') : \
72 (isupper
((int)c
) ?
(c
- 'A' + 10) : (c
- 'a' + 10)))
75 u_int p_ext
, p_alg_enc
, p_alg_auth
, p_replay
, p_mode
;
77 u_int p_key_enc_len
, p_key_auth_len
;
78 const char *p_key_enc
;
79 const char *p_key_auth
;
80 time_t p_lt_hard
, p_lt_soft
;
81 size_t p_lb_hard
, p_lb_soft
;
90 struct security_ctx sec_ctx
;
92 static u_int p_natt_type
;
93 static struct addrinfo
* p_natt_oa
= NULL
;
95 static int p_aiflags
= 0, p_aifamily
= PF_UNSPEC
;
97 static struct addrinfo
*parse_addr __P
((char *, char *));
98 static int fix_portstr __P
((vchar_t
*, vchar_t
*, vchar_t
*));
99 static int setvarbuf __P
((char *, int *, struct sadb_ext
*, int,
101 void parse_init __P
((void));
102 void free_buffer __P
((void));
104 int setkeymsg0 __P
((struct sadb_msg
*, unsigned int, unsigned int, size_t));
105 static int setkeymsg_spdaddr __P
((unsigned int, unsigned int, vchar_t
*,
106 struct addrinfo
*, int, struct addrinfo
*, int));
107 static int setkeymsg_spdaddr_tag __P
((unsigned int, char *, vchar_t
*));
108 static int setkeymsg_addr __P
((unsigned int, unsigned int,
109 struct addrinfo
*, struct addrinfo
*, int));
110 static int setkeymsg_add __P
((unsigned int, unsigned int,
111 struct addrinfo
*, struct addrinfo
*));
118 struct addrinfo
*res
;
121 %token EOT SLASH BLCL ELCL
122 %token ADD GET DELETE DELETEALL FLUSH DUMP EXIT
123 %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
124 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
125 %token F_MODE MODE F_REQID
126 %token F_EXT EXTENSION NOCYCLICSEQ
127 %token ALG_AUTH ALG_AUTH_NOKEY
128 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
130 %token F_LIFETIME_HARD F_LIFETIME_SOFT
131 %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT
132 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
134 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
135 %token F_POLICY PL_REQUESTS
140 %type
<num
> prefix protocol_spec upper_spec
141 %type
<num
> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
142 %type
<num
> ALG_AUTH ALG_AUTH_NOKEY
144 %type
<num
> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
145 %type
<num
> EXTENSION MODE
146 %type
<ulnum
> DECSTRING
147 %type
<val
> PL_REQUESTS portstr key_string
148 %type
<val
> policy_requests
149 %type
<val
> QUOTEDSTRING HEXSTRING STRING
150 %type
<val
> F_AIFLAGS
151 %type
<val
> upper_misc_spec policy_spec
152 %type
<res
> ipaddr ipandport
177 /* commands concerned with management, there is in tail of this file. */
181 : ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
185 status
= setkeymsg_add
(SADB_ADD
, $5, $3, $4);
193 : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
197 if
($3->ai_next ||
$4->ai_next
) {
198 yyerror("multiple address specified");
201 if
(p_mode
!= IPSEC_MODE_ANY
)
202 yyerror("WARNING: mode is obsolete");
204 status
= setkeymsg_addr
(SADB_DELETE
, $5, $3, $4, 0);
210 /* deleteall command */
212 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
215 if
(setkeymsg_addr
(SADB_DELETE
, $5, $3, $4, 1) < 0)
217 #else /* __linux__ */
218 /* linux strictly adheres to RFC2367, and returns
219 * an error if we send an SADB_DELETE request without
220 * an SPI. Therefore, we must first retrieve a list
221 * of SPIs for all matching SADB entries, and then
222 * delete each one separately. */
226 spi
= sendkeymsg_spigrep
($5, $3, $4, &n
);
227 for
(i
= 0; i
< n
; i
++) {
229 if
(setkeymsg_addr
(SADB_DELETE
,
234 #endif /* __linux__ */
240 : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
244 if
(p_mode
!= IPSEC_MODE_ANY
)
245 yyerror("WARNING: mode is obsolete");
247 status
= setkeymsg_addr
(SADB_GET
, $5, $3, $4, 0);
255 : FLUSH protocol_spec EOT
258 setkeymsg0
(&msg
, SADB_FLUSH
, $2, sizeof
(msg
));
259 sendkeymsg
((char *)&msg
, sizeof
(msg
));
265 : DUMP protocol_spec EOT
268 setkeymsg0
(&msg
, SADB_DUMP
, $2, sizeof
(msg
));
269 sendkeymsg
((char *)&msg
, sizeof
(msg
));
276 $$
= SADB_SATYPE_UNSPEC
;
280 $$
= SADB_SATYPE_ESP
;
282 p_ext |
= SADB_X_EXT_OLD
;
284 p_ext
&= ~SADB_X_EXT_OLD
;
290 p_ext |
= SADB_X_EXT_OLD
;
292 p_ext
&= ~SADB_X_EXT_OLD
;
296 $$
= SADB_X_SATYPE_IPCOMP
;
300 $$
= SADB_SATYPE_ESP
;
301 p_ext
&= ~SADB_X_EXT_OLD
;
303 p_natt_type
= UDP_ENCAP_ESPINUDP
;
307 $$
= SADB_SATYPE_ESP
;
308 p_ext
&= ~SADB_X_EXT_OLD
;
310 p_natt_type
= UDP_ENCAP_ESPINUDP
;
314 #ifdef SADB_X_SATYPE_TCPSIGNATURE
315 $$
= SADB_X_SATYPE_TCPSIGNATURE
;
321 : DECSTRING
{ p_spi
= $1; }
328 v
= strtoul
($1.buf
, &ep
, 16);
330 yyerror("invalid SPI");
333 if
(v
& ~
0xffffffff) {
334 yyerror("SPI too big.");
349 : F_ENC enc_alg F_AUTH auth_alg
361 yyerror("unsupported algorithm");
366 | F_COMP ALG_COMP F_RAWCPI
369 yyerror("unsupported algorithm");
373 p_ext |
= SADB_X_EXT_RAWCPI
;
380 yyerror("unsupported algorithm");
387 if
(ipsec_check_keylen
(SADB_EXT_SUPPORTED_ENCRYPT
,
388 p_alg_enc
, PFKEY_UNUNIT64
(p_key_enc_len
)) < 0) {
389 yyerror(ipsec_strerror
());
393 | ALG_ENC key_string
{
395 yyerror("unsupported algorithm");
400 p_key_enc_len
= $2.len
;
402 if
(ipsec_check_keylen
(SADB_EXT_SUPPORTED_ENCRYPT
,
403 p_alg_enc
, PFKEY_UNUNIT64
(p_key_enc_len
)) < 0) {
404 yyerror(ipsec_strerror
());
410 yyerror("unsupported algorithm");
413 yyerror("WARNING: obsolete algorithm");
418 if
(ipsec_check_keylen
(SADB_EXT_SUPPORTED_ENCRYPT
,
419 p_alg_enc
, PFKEY_UNUNIT64
(p_key_enc_len
)) < 0) {
420 yyerror(ipsec_strerror
());
424 | ALG_ENC_DESDERIV key_string
427 yyerror("unsupported algorithm");
431 if
(p_ext
& SADB_X_EXT_OLD
) {
432 yyerror("algorithm mismatched");
435 p_ext |
= SADB_X_EXT_DERIV
;
437 p_key_enc_len
= $2.len
;
439 if
(ipsec_check_keylen
(SADB_EXT_SUPPORTED_ENCRYPT
,
440 p_alg_enc
, PFKEY_UNUNIT64
(p_key_enc_len
)) < 0) {
441 yyerror(ipsec_strerror
());
445 | ALG_ENC_DES32IV key_string
448 yyerror("unsupported algorithm");
452 if
(!(p_ext
& SADB_X_EXT_OLD
)) {
453 yyerror("algorithm mismatched");
456 p_ext |
= SADB_X_EXT_IV4B
;
458 p_key_enc_len
= $2.len
;
460 if
(ipsec_check_keylen
(SADB_EXT_SUPPORTED_ENCRYPT
,
461 p_alg_enc
, PFKEY_UNUNIT64
(p_key_enc_len
)) < 0) {
462 yyerror(ipsec_strerror
());
469 : ALG_AUTH key_string
{
471 yyerror("unsupported algorithm");
476 p_key_auth_len
= $2.len
;
478 #ifdef SADB_X_AALG_TCP_MD5
479 if
(p_alg_auth
== SADB_X_AALG_TCP_MD5
) {
480 if
((p_key_auth_len
< 1) ||
481 (p_key_auth_len
> 80))
486 if
(ipsec_check_keylen
(SADB_EXT_SUPPORTED_AUTH
,
488 PFKEY_UNUNIT64
(p_key_auth_len
)) < 0) {
489 yyerror(ipsec_strerror
());
496 yyerror("unsupported algorithm");
518 l
= strlen
(yp
) %
2 + strlen
(yp
) / 2;
519 if
((pp_key
= malloc
(l
)) == 0) {
520 yyerror("not enough core");
523 memset
(pp_key
, 0, l
);
526 if
(strlen
(yp
) %
2) {
531 *bp
= (ATOX
(yp
[0]) << 4) | ATOX
(yp
[1]);
542 | extension_spec extension
546 : F_EXT EXTENSION
{ p_ext |
= $2; }
547 | F_EXT NOCYCLICSEQ
{ p_ext
&= ~SADB_X_EXT_CYCSEQ
; }
548 | F_MODE MODE
{ p_mode
= $2; }
549 | F_MODE ANY
{ p_mode
= IPSEC_MODE_ANY
; }
550 | F_REQID DECSTRING
{ p_reqid
= $2; }
553 if
((p_ext
& SADB_X_EXT_OLD
) != 0) {
554 yyerror("replay prevention cannot be used with "
560 | F_LIFETIME_HARD DECSTRING
{ p_lt_hard
= $2; }
561 | F_LIFETIME_SOFT DECSTRING
{ p_lt_soft
= $2; }
562 | F_LIFEBYTE_HARD DECSTRING
{ p_lb_hard
= $2; }
563 | F_LIFEBYTE_SOFT DECSTRING
{ p_lb_soft
= $2; }
564 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING
{
567 sec_ctx.len
= $4.len
+1;
568 sec_ctx.buf
= $4.buf
;
572 /* definition about command for SPD management */
575 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
578 struct addrinfo
*src
, *dst
;
580 #ifdef HAVE_PFKEY_POLICY_PRIORITY
581 last_msg_type
= SADB_X_SPDADD
;
584 /* fixed port fields if ulp is icmp */
585 if
($10.buf
!= NULL
) {
586 if
(($9 != IPPROTO_ICMPV6
) &&
587 ($9 != IPPROTO_ICMP
) &&
592 if
(fix_portstr
(&$10, &$5, &$8))
596 src
= parse_addr
($3.buf
, $5.buf
);
597 dst
= parse_addr
($6.buf
, $8.buf
);
599 /* yyerror is already called */
602 if
(src
->ai_next || dst
->ai_next
) {
603 yyerror("multiple address specified");
609 status
= setkeymsg_spdaddr
(SADB_X_SPDADD
, $9, &$12,
616 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT
620 status
= setkeymsg_spdaddr_tag
(SADB_X_SPDADD
,
628 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
631 struct addrinfo
*src
, *dst
;
633 /* fixed port fields if ulp is icmp */
634 if
($10.buf
!= NULL
) {
635 if
(($9 != IPPROTO_ICMPV6
) &&
636 ($9 != IPPROTO_ICMP
) &&
641 if
(fix_portstr
(&$10, &$5, &$8))
645 src
= parse_addr
($3.buf
, $5.buf
);
646 dst
= parse_addr
($6.buf
, $8.buf
);
648 /* yyerror is already called */
651 if
(src
->ai_next || dst
->ai_next
) {
652 yyerror("multiple address specified");
658 status
= setkeymsg_spdaddr
(SADB_X_SPDDELETE
, $9, &$12,
671 setkeymsg0
(&msg
, SADB_X_SPDDUMP
, SADB_SATYPE_UNSPEC
,
673 sendkeymsg
((char *)&msg
, sizeof
(msg
));
682 setkeymsg0
(&msg
, SADB_X_SPDFLUSH
, SADB_SATYPE_UNSPEC
,
684 sendkeymsg
((char *)&msg
, sizeof
(msg
));
690 | ipaddropts ipaddropt
698 for
(p
= $1.buf
+ 1; *p
; p
++)
701 p_aifamily
= AF_INET
;
705 p_aifamily
= AF_INET6
;
709 p_aiflags
= AI_NUMERICHOST
;
712 yyerror("invalid flag");
721 $$
= parse_addr
($1.buf
, NULL
);
723 /* yyerror already called by parse_addr */
732 $$
= parse_addr
($1.buf
, NULL
);
734 /* yyerror already called by parse_addr */
740 $$
= parse_addr
($1.buf
, $2.buf
);
742 /* yyerror already called by parse_addr */
749 : /*NOTHING*/ { $$
= -1; }
750 | SLASH DECSTRING
{ $$
= $2; }
756 $$.buf
= strdup
("0");
758 yyerror("insufficient memory");
761 $$.len
= strlen
($$.buf
);
765 $$.buf
= strdup
("0");
767 yyerror("insufficient memory");
770 $$.len
= strlen
($$.buf
);
772 | BLCL DECSTRING ELCL
775 snprintf
(buf
, sizeof
(buf
), "%lu", $2);
776 $$.buf
= strdup
(buf
);
778 yyerror("insufficient memory");
781 $$.len
= strlen
($$.buf
);
790 : DECSTRING
{ $$
= $1; }
791 | ANY
{ $$
= IPSEC_ULPROTO_ANY
; }
797 struct protoent
*ent
;
799 ent
= getprotobyname
($1.buf
);
803 if
(strcmp
("icmp6", $1.buf
) == 0) {
805 } else if
(strcmp
("ip4", $1.buf
) == 0) {
808 yyerror("invalid upper layer protocol");
824 $$.buf
= strdup
($1.buf
);
826 yyerror("insufficient memory");
829 $$.len
= strlen
($$.buf
);
835 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING
{
838 sec_ctx.len
= $4.len
+1;
839 sec_ctx.buf
= $4.buf
;
844 : F_POLICY policy_requests
847 #ifdef HAVE_PFKEY_POLICY_PRIORITY
848 struct sadb_x_policy
*xpl
;
851 policy
= ipsec_set_policy
($2.buf
, $2.len
);
852 if
(policy
== NULL
) {
853 yyerror(ipsec_strerror
());
858 $$.len
= ipsec_get_policylen
(policy
);
860 #ifdef HAVE_PFKEY_POLICY_PRIORITY
861 xpl
= (struct sadb_x_policy
*) $$.buf
;
862 last_priority
= xpl
->sadb_x_policy_priority
;
868 : PL_REQUESTS
{ $$
= $1; }
882 setkeymsg0
(msg
, type
, satype
, l
)
883 struct sadb_msg
*msg
;
889 msg
->sadb_msg_version
= PF_KEY_V2
;
890 msg
->sadb_msg_type
= type
;
891 msg
->sadb_msg_errno
= 0;
892 msg
->sadb_msg_satype
= satype
;
893 msg
->sadb_msg_reserved
= 0;
894 msg
->sadb_msg_seq
= 0;
895 msg
->sadb_msg_pid
= getpid
();
896 msg
->sadb_msg_len
= PFKEY_UNIT64
(l
);
900 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
902 setkeymsg_spdaddr
(type
, upper
, policy
, srcs
, splen
, dsts
, dplen
)
906 struct addrinfo
*srcs
;
908 struct addrinfo
*dsts
;
911 struct sadb_msg
*msg
;
914 struct sadb_address m_addr
;
915 struct addrinfo
*s
, *d
;
920 struct sadb_x_policy
*sp
;
921 #ifdef HAVE_POLICY_FWD
922 struct sadb_x_ipsecrequest
*ps
= NULL
;
923 int saved_level
, saved_id
= 0;
926 msg
= (struct sadb_msg
*)buf
;
931 /* fix up length afterwards */
932 setkeymsg0
(msg
, type
, SADB_SATYPE_UNSPEC
, 0);
933 l
= sizeof
(struct sadb_msg
);
935 sp
= (struct sadb_x_policy
*) (buf
+ l
);
936 memcpy
(buf
+ l
, policy
->buf
, policy
->len
);
942 /* do it for all src/dst pairs */
943 for
(s
= srcs
; s
; s
= s
->ai_next
) {
944 for
(d
= dsts
; d
; d
= d
->ai_next
) {
948 if
(s
->ai_addr
->sa_family
!= d
->ai_addr
->sa_family
)
950 switch
(s
->ai_addr
->sa_family
) {
952 plen
= sizeof
(struct in_addr
) << 3;
956 plen
= sizeof
(struct in6_addr
) << 3;
965 salen
= sysdep_sa_len
(s
->ai_addr
);
966 m_addr.sadb_address_len
= PFKEY_UNIT64
(sizeof
(m_addr
) +
967 PFKEY_ALIGN8
(salen
));
968 m_addr.sadb_address_exttype
= SADB_EXT_ADDRESS_SRC
;
969 m_addr.sadb_address_proto
= upper
;
970 m_addr.sadb_address_prefixlen
=
971 (splen
>= 0 ? splen
: plen
);
972 m_addr.sadb_address_reserved
= 0;
974 setvarbuf
(buf
, &l
, (struct sadb_ext
*)&m_addr
,
975 sizeof
(m_addr
), (caddr_t
)sa
, salen
);
979 salen
= sysdep_sa_len
(d
->ai_addr
);
980 m_addr.sadb_address_len
= PFKEY_UNIT64
(sizeof
(m_addr
) +
981 PFKEY_ALIGN8
(salen
));
982 m_addr.sadb_address_exttype
= SADB_EXT_ADDRESS_DST
;
983 m_addr.sadb_address_proto
= upper
;
984 m_addr.sadb_address_prefixlen
=
985 (dplen
>= 0 ? dplen
: plen
);
986 m_addr.sadb_address_reserved
= 0;
988 setvarbuf
(buf
, &l
, (struct sadb_ext
*)&m_addr
,
989 sizeof
(m_addr
), sa
, salen
);
990 #ifdef SADB_X_EXT_SEC_CTX
991 /* Add security context label */
993 struct sadb_x_sec_ctx m_sec_ctx
;
994 u_int slen
= sizeof
(struct sadb_x_sec_ctx
);
996 memset
(&m_sec_ctx
, 0, slen
);
998 m_sec_ctx.sadb_x_sec_len
=
999 PFKEY_UNIT64
(slen
+ PFKEY_ALIGN8
(sec_ctx.len
));
1001 m_sec_ctx.sadb_x_sec_exttype
=
1003 m_sec_ctx.sadb_x_ctx_len
= sec_ctx.len
;/*bytes*/
1004 m_sec_ctx.sadb_x_ctx_doi
= sec_ctx.doi
;
1005 m_sec_ctx.sadb_x_ctx_alg
= sec_ctx.alg
;
1007 (struct sadb_ext
*)&m_sec_ctx
, slen
,
1008 (caddr_t
)sec_ctx.buf
, sec_ctx.len
);
1011 msg
->sadb_msg_len
= PFKEY_UNIT64
(l
);
1015 #ifdef HAVE_POLICY_FWD
1016 /* create extra call for FWD policy */
1017 if
(f_rfcmode
&& sp
->sadb_x_policy_dir
== IPSEC_DIR_INBOUND
) {
1018 sp
->sadb_x_policy_dir
= IPSEC_DIR_FWD
;
1019 ps
= (struct sadb_x_ipsecrequest
*) (sp
+1);
1021 /* if request level is unique, change it to
1022 * require for fwd policy */
1023 /* XXX: currently, only first policy is updated
1024 * only. Update following too... */
1025 saved_level
= ps
->sadb_x_ipsecrequest_level
;
1026 if
(saved_level
== IPSEC_LEVEL_UNIQUE
) {
1027 saved_id
= ps
->sadb_x_ipsecrequest_reqid
;
1028 ps
->sadb_x_ipsecrequest_reqid
=0;
1029 ps
->sadb_x_ipsecrequest_level
=IPSEC_LEVEL_REQUIRE
;
1033 /* restoring for next message */
1034 sp
->sadb_x_policy_dir
= IPSEC_DIR_INBOUND
;
1035 if
(saved_level
== IPSEC_LEVEL_UNIQUE
) {
1036 ps
->sadb_x_ipsecrequest_reqid
= saved_id
;
1037 ps
->sadb_x_ipsecrequest_level
= saved_level
;
1053 setkeymsg_spdaddr_tag
(type
, tag
, policy
)
1058 struct sadb_msg
*msg
;
1061 #ifdef SADB_X_EXT_TAG
1062 struct sadb_x_tag m_tag
;
1066 msg
= (struct sadb_msg
*)buf
;
1068 /* fix up length afterwards */
1069 setkeymsg0
(msg
, type
, SADB_SATYPE_UNSPEC
, 0);
1070 l
= sizeof
(struct sadb_msg
);
1072 memcpy
(buf
+ l
, policy
->buf
, policy
->len
);
1078 #ifdef SADB_X_EXT_TAG
1079 memset
(&m_tag
, 0, sizeof
(m_tag
));
1080 m_tag.sadb_x_tag_len
= PFKEY_UNIT64
(sizeof
(m_tag
));
1081 m_tag.sadb_x_tag_exttype
= SADB_X_EXT_TAG
;
1082 if
(strlcpy
(m_tag.sadb_x_tag_name
, tag
,
1083 sizeof
(m_tag.sadb_x_tag_name
)) >= sizeof
(m_tag.sadb_x_tag_name
))
1085 memcpy
(buf
+ l
, &m_tag
, sizeof
(m_tag
));
1089 msg
->sadb_msg_len
= PFKEY_UNIT64
(l
);
1096 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1098 setkeymsg_addr
(type
, satype
, srcs
, dsts
, no_spi
)
1100 unsigned int satype
;
1101 struct addrinfo
*srcs
;
1102 struct addrinfo
*dsts
;
1105 struct sadb_msg
*msg
;
1108 struct sadb_sa m_sa
;
1109 struct sadb_x_sa2 m_sa2
;
1110 struct sadb_address m_addr
;
1111 struct addrinfo
*s
, *d
;
1114 struct sockaddr
*sa
;
1117 msg
= (struct sadb_msg
*)buf
;
1122 /* fix up length afterwards */
1123 setkeymsg0
(msg
, type
, satype
, 0);
1124 l
= sizeof
(struct sadb_msg
);
1127 len
= sizeof
(struct sadb_sa
);
1128 m_sa.sadb_sa_len
= PFKEY_UNIT64
(len
);
1129 m_sa.sadb_sa_exttype
= SADB_EXT_SA
;
1130 m_sa.sadb_sa_spi
= htonl
(p_spi
);
1131 m_sa.sadb_sa_replay
= p_replay
;
1132 m_sa.sadb_sa_state
= 0;
1133 m_sa.sadb_sa_auth
= p_alg_auth
;
1134 m_sa.sadb_sa_encrypt
= p_alg_enc
;
1135 m_sa.sadb_sa_flags
= p_ext
;
1137 memcpy
(buf
+ l
, &m_sa
, len
);
1140 len
= sizeof
(struct sadb_x_sa2
);
1141 m_sa2.sadb_x_sa2_len
= PFKEY_UNIT64
(len
);
1142 m_sa2.sadb_x_sa2_exttype
= SADB_X_EXT_SA2
;
1143 m_sa2.sadb_x_sa2_mode
= p_mode
;
1144 m_sa2.sadb_x_sa2_reqid
= p_reqid
;
1146 memcpy
(buf
+ l
, &m_sa2
, len
);
1153 /* do it for all src/dst pairs */
1154 for
(s
= srcs
; s
; s
= s
->ai_next
) {
1155 for
(d
= dsts
; d
; d
= d
->ai_next
) {
1156 /* rewind pointer */
1159 if
(s
->ai_addr
->sa_family
!= d
->ai_addr
->sa_family
)
1161 switch
(s
->ai_addr
->sa_family
) {
1163 plen
= sizeof
(struct in_addr
) << 3;
1167 plen
= sizeof
(struct in6_addr
) << 3;
1176 salen
= sysdep_sa_len
(s
->ai_addr
);
1177 m_addr.sadb_address_len
= PFKEY_UNIT64
(sizeof
(m_addr
) +
1178 PFKEY_ALIGN8
(salen
));
1179 m_addr.sadb_address_exttype
= SADB_EXT_ADDRESS_SRC
;
1180 m_addr.sadb_address_proto
= IPSEC_ULPROTO_ANY
;
1181 m_addr.sadb_address_prefixlen
= plen
;
1182 m_addr.sadb_address_reserved
= 0;
1184 setvarbuf
(buf
, &l
, (struct sadb_ext
*)&m_addr
,
1185 sizeof
(m_addr
), sa
, salen
);
1189 salen
= sysdep_sa_len
(d
->ai_addr
);
1190 m_addr.sadb_address_len
= PFKEY_UNIT64
(sizeof
(m_addr
) +
1191 PFKEY_ALIGN8
(salen
));
1192 m_addr.sadb_address_exttype
= SADB_EXT_ADDRESS_DST
;
1193 m_addr.sadb_address_proto
= IPSEC_ULPROTO_ANY
;
1194 m_addr.sadb_address_prefixlen
= plen
;
1195 m_addr.sadb_address_reserved
= 0;
1197 setvarbuf
(buf
, &l
, (struct sadb_ext
*)&m_addr
,
1198 sizeof
(m_addr
), sa
, salen
);
1200 msg
->sadb_msg_len
= PFKEY_UNIT64
(l
);
1214 #ifdef SADB_X_EXT_NAT_T_TYPE
1215 static u_int16_t get_port
(struct addrinfo
*addr
)
1217 struct sockaddr
*s
= addr
->ai_addr
;
1220 switch
(s
->sa_family
) {
1223 struct sockaddr_in
*sin4
= (struct sockaddr_in
*)s
;
1224 port
= ntohs
(sin4
->sin_port
);
1229 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)s
;
1230 port
= ntohs
(sin6
->sin6_port
);
1236 port
= DEFAULT_NATT_PORT
;
1242 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1244 setkeymsg_add
(type
, satype
, srcs
, dsts
)
1246 unsigned int satype
;
1247 struct addrinfo
*srcs
;
1248 struct addrinfo
*dsts
;
1250 struct sadb_msg
*msg
;
1253 struct sadb_sa m_sa
;
1254 struct sadb_x_sa2 m_sa2
;
1255 struct sadb_address m_addr
;
1256 struct addrinfo
*s
, *d
;
1259 struct sockaddr
*sa
;
1262 msg
= (struct sadb_msg
*)buf
;
1267 /* fix up length afterwards */
1268 setkeymsg0
(msg
, type
, satype
, 0);
1269 l
= sizeof
(struct sadb_msg
);
1271 /* set encryption algorithm, if present. */
1272 if
(satype
!= SADB_X_SATYPE_IPCOMP
&& p_key_enc
) {
1274 struct sadb_key key
;
1275 struct sadb_ext ext
;
1278 m.key.sadb_key_len
=
1279 PFKEY_UNIT64
(sizeof
(m.key
)
1280 + PFKEY_ALIGN8
(p_key_enc_len
));
1281 m.key.sadb_key_exttype
= SADB_EXT_KEY_ENCRYPT
;
1282 m.key.sadb_key_bits
= p_key_enc_len
* 8;
1283 m.key.sadb_key_reserved
= 0;
1285 setvarbuf
(buf
, &l
, &m.ext
, sizeof
(m.key
),
1286 p_key_enc
, p_key_enc_len
);
1289 /* set authentication algorithm, if present. */
1292 struct sadb_key key
;
1293 struct sadb_ext ext
;
1296 m.key.sadb_key_len
=
1297 PFKEY_UNIT64
(sizeof
(m.key
)
1298 + PFKEY_ALIGN8
(p_key_auth_len
));
1299 m.key.sadb_key_exttype
= SADB_EXT_KEY_AUTH
;
1300 m.key.sadb_key_bits
= p_key_auth_len
* 8;
1301 m.key.sadb_key_reserved
= 0;
1303 setvarbuf
(buf
, &l
, &m.ext
, sizeof
(m.key
),
1304 p_key_auth
, p_key_auth_len
);
1307 /* set lifetime for HARD */
1308 if
(p_lt_hard
!= 0 || p_lb_hard
!= 0) {
1309 struct sadb_lifetime m_lt
;
1310 u_int slen
= sizeof
(struct sadb_lifetime
);
1312 m_lt.sadb_lifetime_len
= PFKEY_UNIT64
(slen
);
1313 m_lt.sadb_lifetime_exttype
= SADB_EXT_LIFETIME_HARD
;
1314 m_lt.sadb_lifetime_allocations
= 0;
1315 m_lt.sadb_lifetime_bytes
= p_lb_hard
;
1316 m_lt.sadb_lifetime_addtime
= p_lt_hard
;
1317 m_lt.sadb_lifetime_usetime
= 0;
1319 memcpy
(buf
+ l
, &m_lt
, slen
);
1323 /* set lifetime for SOFT */
1324 if
(p_lt_soft
!= 0 || p_lb_soft
!= 0) {
1325 struct sadb_lifetime m_lt
;
1326 u_int slen
= sizeof
(struct sadb_lifetime
);
1328 m_lt.sadb_lifetime_len
= PFKEY_UNIT64
(slen
);
1329 m_lt.sadb_lifetime_exttype
= SADB_EXT_LIFETIME_SOFT
;
1330 m_lt.sadb_lifetime_allocations
= 0;
1331 m_lt.sadb_lifetime_bytes
= p_lb_soft
;
1332 m_lt.sadb_lifetime_addtime
= p_lt_soft
;
1333 m_lt.sadb_lifetime_usetime
= 0;
1335 memcpy
(buf
+ l
, &m_lt
, slen
);
1339 #ifdef SADB_X_EXT_SEC_CTX
1340 /* Add security context label */
1342 struct sadb_x_sec_ctx m_sec_ctx
;
1343 u_int slen
= sizeof
(struct sadb_x_sec_ctx
);
1345 memset
(&m_sec_ctx
, 0, slen
);
1347 m_sec_ctx.sadb_x_sec_len
= PFKEY_UNIT64
(slen
+
1348 PFKEY_ALIGN8
(sec_ctx.len
));
1349 m_sec_ctx.sadb_x_sec_exttype
= SADB_X_EXT_SEC_CTX
;
1350 m_sec_ctx.sadb_x_ctx_len
= sec_ctx.len
; /* bytes */
1351 m_sec_ctx.sadb_x_ctx_doi
= sec_ctx.doi
;
1352 m_sec_ctx.sadb_x_ctx_alg
= sec_ctx.alg
;
1353 setvarbuf
(buf
, &l
, (struct sadb_ext
*)&m_sec_ctx
, slen
,
1354 (caddr_t
)sec_ctx.buf
, sec_ctx.len
);
1358 len
= sizeof
(struct sadb_sa
);
1359 m_sa.sadb_sa_len
= PFKEY_UNIT64
(len
);
1360 m_sa.sadb_sa_exttype
= SADB_EXT_SA
;
1361 m_sa.sadb_sa_spi
= htonl
(p_spi
);
1362 m_sa.sadb_sa_replay
= p_replay
;
1363 m_sa.sadb_sa_state
= 0;
1364 m_sa.sadb_sa_auth
= p_alg_auth
;
1365 m_sa.sadb_sa_encrypt
= p_alg_enc
;
1366 m_sa.sadb_sa_flags
= p_ext
;
1368 memcpy
(buf
+ l
, &m_sa
, len
);
1371 len
= sizeof
(struct sadb_x_sa2
);
1372 m_sa2.sadb_x_sa2_len
= PFKEY_UNIT64
(len
);
1373 m_sa2.sadb_x_sa2_exttype
= SADB_X_EXT_SA2
;
1374 m_sa2.sadb_x_sa2_mode
= p_mode
;
1375 m_sa2.sadb_x_sa2_reqid
= p_reqid
;
1377 memcpy
(buf
+ l
, &m_sa2
, len
);
1380 #ifdef SADB_X_EXT_NAT_T_TYPE
1382 struct sadb_x_nat_t_type natt_type
;
1384 len
= sizeof
(struct sadb_x_nat_t_type
);
1385 memset
(&natt_type
, 0, len
);
1386 natt_type.sadb_x_nat_t_type_len
= PFKEY_UNIT64
(len
);
1387 natt_type.sadb_x_nat_t_type_exttype
= SADB_X_EXT_NAT_T_TYPE
;
1388 natt_type.sadb_x_nat_t_type_type
= p_natt_type
;
1390 memcpy
(buf
+ l
, &natt_type
, len
);
1394 sa
= p_natt_oa
->ai_addr
;
1395 switch
(sa
->sa_family
) {
1397 plen
= sizeof
(struct in_addr
) << 3;
1401 plen
= sizeof
(struct in6_addr
) << 3;
1407 salen
= sysdep_sa_len
(sa
);
1408 m_addr.sadb_address_len
= PFKEY_UNIT64
(sizeof
(m_addr
) +
1409 PFKEY_ALIGN8
(salen
));
1410 m_addr.sadb_address_exttype
= SADB_X_EXT_NAT_T_OA
;
1411 m_addr.sadb_address_proto
= IPSEC_ULPROTO_ANY
;
1412 m_addr.sadb_address_prefixlen
= plen
;
1413 m_addr.sadb_address_reserved
= 0;
1415 setvarbuf
(buf
, &l
, (struct sadb_ext
*)&m_addr
,
1416 sizeof
(m_addr
), sa
, salen
);
1424 /* do it for all src/dst pairs */
1425 for
(s
= srcs
; s
; s
= s
->ai_next
) {
1426 for
(d
= dsts
; d
; d
= d
->ai_next
) {
1427 /* rewind pointer */
1430 if
(s
->ai_addr
->sa_family
!= d
->ai_addr
->sa_family
)
1432 switch
(s
->ai_addr
->sa_family
) {
1434 plen
= sizeof
(struct in_addr
) << 3;
1438 plen
= sizeof
(struct in6_addr
) << 3;
1447 salen
= sysdep_sa_len
(s
->ai_addr
);
1448 m_addr.sadb_address_len
= PFKEY_UNIT64
(sizeof
(m_addr
) +
1449 PFKEY_ALIGN8
(salen
));
1450 m_addr.sadb_address_exttype
= SADB_EXT_ADDRESS_SRC
;
1451 m_addr.sadb_address_proto
= IPSEC_ULPROTO_ANY
;
1452 m_addr.sadb_address_prefixlen
= plen
;
1453 m_addr.sadb_address_reserved
= 0;
1455 setvarbuf
(buf
, &l
, (struct sadb_ext
*)&m_addr
,
1456 sizeof
(m_addr
), sa
, salen
);
1460 salen
= sysdep_sa_len
(d
->ai_addr
);
1461 m_addr.sadb_address_len
= PFKEY_UNIT64
(sizeof
(m_addr
) +
1462 PFKEY_ALIGN8
(salen
));
1463 m_addr.sadb_address_exttype
= SADB_EXT_ADDRESS_DST
;
1464 m_addr.sadb_address_proto
= IPSEC_ULPROTO_ANY
;
1465 m_addr.sadb_address_prefixlen
= plen
;
1466 m_addr.sadb_address_reserved
= 0;
1468 setvarbuf
(buf
, &l
, (struct sadb_ext
*)&m_addr
,
1469 sizeof
(m_addr
), sa
, salen
);
1471 #ifdef SADB_X_EXT_NAT_T_TYPE
1473 struct sadb_x_nat_t_port natt_port
;
1476 len
= sizeof
(struct sadb_x_nat_t_port
);
1477 memset
(&natt_port
, 0, len
);
1478 natt_port.sadb_x_nat_t_port_len
= PFKEY_UNIT64
(len
);
1479 natt_port.sadb_x_nat_t_port_exttype
=
1480 SADB_X_EXT_NAT_T_SPORT
;
1481 natt_port.sadb_x_nat_t_port_port
= htons
(get_port
(s
));
1483 memcpy
(buf
+ l
, &natt_port
, len
);
1487 natt_port.sadb_x_nat_t_port_exttype
=
1488 SADB_X_EXT_NAT_T_DPORT
;
1489 natt_port.sadb_x_nat_t_port_port
= htons
(get_port
(d
));
1491 memcpy
(buf
+ l
, &natt_port
, len
);
1495 msg
->sadb_msg_len
= PFKEY_UNIT64
(l
);
1509 static struct addrinfo
*
1510 parse_addr
(host
, port
)
1514 struct addrinfo hints
, *res
= NULL
;
1517 memset
(&hints
, 0, sizeof
(hints
));
1518 hints.ai_family
= p_aifamily
;
1519 hints.ai_socktype
= SOCK_DGRAM
; /*dummy*/
1520 hints.ai_protocol
= IPPROTO_UDP
; /*dummy*/
1521 hints.ai_flags
= p_aiflags
;
1522 error = getaddrinfo
(host
, port
, &hints
, &res
);
1524 yyerror(gai_strerror
(error));
1531 fix_portstr
(spec
, sport
, dport
)
1532 vchar_t
*spec
, *sport
, *dport
;
1534 const char *p
, *p2
= "0";
1539 for
(q
= spec
->buf
; *q
!= ',' && *q
!= '\0' && l
< spec
->len
; q
++, l
++)
1546 for
(p
= p2
; *p
!= '\0' && l
< spec
->len
; p
++, l
++)
1548 if
(*p
!= '\0' ||
*p2
== '\0') {
1549 yyerror("invalid an upper layer protocol spec");
1554 sport
->buf
= strdup
(spec
->buf
);
1556 yyerror("insufficient memory");
1559 sport
->len
= strlen
(sport
->buf
);
1560 dport
->buf
= strdup
(p2
);
1562 yyerror("insufficient memory");
1565 dport
->len
= strlen
(dport
->buf
);
1571 setvarbuf
(buf
, off
, ebuf
, elen
, vbuf
, vlen
)
1574 struct sadb_ext
*ebuf
;
1579 memset
(buf
+ *off
, 0, PFKEY_UNUNIT64
(ebuf
->sadb_ext_len
));
1580 memcpy
(buf
+ *off
, (caddr_t
)ebuf
, elen
);
1581 memcpy
(buf
+ *off
+ elen
, vbuf
, vlen
);
1582 (*off
) += PFKEY_ALIGN8
(elen
+ vlen
);
1592 p_ext
= SADB_X_EXT_CYCSEQ
;
1593 p_alg_enc
= SADB_EALG_NONE
;
1594 p_alg_auth
= SADB_AALG_NONE
;
1595 p_mode
= IPSEC_MODE_ANY
;
1598 p_key_enc_len
= p_key_auth_len
= 0;
1599 p_key_enc
= p_key_auth
= 0;
1600 p_lt_hard
= p_lt_soft
= 0;
1601 p_lb_hard
= p_lb_soft
= 0;
1603 memset
(&sec_ctx
, 0, sizeof
(struct security_ctx
));
1606 p_aifamily
= PF_UNSPEC
;
1608 /* Clear out any natt OA information */
1610 freeaddrinfo
(p_natt_oa
);
1620 /* we got tons of memory leaks in the parser anyways, leave them */