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 MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D10375
This commit is contained in:
parent
35e492f3bd
commit
4e0e8f3107
@ -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;
|
||||
@ -1991,6 +2007,31 @@ pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
|
||||
return(buf + len);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
|
@ -51,6 +51,9 @@ CFLAGS+= -I${SRCTOP}/sys
|
||||
SRCS+= y.tab.h
|
||||
y.tab.h: parse.y
|
||||
CFLAGS+= -DIPSEC_DEBUG -DYY_NO_UNPUT
|
||||
.if ${MK_INET_SUPPORT} != "no"
|
||||
CFLAGS+= -DINET
|
||||
.endif
|
||||
.if ${MK_INET6_SUPPORT} != "no"
|
||||
CFLAGS+= -DINET6
|
||||
.endif
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -513,6 +514,8 @@ extension
|
||||
return -1;
|
||||
}
|
||||
p_replay = $2;
|
||||
if (p_replay > (UINT32_MAX - 32) >> 3)
|
||||
yyerror("replay window is too large");
|
||||
}
|
||||
| F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
|
||||
| F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
|
||||
@ -899,6 +902,7 @@ setkeymsg_addr(type, satype, srcs, dsts, no_spi)
|
||||
int l, l0, len;
|
||||
struct sadb_sa m_sa;
|
||||
struct sadb_x_sa2 m_sa2;
|
||||
struct sadb_x_sa_replay m_replay;
|
||||
struct sadb_address m_addr;
|
||||
struct addrinfo *s, *d;
|
||||
int n;
|
||||
@ -920,7 +924,8 @@ setkeymsg_addr(type, satype, srcs, dsts, no_spi)
|
||||
m_sa.sadb_sa_len = PFKEY_UNIT64(len);
|
||||
m_sa.sadb_sa_exttype = SADB_EXT_SA;
|
||||
m_sa.sadb_sa_spi = htonl(p_spi);
|
||||
m_sa.sadb_sa_replay = p_replay;
|
||||
m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX:
|
||||
p_replay;
|
||||
m_sa.sadb_sa_state = 0;
|
||||
m_sa.sadb_sa_auth = p_alg_auth;
|
||||
m_sa.sadb_sa_encrypt = p_alg_enc;
|
||||
@ -937,6 +942,17 @@ setkeymsg_addr(type, satype, srcs, dsts, no_spi)
|
||||
|
||||
memcpy(buf + l, &m_sa2, len);
|
||||
l += len;
|
||||
|
||||
if (p_replay > UINT8_MAX) {
|
||||
len = sizeof(struct sadb_x_sa_replay);
|
||||
m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
|
||||
m_replay.sadb_x_sa_replay_exttype =
|
||||
SADB_X_EXT_SA_REPLAY;
|
||||
m_replay.sadb_x_sa_replay_replay = p_replay << 3;
|
||||
|
||||
memcpy(buf + l, &m_replay, len);
|
||||
l += len;
|
||||
}
|
||||
}
|
||||
|
||||
l0 = l;
|
||||
@ -1017,6 +1033,7 @@ setkeymsg_add(type, satype, srcs, dsts)
|
||||
struct sadb_sa m_sa;
|
||||
struct sadb_x_sa2 m_sa2;
|
||||
struct sadb_address m_addr;
|
||||
struct sadb_x_sa_replay m_replay;
|
||||
struct addrinfo *s, *d;
|
||||
int n;
|
||||
int plen;
|
||||
@ -1100,7 +1117,7 @@ setkeymsg_add(type, satype, srcs, dsts)
|
||||
m_sa.sadb_sa_len = PFKEY_UNIT64(len);
|
||||
m_sa.sadb_sa_exttype = SADB_EXT_SA;
|
||||
m_sa.sadb_sa_spi = htonl(p_spi);
|
||||
m_sa.sadb_sa_replay = p_replay;
|
||||
m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX: p_replay;
|
||||
m_sa.sadb_sa_state = 0;
|
||||
m_sa.sadb_sa_auth = p_alg_auth;
|
||||
m_sa.sadb_sa_encrypt = p_alg_enc;
|
||||
@ -1118,6 +1135,15 @@ setkeymsg_add(type, satype, srcs, dsts)
|
||||
memcpy(buf + l, &m_sa2, len);
|
||||
l += len;
|
||||
|
||||
if (p_replay > UINT8_MAX) {
|
||||
len = sizeof(struct sadb_x_sa_replay);
|
||||
m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
|
||||
m_replay.sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY;
|
||||
m_replay.sadb_x_sa_replay_replay = p_replay << 3;
|
||||
|
||||
memcpy(buf + l, &m_replay, len);
|
||||
l += len;
|
||||
}
|
||||
l0 = l;
|
||||
n = 0;
|
||||
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
static void kdebug_sadb_prop(struct sadb_ext *);
|
||||
@ -73,6 +74,8 @@ static void kdebug_sadb_sa(struct sadb_ext *);
|
||||
static void kdebug_sadb_address(struct sadb_ext *);
|
||||
static void kdebug_sadb_key(struct sadb_ext *);
|
||||
static void kdebug_sadb_x_sa2(struct sadb_ext *);
|
||||
static void kdebug_sadb_x_sa_replay(struct sadb_ext *);
|
||||
static void kdebug_sadb_x_natt(struct sadb_ext *);
|
||||
|
||||
#ifdef _KERNEL
|
||||
static void kdebug_secreplay(struct secreplay *);
|
||||
@ -131,6 +134,10 @@ kdebug_sadb(struct sadb_msg *base)
|
||||
case SADB_EXT_ADDRESS_SRC:
|
||||
case SADB_EXT_ADDRESS_DST:
|
||||
case SADB_EXT_ADDRESS_PROXY:
|
||||
case SADB_X_EXT_NAT_T_OAI:
|
||||
case SADB_X_EXT_NAT_T_OAR:
|
||||
case SADB_X_EXT_NEW_ADDRESS_SRC:
|
||||
case SADB_X_EXT_NEW_ADDRESS_DST:
|
||||
kdebug_sadb_address(ext);
|
||||
break;
|
||||
case SADB_EXT_KEY_AUTH:
|
||||
@ -159,6 +166,14 @@ kdebug_sadb(struct sadb_msg *base)
|
||||
case SADB_X_EXT_SA2:
|
||||
kdebug_sadb_x_sa2(ext);
|
||||
break;
|
||||
case SADB_X_EXT_SA_REPLAY:
|
||||
kdebug_sadb_x_sa_replay(ext);
|
||||
break;
|
||||
case SADB_X_EXT_NAT_T_TYPE:
|
||||
case SADB_X_EXT_NAT_T_SPORT:
|
||||
case SADB_X_EXT_NAT_T_DPORT:
|
||||
kdebug_sadb_x_natt(ext);
|
||||
break;
|
||||
default:
|
||||
printf("%s: invalid ext_type %u\n", __func__,
|
||||
ext->sadb_ext_type);
|
||||
@ -342,8 +357,6 @@ kdebug_sadb_address(struct sadb_ext *ext)
|
||||
((u_char *)&addr->sadb_address_reserved)[1]);
|
||||
|
||||
kdebug_sockaddr((struct sockaddr *)((caddr_t)ext + sizeof(*addr)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -392,6 +405,41 @@ kdebug_sadb_x_sa2(struct sadb_ext *ext)
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
kdebug_sadb_x_sa_replay(struct sadb_ext *ext)
|
||||
{
|
||||
struct sadb_x_sa_replay *replay;
|
||||
|
||||
/* sanity check */
|
||||
if (ext == NULL)
|
||||
panic("%s: NULL pointer was passed.\n", __func__);
|
||||
|
||||
replay = (struct sadb_x_sa_replay *)ext;
|
||||
printf("sadb_x_sa_replay{ replay=%u }\n",
|
||||
replay->sadb_x_sa_replay_replay);
|
||||
}
|
||||
|
||||
static void
|
||||
kdebug_sadb_x_natt(struct sadb_ext *ext)
|
||||
{
|
||||
struct sadb_x_nat_t_type *type;
|
||||
struct sadb_x_nat_t_port *port;
|
||||
|
||||
/* sanity check */
|
||||
if (ext == NULL)
|
||||
panic("%s: NULL pointer was passed.\n", __func__);
|
||||
|
||||
if (ext->sadb_ext_type == SADB_X_EXT_NAT_T_TYPE) {
|
||||
type = (struct sadb_x_nat_t_type *)ext;
|
||||
printf("sadb_x_nat_t_type{ type=%u }\n",
|
||||
type->sadb_x_nat_t_type_type);
|
||||
} else {
|
||||
port = (struct sadb_x_nat_t_port *)ext;
|
||||
printf("sadb_x_nat_t_port{ port=%u }\n",
|
||||
ntohs(port->sadb_x_nat_t_port_port));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kdebug_sadb_x_policy(struct sadb_ext *ext)
|
||||
{
|
||||
@ -402,9 +450,11 @@ kdebug_sadb_x_policy(struct sadb_ext *ext)
|
||||
if (ext == NULL)
|
||||
panic("%s: NULL pointer was passed.\n", __func__);
|
||||
|
||||
printf("sadb_x_policy{ type=%u dir=%u id=%x }\n",
|
||||
printf("sadb_x_policy{ type=%u dir=%u id=%x scope=%u %s=%u }\n",
|
||||
xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir,
|
||||
xpl->sadb_x_policy_id);
|
||||
xpl->sadb_x_policy_id, xpl->sadb_x_policy_scope,
|
||||
xpl->sadb_x_policy_scope == IPSEC_POLICYSCOPE_IFNET ?
|
||||
"ifindex": "priority", xpl->sadb_x_policy_priority);
|
||||
|
||||
if (xpl->sadb_x_policy_type == IPSEC_POLICY_IPSEC) {
|
||||
int tlen;
|
||||
@ -850,39 +900,42 @@ ipsec_sa2str(struct secasvar *sav, char *buf, size_t size)
|
||||
void
|
||||
kdebug_sockaddr(struct sockaddr *addr)
|
||||
{
|
||||
struct sockaddr_in *sin4;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
|
||||
/* sanity check */
|
||||
if (addr == NULL)
|
||||
panic("%s: NULL pointer was passed.\n", __func__);
|
||||
|
||||
/* NOTE: We deal with port number as host byte order. */
|
||||
printf("sockaddr{ len=%u family=%u", addr->sa_len, addr->sa_family);
|
||||
|
||||
switch (addr->sa_family) {
|
||||
case AF_INET:
|
||||
sin4 = (struct sockaddr_in *)addr;
|
||||
printf(" port=%u\n", ntohs(sin4->sin_port));
|
||||
ipsec_hexdump((caddr_t)&sin4->sin_addr, sizeof(sin4->sin_addr));
|
||||
#ifdef INET
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)addr;
|
||||
inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf));
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)addr;
|
||||
printf(" port=%u\n", ntohs(sin6->sin6_port));
|
||||
printf(" flowinfo=0x%08x, scope_id=0x%08x\n",
|
||||
sin6->sin6_flowinfo, sin6->sin6_scope_id);
|
||||
ipsec_hexdump((caddr_t)&sin6->sin6_addr,
|
||||
sizeof(sin6->sin6_addr));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
printf(" }\n");
|
||||
|
||||
return;
|
||||
sin6 = (struct sockaddr_in6 *)addr;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
snprintf(buf, sizeof(buf), "%s%%%u",
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, buf,
|
||||
sizeof(buf)), sin6->sin6_scope_id);
|
||||
} else
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, buf,
|
||||
sizeof(buf));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
sprintf(buf, "unknown");
|
||||
}
|
||||
printf("sockaddr{ len=%u family=%u addr=%s }\n", addr->sa_len,
|
||||
addr->sa_family, buf);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user