1 /* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */
4 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <System/net/pfkeyv2.h>
44 #ifdef HAVE_NETINET6_IPSEC
45 # include <netinet6/ipsec.h>
47 # include <netinet/ipsec.h>
49 #include <arpa/inet.h>
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;
83 static u_int p_natt_type;
84 static struct addrinfo * p_natt_oa = NULL;
86 static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
88 static struct addrinfo *parse_addr __P((char *, char *));
89 static int fix_portstr __P((vchar_t *, vchar_t *, vchar_t *));
90 static int setvarbuf __P((char *, int *, struct sadb_ext *, int,
92 void parse_init __P((void));
93 void free_buffer __P((void));
95 int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t));
96 static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *,
97 struct addrinfo *, int, struct addrinfo *, int));
98 static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *));
99 static int setkeymsg_addr __P((unsigned int, unsigned int,
100 struct addrinfo *, struct addrinfo *, int));
101 static int setkeymsg_add __P((unsigned int, unsigned int,
102 struct addrinfo *, struct addrinfo *));
109 struct addrinfo *res;
112 %token EOT SLASH BLCL ELCL
113 %token ADD GET DELETE DELETEALL FLUSH DUMP EXIT
114 %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
115 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
116 %token F_MODE MODE F_REQID
117 %token F_EXT EXTENSION NOCYCLICSEQ
118 %token ALG_AUTH ALG_AUTH_NOKEY
119 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
121 %token F_LIFETIME_HARD F_LIFETIME_SOFT
122 %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT
123 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
125 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
126 %token F_POLICY PL_REQUESTS
130 %type <num> prefix protocol_spec upper_spec
131 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
132 %type <num> ALG_AUTH ALG_AUTH_NOKEY
134 %type <num> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
135 %type <num> EXTENSION MODE
136 %type <ulnum> DECSTRING
137 %type <val> PL_REQUESTS portstr key_string
138 %type <val> policy_requests
139 %type <val> QUOTEDSTRING HEXSTRING STRING
140 %type <val> F_AIFLAGS
141 %type <val> upper_misc_spec policy_spec
142 %type <res> ipaddr ipandport
167 /* commands concerned with management, there is in tail of this file. */
171 : ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
175 status = setkeymsg_add(SADB_ADD, $5, $3, $4);
183 : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
187 if ($3->ai_next || $4->ai_next) {
188 yyerror("multiple address specified");
191 if (p_mode != IPSEC_MODE_ANY)
192 yyerror("WARNING: mode is obsolete");
194 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
200 /* deleteall command */
202 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
206 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
214 : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
218 if (p_mode != IPSEC_MODE_ANY)
219 yyerror("WARNING: mode is obsolete");
221 status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
229 : FLUSH protocol_spec EOT
232 setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
233 sendkeymsg((char *)&msg, sizeof(msg));
239 : DUMP protocol_spec EOT
242 setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
243 sendkeymsg((char *)&msg, sizeof(msg));
250 $$ = SADB_SATYPE_UNSPEC;
254 $$ = SADB_SATYPE_ESP;
256 p_ext |= SADB_X_EXT_OLD;
258 p_ext &= ~SADB_X_EXT_OLD;
264 p_ext |= SADB_X_EXT_OLD;
266 p_ext &= ~SADB_X_EXT_OLD;
270 $$ = SADB_X_SATYPE_IPCOMP;
274 $$ = SADB_SATYPE_ESP;
275 p_ext &= ~SADB_X_EXT_OLD;
277 p_natt_type = UDP_ENCAP_ESPINUDP;
281 $$ = SADB_SATYPE_ESP;
282 p_ext &= ~SADB_X_EXT_OLD;
284 p_natt_type = UDP_ENCAP_ESPINUDP;
288 #ifdef SADB_X_SATYPE_TCPSIGNATURE
289 $$ = SADB_X_SATYPE_TCPSIGNATURE;
295 : DECSTRING { p_spi = $1; }
302 v = strtoul($1.buf, &ep, 16);
304 yyerror("invalid SPI");
307 if (v & ~0xffffffff) {
308 yyerror("SPI too big.");
323 : F_ENC enc_alg F_AUTH auth_alg
335 yyerror("unsupported algorithm");
340 | F_COMP ALG_COMP F_RAWCPI
343 yyerror("unsupported algorithm");
347 p_ext |= SADB_X_EXT_RAWCPI;
354 yyerror("unsupported algorithm");
361 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
362 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
363 yyerror(ipsec_strerror());
367 | ALG_ENC key_string {
369 yyerror("unsupported algorithm");
374 p_key_enc_len = $2.len;
376 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
377 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
378 yyerror(ipsec_strerror());
384 yyerror("unsupported algorithm");
387 yyerror("WARNING: obsolete algorithm");
392 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
393 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
394 yyerror(ipsec_strerror());
398 | ALG_ENC_DESDERIV key_string
401 yyerror("unsupported algorithm");
405 if (p_ext & SADB_X_EXT_OLD) {
406 yyerror("algorithm mismatched");
409 p_ext |= SADB_X_EXT_DERIV;
411 p_key_enc_len = $2.len;
413 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
414 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
415 yyerror(ipsec_strerror());
419 | ALG_ENC_DES32IV key_string
422 yyerror("unsupported algorithm");
426 if (!(p_ext & SADB_X_EXT_OLD)) {
427 yyerror("algorithm mismatched");
430 p_ext |= SADB_X_EXT_IV4B;
432 p_key_enc_len = $2.len;
434 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
435 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
436 yyerror(ipsec_strerror());
443 : ALG_AUTH key_string {
445 yyerror("unsupported algorithm");
450 p_key_auth_len = $2.len;
452 #ifdef SADB_X_AALG_TCP_MD5
453 if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
454 if ((p_key_auth_len < 1) ||
455 (p_key_auth_len > 80))
460 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
462 PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
463 yyerror(ipsec_strerror());
470 yyerror("unsupported algorithm");
492 l = strlen(yp) % 2 + strlen(yp) / 2;
493 if ((pp_key = malloc(l)) == 0) {
494 yyerror("not enough core");
497 memset(pp_key, 0, l);
500 if (strlen(yp) % 2) {
505 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
516 | extension_spec extension
520 : F_EXT EXTENSION { p_ext |= $2; }
521 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
522 | F_MODE MODE { p_mode = $2; }
523 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
524 | F_REQID DECSTRING { p_reqid = $2; }
527 if ((p_ext & SADB_X_EXT_OLD) != 0) {
528 yyerror("replay prevention cannot be used with "
534 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
535 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
536 | F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; }
537 | F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; }
540 /* definition about command for SPD management */
543 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
546 struct addrinfo *src, *dst;
548 #ifdef HAVE_PFKEY_POLICY_PRIORITY
549 last_msg_type = SADB_X_SPDADD;
552 /* fixed port fields if ulp is icmpv6 */
553 if ($10.buf != NULL) {
554 if ($9 != IPPROTO_ICMPV6)
558 if (fix_portstr(&$10, &$5, &$8))
562 src = parse_addr($3.buf, $5.buf);
563 dst = parse_addr($6.buf, $8.buf);
565 /* yyerror is already called */
568 if (src->ai_next || dst->ai_next) {
569 yyerror("multiple address specified");
575 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
582 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT
586 status = setkeymsg_spdaddr_tag(SADB_X_SPDADD,
594 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
597 struct addrinfo *src, *dst;
599 /* fixed port fields if ulp is icmpv6 */
600 if ($10.buf != NULL) {
601 if ($9 != IPPROTO_ICMPV6)
605 if (fix_portstr(&$10, &$5, &$8))
609 src = parse_addr($3.buf, $5.buf);
610 dst = parse_addr($6.buf, $8.buf);
612 /* yyerror is already called */
615 if (src->ai_next || dst->ai_next) {
616 yyerror("multiple address specified");
622 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
635 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
637 sendkeymsg((char *)&msg, sizeof(msg));
646 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
648 sendkeymsg((char *)&msg, sizeof(msg));
654 | ipaddropts ipaddropt
662 for (p = $1.buf + 1; *p; p++)
665 p_aifamily = AF_INET;
669 p_aifamily = AF_INET6;
673 p_aiflags = AI_NUMERICHOST;
676 yyerror("invalid flag");
685 $$ = parse_addr($1.buf, NULL);
687 /* yyerror already called by parse_addr */
696 $$ = parse_addr($1.buf, NULL);
698 /* yyerror already called by parse_addr */
704 $$ = parse_addr($1.buf, $2.buf);
706 /* yyerror already called by parse_addr */
713 : /*NOTHING*/ { $$ = -1; }
714 | SLASH DECSTRING { $$ = $2; }
720 $$.buf = strdup("0");
722 yyerror("insufficient memory");
725 $$.len = strlen($$.buf);
729 $$.buf = strdup("0");
731 yyerror("insufficient memory");
734 $$.len = strlen($$.buf);
736 | BLCL DECSTRING ELCL
739 snprintf(buf, sizeof(buf), "%lu", $2);
740 $$.buf = strdup(buf);
742 yyerror("insufficient memory");
745 $$.len = strlen($$.buf);
754 : DECSTRING { $$ = $1; }
755 | ANY { $$ = IPSEC_ULPROTO_ANY; }
761 struct protoent *ent;
763 ent = getprotobyname($1.buf);
767 if (strcmp("icmp6", $1.buf) == 0) {
769 } else if(strcmp("ip4", $1.buf) == 0) {
772 yyerror("invalid upper layer protocol");
788 $$.buf = strdup($1.buf);
790 yyerror("insufficient memory");
793 $$.len = strlen($$.buf);
798 : F_POLICY policy_requests
801 #ifdef HAVE_PFKEY_POLICY_PRIORITY
802 struct sadb_x_policy *xpl;
805 policy = ipsec_set_policy($2.buf, $2.len);
806 if (policy == NULL) {
807 yyerror(ipsec_strerror());
812 $$.len = ipsec_get_policylen(policy);
814 #ifdef HAVE_PFKEY_POLICY_PRIORITY
815 xpl = (struct sadb_x_policy *) $$.buf;
816 last_priority = xpl->sadb_x_policy_priority;
822 : PL_REQUESTS { $$ = $1; }
836 setkeymsg0(msg, type, satype, l)
837 struct sadb_msg *msg;
843 msg->sadb_msg_version = PF_KEY_V2;
844 msg->sadb_msg_type = type;
845 msg->sadb_msg_errno = 0;
846 msg->sadb_msg_satype = satype;
847 msg->sadb_msg_reserved = 0;
848 msg->sadb_msg_seq = 0;
849 msg->sadb_msg_pid = getpid();
850 msg->sadb_msg_len = PFKEY_UNIT64(l);
854 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
856 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen)
860 struct addrinfo *srcs;
862 struct addrinfo *dsts;
865 struct sadb_msg *msg;
866 union { // Wcast-align fix - force alignment
867 u_int64_t force_align;
871 struct sadb_address m_addr;
872 struct addrinfo *s, *d;
877 struct sadb_x_policy *sp;
878 #ifdef HAVE_POLICY_FWD
879 struct sadb_x_ipsecrequest *ps = NULL;
880 int saved_level, saved_id = 0;
883 msg = (struct sadb_msg *)&u_buf;
888 /* fix up length afterwards */
889 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
890 l = sizeof(struct sadb_msg);
892 sp = ALIGNED_CAST(struct sadb_x_policy*)(u_buf.buf + l);
893 memcpy(u_buf.buf + l, policy->buf, policy->len);
899 /* do it for all src/dst pairs */
900 for (s = srcs; s; s = s->ai_next) {
901 for (d = dsts; d; d = d->ai_next) {
905 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
907 switch (s->ai_addr->sa_family) {
909 plen = sizeof(struct in_addr) << 3;
913 plen = sizeof(struct in6_addr) << 3;
922 salen = sysdep_sa_len(s->ai_addr);
923 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
924 PFKEY_ALIGN8(salen));
925 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
926 m_addr.sadb_address_proto = upper;
927 m_addr.sadb_address_prefixlen =
928 (splen >= 0 ? splen : plen);
929 m_addr.sadb_address_reserved = 0;
931 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
932 sizeof(m_addr), (caddr_t)sa, salen);
936 salen = sysdep_sa_len(d->ai_addr);
937 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
938 PFKEY_ALIGN8(salen));
939 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
940 m_addr.sadb_address_proto = upper;
941 m_addr.sadb_address_prefixlen =
942 (dplen >= 0 ? dplen : plen);
943 m_addr.sadb_address_reserved = 0;
945 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
946 sizeof(m_addr), sa, salen);
948 msg->sadb_msg_len = PFKEY_UNIT64(l);
950 sendkeymsg(u_buf.buf, l);
952 #ifdef HAVE_POLICY_FWD
953 /* create extra call for FWD policy */
954 if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) {
955 sp->sadb_x_policy_dir = IPSEC_DIR_FWD;
956 ps = (struct sadb_x_ipsecrequest*) (sp+1);
958 /* if request level is unique, change it to
959 * require for fwd policy */
960 /* XXX: currently, only first policy is updated
961 * only. Update following too... */
962 saved_level = ps->sadb_x_ipsecrequest_level;
963 if (saved_level == IPSEC_LEVEL_UNIQUE) {
964 saved_id = ps->sadb_x_ipsecrequest_reqid;
965 ps->sadb_x_ipsecrequest_reqid=0;
966 ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE;
970 /* restoring for next message */
971 sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
972 if (saved_level == IPSEC_LEVEL_UNIQUE) {
973 ps->sadb_x_ipsecrequest_reqid = saved_id;
974 ps->sadb_x_ipsecrequest_level = saved_level;
990 setkeymsg_spdaddr_tag(type, tag, policy)
995 struct sadb_msg *msg;
996 union { // Wcast-align fix - force alignment
997 u_int64_t force_align;
1001 #ifdef SADB_X_EXT_TAG
1002 struct sadb_x_tag m_tag;
1006 msg = (struct sadb_msg *)&u_buf;
1008 /* fix up length afterwards */
1009 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
1010 l = sizeof(struct sadb_msg);
1012 memcpy(u_buf.buf + l, policy->buf, policy->len);
1018 #ifdef SADB_X_EXT_TAG
1019 memset(&m_tag, 0, sizeof(m_tag));
1020 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag));
1021 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG;
1022 if (strlcpy(m_tag.sadb_x_tag_name, tag,
1023 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name))
1025 memcpy(buf + l, &m_tag, sizeof(m_tag));
1029 msg->sadb_msg_len = PFKEY_UNIT64(l);
1031 sendkeymsg(u_buf.buf, l);
1036 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1038 setkeymsg_addr(type, satype, srcs, dsts, no_spi)
1040 unsigned int satype;
1041 struct addrinfo *srcs;
1042 struct addrinfo *dsts;
1045 struct sadb_msg *msg;
1046 union { // Wcast-align fix - force alignment
1047 u_int64_t force_align;
1051 struct sadb_sa m_sa;
1052 struct sadb_x_sa2 m_sa2;
1053 struct sadb_address m_addr;
1054 struct addrinfo *s, *d;
1057 struct sockaddr *sa;
1060 msg = (struct sadb_msg *)&u_buf;
1065 /* fix up length afterwards */
1066 setkeymsg0(msg, type, satype, 0);
1067 l = sizeof(struct sadb_msg);
1070 len = sizeof(struct sadb_sa);
1071 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1072 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1073 m_sa.sadb_sa_spi = htonl(p_spi);
1074 m_sa.sadb_sa_replay = p_replay;
1075 m_sa.sadb_sa_state = 0;
1076 m_sa.sadb_sa_auth = p_alg_auth;
1077 m_sa.sadb_sa_encrypt = p_alg_enc;
1078 m_sa.sadb_sa_flags = p_ext;
1080 memcpy(u_buf.buf + l, &m_sa, len);
1083 len = sizeof(struct sadb_x_sa2);
1084 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1085 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1086 m_sa2.sadb_x_sa2_mode = p_mode;
1087 m_sa2.sadb_x_sa2_reqid = p_reqid;
1089 memcpy(u_buf.buf + l, &m_sa2, len);
1096 /* do it for all src/dst pairs */
1097 for (s = srcs; s; s = s->ai_next) {
1098 for (d = dsts; d; d = d->ai_next) {
1099 /* rewind pointer */
1102 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1104 switch (s->ai_addr->sa_family) {
1106 plen = sizeof(struct in_addr) << 3;
1110 plen = sizeof(struct in6_addr) << 3;
1119 salen = sysdep_sa_len(s->ai_addr);
1120 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1121 PFKEY_ALIGN8(salen));
1122 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1123 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1124 m_addr.sadb_address_prefixlen = plen;
1125 m_addr.sadb_address_reserved = 0;
1127 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
1128 sizeof(m_addr), sa, salen);
1132 salen = sysdep_sa_len(d->ai_addr);
1133 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1134 PFKEY_ALIGN8(salen));
1135 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1136 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1137 m_addr.sadb_address_prefixlen = plen;
1138 m_addr.sadb_address_reserved = 0;
1140 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
1141 sizeof(m_addr), sa, salen);
1143 msg->sadb_msg_len = PFKEY_UNIT64(l);
1145 sendkeymsg(u_buf.buf, l);
1157 #ifdef SADB_X_EXT_NAT_T_TYPE
1158 static u_int16_t get_port (struct addrinfo *addr)
1160 struct sockaddr_storage *s = addr->ai_addr;
1163 switch (s->sa_family) {
1166 struct sockaddr_in *sin4 = (struct sockaddr_in *)s;
1167 port = ntohs(sin4->sin_port);
1172 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s;
1173 port = ntohs(sin6->sin6_port);
1179 port = DEFAULT_NATT_PORT;
1185 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1187 setkeymsg_add(type, satype, srcs, dsts)
1189 unsigned int satype;
1190 struct addrinfo *srcs;
1191 struct addrinfo *dsts;
1193 struct sadb_msg *msg;
1194 union { // Wcast-align fix - force alignment
1195 u_int64_t force_align;
1199 struct sadb_sa m_sa;
1200 struct sadb_x_sa2 m_sa2;
1201 struct sadb_address m_addr;
1202 struct addrinfo *s, *d;
1205 struct sockaddr *sa;
1208 msg = (struct sadb_msg *)&u_buf;
1213 /* fix up length afterwards */
1214 setkeymsg0(msg, type, satype, 0);
1215 l = sizeof(struct sadb_msg);
1217 /* set encryption algorithm, if present. */
1218 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1220 struct sadb_key key;
1221 struct sadb_ext ext;
1224 m.key.sadb_key_len =
1225 PFKEY_UNIT64(sizeof(m.key)
1226 + PFKEY_ALIGN8(p_key_enc_len));
1227 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1228 m.key.sadb_key_bits = p_key_enc_len * 8;
1229 m.key.sadb_key_reserved = 0;
1231 setvarbuf(u_buf.buf, &l, &m.ext, sizeof(m.key),
1232 p_key_enc, p_key_enc_len);
1235 /* set authentication algorithm, if present. */
1238 struct sadb_key key;
1239 struct sadb_ext ext;
1242 m.key.sadb_key_len =
1243 PFKEY_UNIT64(sizeof(m.key)
1244 + PFKEY_ALIGN8(p_key_auth_len));
1245 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1246 m.key.sadb_key_bits = p_key_auth_len * 8;
1247 m.key.sadb_key_reserved = 0;
1249 setvarbuf(u_buf.buf, &l, &m.ext, sizeof(m.key),
1250 p_key_auth, p_key_auth_len);
1253 /* set lifetime for HARD */
1254 if (p_lt_hard != 0 || p_lb_hard != 0) {
1255 struct sadb_lifetime m_lt;
1256 u_int slen = sizeof(struct sadb_lifetime);
1258 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1259 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1260 m_lt.sadb_lifetime_allocations = 0;
1261 m_lt.sadb_lifetime_bytes = p_lb_hard;
1262 m_lt.sadb_lifetime_addtime = p_lt_hard;
1263 m_lt.sadb_lifetime_usetime = 0;
1265 memcpy(u_buf.buf + l, &m_lt, slen);
1269 /* set lifetime for SOFT */
1270 if (p_lt_soft != 0 || p_lb_soft != 0) {
1271 struct sadb_lifetime m_lt;
1272 u_int slen = sizeof(struct sadb_lifetime);
1274 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1275 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1276 m_lt.sadb_lifetime_allocations = 0;
1277 m_lt.sadb_lifetime_bytes = p_lb_soft;
1278 m_lt.sadb_lifetime_addtime = p_lt_soft;
1279 m_lt.sadb_lifetime_usetime = 0;
1281 memcpy(u_buf.buf + l, &m_lt, slen);
1285 len = sizeof(struct sadb_sa);
1286 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1287 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1288 m_sa.sadb_sa_spi = htonl(p_spi);
1289 m_sa.sadb_sa_replay = p_replay;
1290 m_sa.sadb_sa_state = 0;
1291 m_sa.sadb_sa_auth = p_alg_auth;
1292 m_sa.sadb_sa_encrypt = p_alg_enc;
1293 m_sa.sadb_sa_flags = p_ext;
1295 memcpy(u_buf.buf + l, &m_sa, len);
1298 len = sizeof(struct sadb_x_sa2);
1299 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1300 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1301 m_sa2.sadb_x_sa2_mode = p_mode;
1302 m_sa2.sadb_x_sa2_reqid = p_reqid;
1304 memcpy(u_buf.buf + l, &m_sa2, len);
1307 #ifdef SADB_X_EXT_NAT_T_TYPE
1309 struct sadb_x_nat_t_type natt_type;
1311 len = sizeof(struct sadb_x_nat_t_type);
1312 memset(&natt_type, 0, len);
1313 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1314 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1315 natt_type.sadb_x_nat_t_type_type = p_natt_type;
1317 memcpy(buf + l, &natt_type, len);
1321 sa = p_natt_oa->ai_addr;
1322 switch (sa->sa_family) {
1324 plen = sizeof(struct in_addr) << 3;
1328 plen = sizeof(struct in6_addr) << 3;
1334 salen = sysdep_sa_len(sa);
1335 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1336 PFKEY_ALIGN8(salen));
1337 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA;
1338 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1339 m_addr.sadb_address_prefixlen = plen;
1340 m_addr.sadb_address_reserved = 0;
1342 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1343 sizeof(m_addr), sa, salen);
1351 /* do it for all src/dst pairs */
1352 for (s = srcs; s; s = s->ai_next) {
1353 for (d = dsts; d; d = d->ai_next) {
1354 /* rewind pointer */
1357 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1359 switch (s->ai_addr->sa_family) {
1361 plen = sizeof(struct in_addr) << 3;
1365 plen = sizeof(struct in6_addr) << 3;
1374 salen = sysdep_sa_len(s->ai_addr);
1375 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1376 PFKEY_ALIGN8(salen));
1377 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1378 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1379 m_addr.sadb_address_prefixlen = plen;
1380 m_addr.sadb_address_reserved = 0;
1382 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
1383 sizeof(m_addr), sa, salen);
1387 salen = sysdep_sa_len(d->ai_addr);
1388 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1389 PFKEY_ALIGN8(salen));
1390 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1391 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1392 m_addr.sadb_address_prefixlen = plen;
1393 m_addr.sadb_address_reserved = 0;
1395 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
1396 sizeof(m_addr), sa, salen);
1398 #ifdef SADB_X_EXT_NAT_T_TYPE
1400 struct sadb_x_nat_t_port natt_port;
1403 len = sizeof(struct sadb_x_nat_t_port);
1404 memset(&natt_port, 0, len);
1405 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1406 natt_port.sadb_x_nat_t_port_exttype =
1407 SADB_X_EXT_NAT_T_SPORT;
1408 natt_port.sadb_x_nat_t_port_port = htons(get_port(s));
1410 memcpy(buf + l, &natt_port, len);
1414 natt_port.sadb_x_nat_t_port_exttype =
1415 SADB_X_EXT_NAT_T_DPORT;
1416 natt_port.sadb_x_nat_t_port_port = htons(get_port(d));
1418 memcpy(buf + l, &natt_port, len);
1422 msg->sadb_msg_len = PFKEY_UNIT64(l);
1424 sendkeymsg(u_buf.buf, l);
1436 static struct addrinfo *
1437 parse_addr(host, port)
1441 struct addrinfo hints, *res = NULL;
1444 memset(&hints, 0, sizeof(hints));
1445 hints.ai_family = p_aifamily;
1446 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
1447 hints.ai_protocol = IPPROTO_UDP; /*dummy*/
1448 hints.ai_flags = p_aiflags;
1449 error = getaddrinfo(host, port, &hints, &res);
1451 yyerror(gai_strerror(error));
1458 fix_portstr(spec, sport, dport)
1459 vchar_t *spec, *sport, *dport;
1461 const char *p, *p2 = "0";
1466 for (q = spec->buf; *q != ',' && *q != '\0' && l < spec->len; q++, l++)
1473 for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1475 if (*p != '\0' || *p2 == '\0') {
1476 yyerror("invalid an upper layer protocol spec");
1481 sport->buf = strdup(spec->buf);
1483 yyerror("insufficient memory");
1486 sport->len = strlen(sport->buf);
1487 dport->buf = strdup(p2);
1489 yyerror("insufficient memory");
1492 dport->len = strlen(dport->buf);
1498 setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
1501 struct sadb_ext *ebuf;
1506 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1507 memcpy(buf + *off, (caddr_t)ebuf, elen);
1508 memcpy(buf + *off + elen, vbuf, vlen);
1509 (*off) += PFKEY_ALIGN8(elen + vlen);
1519 p_ext = SADB_X_EXT_CYCSEQ;
1520 p_alg_enc = SADB_EALG_NONE;
1521 p_alg_auth = SADB_AALG_NONE;
1522 p_mode = IPSEC_MODE_ANY;
1525 p_key_enc_len = p_key_auth_len = 0;
1526 p_key_enc = p_key_auth = 0;
1527 p_lt_hard = p_lt_soft = 0;
1528 p_lb_hard = p_lb_soft = 0;
1531 p_aifamily = PF_UNSPEC;
1533 /* Clear out any natt OA information */
1535 freeaddrinfo (p_natt_oa);
1545 /* we got tons of memory leaks in the parser anyways, leave them */