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>
44 #include <System/net/pfkeyv2.h>
46 #include <net/pfkeyv2.h>
48 #ifdef HAVE_NETINET6_IPSEC
49 # include <netinet6/ipsec.h>
51 # include <netinet/ipsec.h>
53 #include <arpa/inet.h>
67 #define DEFAULT_NATT_PORT 4500
69 #ifndef UDP_ENCAP_ESPINUDP
70 #define UDP_ENCAP_ESPINUDP 2
74 (isdigit((int)c) ? (c - '0') : \
75 (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10)))
78 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
80 u_int p_key_enc_len, p_key_auth_len;
81 const char *p_key_enc;
82 const char *p_key_auth;
83 time_t p_lt_hard, p_lt_soft;
84 size_t p_lb_hard, p_lb_soft;
86 static u_int p_natt_type;
87 static struct addrinfo * p_natt_oa = NULL;
89 static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
91 static struct addrinfo *parse_addr __P((char *, char *));
92 static int fix_portstr __P((vchar_t *, vchar_t *, vchar_t *));
93 static int setvarbuf __P((char *, int *, struct sadb_ext *, int,
95 void parse_init __P((void));
96 void free_buffer __P((void));
98 int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t));
99 static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *,
100 struct addrinfo *, int, struct addrinfo *, int));
101 static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *));
102 static int setkeymsg_addr __P((unsigned int, unsigned int,
103 struct addrinfo *, struct addrinfo *, int));
104 static int setkeymsg_add __P((unsigned int, unsigned int,
105 struct addrinfo *, struct addrinfo *));
112 struct addrinfo *res;
115 %token EOT SLASH BLCL ELCL
116 %token ADD GET DELETE DELETEALL FLUSH DUMP EXIT
117 %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
118 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
119 %token F_MODE MODE F_REQID
120 %token F_EXT EXTENSION NOCYCLICSEQ
121 %token ALG_AUTH ALG_AUTH_NOKEY
122 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
124 %token F_LIFETIME_HARD F_LIFETIME_SOFT
125 %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT
126 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
128 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
129 %token F_POLICY PL_REQUESTS
133 %type <num> prefix protocol_spec upper_spec
134 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
135 %type <num> ALG_AUTH ALG_AUTH_NOKEY
137 %type <num> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
138 %type <num> EXTENSION MODE
139 %type <ulnum> DECSTRING
140 %type <val> PL_REQUESTS portstr key_string
141 %type <val> policy_requests
142 %type <val> QUOTEDSTRING HEXSTRING STRING
143 %type <val> F_AIFLAGS
144 %type <val> upper_misc_spec policy_spec
145 %type <res> ipaddr ipandport
170 /* commands concerned with management, there is in tail of this file. */
174 : ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
178 status = setkeymsg_add(SADB_ADD, $5, $3, $4);
186 : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
190 if ($3->ai_next || $4->ai_next) {
191 yyerror("multiple address specified");
194 if (p_mode != IPSEC_MODE_ANY)
195 yyerror("WARNING: mode is obsolete");
197 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
203 /* deleteall command */
205 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
209 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
217 : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
221 if (p_mode != IPSEC_MODE_ANY)
222 yyerror("WARNING: mode is obsolete");
224 status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
232 : FLUSH protocol_spec EOT
235 setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
236 sendkeymsg((char *)&msg, sizeof(msg));
242 : DUMP protocol_spec EOT
245 setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
246 sendkeymsg((char *)&msg, sizeof(msg));
253 $$ = SADB_SATYPE_UNSPEC;
257 $$ = SADB_SATYPE_ESP;
259 p_ext |= SADB_X_EXT_OLD;
261 p_ext &= ~SADB_X_EXT_OLD;
267 p_ext |= SADB_X_EXT_OLD;
269 p_ext &= ~SADB_X_EXT_OLD;
273 $$ = SADB_X_SATYPE_IPCOMP;
277 $$ = SADB_SATYPE_ESP;
278 p_ext &= ~SADB_X_EXT_OLD;
280 p_natt_type = UDP_ENCAP_ESPINUDP;
284 $$ = SADB_SATYPE_ESP;
285 p_ext &= ~SADB_X_EXT_OLD;
287 p_natt_type = UDP_ENCAP_ESPINUDP;
291 #ifdef SADB_X_SATYPE_TCPSIGNATURE
292 $$ = SADB_X_SATYPE_TCPSIGNATURE;
298 : DECSTRING { p_spi = $1; }
305 v = strtoul($1.buf, &ep, 16);
307 yyerror("invalid SPI");
310 if (v & ~0xffffffff) {
311 yyerror("SPI too big.");
326 : F_ENC enc_alg F_AUTH auth_alg
338 yyerror("unsupported algorithm");
343 | F_COMP ALG_COMP F_RAWCPI
346 yyerror("unsupported algorithm");
350 p_ext |= SADB_X_EXT_RAWCPI;
357 yyerror("unsupported algorithm");
364 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
365 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
366 yyerror(ipsec_strerror());
370 | ALG_ENC key_string {
372 yyerror("unsupported algorithm");
377 p_key_enc_len = $2.len;
379 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
380 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
381 yyerror(ipsec_strerror());
387 yyerror("unsupported algorithm");
390 yyerror("WARNING: obsolete algorithm");
395 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
396 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
397 yyerror(ipsec_strerror());
401 | ALG_ENC_DESDERIV key_string
404 yyerror("unsupported algorithm");
408 if (p_ext & SADB_X_EXT_OLD) {
409 yyerror("algorithm mismatched");
412 p_ext |= SADB_X_EXT_DERIV;
414 p_key_enc_len = $2.len;
416 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
417 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
418 yyerror(ipsec_strerror());
422 | ALG_ENC_DES32IV key_string
425 yyerror("unsupported algorithm");
429 if (!(p_ext & SADB_X_EXT_OLD)) {
430 yyerror("algorithm mismatched");
433 p_ext |= SADB_X_EXT_IV4B;
435 p_key_enc_len = $2.len;
437 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
438 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
439 yyerror(ipsec_strerror());
446 : ALG_AUTH key_string {
448 yyerror("unsupported algorithm");
453 p_key_auth_len = $2.len;
455 #ifdef SADB_X_AALG_TCP_MD5
456 if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
457 if ((p_key_auth_len < 1) ||
458 (p_key_auth_len > 80))
463 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
465 PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
466 yyerror(ipsec_strerror());
473 yyerror("unsupported algorithm");
495 l = strlen(yp) % 2 + strlen(yp) / 2;
496 if ((pp_key = malloc(l)) == 0) {
497 yyerror("not enough core");
500 memset(pp_key, 0, l);
503 if (strlen(yp) % 2) {
508 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
519 | extension_spec extension
523 : F_EXT EXTENSION { p_ext |= $2; }
524 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
525 | F_MODE MODE { p_mode = $2; }
526 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
527 | F_REQID DECSTRING { p_reqid = $2; }
530 if ((p_ext & SADB_X_EXT_OLD) != 0) {
531 yyerror("replay prevention cannot be used with "
537 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
538 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
539 | F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; }
540 | F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; }
543 /* definition about command for SPD management */
546 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
549 struct addrinfo *src, *dst;
551 #ifdef HAVE_PFKEY_POLICY_PRIORITY
552 last_msg_type = SADB_X_SPDADD;
555 /* fixed port fields if ulp is icmpv6 */
556 if ($10.buf != NULL) {
557 if ($9 != IPPROTO_ICMPV6)
561 if (fix_portstr(&$10, &$5, &$8))
565 src = parse_addr($3.buf, $5.buf);
566 dst = parse_addr($6.buf, $8.buf);
568 /* yyerror is already called */
571 if (src->ai_next || dst->ai_next) {
572 yyerror("multiple address specified");
578 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
585 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT
589 status = setkeymsg_spdaddr_tag(SADB_X_SPDADD,
597 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
600 struct addrinfo *src, *dst;
602 /* fixed port fields if ulp is icmpv6 */
603 if ($10.buf != NULL) {
604 if ($9 != IPPROTO_ICMPV6)
608 if (fix_portstr(&$10, &$5, &$8))
612 src = parse_addr($3.buf, $5.buf);
613 dst = parse_addr($6.buf, $8.buf);
615 /* yyerror is already called */
618 if (src->ai_next || dst->ai_next) {
619 yyerror("multiple address specified");
625 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
638 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
640 sendkeymsg((char *)&msg, sizeof(msg));
649 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
651 sendkeymsg((char *)&msg, sizeof(msg));
657 | ipaddropts ipaddropt
665 for (p = $1.buf + 1; *p; p++)
668 p_aifamily = AF_INET;
672 p_aifamily = AF_INET6;
676 p_aiflags = AI_NUMERICHOST;
679 yyerror("invalid flag");
688 $$ = parse_addr($1.buf, NULL);
690 /* yyerror already called by parse_addr */
699 $$ = parse_addr($1.buf, NULL);
701 /* yyerror already called by parse_addr */
707 $$ = parse_addr($1.buf, $2.buf);
709 /* yyerror already called by parse_addr */
716 : /*NOTHING*/ { $$ = -1; }
717 | SLASH DECSTRING { $$ = $2; }
723 $$.buf = strdup("0");
725 yyerror("insufficient memory");
728 $$.len = strlen($$.buf);
732 $$.buf = strdup("0");
734 yyerror("insufficient memory");
737 $$.len = strlen($$.buf);
739 | BLCL DECSTRING ELCL
742 snprintf(buf, sizeof(buf), "%lu", $2);
743 $$.buf = strdup(buf);
745 yyerror("insufficient memory");
748 $$.len = strlen($$.buf);
757 : DECSTRING { $$ = $1; }
758 | ANY { $$ = IPSEC_ULPROTO_ANY; }
764 struct protoent *ent;
766 ent = getprotobyname($1.buf);
770 if (strcmp("icmp6", $1.buf) == 0) {
772 } else if(strcmp("ip4", $1.buf) == 0) {
775 yyerror("invalid upper layer protocol");
791 $$.buf = strdup($1.buf);
793 yyerror("insufficient memory");
796 $$.len = strlen($$.buf);
801 : F_POLICY policy_requests
804 #ifdef HAVE_PFKEY_POLICY_PRIORITY
805 struct sadb_x_policy *xpl;
808 policy = ipsec_set_policy($2.buf, $2.len);
809 if (policy == NULL) {
810 yyerror(ipsec_strerror());
815 $$.len = ipsec_get_policylen(policy);
817 #ifdef HAVE_PFKEY_POLICY_PRIORITY
818 xpl = (struct sadb_x_policy *) $$.buf;
819 last_priority = xpl->sadb_x_policy_priority;
825 : PL_REQUESTS { $$ = $1; }
839 setkeymsg0(msg, type, satype, l)
840 struct sadb_msg *msg;
846 msg->sadb_msg_version = PF_KEY_V2;
847 msg->sadb_msg_type = type;
848 msg->sadb_msg_errno = 0;
849 msg->sadb_msg_satype = satype;
850 msg->sadb_msg_reserved = 0;
851 msg->sadb_msg_seq = 0;
852 msg->sadb_msg_pid = getpid();
853 msg->sadb_msg_len = PFKEY_UNIT64(l);
857 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
859 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen)
863 struct addrinfo *srcs;
865 struct addrinfo *dsts;
868 struct sadb_msg *msg;
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 *)buf;
888 /* fix up length afterwards */
889 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
890 l = sizeof(struct sadb_msg);
892 sp = (struct sadb_x_policy*) (buf + l);
893 memcpy(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(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(buf, &l, (struct sadb_ext *)&m_addr,
946 sizeof(m_addr), sa, salen);
948 msg->sadb_msg_len = PFKEY_UNIT64(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;
998 #ifdef SADB_X_EXT_TAG
999 struct sadb_x_tag m_tag;
1003 msg = (struct sadb_msg *)buf;
1005 /* fix up length afterwards */
1006 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
1007 l = sizeof(struct sadb_msg);
1009 memcpy(buf + l, policy->buf, policy->len);
1015 #ifdef SADB_X_EXT_TAG
1016 memset(&m_tag, 0, sizeof(m_tag));
1017 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag));
1018 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG;
1019 if (strlcpy(m_tag.sadb_x_tag_name, tag,
1020 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name))
1022 memcpy(buf + l, &m_tag, sizeof(m_tag));
1026 msg->sadb_msg_len = PFKEY_UNIT64(l);
1033 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1035 setkeymsg_addr(type, satype, srcs, dsts, no_spi)
1037 unsigned int satype;
1038 struct addrinfo *srcs;
1039 struct addrinfo *dsts;
1042 struct sadb_msg *msg;
1045 struct sadb_sa m_sa;
1046 struct sadb_x_sa2 m_sa2;
1047 struct sadb_address m_addr;
1048 struct addrinfo *s, *d;
1051 struct sockaddr *sa;
1054 msg = (struct sadb_msg *)buf;
1059 /* fix up length afterwards */
1060 setkeymsg0(msg, type, satype, 0);
1061 l = sizeof(struct sadb_msg);
1064 len = sizeof(struct sadb_sa);
1065 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1066 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1067 m_sa.sadb_sa_spi = htonl(p_spi);
1068 m_sa.sadb_sa_replay = p_replay;
1069 m_sa.sadb_sa_state = 0;
1070 m_sa.sadb_sa_auth = p_alg_auth;
1071 m_sa.sadb_sa_encrypt = p_alg_enc;
1072 m_sa.sadb_sa_flags = p_ext;
1074 memcpy(buf + l, &m_sa, len);
1077 len = sizeof(struct sadb_x_sa2);
1078 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1079 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1080 m_sa2.sadb_x_sa2_mode = p_mode;
1081 m_sa2.sadb_x_sa2_reqid = p_reqid;
1083 memcpy(buf + l, &m_sa2, len);
1090 /* do it for all src/dst pairs */
1091 for (s = srcs; s; s = s->ai_next) {
1092 for (d = dsts; d; d = d->ai_next) {
1093 /* rewind pointer */
1096 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1098 switch (s->ai_addr->sa_family) {
1100 plen = sizeof(struct in_addr) << 3;
1104 plen = sizeof(struct in6_addr) << 3;
1113 salen = sysdep_sa_len(s->ai_addr);
1114 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1115 PFKEY_ALIGN8(salen));
1116 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1117 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1118 m_addr.sadb_address_prefixlen = plen;
1119 m_addr.sadb_address_reserved = 0;
1121 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1122 sizeof(m_addr), sa, salen);
1126 salen = sysdep_sa_len(d->ai_addr);
1127 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1128 PFKEY_ALIGN8(salen));
1129 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1130 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1131 m_addr.sadb_address_prefixlen = plen;
1132 m_addr.sadb_address_reserved = 0;
1134 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1135 sizeof(m_addr), sa, salen);
1137 msg->sadb_msg_len = PFKEY_UNIT64(l);
1151 #ifdef SADB_X_EXT_NAT_T_TYPE
1152 static u_int16_t get_port (struct addrinfo *addr)
1154 struct sockaddr *s = addr->ai_addr;
1157 switch (s->sa_family) {
1160 struct sockaddr_in *sin4 = (struct sockaddr_in *)s;
1161 port = ntohs(sin4->sin_port);
1166 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s;
1167 port = ntohs(sin6->sin6_port);
1173 port = DEFAULT_NATT_PORT;
1179 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1181 setkeymsg_add(type, satype, srcs, dsts)
1183 unsigned int satype;
1184 struct addrinfo *srcs;
1185 struct addrinfo *dsts;
1187 struct sadb_msg *msg;
1190 struct sadb_sa m_sa;
1191 struct sadb_x_sa2 m_sa2;
1192 struct sadb_address m_addr;
1193 struct addrinfo *s, *d;
1196 struct sockaddr *sa;
1199 msg = (struct sadb_msg *)buf;
1204 /* fix up length afterwards */
1205 setkeymsg0(msg, type, satype, 0);
1206 l = sizeof(struct sadb_msg);
1208 /* set encryption algorithm, if present. */
1209 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1211 struct sadb_key key;
1212 struct sadb_ext ext;
1215 m.key.sadb_key_len =
1216 PFKEY_UNIT64(sizeof(m.key)
1217 + PFKEY_ALIGN8(p_key_enc_len));
1218 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1219 m.key.sadb_key_bits = p_key_enc_len * 8;
1220 m.key.sadb_key_reserved = 0;
1222 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1223 p_key_enc, p_key_enc_len);
1226 /* set authentication algorithm, if present. */
1229 struct sadb_key key;
1230 struct sadb_ext ext;
1233 m.key.sadb_key_len =
1234 PFKEY_UNIT64(sizeof(m.key)
1235 + PFKEY_ALIGN8(p_key_auth_len));
1236 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1237 m.key.sadb_key_bits = p_key_auth_len * 8;
1238 m.key.sadb_key_reserved = 0;
1240 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1241 p_key_auth, p_key_auth_len);
1244 /* set lifetime for HARD */
1245 if (p_lt_hard != 0 || p_lb_hard != 0) {
1246 struct sadb_lifetime m_lt;
1247 u_int slen = sizeof(struct sadb_lifetime);
1249 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1250 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1251 m_lt.sadb_lifetime_allocations = 0;
1252 m_lt.sadb_lifetime_bytes = p_lb_hard;
1253 m_lt.sadb_lifetime_addtime = p_lt_hard;
1254 m_lt.sadb_lifetime_usetime = 0;
1256 memcpy(buf + l, &m_lt, slen);
1260 /* set lifetime for SOFT */
1261 if (p_lt_soft != 0 || p_lb_soft != 0) {
1262 struct sadb_lifetime m_lt;
1263 u_int slen = sizeof(struct sadb_lifetime);
1265 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1266 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1267 m_lt.sadb_lifetime_allocations = 0;
1268 m_lt.sadb_lifetime_bytes = p_lb_soft;
1269 m_lt.sadb_lifetime_addtime = p_lt_soft;
1270 m_lt.sadb_lifetime_usetime = 0;
1272 memcpy(buf + l, &m_lt, slen);
1276 len = sizeof(struct sadb_sa);
1277 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1278 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1279 m_sa.sadb_sa_spi = htonl(p_spi);
1280 m_sa.sadb_sa_replay = p_replay;
1281 m_sa.sadb_sa_state = 0;
1282 m_sa.sadb_sa_auth = p_alg_auth;
1283 m_sa.sadb_sa_encrypt = p_alg_enc;
1284 m_sa.sadb_sa_flags = p_ext;
1286 memcpy(buf + l, &m_sa, len);
1289 len = sizeof(struct sadb_x_sa2);
1290 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1291 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1292 m_sa2.sadb_x_sa2_mode = p_mode;
1293 m_sa2.sadb_x_sa2_reqid = p_reqid;
1295 memcpy(buf + l, &m_sa2, len);
1298 #ifdef SADB_X_EXT_NAT_T_TYPE
1300 struct sadb_x_nat_t_type natt_type;
1302 len = sizeof(struct sadb_x_nat_t_type);
1303 memset(&natt_type, 0, len);
1304 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1305 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1306 natt_type.sadb_x_nat_t_type_type = p_natt_type;
1308 memcpy(buf + l, &natt_type, len);
1312 sa = p_natt_oa->ai_addr;
1313 switch (sa->sa_family) {
1315 plen = sizeof(struct in_addr) << 3;
1319 plen = sizeof(struct in6_addr) << 3;
1325 salen = sysdep_sa_len(sa);
1326 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1327 PFKEY_ALIGN8(salen));
1328 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA;
1329 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1330 m_addr.sadb_address_prefixlen = plen;
1331 m_addr.sadb_address_reserved = 0;
1333 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1334 sizeof(m_addr), sa, salen);
1342 /* do it for all src/dst pairs */
1343 for (s = srcs; s; s = s->ai_next) {
1344 for (d = dsts; d; d = d->ai_next) {
1345 /* rewind pointer */
1348 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1350 switch (s->ai_addr->sa_family) {
1352 plen = sizeof(struct in_addr) << 3;
1356 plen = sizeof(struct in6_addr) << 3;
1365 salen = sysdep_sa_len(s->ai_addr);
1366 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1367 PFKEY_ALIGN8(salen));
1368 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1369 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1370 m_addr.sadb_address_prefixlen = plen;
1371 m_addr.sadb_address_reserved = 0;
1373 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1374 sizeof(m_addr), sa, salen);
1378 salen = sysdep_sa_len(d->ai_addr);
1379 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1380 PFKEY_ALIGN8(salen));
1381 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1382 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1383 m_addr.sadb_address_prefixlen = plen;
1384 m_addr.sadb_address_reserved = 0;
1386 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1387 sizeof(m_addr), sa, salen);
1389 #ifdef SADB_X_EXT_NAT_T_TYPE
1391 struct sadb_x_nat_t_port natt_port;
1394 len = sizeof(struct sadb_x_nat_t_port);
1395 memset(&natt_port, 0, len);
1396 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1397 natt_port.sadb_x_nat_t_port_exttype =
1398 SADB_X_EXT_NAT_T_SPORT;
1399 natt_port.sadb_x_nat_t_port_port = htons(get_port(s));
1401 memcpy(buf + l, &natt_port, len);
1405 natt_port.sadb_x_nat_t_port_exttype =
1406 SADB_X_EXT_NAT_T_DPORT;
1407 natt_port.sadb_x_nat_t_port_port = htons(get_port(d));
1409 memcpy(buf + l, &natt_port, len);
1413 msg->sadb_msg_len = PFKEY_UNIT64(l);
1427 static struct addrinfo *
1428 parse_addr(host, port)
1432 struct addrinfo hints, *res = NULL;
1435 memset(&hints, 0, sizeof(hints));
1436 hints.ai_family = p_aifamily;
1437 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
1438 hints.ai_protocol = IPPROTO_UDP; /*dummy*/
1439 hints.ai_flags = p_aiflags;
1440 error = getaddrinfo(host, port, &hints, &res);
1442 yyerror(gai_strerror(error));
1449 fix_portstr(spec, sport, dport)
1450 vchar_t *spec, *sport, *dport;
1452 const char *p, *p2 = "0";
1457 for (q = spec->buf; *q != ',' && *q != '\0' && l < spec->len; q++, l++)
1464 for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1466 if (*p != '\0' || *p2 == '\0') {
1467 yyerror("invalid an upper layer protocol spec");
1472 sport->buf = strdup(spec->buf);
1474 yyerror("insufficient memory");
1477 sport->len = strlen(sport->buf);
1478 dport->buf = strdup(p2);
1480 yyerror("insufficient memory");
1483 dport->len = strlen(dport->buf);
1489 setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
1492 struct sadb_ext *ebuf;
1497 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1498 memcpy(buf + *off, (caddr_t)ebuf, elen);
1499 memcpy(buf + *off + elen, vbuf, vlen);
1500 (*off) += PFKEY_ALIGN8(elen + vlen);
1510 p_ext = SADB_X_EXT_CYCSEQ;
1511 p_alg_enc = SADB_EALG_NONE;
1512 p_alg_auth = SADB_AALG_NONE;
1513 p_mode = IPSEC_MODE_ANY;
1516 p_key_enc_len = p_key_auth_len = 0;
1517 p_key_enc = p_key_auth = 0;
1518 p_lt_hard = p_lt_soft = 0;
1519 p_lb_hard = p_lb_soft = 0;
1522 p_aifamily = PF_UNSPEC;
1524 /* Clear out any natt OA information */
1526 freeaddrinfo (p_natt_oa);
1536 /* we got tons of memory leaks in the parser anyways, leave them */