diff options
author | ae <ae@FreeBSD.org> | 2017-04-27 12:16:58 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2017-04-27 12:16:58 +0000 |
commit | 50ac70e9ae73d6c1dc2690d5c4e5266ab1a59601 (patch) | |
tree | 79cab23ec9de3cbda06793ced7044ad940801d19 /lib/libipsec | |
parent | 6286e9852a12088fe739142a3ff25c51f33d539a (diff) | |
download | FreeBSD-src-50ac70e9ae73d6c1dc2690d5c4e5266ab1a59601.zip FreeBSD-src-50ac70e9ae73d6c1dc2690d5c4e5266ab1a59601.tar.gz |
MFC r316759:
Add large replay widow support to setkey(8) and libipsec.
When the replay window size is large than UINT8_MAX, add to the request
the SADB_X_EXT_SA_REPLAY extension header that was added in r309144.
Also add support of SADB_X_EXT_NAT_T_TYPE, SADB_X_EXT_NAT_T_SPORT,
SADB_X_EXT_NAT_T_DPORT, SADB_X_EXT_NAT_T_OAI, SADB_X_EXT_NAT_T_OAR,
SADB_X_EXT_SA_REPLAY, SADB_X_EXT_NEW_ADDRESS_SRC, SADB_X_EXT_NEW_ADDRESS_DST
extension headers to the key_debug that is used by `setkey -x`.
Modify kdebug_sockaddr() to use inet_ntop() for IP addresses formatting.
And modify kdebug_sadb_x_policy() to show policy scope and priority.
Reviewed by: gnn, Emeric Poupon
Differential Revision: https://reviews.freebsd.org/D10375
Diffstat (limited to 'lib/libipsec')
-rw-r--r-- | lib/libipsec/pfkey.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/lib/libipsec/pfkey.c b/lib/libipsec/pfkey.c index 34a3ac3..4791ddc 100644 --- a/lib/libipsec/pfkey.c +++ b/lib/libipsec/pfkey.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <netipsec/ipsec.h> #include <stdlib.h> +#include <stdint.h> #include <unistd.h> #include <string.h> #include <errno.h> @@ -69,6 +70,7 @@ static caddr_t pfkey_setsadbmsg(caddr_t, caddr_t, u_int, u_int, u_int, u_int32_t, pid_t); static caddr_t pfkey_setsadbsa(caddr_t, caddr_t, u_int32_t, u_int, u_int, u_int, u_int32_t); +static caddr_t pfkey_setsadbxreplay(caddr_t, caddr_t, uint32_t); static caddr_t pfkey_setsadbaddr(caddr_t, caddr_t, u_int, struct sockaddr *, u_int, u_int); static caddr_t pfkey_setsadbkey(caddr_t, caddr_t, u_int, caddr_t, u_int); @@ -1196,6 +1198,13 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, + sizeof(struct sadb_lifetime) + sizeof(struct sadb_lifetime); + if (wsize > UINT8_MAX) { + if (wsize > (UINT32_MAX - 32) >> 3) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return (-1); + } + len += sizeof(struct sadb_x_sa_replay); + } if (e_type != SADB_EALG_NONE) len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); if (a_type != SADB_AALG_NONE) @@ -1223,6 +1232,13 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, free(newmsg); return -1; } + if (wsize > UINT8_MAX) { + p = pfkey_setsadbxreplay(p, ep, wsize); + if (!p) { + free(newmsg); + return (-1); + } + } p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen, IPSEC_ULPROTO_ANY); if (!p) { @@ -1982,7 +1998,7 @@ pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags) p->sadb_sa_len = PFKEY_UNIT64(len); p->sadb_sa_exttype = SADB_EXT_SA; p->sadb_sa_spi = spi; - p->sadb_sa_replay = wsize; + p->sadb_sa_replay = wsize > UINT8_MAX ? UINT8_MAX: wsize; p->sadb_sa_state = SADB_SASTATE_LARVAL; p->sadb_sa_auth = auth; p->sadb_sa_encrypt = enc; @@ -1992,6 +2008,31 @@ pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags) } /* + * Set data into sadb_x_sa_replay. + * `buf' must has been allocated sufficiently. + */ +static caddr_t +pfkey_setsadbxreplay(caddr_t buf, caddr_t lim, uint32_t wsize) +{ + struct sadb_x_sa_replay *p; + u_int len; + + p = (struct sadb_x_sa_replay *)buf; + len = sizeof(struct sadb_x_sa_replay); + + if (buf + len > lim) + return (NULL); + + memset(p, 0, len); + p->sadb_x_sa_replay_len = PFKEY_UNIT64(len); + p->sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY; + /* Convert wsize from bytes to number of packets. */ + p->sadb_x_sa_replay_replay = wsize << 3; + + return (buf + len); +} + +/* * set data into sadb_address. * `buf' must has been allocated sufficiently. * prefixlen is in bits. |