summaryrefslogtreecommitdiffstats
path: root/lib/libipsec/pfkey.c
diff options
context:
space:
mode:
authoritojun <itojun@FreeBSD.org>2000-07-04 16:22:05 +0000
committeritojun <itojun@FreeBSD.org>2000-07-04 16:22:05 +0000
commit0bbd943f404b5100a81abdec2bd8519971e0c58e (patch)
treeb98b84ed27cb35ed58163ab9530a39ecc47f3254 /lib/libipsec/pfkey.c
parent993cb1d94fc91849b548394143e230fa61400d5b (diff)
downloadFreeBSD-src-0bbd943f404b5100a81abdec2bd8519971e0c58e.zip
FreeBSD-src-0bbd943f404b5100a81abdec2bd8519971e0c58e.tar.gz
synchronize with latest kame tree.
behavior change: policy syntax was changed. you may need to update your setkey(8) configuration files.
Diffstat (limited to 'lib/libipsec/pfkey.c')
-rw-r--r--lib/libipsec/pfkey.c630
1 files changed, 402 insertions, 228 deletions
diff --git a/lib/libipsec/pfkey.c b/lib/libipsec/pfkey.c
index 318be33..11b6722 100644
--- a/lib/libipsec/pfkey.c
+++ b/lib/libipsec/pfkey.c
@@ -1,3 +1,6 @@
+/* $FreeBSD$ */
+/* $KAME: pfkey.c,v 1.31 2000/06/10 14:17:43 sakane Exp $ */
+
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* All rights reserved.
@@ -25,21 +28,14 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
-#ifndef lint
-static char *rcsid = "@(#) pfkey.c $Revision: 1.10 $";
-#endif
-
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/pfkeyv2.h>
#include <netkey/key_var.h>
#include <netinet/in.h>
-#include <netinet6/in6.h>
#include <netinet6/ipsec.h>
#include <stdlib.h>
@@ -48,31 +44,31 @@ static char *rcsid = "@(#) pfkey.c $Revision: 1.10 $";
#include <errno.h>
#include "ipsec_strerror.h"
-
-#define CALLOC(size, cast) (cast)calloc(1, (size))
-
-static int pfkey_send_x1 __P((int so, u_int type, u_int satype, u_int mode,
- struct sockaddr *src, struct sockaddr *dst, u_int32_t spi, u_int wsize,
- caddr_t keymat,
- u_int e_type, u_int e_keylen, u_int a_type, u_int a_keylen,
- u_int flags,
- u_int32_t l_alloc, u_int32_t l_bytes,
- u_int32_t l_addtime, u_int32_t l_usetime, u_int32_t seq));
-static int pfkey_send_x2 __P((int so, u_int type, u_int satype, u_int mode,
- struct sockaddr *src, struct sockaddr *dst, u_int32_t spi));
-static int pfkey_send_x3 __P((int so, u_int type, u_int satype));
-
-static caddr_t pfkey_setsadbmsg __P((caddr_t buf, u_int type, u_int tlen,
- u_int satype, u_int mode, u_int32_t seq, pid_t pid));
-static caddr_t pfkey_setsadbsa __P((caddr_t buf, u_int32_t spi, u_int wsize,
- u_int auth, u_int enc, u_int32_t flags));
-static caddr_t pfkey_setsadbaddr __P((caddr_t buf, u_int exttype,
- struct sockaddr *saddr, u_int prefixlen, u_int ul_proto));
-static caddr_t pfkey_setsadbkey(caddr_t buf, u_int type,
- caddr_t key, u_int keylen);
-static caddr_t pfkey_setsadblifetime(caddr_t buf, u_int type,
- u_int32_t l_alloc, u_int32_t l_bytes,
- u_int32_t l_addtime, u_int32_t l_usetime);
+#include "libpfkey.h"
+
+#define CALLOC(size, cast) (cast)calloc(1, (size))
+
+static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *,
+ struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t,
+ u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t,
+ u_int32_t, u_int32_t, u_int32_t));
+static int pfkey_send_x2 __P((int, u_int, u_int, u_int,
+ struct sockaddr *, struct sockaddr *, u_int32_t));
+static int pfkey_send_x3 __P((int, u_int, u_int));
+static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int,
+ struct sockaddr *, u_int, u_int, char *, int, u_int32_t));
+static int pfkey_send_x5 __P((int, u_int, u_int32_t));
+
+static caddr_t pfkey_setsadbmsg __P((caddr_t, u_int, u_int,
+ u_int, u_int32_t, pid_t));
+static caddr_t pfkey_setsadbsa __P((caddr_t, u_int32_t, u_int,
+ u_int, u_int, u_int32_t));
+static caddr_t pfkey_setsadbaddr __P((caddr_t, u_int,
+ struct sockaddr *, u_int, u_int));
+static caddr_t pfkey_setsadbkey __P((caddr_t, u_int, caddr_t, u_int));
+static caddr_t pfkey_setsadblifetime __P((caddr_t, u_int, u_int32_t, u_int32_t,
+ u_int32_t, u_int32_t));
+static caddr_t pfkey_setsadbxsa2 __P((caddr_t, u_int32_t, u_int32_t));
/*
* check key length against algorithm specified.
@@ -98,7 +94,7 @@ ipsec_check_keylen(supported, alg_id, keylen)
/* validity check */
if (ipsec_supported == NULL) {
- ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST;
+ __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST;
return -1;
}
switch (supported) {
@@ -106,7 +102,7 @@ ipsec_check_keylen(supported, alg_id, keylen)
case SADB_EXT_SUPPORTED_ENCRYPT:
break;
default:
- ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
@@ -137,18 +133,18 @@ ipsec_check_keylen(supported, alg_id, keylen)
}
}
- ipsec_errcode = EIPSEC_NOT_SUPPORTED;
+ __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
return -1;
/* NOTREACHED */
found:
if (keylen < alg->sadb_alg_minbits
|| keylen > alg->sadb_alg_maxbits) {
- ipsec_errcode = EIPSEC_INVAL_KEYLEN;
+ __ipsec_errcode = EIPSEC_INVAL_KEYLEN;
return -1;
}
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
@@ -165,7 +161,7 @@ u_int
pfkey_set_softrate(type, rate)
u_int type, rate;
{
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
if (rate > 100 || rate == 0)
rate = 100;
@@ -185,7 +181,7 @@ pfkey_set_softrate(type, rate)
return 0;
}
- ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return 1;
}
@@ -218,33 +214,46 @@ pfkey_get_softrate(type)
* -1 : error occured, and set errno.
*/
int
-pfkey_send_getspi(so, satype, mode, src, dst, min, max, seq)
+pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
int so;
u_int satype, mode;
struct sockaddr *src, *dst;
- u_int32_t min, max, seq;
+ u_int32_t min, max, reqid, seq;
{
struct sadb_msg *newmsg;
int len;
int need_spirange = 0;
caddr_t p;
+ int plen;
/* validity check */
if (src == NULL || dst == NULL) {
- ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
if (src->sa_family != dst->sa_family) {
- ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
+ __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
return -1;
}
if (min > max || (min > 0 && min <= 255)) {
- ipsec_errcode = EIPSEC_INVAL_SPI;
+ __ipsec_errcode = EIPSEC_INVAL_SPI;
+ return -1;
+ }
+ switch (src->sa_family) {
+ case AF_INET:
+ plen = sizeof(struct in_addr) << 3;
+ break;
+ case AF_INET6:
+ plen = sizeof(struct in6_addr) << 3;
+ break;
+ default:
+ __ipsec_errcode = EIPSEC_INVAL_FAMILY;
return -1;
}
/* create new sadb_msg to send. */
len = sizeof(struct sadb_msg)
+ + sizeof(struct sadb_x_sa2)
+ sizeof(struct sadb_address)
+ PFKEY_ALIGN8(src->sa_len)
+ sizeof(struct sadb_address)
@@ -256,32 +265,28 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, seq)
}
if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
- ipsec_set_strerror(strerror(errno));
+ __ipsec_set_strerror(strerror(errno));
return -1;
}
p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_GETSPI,
- len, satype, mode, seq, getpid());
+ len, satype, seq, getpid());
+
+ p = pfkey_setsadbxsa2(p, mode, reqid);
/* set sadb_address for source */
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_SRC,
- src,
- _INALENBYAF(src->sa_family) << 3,
- IPSEC_ULPROTO_ANY);
+ p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen,
+ IPSEC_ULPROTO_ANY);
/* set sadb_address for destination */
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_DST,
- dst,
- _INALENBYAF(dst->sa_family) << 3,
- IPSEC_ULPROTO_ANY);
+ p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen,
+ IPSEC_ULPROTO_ANY);
/* proccessing spi range */
if (need_spirange) {
int _len = sizeof(struct sadb_spirange);
-#define _SADB_SPIRANGE(p) ((struct sadb_spirange *)(p))
+#define _SADB_SPIRANGE(p) ((struct sadb_spirange *)(p))
_SADB_SPIRANGE(p)->sadb_spirange_len = PFKEY_UNIT64(_len);
_SADB_SPIRANGE(p)->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
_SADB_SPIRANGE(p)->sadb_spirange_min = min;
@@ -297,7 +302,7 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, seq)
if (len < 0)
return -1;
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return len;
}
@@ -309,13 +314,13 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, seq)
* -1 : error occured, and set errno.
*/
int
-pfkey_send_update(so, satype, mode, src, dst, spi, wsize,
+pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize,
keymat, e_type, e_keylen, a_type, a_keylen, flags,
l_alloc, l_bytes, l_addtime, l_usetime, seq)
int so;
u_int satype, mode, wsize;
struct sockaddr *src, *dst;
- u_int32_t spi;
+ u_int32_t spi, reqid;
caddr_t keymat;
u_int e_type, e_keylen, a_type, a_keylen, flags;
u_int32_t l_alloc;
@@ -324,7 +329,8 @@ pfkey_send_update(so, satype, mode, src, dst, spi, wsize,
{
int len;
if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
- wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags,
+ reqid, wsize,
+ keymat, e_type, e_keylen, a_type, a_keylen, flags,
l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
return -1;
@@ -339,13 +345,13 @@ pfkey_send_update(so, satype, mode, src, dst, spi, wsize,
* -1 : error occured, and set errno.
*/
int
-pfkey_send_add(so, satype, mode, src, dst, spi, wsize,
+pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize,
keymat, e_type, e_keylen, a_type, a_keylen, flags,
l_alloc, l_bytes, l_addtime, l_usetime, seq)
int so;
u_int satype, mode, wsize;
struct sockaddr *src, *dst;
- u_int32_t spi;
+ u_int32_t spi, reqid;
caddr_t keymat;
u_int e_type, e_keylen, a_type, a_keylen, flags;
u_int32_t l_alloc;
@@ -354,7 +360,8 @@ pfkey_send_add(so, satype, mode, src, dst, spi, wsize,
{
int len;
if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
- wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags,
+ reqid, wsize,
+ keymat, e_type, e_keylen, a_type, a_keylen, flags,
l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
return -1;
@@ -458,7 +465,7 @@ pfkey_recv_register(so)
sup->sadb_supported_len = PFKEY_EXTLEN(sup);
break;
default:
- ipsec_errcode = EIPSEC_INVAL_SATYPE;
+ __ipsec_errcode = EIPSEC_INVAL_SATYPE;
free(newmsg);
return -1;
}
@@ -468,7 +475,7 @@ pfkey_recv_register(so)
}
if (tlen < 0) {
- ipsec_errcode = EIPSEC_INVAL_SATYPE;
+ __ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
@@ -477,7 +484,7 @@ pfkey_recv_register(so)
ipsec_supported = newmsg;
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
@@ -546,7 +553,6 @@ pfkey_send_promisc_toggle(so, flag)
/*
* sending SADB_X_SPDADD message to the kernel.
- * The length of key material is a_keylen + e_keylen.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
@@ -556,133 +562,140 @@ pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
int so;
struct sockaddr *src, *dst;
u_int prefs, prefd, proto;
- char *policy;
+ caddr_t policy;
int policylen;
u_int32_t seq;
{
- struct sadb_msg *newmsg;
int len;
- caddr_t p;
-
- /* validity check */
- if (src == NULL || dst == NULL) {
- ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
- return -1;
- }
- if (src->sa_family != dst->sa_family) {
- ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
- return -1;
- }
- if (prefs > (_INALENBYAF(src->sa_family) << 3)
- || prefd > (_INALENBYAF(dst->sa_family) << 3)) {
- ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
- return -1;
- }
-
- /* create new sadb_msg to reply. */
- len = sizeof(struct sadb_msg)
- + sizeof(struct sadb_address)
- + PFKEY_ALIGN8(_SALENBYAF(src->sa_family))
- + sizeof(struct sadb_address)
- + PFKEY_ALIGN8(_SALENBYAF(src->sa_family))
- + policylen;
- if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
- ipsec_set_strerror(strerror(errno));
+ if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
+ src, prefs, dst, prefd, proto,
+ policy, policylen, seq)) < 0)
return -1;
- }
- p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_X_SPDADD, len,
- SADB_SATYPE_UNSPEC, IPSEC_MODE_ANY, seq, getpid());
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_SRC,
- src,
- prefs,
- proto);
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_DST,
- dst,
- prefd,
- proto);
- memcpy(p, policy, policylen);
+ return len;
+}
- /* send message */
- len = pfkey_send(so, newmsg, len);
- free(newmsg);
+/*
+ * sending SADB_X_SPDUPDATE message to the kernel.
+ * OUT:
+ * positive: success and return length sent.
+ * -1 : error occured, and set errno.
+ */
+int
+pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
+ int so;
+ struct sockaddr *src, *dst;
+ u_int prefs, prefd, proto;
+ caddr_t policy;
+ int policylen;
+ u_int32_t seq;
+{
+ int len;
- if (len < 0)
+ if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
+ src, prefs, dst, prefd, proto,
+ policy, policylen, seq)) < 0)
return -1;
- ipsec_errcode = EIPSEC_NO_ERROR;
return len;
}
/*
* sending SADB_X_SPDDELETE message to the kernel.
- * The length of key material is a_keylen + e_keylen.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
-pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, seq)
+pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
int so;
struct sockaddr *src, *dst;
u_int prefs, prefd, proto;
+ caddr_t policy;
+ int policylen;
u_int32_t seq;
{
- struct sadb_msg *newmsg;
int len;
- caddr_t p;
- /* validity check */
- if (src == NULL || dst == NULL) {
- ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ if (policylen != sizeof(struct sadb_x_policy)) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
- if (src->sa_family != dst->sa_family) {
- ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
+
+ if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE,
+ src, prefs, dst, prefd, proto,
+ policy, policylen, seq)) < 0)
return -1;
- }
- if (prefs > (_INALENBYAF(src->sa_family) << 3)
- || prefd > (_INALENBYAF(dst->sa_family) << 3)) {
- ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
+
+ return len;
+}
+
+/*
+ * sending SADB_X_SPDDELETE message to the kernel.
+ * OUT:
+ * positive: success and return length sent.
+ * -1 : error occured, and set errno.
+ */
+int
+pfkey_send_spddelete2(so, spid)
+ int so;
+ u_int32_t spid;
+{
+ int len;
+
+ if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0)
return -1;
- }
- /* create new sadb_msg to reply. */
- len = sizeof(struct sadb_msg)
- + sizeof(struct sadb_address)
- + PFKEY_ALIGN8(_SALENBYAF(src->sa_family))
- + sizeof(struct sadb_address)
- + PFKEY_ALIGN8(_SALENBYAF(src->sa_family));
+ return len;
+}
- if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
- ipsec_set_strerror(strerror(errno));
+/*
+ * sending SADB_X_SPDGET message to the kernel.
+ * OUT:
+ * positive: success and return length sent.
+ * -1 : error occured, and set errno.
+ */
+int
+pfkey_send_spdget(so, spid)
+ int so;
+ u_int32_t spid;
+{
+ int len;
+
+ if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0)
return -1;
- }
- p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_X_SPDDELETE, len,
- SADB_SATYPE_UNSPEC, IPSEC_MODE_ANY, seq, getpid());
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_SRC,
- src,
- prefs,
- proto);
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_DST,
- dst,
- prefd,
- proto);
+ return len;
+}
- /* send message */
- len = pfkey_send(so, newmsg, len);
- free(newmsg);
+/*
+ * sending SADB_X_SPDSETIDX message to the kernel.
+ * OUT:
+ * positive: success and return length sent.
+ * -1 : error occured, and set errno.
+ */
+int
+pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
+ int so;
+ struct sockaddr *src, *dst;
+ u_int prefs, prefd, proto;
+ caddr_t policy;
+ int policylen;
+ u_int32_t seq;
+{
+ int len;
- if (len < 0)
+ if (policylen != sizeof(struct sadb_x_policy)) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ return -1;
+ }
+
+ if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX,
+ src, prefs, dst, prefd, proto,
+ policy, policylen, seq)) < 0)
return -1;
- ipsec_errcode = EIPSEC_NO_ERROR;
return len;
}
@@ -724,13 +737,13 @@ pfkey_send_spddump(so)
/* sending SADB_ADD or SADB_UPDATE message to the kernel */
static int
-pfkey_send_x1(so, type, satype, mode, src, dst, spi, wsize,
+pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
keymat, e_type, e_keylen, a_type, a_keylen, flags,
l_alloc, l_bytes, l_addtime, l_usetime, seq)
int so;
u_int type, satype, mode;
struct sockaddr *src, *dst;
- u_int32_t spi;
+ u_int32_t spi, reqid;
u_int wsize;
caddr_t keymat;
u_int e_type, e_keylen, a_type, a_keylen, flags;
@@ -739,44 +752,57 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, wsize,
struct sadb_msg *newmsg;
int len;
caddr_t p;
+ int plen;
/* validity check */
if (src == NULL || dst == NULL) {
- ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
if (src->sa_family != dst->sa_family) {
- ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
+ __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
+ return -1;
+ }
+ switch (src->sa_family) {
+ case AF_INET:
+ plen = sizeof(struct in_addr) << 3;
+ break;
+ case AF_INET6:
+ plen = sizeof(struct in6_addr) << 3;
+ break;
+ default:
+ __ipsec_errcode = EIPSEC_INVAL_FAMILY;
return -1;
}
switch (satype) {
case SADB_SATYPE_ESP:
if (e_type == SADB_EALG_NONE) {
- ipsec_errcode = EIPSEC_NO_ALGS;
+ __ipsec_errcode = EIPSEC_NO_ALGS;
return -1;
}
break;
case SADB_SATYPE_AH:
if (e_type != SADB_EALG_NONE) {
- ipsec_errcode = EIPSEC_INVAL_ALGS;
+ __ipsec_errcode = EIPSEC_INVAL_ALGS;
return -1;
}
if (a_type == SADB_AALG_NONE) {
- ipsec_errcode = EIPSEC_NO_ALGS;
+ __ipsec_errcode = EIPSEC_NO_ALGS;
return -1;
}
break;
case SADB_X_SATYPE_IPCOMP:
break;
default:
- ipsec_errcode = EIPSEC_INVAL_SATYPE;
+ __ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
/* create new sadb_msg to reply. */
len = sizeof(struct sadb_msg)
+ sizeof(struct sadb_sa)
+ + sizeof(struct sadb_x_sa2)
+ sizeof(struct sadb_address)
+ PFKEY_ALIGN8(src->sa_len)
+ sizeof(struct sadb_address)
@@ -790,23 +816,18 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, wsize,
len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen));
if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
- ipsec_set_strerror(strerror(errno));
+ __ipsec_set_strerror(strerror(errno));
return -1;
}
p = pfkey_setsadbmsg((caddr_t)newmsg, type, len,
- satype, mode, seq, getpid());
+ satype, seq, getpid());
p = pfkey_setsadbsa(p, spi, wsize, a_type, e_type, flags);
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_SRC,
- src,
- _INALENBYAF(src->sa_family) << 3,
- IPSEC_ULPROTO_ANY);
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_DST,
- dst,
- _INALENBYAF(dst->sa_family) << 3,
- IPSEC_ULPROTO_ANY);
+ p = pfkey_setsadbxsa2(p, mode, reqid);
+ p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen,
+ IPSEC_ULPROTO_ANY);
+ p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen,
+ IPSEC_ULPROTO_ANY);
if (e_type != SADB_EALG_NONE)
p = pfkey_setsadbkey(p, SADB_EXT_KEY_ENCRYPT,
@@ -828,7 +849,7 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, wsize,
if (len < 0)
return -1;
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return len;
}
@@ -843,14 +864,26 @@ pfkey_send_x2(so, type, satype, mode, src, dst, spi)
struct sadb_msg *newmsg;
int len;
caddr_t p;
+ int plen;
/* validity check */
if (src == NULL || dst == NULL) {
- ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
if (src->sa_family != dst->sa_family) {
- ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
+ __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
+ return -1;
+ }
+ switch (src->sa_family) {
+ case AF_INET:
+ plen = sizeof(struct in_addr) << 3;
+ break;
+ case AF_INET6:
+ plen = sizeof(struct in6_addr) << 3;
+ break;
+ default:
+ __ipsec_errcode = EIPSEC_INVAL_FAMILY;
return -1;
}
@@ -863,22 +896,16 @@ pfkey_send_x2(so, type, satype, mode, src, dst, spi)
+ PFKEY_ALIGN8(dst->sa_len);
if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
- ipsec_set_strerror(strerror(errno));
+ __ipsec_set_strerror(strerror(errno));
return -1;
}
- p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, mode, 0, getpid());
+ p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid());
p = pfkey_setsadbsa(p, spi, 0, 0, 0, 0);
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_SRC,
- src,
- _INALENBYAF(src->sa_family) << 3,
- IPSEC_ULPROTO_ANY);
- p = pfkey_setsadbaddr(p,
- SADB_EXT_ADDRESS_DST,
- dst,
- _INALENBYAF(dst->sa_family) << 3,
- IPSEC_ULPROTO_ANY);
+ p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen,
+ IPSEC_ULPROTO_ANY);
+ p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen,
+ IPSEC_ULPROTO_ANY);
/* send message */
len = pfkey_send(so, newmsg, len);
@@ -887,7 +914,7 @@ pfkey_send_x2(so, type, satype, mode, src, dst, spi)
if (len < 0)
return -1;
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return len;
}
@@ -907,7 +934,7 @@ pfkey_send_x3(so, type, satype)
switch (type) {
case SADB_X_PROMISC:
if (satype != 0 && satype != 1) {
- ipsec_errcode = EIPSEC_INVAL_SATYPE;
+ __ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
break;
@@ -919,7 +946,7 @@ pfkey_send_x3(so, type, satype)
case SADB_X_SATYPE_IPCOMP:
break;
default:
- ipsec_errcode = EIPSEC_INVAL_SATYPE;
+ __ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
}
@@ -928,11 +955,11 @@ pfkey_send_x3(so, type, satype)
len = sizeof(struct sadb_msg);
if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
- ipsec_set_strerror(strerror(errno));
+ __ipsec_set_strerror(strerror(errno));
return -1;
}
- (void)pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, 0, getpid());
+ (void)pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid());
/* send message */
len = pfkey_send(so, newmsg, len);
@@ -941,7 +968,128 @@ pfkey_send_x3(so, type, satype)
if (len < 0)
return -1;
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
+ return len;
+}
+
+/* sending SADB_X_SPDADD message to the kernel */
+static int
+pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, policy, policylen, seq)
+ int so;
+ struct sockaddr *src, *dst;
+ u_int type, prefs, prefd, proto;
+ char *policy;
+ int policylen;
+ u_int32_t seq;
+{
+ struct sadb_msg *newmsg;
+ int len;
+ caddr_t p;
+ int plen;
+
+ /* validity check */
+ if (src == NULL || dst == NULL) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ return -1;
+ }
+ if (src->sa_family != dst->sa_family) {
+ __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
+ return -1;
+ }
+
+ switch (src->sa_family) {
+ case AF_INET:
+ plen = sizeof(struct in_addr) << 3;
+ break;
+ case AF_INET6:
+ plen = sizeof(struct in6_addr) << 3;
+ break;
+ default:
+ __ipsec_errcode = EIPSEC_INVAL_FAMILY;
+ return -1;
+ }
+ if (prefs > plen || prefd > plen) {
+ __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
+ return -1;
+ }
+
+ /* create new sadb_msg to reply. */
+ len = sizeof(struct sadb_msg)
+ + sizeof(struct sadb_address)
+ + PFKEY_ALIGN8(src->sa_len)
+ + sizeof(struct sadb_address)
+ + PFKEY_ALIGN8(src->sa_len)
+ + policylen;
+
+ if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
+ __ipsec_set_strerror(strerror(errno));
+ return -1;
+ }
+
+ p = pfkey_setsadbmsg((caddr_t)newmsg, type, len,
+ SADB_SATYPE_UNSPEC, seq, getpid());
+ p = pfkey_setsadbaddr(p,
+ SADB_EXT_ADDRESS_SRC,
+ src,
+ prefs,
+ proto);
+ p = pfkey_setsadbaddr(p,
+ SADB_EXT_ADDRESS_DST,
+ dst,
+ prefd,
+ proto);
+ memcpy(p, policy, policylen);
+
+ /* send message */
+ len = pfkey_send(so, newmsg, len);
+ free(newmsg);
+
+ if (len < 0)
+ return -1;
+
+ __ipsec_errcode = EIPSEC_NO_ERROR;
+ return len;
+}
+
+/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
+static int
+pfkey_send_x5(so, type, spid)
+ int so;
+ u_int type;
+ u_int32_t spid;
+{
+ struct sadb_msg *newmsg;
+ struct sadb_x_policy xpl;
+ int len;
+ caddr_t p;
+
+ /* create new sadb_msg to reply. */
+ len = sizeof(struct sadb_msg)
+ + sizeof(xpl);
+
+ if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
+ __ipsec_set_strerror(strerror(errno));
+ return -1;
+ }
+
+ p = pfkey_setsadbmsg((caddr_t)newmsg, type, len,
+ SADB_SATYPE_UNSPEC, 0, getpid());
+
+ memset(&xpl, 0, sizeof(xpl));
+ xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl));
+ xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
+ xpl.sadb_x_policy_id = spid;
+
+ memcpy(p, &xpl, sizeof(xpl));
+
+ /* send message */
+ len = pfkey_send(so, newmsg, len);
+ free(newmsg);
+
+ if (len < 0)
+ return -1;
+
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return len;
}
@@ -958,7 +1106,7 @@ pfkey_open()
const int bufsiz = 128 * 1024; /*is 128K enough?*/
if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
- ipsec_set_strerror(strerror(errno));
+ __ipsec_set_strerror(strerror(errno));
return -1;
}
@@ -969,7 +1117,7 @@ pfkey_open()
(void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
(void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return so;
}
@@ -985,7 +1133,7 @@ pfkey_close(so)
{
(void)close(so);
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return;
}
@@ -1005,37 +1153,37 @@ pfkey_recv(so)
while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) {
if (errno == EINTR) continue;
- ipsec_set_strerror(strerror(errno));
+ __ipsec_set_strerror(strerror(errno));
return NULL;
}
if (len < sizeof(buf)) {
recv(so, (caddr_t)&buf, sizeof(buf), 0);
- ipsec_errcode = EIPSEC_MAX;
+ __ipsec_errcode = EIPSEC_MAX;
return NULL;
}
/* read real message */
reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) {
- ipsec_set_strerror(strerror(errno));
+ __ipsec_set_strerror(strerror(errno));
return NULL;
}
while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
if (errno == EINTR) continue;
- ipsec_set_strerror(strerror(errno));
+ __ipsec_set_strerror(strerror(errno));
free(newmsg);
return NULL;
}
if (len != reallen) {
- ipsec_errcode = EIPSEC_SYSTEM_ERROR;
+ __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
free(newmsg);
return NULL;
}
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return newmsg;
}
@@ -1052,11 +1200,11 @@ pfkey_send(so, msg, len)
int len;
{
if ((len = send(so, (caddr_t)msg, len, 0)) < 0) {
- ipsec_set_strerror(strerror(errno));
+ __ipsec_set_strerror(strerror(errno));
return -1;
}
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return len;
}
@@ -1083,7 +1231,7 @@ pfkey_align(msg, mhp)
/* validity check */
if (msg == NULL || mhp == NULL) {
- ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
@@ -1100,7 +1248,7 @@ pfkey_align(msg, mhp)
/* duplicate check */
/* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
if (mhp[ext->sadb_ext_type] != NULL) {
- ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
+ __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
return -1;
}
@@ -1125,10 +1273,11 @@ pfkey_align(msg, mhp)
case SADB_EXT_SUPPORTED_ENCRYPT:
case SADB_EXT_SPIRANGE:
case SADB_X_EXT_POLICY:
+ case SADB_X_EXT_SA2:
mhp[ext->sadb_ext_type] = (caddr_t)ext;
break;
default:
- ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
+ __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
return -1;
}
@@ -1137,7 +1286,7 @@ pfkey_align(msg, mhp)
ext = (struct sadb_ext *)((caddr_t)ext + extlen);
}
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
@@ -1160,7 +1309,7 @@ pfkey_check(mhp)
/* validity check */
if (mhp == NULL || mhp[0] == NULL) {
- ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
@@ -1168,13 +1317,13 @@ pfkey_check(mhp)
/* check version */
if (msg->sadb_msg_version != PF_KEY_V2) {
- ipsec_errcode = EIPSEC_INVAL_VERSION;
+ __ipsec_errcode = EIPSEC_INVAL_VERSION;
return -1;
}
/* check type */
if (msg->sadb_msg_type > SADB_MAX) {
- ipsec_errcode = EIPSEC_INVAL_MSGTYPE;
+ __ipsec_errcode = EIPSEC_INVAL_MSGTYPE;
return -1;
}
@@ -1189,7 +1338,7 @@ pfkey_check(mhp)
case SADB_GET:
case SADB_ACQUIRE:
case SADB_EXPIRE:
- ipsec_errcode = EIPSEC_INVAL_SATYPE;
+ __ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
break;
@@ -1202,7 +1351,7 @@ pfkey_check(mhp)
case SADB_X_SPDGET:
case SADB_X_SPDDUMP:
case SADB_X_SPDFLUSH:
- ipsec_errcode = EIPSEC_INVAL_SATYPE;
+ __ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
break;
@@ -1210,14 +1359,14 @@ pfkey_check(mhp)
case SADB_SATYPE_OSPFV2:
case SADB_SATYPE_RIPV2:
case SADB_SATYPE_MIP:
- ipsec_errcode = EIPSEC_NOT_SUPPORTED;
+ __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
return -1;
case 1: /* XXX: What does it do ? */
if (msg->sadb_msg_type == SADB_X_PROMISC)
break;
/*FALLTHROUGH*/
default:
- ipsec_errcode = EIPSEC_INVAL_SATYPE;
+ __ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
@@ -1230,13 +1379,13 @@ pfkey_check(mhp)
dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]);
if (src0->sadb_address_proto != dst0->sadb_address_proto) {
- ipsec_errcode = EIPSEC_PROTO_MISMATCH;
+ __ipsec_errcode = EIPSEC_PROTO_MISMATCH;
return -1;
}
if (PFKEY_ADDR_SADDR(src0)->sa_family
!= PFKEY_ADDR_SADDR(dst0)->sa_family) {
- ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
+ __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
return -1;
}
@@ -1245,7 +1394,7 @@ pfkey_check(mhp)
case AF_INET6:
break;
default:
- ipsec_errcode = EIPSEC_INVAL_FAMILY;
+ __ipsec_errcode = EIPSEC_INVAL_FAMILY;
return -1;
}
@@ -1255,7 +1404,7 @@ pfkey_check(mhp)
*/
}
- ipsec_errcode = EIPSEC_NO_ERROR;
+ __ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
@@ -1264,9 +1413,9 @@ pfkey_check(mhp)
* `buf' must has been allocated sufficiently.
*/
static caddr_t
-pfkey_setsadbmsg(buf, type, tlen, satype, mode, seq, pid)
+pfkey_setsadbmsg(buf, type, tlen, satype, seq, pid)
caddr_t buf;
- u_int type, satype, mode;
+ u_int type, satype;
u_int tlen;
u_int32_t seq;
pid_t pid;
@@ -1275,7 +1424,7 @@ pfkey_setsadbmsg(buf, type, tlen, satype, mode, seq, pid)
u_int len;
p = (struct sadb_msg *)buf;
- len = sizeof(struct sadb_sa);
+ len = sizeof(struct sadb_msg);
memset(p, 0, len);
p->sadb_msg_version = PF_KEY_V2;
@@ -1283,7 +1432,6 @@ pfkey_setsadbmsg(buf, type, tlen, satype, mode, seq, pid)
p->sadb_msg_errno = 0;
p->sadb_msg_satype = satype;
p->sadb_msg_len = PFKEY_UNIT64(tlen);
- p->sadb_msg_mode = mode;
p->sadb_msg_reserved = 0;
p->sadb_msg_seq = seq;
p->sadb_msg_pid = (u_int32_t)pid;
@@ -1402,7 +1550,7 @@ pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime)
p->sadb_lifetime_allocations
= (l_alloc * soft_lifetime_allocations_rate) /100;
p->sadb_lifetime_bytes
- = ((l_bytes * soft_lifetime_bytes_rate) /100) << 10;
+ = (l_bytes * soft_lifetime_bytes_rate) /100;
p->sadb_lifetime_addtime
= (l_addtime * soft_lifetime_addtime_rate) /100;
p->sadb_lifetime_usetime
@@ -1410,7 +1558,7 @@ pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime)
break;
case SADB_EXT_LIFETIME_HARD:
p->sadb_lifetime_allocations = l_alloc;
- p->sadb_lifetime_bytes = l_bytes << 10;
+ p->sadb_lifetime_bytes = l_bytes;
p->sadb_lifetime_addtime = l_addtime;
p->sadb_lifetime_usetime = l_usetime;
break;
@@ -1419,3 +1567,29 @@ pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime)
return buf + len;
}
+/*
+ * copy secasvar data into sadb_address.
+ * `buf' must has been allocated sufficiently.
+ */
+static caddr_t
+pfkey_setsadbxsa2(buf, mode0, reqid)
+ caddr_t buf;
+ u_int32_t mode0;
+ u_int32_t reqid;
+{
+ struct sadb_x_sa2 *p;
+ u_int8_t mode = mode0 & 0xff;
+ u_int len;
+
+ p = (struct sadb_x_sa2 *)buf;
+ len = sizeof(struct sadb_x_sa2);
+
+ memset(p, 0, len);
+ p->sadb_x_sa2_len = PFKEY_UNIT64(len);
+ p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
+ p->sadb_x_sa2_mode = mode;
+ p->sadb_x_sa2_reqid = reqid;
+
+ return(buf + len);
+}
+
OpenPOWER on IntegriCloud