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>
63 #define DEFAULT_NATT_PORT 4500
65 #ifndef UDP_ENCAP_ESPINUDP
66 #define UDP_ENCAP_ESPINUDP 2
70 (isdigit((int)c) ? (c - '0') : \
71 (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10)))
74 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
76 u_int p_key_enc_len, p_key_auth_len;
77 const char *p_key_enc;
78 const char *p_key_auth;
79 time_t p_lt_hard, p_lt_soft;
80 size_t p_lb_hard, p_lb_soft;
82 static u_int p_natt_type;
83 static struct addrinfo * p_natt_oa = NULL;
85 static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
87 static struct addrinfo *parse_addr __P((char *, char *));
88 static int fix_portstr __P((vchar_t *, vchar_t *, vchar_t *));
89 static int setvarbuf __P((char *, int *, struct sadb_ext *, int,
91 void parse_init __P((void));
92 void free_buffer __P((void));
94 int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t));
95 static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *,
96 struct addrinfo *, int, struct addrinfo *, int));
97 static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *));
98 static int setkeymsg_addr __P((unsigned int, unsigned int,
99 struct addrinfo *, struct addrinfo *, int));
100 static int setkeymsg_add __P((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;
867 struct sadb_address m_addr;
868 struct addrinfo *s, *d;
873 struct sadb_x_policy *sp;
874 #ifdef HAVE_POLICY_FWD
875 struct sadb_x_ipsecrequest *ps = NULL;
876 int saved_level, saved_id = 0;
879 msg = (struct sadb_msg *)buf;
884 /* fix up length afterwards */
885 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
886 l = sizeof(struct sadb_msg);
888 sp = (struct sadb_x_policy*) (buf + l);
889 memcpy(buf + l, policy->buf, policy->len);
895 /* do it for all src/dst pairs */
896 for (s = srcs; s; s = s->ai_next) {
897 for (d = dsts; d; d = d->ai_next) {
901 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
903 switch (s->ai_addr->sa_family) {
905 plen = sizeof(struct in_addr) << 3;
909 plen = sizeof(struct in6_addr) << 3;
918 salen = sysdep_sa_len(s->ai_addr);
919 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
920 PFKEY_ALIGN8(salen));
921 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
922 m_addr.sadb_address_proto = upper;
923 m_addr.sadb_address_prefixlen =
924 (splen >= 0 ? splen : plen);
925 m_addr.sadb_address_reserved = 0;
927 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
928 sizeof(m_addr), (caddr_t)sa, salen);
932 salen = sysdep_sa_len(d->ai_addr);
933 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
934 PFKEY_ALIGN8(salen));
935 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
936 m_addr.sadb_address_proto = upper;
937 m_addr.sadb_address_prefixlen =
938 (dplen >= 0 ? dplen : plen);
939 m_addr.sadb_address_reserved = 0;
941 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
942 sizeof(m_addr), sa, salen);
944 msg->sadb_msg_len = PFKEY_UNIT64(l);
948 #ifdef HAVE_POLICY_FWD
949 /* create extra call for FWD policy */
950 if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) {
951 sp->sadb_x_policy_dir = IPSEC_DIR_FWD;
952 ps = (struct sadb_x_ipsecrequest*) (sp+1);
954 /* if request level is unique, change it to
955 * require for fwd policy */
956 /* XXX: currently, only first policy is updated
957 * only. Update following too... */
958 saved_level = ps->sadb_x_ipsecrequest_level;
959 if (saved_level == IPSEC_LEVEL_UNIQUE) {
960 saved_id = ps->sadb_x_ipsecrequest_reqid;
961 ps->sadb_x_ipsecrequest_reqid=0;
962 ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE;
966 /* restoring for next message */
967 sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
968 if (saved_level == IPSEC_LEVEL_UNIQUE) {
969 ps->sadb_x_ipsecrequest_reqid = saved_id;
970 ps->sadb_x_ipsecrequest_level = saved_level;
986 setkeymsg_spdaddr_tag(type, tag, policy)
991 struct sadb_msg *msg;
994 #ifdef SADB_X_EXT_TAG
995 struct sadb_x_tag m_tag;
999 msg = (struct sadb_msg *)buf;
1001 /* fix up length afterwards */
1002 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
1003 l = sizeof(struct sadb_msg);
1005 memcpy(buf + l, policy->buf, policy->len);
1011 #ifdef SADB_X_EXT_TAG
1012 memset(&m_tag, 0, sizeof(m_tag));
1013 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag));
1014 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG;
1015 if (strlcpy(m_tag.sadb_x_tag_name, tag,
1016 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name))
1018 memcpy(buf + l, &m_tag, sizeof(m_tag));
1022 msg->sadb_msg_len = PFKEY_UNIT64(l);
1029 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1031 setkeymsg_addr(type, satype, srcs, dsts, no_spi)
1033 unsigned int satype;
1034 struct addrinfo *srcs;
1035 struct addrinfo *dsts;
1038 struct sadb_msg *msg;
1041 struct sadb_sa m_sa;
1042 struct sadb_x_sa2 m_sa2;
1043 struct sadb_address m_addr;
1044 struct addrinfo *s, *d;
1047 struct sockaddr *sa;
1050 msg = (struct sadb_msg *)buf;
1055 /* fix up length afterwards */
1056 setkeymsg0(msg, type, satype, 0);
1057 l = sizeof(struct sadb_msg);
1060 len = sizeof(struct sadb_sa);
1061 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1062 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1063 m_sa.sadb_sa_spi = htonl(p_spi);
1064 m_sa.sadb_sa_replay = p_replay;
1065 m_sa.sadb_sa_state = 0;
1066 m_sa.sadb_sa_auth = p_alg_auth;
1067 m_sa.sadb_sa_encrypt = p_alg_enc;
1068 m_sa.sadb_sa_flags = p_ext;
1070 memcpy(buf + l, &m_sa, len);
1073 len = sizeof(struct sadb_x_sa2);
1074 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1075 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1076 m_sa2.sadb_x_sa2_mode = p_mode;
1077 m_sa2.sadb_x_sa2_reqid = p_reqid;
1079 memcpy(buf + l, &m_sa2, len);
1086 /* do it for all src/dst pairs */
1087 for (s = srcs; s; s = s->ai_next) {
1088 for (d = dsts; d; d = d->ai_next) {
1089 /* rewind pointer */
1092 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1094 switch (s->ai_addr->sa_family) {
1096 plen = sizeof(struct in_addr) << 3;
1100 plen = sizeof(struct in6_addr) << 3;
1109 salen = sysdep_sa_len(s->ai_addr);
1110 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1111 PFKEY_ALIGN8(salen));
1112 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1113 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1114 m_addr.sadb_address_prefixlen = plen;
1115 m_addr.sadb_address_reserved = 0;
1117 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1118 sizeof(m_addr), sa, salen);
1122 salen = sysdep_sa_len(d->ai_addr);
1123 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1124 PFKEY_ALIGN8(salen));
1125 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1126 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1127 m_addr.sadb_address_prefixlen = plen;
1128 m_addr.sadb_address_reserved = 0;
1130 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1131 sizeof(m_addr), sa, salen);
1133 msg->sadb_msg_len = PFKEY_UNIT64(l);
1147 #ifdef SADB_X_EXT_NAT_T_TYPE
1148 static u_int16_t get_port (struct addrinfo *addr)
1150 struct sockaddr *s = addr->ai_addr;
1153 switch (s->sa_family) {
1156 struct sockaddr_in *sin4 = (struct sockaddr_in *)s;
1157 port = ntohs(sin4->sin_port);
1162 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s;
1163 port = ntohs(sin6->sin6_port);
1169 port = DEFAULT_NATT_PORT;
1175 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1177 setkeymsg_add(type, satype, srcs, dsts)
1179 unsigned int satype;
1180 struct addrinfo *srcs;
1181 struct addrinfo *dsts;
1183 struct sadb_msg *msg;
1186 struct sadb_sa m_sa;
1187 struct sadb_x_sa2 m_sa2;
1188 struct sadb_address m_addr;
1189 struct addrinfo *s, *d;
1192 struct sockaddr *sa;
1195 msg = (struct sadb_msg *)buf;
1200 /* fix up length afterwards */
1201 setkeymsg0(msg, type, satype, 0);
1202 l = sizeof(struct sadb_msg);
1204 /* set encryption algorithm, if present. */
1205 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1207 struct sadb_key key;
1208 struct sadb_ext ext;
1211 m.key.sadb_key_len =
1212 PFKEY_UNIT64(sizeof(m.key)
1213 + PFKEY_ALIGN8(p_key_enc_len));
1214 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1215 m.key.sadb_key_bits = p_key_enc_len * 8;
1216 m.key.sadb_key_reserved = 0;
1218 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1219 p_key_enc, p_key_enc_len);
1222 /* set authentication algorithm, if present. */
1225 struct sadb_key key;
1226 struct sadb_ext ext;
1229 m.key.sadb_key_len =
1230 PFKEY_UNIT64(sizeof(m.key)
1231 + PFKEY_ALIGN8(p_key_auth_len));
1232 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1233 m.key.sadb_key_bits = p_key_auth_len * 8;
1234 m.key.sadb_key_reserved = 0;
1236 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1237 p_key_auth, p_key_auth_len);
1240 /* set lifetime for HARD */
1241 if (p_lt_hard != 0 || p_lb_hard != 0) {
1242 struct sadb_lifetime m_lt;
1243 u_int slen = sizeof(struct sadb_lifetime);
1245 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1246 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1247 m_lt.sadb_lifetime_allocations = 0;
1248 m_lt.sadb_lifetime_bytes = p_lb_hard;
1249 m_lt.sadb_lifetime_addtime = p_lt_hard;
1250 m_lt.sadb_lifetime_usetime = 0;
1252 memcpy(buf + l, &m_lt, slen);
1256 /* set lifetime for SOFT */
1257 if (p_lt_soft != 0 || p_lb_soft != 0) {
1258 struct sadb_lifetime m_lt;
1259 u_int slen = sizeof(struct sadb_lifetime);
1261 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1262 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1263 m_lt.sadb_lifetime_allocations = 0;
1264 m_lt.sadb_lifetime_bytes = p_lb_soft;
1265 m_lt.sadb_lifetime_addtime = p_lt_soft;
1266 m_lt.sadb_lifetime_usetime = 0;
1268 memcpy(buf + l, &m_lt, slen);
1272 len = sizeof(struct sadb_sa);
1273 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1274 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1275 m_sa.sadb_sa_spi = htonl(p_spi);
1276 m_sa.sadb_sa_replay = p_replay;
1277 m_sa.sadb_sa_state = 0;
1278 m_sa.sadb_sa_auth = p_alg_auth;
1279 m_sa.sadb_sa_encrypt = p_alg_enc;
1280 m_sa.sadb_sa_flags = p_ext;
1282 memcpy(buf + l, &m_sa, len);
1285 len = sizeof(struct sadb_x_sa2);
1286 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1287 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1288 m_sa2.sadb_x_sa2_mode = p_mode;
1289 m_sa2.sadb_x_sa2_reqid = p_reqid;
1291 memcpy(buf + l, &m_sa2, len);
1294 #ifdef SADB_X_EXT_NAT_T_TYPE
1296 struct sadb_x_nat_t_type natt_type;
1298 len = sizeof(struct sadb_x_nat_t_type);
1299 memset(&natt_type, 0, len);
1300 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1301 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1302 natt_type.sadb_x_nat_t_type_type = p_natt_type;
1304 memcpy(buf + l, &natt_type, len);
1308 sa = p_natt_oa->ai_addr;
1309 switch (sa->sa_family) {
1311 plen = sizeof(struct in_addr) << 3;
1315 plen = sizeof(struct in6_addr) << 3;
1321 salen = sysdep_sa_len(sa);
1322 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1323 PFKEY_ALIGN8(salen));
1324 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA;
1325 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1326 m_addr.sadb_address_prefixlen = plen;
1327 m_addr.sadb_address_reserved = 0;
1329 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1330 sizeof(m_addr), sa, salen);
1338 /* do it for all src/dst pairs */
1339 for (s = srcs; s; s = s->ai_next) {
1340 for (d = dsts; d; d = d->ai_next) {
1341 /* rewind pointer */
1344 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1346 switch (s->ai_addr->sa_family) {
1348 plen = sizeof(struct in_addr) << 3;
1352 plen = sizeof(struct in6_addr) << 3;
1361 salen = sysdep_sa_len(s->ai_addr);
1362 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1363 PFKEY_ALIGN8(salen));
1364 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1365 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1366 m_addr.sadb_address_prefixlen = plen;
1367 m_addr.sadb_address_reserved = 0;
1369 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1370 sizeof(m_addr), sa, salen);
1374 salen = sysdep_sa_len(d->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_DST;
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(buf, &l, (struct sadb_ext *)&m_addr,
1383 sizeof(m_addr), sa, salen);
1385 #ifdef SADB_X_EXT_NAT_T_TYPE
1387 struct sadb_x_nat_t_port natt_port;
1390 len = sizeof(struct sadb_x_nat_t_port);
1391 memset(&natt_port, 0, len);
1392 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1393 natt_port.sadb_x_nat_t_port_exttype =
1394 SADB_X_EXT_NAT_T_SPORT;
1395 natt_port.sadb_x_nat_t_port_port = htons(get_port(s));
1397 memcpy(buf + l, &natt_port, len);
1401 natt_port.sadb_x_nat_t_port_exttype =
1402 SADB_X_EXT_NAT_T_DPORT;
1403 natt_port.sadb_x_nat_t_port_port = htons(get_port(d));
1405 memcpy(buf + l, &natt_port, len);
1409 msg->sadb_msg_len = PFKEY_UNIT64(l);
1423 static struct addrinfo *
1424 parse_addr(host, port)
1428 struct addrinfo hints, *res = NULL;
1431 memset(&hints, 0, sizeof(hints));
1432 hints.ai_family = p_aifamily;
1433 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
1434 hints.ai_protocol = IPPROTO_UDP; /*dummy*/
1435 hints.ai_flags = p_aiflags;
1436 error = getaddrinfo(host, port, &hints, &res);
1438 yyerror(gai_strerror(error));
1445 fix_portstr(spec, sport, dport)
1446 vchar_t *spec, *sport, *dport;
1448 const char *p, *p2 = "0";
1453 for (q = spec->buf; *q != ',' && *q != '\0' && l < spec->len; q++, l++)
1460 for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1462 if (*p != '\0' || *p2 == '\0') {
1463 yyerror("invalid an upper layer protocol spec");
1468 sport->buf = strdup(spec->buf);
1470 yyerror("insufficient memory");
1473 sport->len = strlen(sport->buf);
1474 dport->buf = strdup(p2);
1476 yyerror("insufficient memory");
1479 dport->len = strlen(dport->buf);
1485 setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
1488 struct sadb_ext *ebuf;
1493 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1494 memcpy(buf + *off, (caddr_t)ebuf, elen);
1495 memcpy(buf + *off + elen, vbuf, vlen);
1496 (*off) += PFKEY_ALIGN8(elen + vlen);
1506 p_ext = SADB_X_EXT_CYCSEQ;
1507 p_alg_enc = SADB_EALG_NONE;
1508 p_alg_auth = SADB_AALG_NONE;
1509 p_mode = IPSEC_MODE_ANY;
1512 p_key_enc_len = p_key_auth_len = 0;
1513 p_key_enc = p_key_auth = 0;
1514 p_lt_hard = p_lt_soft = 0;
1515 p_lb_hard = p_lb_soft = 0;
1518 p_aifamily = PF_UNSPEC;
1520 /* Clear out any natt OA information */
1522 freeaddrinfo (p_natt_oa);
1532 /* we got tons of memory leaks in the parser anyways, leave them */