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 <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(char *, char *);
89 static int fix_portstr(vchar_t *, vchar_t *, vchar_t *);
90 static int setvarbuf(char *, int *, struct sadb_ext *, int, const void *, int);
91 void parse_init(void);
92 void free_buffer(void);
94 int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t);
95 static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *,
96 struct addrinfo *, int, struct addrinfo *, int);
97 static int setkeymsg_spdaddr_tag(unsigned int, char *, vchar_t *);
98 static int setkeymsg_addr(unsigned int, unsigned int,
99 struct addrinfo *, struct addrinfo *, int);
100 static int setkeymsg_add(unsigned int, unsigned int,
101 struct addrinfo *, struct addrinfo *);
108 struct addrinfo *res;
111 %token EOT SLASH BLCL ELCL
112 %token ADD GET DELETE DELETEALL FLUSH DUMP EXIT
113 %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
114 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
115 %token F_MODE MODE F_REQID
116 %token F_EXT EXTENSION NOCYCLICSEQ
117 %token ALG_AUTH ALG_AUTH_NOKEY
118 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
120 %token F_LIFETIME_HARD F_LIFETIME_SOFT
121 %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT
122 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
124 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
125 %token F_POLICY PL_REQUESTS
129 %type <num> prefix protocol_spec upper_spec
130 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
131 %type <num> ALG_AUTH ALG_AUTH_NOKEY
133 %type <num> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
134 %type <num> EXTENSION MODE
135 %type <ulnum> DECSTRING
136 %type <val> PL_REQUESTS portstr key_string
137 %type <val> policy_requests
138 %type <val> QUOTEDSTRING HEXSTRING STRING
139 %type <val> F_AIFLAGS
140 %type <val> upper_misc_spec policy_spec
141 %type <res> ipaddr ipandport
166 /* commands concerned with management, there is in tail of this file. */
170 : ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
174 status = setkeymsg_add(SADB_ADD, $5, $3, $4);
182 : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
186 if ($3->ai_next || $4->ai_next) {
187 yyerror("multiple address specified");
190 if (p_mode != IPSEC_MODE_ANY)
191 yyerror("WARNING: mode is obsolete");
193 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
199 /* deleteall command */
201 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
205 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
213 : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
217 if (p_mode != IPSEC_MODE_ANY)
218 yyerror("WARNING: mode is obsolete");
220 status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
228 : FLUSH protocol_spec EOT
231 setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
232 sendkeymsg((char *)&msg, sizeof(msg));
238 : DUMP protocol_spec EOT
241 setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
242 sendkeymsg((char *)&msg, sizeof(msg));
249 $$ = SADB_SATYPE_UNSPEC;
253 $$ = SADB_SATYPE_ESP;
255 p_ext |= SADB_X_EXT_OLD;
257 p_ext &= ~SADB_X_EXT_OLD;
263 p_ext |= SADB_X_EXT_OLD;
265 p_ext &= ~SADB_X_EXT_OLD;
269 $$ = SADB_X_SATYPE_IPCOMP;
273 $$ = SADB_SATYPE_ESP;
274 p_ext &= ~SADB_X_EXT_OLD;
276 p_natt_type = UDP_ENCAP_ESPINUDP;
280 $$ = SADB_SATYPE_ESP;
281 p_ext &= ~SADB_X_EXT_OLD;
283 p_natt_type = UDP_ENCAP_ESPINUDP;
287 #ifdef SADB_X_SATYPE_TCPSIGNATURE
288 $$ = SADB_X_SATYPE_TCPSIGNATURE;
294 : DECSTRING { p_spi = $1; }
301 v = strtoul($1.buf, &ep, 16);
303 yyerror("invalid SPI");
306 if (v & ~0xffffffff) {
307 yyerror("SPI too big.");
322 : F_ENC enc_alg F_AUTH auth_alg
334 yyerror("unsupported algorithm");
339 | F_COMP ALG_COMP F_RAWCPI
342 yyerror("unsupported algorithm");
346 p_ext |= SADB_X_EXT_RAWCPI;
353 yyerror("unsupported algorithm");
360 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
361 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
362 yyerror(ipsec_strerror());
366 | ALG_ENC key_string {
368 yyerror("unsupported algorithm");
373 p_key_enc_len = $2.len;
375 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
376 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
377 yyerror(ipsec_strerror());
383 yyerror("unsupported algorithm");
386 yyerror("WARNING: obsolete algorithm");
391 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
392 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
393 yyerror(ipsec_strerror());
397 | ALG_ENC_DESDERIV key_string
400 yyerror("unsupported algorithm");
404 if (p_ext & SADB_X_EXT_OLD) {
405 yyerror("algorithm mismatched");
408 p_ext |= SADB_X_EXT_DERIV;
410 p_key_enc_len = $2.len;
412 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
413 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
414 yyerror(ipsec_strerror());
418 | ALG_ENC_DES32IV key_string
421 yyerror("unsupported algorithm");
425 if (!(p_ext & SADB_X_EXT_OLD)) {
426 yyerror("algorithm mismatched");
429 p_ext |= SADB_X_EXT_IV4B;
431 p_key_enc_len = $2.len;
433 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
434 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
435 yyerror(ipsec_strerror());
442 : ALG_AUTH key_string {
444 yyerror("unsupported algorithm");
449 p_key_auth_len = $2.len;
451 #ifdef SADB_X_AALG_TCP_MD5
452 if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
453 if ((p_key_auth_len < 1) ||
454 (p_key_auth_len > 80))
459 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
461 PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
462 yyerror(ipsec_strerror());
469 yyerror("unsupported algorithm");
491 l = strlen(yp) % 2 + strlen(yp) / 2;
492 if ((pp_key = malloc(l)) == 0) {
493 yyerror("not enough core");
496 memset(pp_key, 0, l);
499 if (strlen(yp) % 2) {
504 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
515 | extension_spec extension
519 : F_EXT EXTENSION { p_ext |= $2; }
520 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
521 | F_MODE MODE { p_mode = $2; }
522 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
523 | F_REQID DECSTRING { p_reqid = $2; }
526 if ((p_ext & SADB_X_EXT_OLD) != 0) {
527 yyerror("replay prevention cannot be used with "
533 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
534 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
535 | F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; }
536 | F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; }
539 /* definition about command for SPD management */
542 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
545 struct addrinfo *src, *dst;
547 #ifdef HAVE_PFKEY_POLICY_PRIORITY
548 last_msg_type = SADB_X_SPDADD;
551 /* fixed port fields if ulp is icmpv6 */
552 if ($10.buf != NULL) {
553 if ($9 != IPPROTO_ICMPV6)
557 if (fix_portstr(&$10, &$5, &$8))
561 src = parse_addr($3.buf, $5.buf);
562 dst = parse_addr($6.buf, $8.buf);
564 /* yyerror is already called */
567 if (src->ai_next || dst->ai_next) {
568 yyerror("multiple address specified");
574 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
581 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT
585 status = setkeymsg_spdaddr_tag(SADB_X_SPDADD,
593 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
596 struct addrinfo *src, *dst;
598 /* fixed port fields if ulp is icmpv6 */
599 if ($10.buf != NULL) {
600 if ($9 != IPPROTO_ICMPV6)
604 if (fix_portstr(&$10, &$5, &$8))
608 src = parse_addr($3.buf, $5.buf);
609 dst = parse_addr($6.buf, $8.buf);
611 /* yyerror is already called */
614 if (src->ai_next || dst->ai_next) {
615 yyerror("multiple address specified");
621 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
634 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
636 sendkeymsg((char *)&msg, sizeof(msg));
645 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
647 sendkeymsg((char *)&msg, sizeof(msg));
653 | ipaddropts ipaddropt
661 for (p = $1.buf + 1; *p; p++)
664 p_aifamily = AF_INET;
668 p_aifamily = AF_INET6;
672 p_aiflags = AI_NUMERICHOST;
675 yyerror("invalid flag");
684 $$ = parse_addr($1.buf, NULL);
686 /* yyerror already called by parse_addr */
695 $$ = parse_addr($1.buf, NULL);
697 /* yyerror already called by parse_addr */
703 $$ = parse_addr($1.buf, $2.buf);
705 /* yyerror already called by parse_addr */
712 : /*NOTHING*/ { $$ = -1; }
713 | SLASH DECSTRING { $$ = $2; }
719 $$.buf = strdup("0");
721 yyerror("insufficient memory");
724 $$.len = strlen($$.buf);
728 $$.buf = strdup("0");
730 yyerror("insufficient memory");
733 $$.len = strlen($$.buf);
735 | BLCL DECSTRING ELCL
738 snprintf(buf, sizeof(buf), "%lu", $2);
739 $$.buf = strdup(buf);
741 yyerror("insufficient memory");
744 $$.len = strlen($$.buf);
753 : DECSTRING { $$ = $1; }
754 | ANY { $$ = IPSEC_ULPROTO_ANY; }
760 struct protoent *ent;
762 ent = getprotobyname($1.buf);
766 if (strcmp("icmp6", $1.buf) == 0) {
768 } else if(strcmp("ip4", $1.buf) == 0) {
771 yyerror("invalid upper layer protocol");
787 $$.buf = strdup($1.buf);
789 yyerror("insufficient memory");
792 $$.len = strlen($$.buf);
797 : F_POLICY policy_requests
800 #ifdef HAVE_PFKEY_POLICY_PRIORITY
801 struct sadb_x_policy *xpl;
804 policy = ipsec_set_policy($2.buf, $2.len);
805 if (policy == NULL) {
806 yyerror(ipsec_strerror());
811 $$.len = ipsec_get_policylen(policy);
813 #ifdef HAVE_PFKEY_POLICY_PRIORITY
814 xpl = (struct sadb_x_policy *) $$.buf;
815 last_priority = xpl->sadb_x_policy_priority;
821 : PL_REQUESTS { $$ = $1; }
835 setkeymsg0(msg, type, satype, l)
836 struct sadb_msg *msg;
842 msg->sadb_msg_version = PF_KEY_V2;
843 msg->sadb_msg_type = type;
844 msg->sadb_msg_errno = 0;
845 msg->sadb_msg_satype = satype;
846 msg->sadb_msg_reserved = 0;
847 msg->sadb_msg_seq = 0;
848 msg->sadb_msg_pid = getpid();
849 msg->sadb_msg_len = PFKEY_UNIT64(l);
853 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
855 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen)
859 struct addrinfo *srcs;
861 struct addrinfo *dsts;
864 struct sadb_msg *msg;
865 union { // Wcast-align fix - force alignment
866 u_int64_t force_align;
870 struct sadb_address m_addr;
871 struct addrinfo *s, *d;
876 struct sadb_x_policy *sp;
877 #ifdef HAVE_POLICY_FWD
878 struct sadb_x_ipsecrequest *ps = NULL;
879 int saved_level, saved_id = 0;
882 msg = (struct sadb_msg *)&u_buf;
887 /* fix up length afterwards */
888 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
889 l = sizeof(struct sadb_msg);
891 sp = ALIGNED_CAST(struct sadb_x_policy*)(u_buf.buf + l);
892 memcpy(u_buf.buf + l, policy->buf, policy->len);
898 /* do it for all src/dst pairs */
899 for (s = srcs; s; s = s->ai_next) {
900 for (d = dsts; d; d = d->ai_next) {
904 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
906 switch (s->ai_addr->sa_family) {
908 plen = sizeof(struct in_addr) << 3;
912 plen = sizeof(struct in6_addr) << 3;
921 salen = sysdep_sa_len(s->ai_addr);
922 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
923 PFKEY_ALIGN8(salen));
924 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
925 m_addr.sadb_address_proto = upper;
926 m_addr.sadb_address_prefixlen =
927 (splen >= 0 ? splen : plen);
928 m_addr.sadb_address_reserved = 0;
930 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
931 sizeof(m_addr), (caddr_t)sa, salen);
935 salen = sysdep_sa_len(d->ai_addr);
936 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
937 PFKEY_ALIGN8(salen));
938 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
939 m_addr.sadb_address_proto = upper;
940 m_addr.sadb_address_prefixlen =
941 (dplen >= 0 ? dplen : plen);
942 m_addr.sadb_address_reserved = 0;
944 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
945 sizeof(m_addr), sa, salen);
947 msg->sadb_msg_len = PFKEY_UNIT64(l);
949 sendkeymsg(u_buf.buf, l);
951 #ifdef HAVE_POLICY_FWD
952 /* create extra call for FWD policy */
953 if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) {
954 sp->sadb_x_policy_dir = IPSEC_DIR_FWD;
955 ps = (struct sadb_x_ipsecrequest*) (sp+1);
957 /* if request level is unique, change it to
958 * require for fwd policy */
959 /* XXX: currently, only first policy is updated
960 * only. Update following too... */
961 saved_level = ps->sadb_x_ipsecrequest_level;
962 if (saved_level == IPSEC_LEVEL_UNIQUE) {
963 saved_id = ps->sadb_x_ipsecrequest_reqid;
964 ps->sadb_x_ipsecrequest_reqid=0;
965 ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE;
969 /* restoring for next message */
970 sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
971 if (saved_level == IPSEC_LEVEL_UNIQUE) {
972 ps->sadb_x_ipsecrequest_reqid = saved_id;
973 ps->sadb_x_ipsecrequest_level = saved_level;
989 setkeymsg_spdaddr_tag(type, tag, policy)
994 struct sadb_msg *msg;
995 union { // Wcast-align fix - force alignment
996 u_int64_t force_align;
1000 #ifdef SADB_X_EXT_TAG
1001 struct sadb_x_tag m_tag;
1005 msg = (struct sadb_msg *)&u_buf;
1007 /* fix up length afterwards */
1008 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
1009 l = sizeof(struct sadb_msg);
1011 memcpy(u_buf.buf + l, policy->buf, policy->len);
1017 #ifdef SADB_X_EXT_TAG
1018 memset(&m_tag, 0, sizeof(m_tag));
1019 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag));
1020 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG;
1021 if (strlcpy(m_tag.sadb_x_tag_name, tag,
1022 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name))
1024 memcpy(buf + l, &m_tag, sizeof(m_tag));
1028 msg->sadb_msg_len = PFKEY_UNIT64(l);
1030 sendkeymsg(u_buf.buf, l);
1035 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1037 setkeymsg_addr(type, satype, srcs, dsts, no_spi)
1039 unsigned int satype;
1040 struct addrinfo *srcs;
1041 struct addrinfo *dsts;
1044 struct sadb_msg *msg;
1045 union { // Wcast-align fix - force alignment
1046 u_int64_t force_align;
1050 struct sadb_sa m_sa;
1051 struct sadb_x_sa2 m_sa2;
1052 struct sadb_address m_addr;
1053 struct addrinfo *s, *d;
1056 struct sockaddr *sa;
1059 msg = (struct sadb_msg *)&u_buf;
1064 /* fix up length afterwards */
1065 setkeymsg0(msg, type, satype, 0);
1066 l = sizeof(struct sadb_msg);
1069 len = sizeof(struct sadb_sa);
1070 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1071 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1072 m_sa.sadb_sa_spi = htonl(p_spi);
1073 m_sa.sadb_sa_replay = p_replay;
1074 m_sa.sadb_sa_state = 0;
1075 m_sa.sadb_sa_auth = p_alg_auth;
1076 m_sa.sadb_sa_encrypt = p_alg_enc;
1077 m_sa.sadb_sa_flags = p_ext;
1079 memcpy(u_buf.buf + l, &m_sa, len);
1082 len = sizeof(struct sadb_x_sa2);
1083 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1084 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1085 m_sa2.sadb_x_sa2_mode = p_mode;
1086 m_sa2.sadb_x_sa2_reqid = p_reqid;
1088 memcpy(u_buf.buf + l, &m_sa2, len);
1095 /* do it for all src/dst pairs */
1096 for (s = srcs; s; s = s->ai_next) {
1097 for (d = dsts; d; d = d->ai_next) {
1098 /* rewind pointer */
1101 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1103 switch (s->ai_addr->sa_family) {
1105 plen = sizeof(struct in_addr) << 3;
1109 plen = sizeof(struct in6_addr) << 3;
1118 salen = sysdep_sa_len(s->ai_addr);
1119 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1120 PFKEY_ALIGN8(salen));
1121 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1122 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1123 m_addr.sadb_address_prefixlen = plen;
1124 m_addr.sadb_address_reserved = 0;
1126 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
1127 sizeof(m_addr), sa, salen);
1131 salen = sysdep_sa_len(d->ai_addr);
1132 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1133 PFKEY_ALIGN8(salen));
1134 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1135 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1136 m_addr.sadb_address_prefixlen = plen;
1137 m_addr.sadb_address_reserved = 0;
1139 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
1140 sizeof(m_addr), sa, salen);
1142 msg->sadb_msg_len = PFKEY_UNIT64(l);
1144 sendkeymsg(u_buf.buf, l);
1156 #ifdef SADB_X_EXT_NAT_T_TYPE
1157 static u_int16_t get_port (struct addrinfo *addr)
1159 struct sockaddr_storage *s = addr->ai_addr;
1162 switch (s->sa_family) {
1165 struct sockaddr_in *sin4 = (struct sockaddr_in *)s;
1166 port = ntohs(sin4->sin_port);
1171 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s;
1172 port = ntohs(sin6->sin6_port);
1178 port = DEFAULT_NATT_PORT;
1184 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1186 setkeymsg_add(type, satype, srcs, dsts)
1188 unsigned int satype;
1189 struct addrinfo *srcs;
1190 struct addrinfo *dsts;
1192 struct sadb_msg *msg;
1193 union { // Wcast-align fix - force alignment
1194 u_int64_t force_align;
1198 struct sadb_sa m_sa;
1199 struct sadb_x_sa2 m_sa2;
1200 struct sadb_address m_addr;
1201 struct addrinfo *s, *d;
1204 struct sockaddr *sa;
1207 msg = (struct sadb_msg *)&u_buf;
1212 /* fix up length afterwards */
1213 setkeymsg0(msg, type, satype, 0);
1214 l = sizeof(struct sadb_msg);
1216 /* set encryption algorithm, if present. */
1217 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1219 struct sadb_key key;
1220 struct sadb_ext ext;
1223 m.key.sadb_key_len =
1224 PFKEY_UNIT64(sizeof(m.key)
1225 + PFKEY_ALIGN8(p_key_enc_len));
1226 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1227 m.key.sadb_key_bits = p_key_enc_len * 8;
1228 m.key.sadb_key_reserved = 0;
1230 setvarbuf(u_buf.buf, &l, &m.ext, sizeof(m.key),
1231 p_key_enc, p_key_enc_len);
1234 /* set authentication algorithm, if present. */
1237 struct sadb_key key;
1238 struct sadb_ext ext;
1241 m.key.sadb_key_len =
1242 PFKEY_UNIT64(sizeof(m.key)
1243 + PFKEY_ALIGN8(p_key_auth_len));
1244 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1245 m.key.sadb_key_bits = p_key_auth_len * 8;
1246 m.key.sadb_key_reserved = 0;
1248 setvarbuf(u_buf.buf, &l, &m.ext, sizeof(m.key),
1249 p_key_auth, p_key_auth_len);
1252 /* set lifetime for HARD */
1253 if (p_lt_hard != 0 || p_lb_hard != 0) {
1254 struct sadb_lifetime m_lt;
1255 u_int slen = sizeof(struct sadb_lifetime);
1257 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1258 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1259 m_lt.sadb_lifetime_allocations = 0;
1260 m_lt.sadb_lifetime_bytes = p_lb_hard;
1261 m_lt.sadb_lifetime_addtime = p_lt_hard;
1262 m_lt.sadb_lifetime_usetime = 0;
1264 memcpy(u_buf.buf + l, &m_lt, slen);
1268 /* set lifetime for SOFT */
1269 if (p_lt_soft != 0 || p_lb_soft != 0) {
1270 struct sadb_lifetime m_lt;
1271 u_int slen = sizeof(struct sadb_lifetime);
1273 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1274 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1275 m_lt.sadb_lifetime_allocations = 0;
1276 m_lt.sadb_lifetime_bytes = p_lb_soft;
1277 m_lt.sadb_lifetime_addtime = p_lt_soft;
1278 m_lt.sadb_lifetime_usetime = 0;
1280 memcpy(u_buf.buf + l, &m_lt, slen);
1284 len = sizeof(struct sadb_sa);
1285 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1286 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1287 m_sa.sadb_sa_spi = htonl(p_spi);
1288 m_sa.sadb_sa_replay = p_replay;
1289 m_sa.sadb_sa_state = 0;
1290 m_sa.sadb_sa_auth = p_alg_auth;
1291 m_sa.sadb_sa_encrypt = p_alg_enc;
1292 m_sa.sadb_sa_flags = p_ext;
1294 memcpy(u_buf.buf + l, &m_sa, len);
1297 len = sizeof(struct sadb_x_sa2);
1298 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1299 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1300 m_sa2.sadb_x_sa2_mode = p_mode;
1301 m_sa2.sadb_x_sa2_reqid = p_reqid;
1303 memcpy(u_buf.buf + l, &m_sa2, len);
1306 #ifdef SADB_X_EXT_NAT_T_TYPE
1308 struct sadb_x_nat_t_type natt_type;
1310 len = sizeof(struct sadb_x_nat_t_type);
1311 memset(&natt_type, 0, len);
1312 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1313 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1314 natt_type.sadb_x_nat_t_type_type = p_natt_type;
1316 memcpy(buf + l, &natt_type, len);
1320 sa = p_natt_oa->ai_addr;
1321 switch (sa->sa_family) {
1323 plen = sizeof(struct in_addr) << 3;
1327 plen = sizeof(struct in6_addr) << 3;
1333 salen = sysdep_sa_len(sa);
1334 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1335 PFKEY_ALIGN8(salen));
1336 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA;
1337 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1338 m_addr.sadb_address_prefixlen = plen;
1339 m_addr.sadb_address_reserved = 0;
1341 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1342 sizeof(m_addr), sa, salen);
1350 /* do it for all src/dst pairs */
1351 for (s = srcs; s; s = s->ai_next) {
1352 for (d = dsts; d; d = d->ai_next) {
1353 /* rewind pointer */
1356 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1358 switch (s->ai_addr->sa_family) {
1360 plen = sizeof(struct in_addr) << 3;
1364 plen = sizeof(struct in6_addr) << 3;
1373 salen = sysdep_sa_len(s->ai_addr);
1374 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1375 PFKEY_ALIGN8(salen));
1376 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1377 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1378 m_addr.sadb_address_prefixlen = plen;
1379 m_addr.sadb_address_reserved = 0;
1381 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
1382 sizeof(m_addr), sa, salen);
1386 salen = sysdep_sa_len(d->ai_addr);
1387 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1388 PFKEY_ALIGN8(salen));
1389 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1390 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1391 m_addr.sadb_address_prefixlen = plen;
1392 m_addr.sadb_address_reserved = 0;
1394 setvarbuf(u_buf.buf, &l, (struct sadb_ext *)&m_addr,
1395 sizeof(m_addr), sa, salen);
1397 #ifdef SADB_X_EXT_NAT_T_TYPE
1399 struct sadb_x_nat_t_port natt_port;
1402 len = sizeof(struct sadb_x_nat_t_port);
1403 memset(&natt_port, 0, len);
1404 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1405 natt_port.sadb_x_nat_t_port_exttype =
1406 SADB_X_EXT_NAT_T_SPORT;
1407 natt_port.sadb_x_nat_t_port_port = htons(get_port(s));
1409 memcpy(buf + l, &natt_port, len);
1413 natt_port.sadb_x_nat_t_port_exttype =
1414 SADB_X_EXT_NAT_T_DPORT;
1415 natt_port.sadb_x_nat_t_port_port = htons(get_port(d));
1417 memcpy(buf + l, &natt_port, len);
1421 msg->sadb_msg_len = PFKEY_UNIT64(l);
1423 sendkeymsg(u_buf.buf, l);
1435 static struct addrinfo *
1436 parse_addr(host, port)
1440 struct addrinfo hints, *res = NULL;
1443 memset(&hints, 0, sizeof(hints));
1444 hints.ai_family = p_aifamily;
1445 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
1446 hints.ai_protocol = IPPROTO_UDP; /*dummy*/
1447 hints.ai_flags = p_aiflags;
1448 error = getaddrinfo(host, port, &hints, &res);
1450 yyerror(gai_strerror(error));
1457 fix_portstr(spec, sport, dport)
1458 vchar_t *spec, *sport, *dport;
1460 const char *p, *p2 = "0";
1465 for (q = spec->buf; *q != ',' && *q != '\0' && l < spec->len; q++, l++)
1472 for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1474 if (*p != '\0' || *p2 == '\0') {
1475 yyerror("invalid an upper layer protocol spec");
1480 sport->buf = strdup(spec->buf);
1482 yyerror("insufficient memory");
1485 sport->len = strlen(sport->buf);
1486 dport->buf = strdup(p2);
1488 yyerror("insufficient memory");
1491 dport->len = strlen(dport->buf);
1497 setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
1500 struct sadb_ext *ebuf;
1505 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1506 memcpy(buf + *off, (caddr_t)ebuf, elen);
1507 memcpy(buf + *off + elen, vbuf, vlen);
1508 (*off) += PFKEY_ALIGN8(elen + vlen);
1518 p_ext = SADB_X_EXT_CYCSEQ;
1519 p_alg_enc = SADB_EALG_NONE;
1520 p_alg_auth = SADB_AALG_NONE;
1521 p_mode = IPSEC_MODE_ANY;
1524 p_key_enc_len = p_key_auth_len = 0;
1525 p_key_enc = p_key_auth = 0;
1526 p_lt_hard = p_lt_soft = 0;
1527 p_lb_hard = p_lb_soft = 0;
1530 p_aifamily = PF_UNSPEC;
1532 /* Clear out any natt OA information */
1534 freeaddrinfo (p_natt_oa);
1544 /* we got tons of memory leaks in the parser anyways, leave them */