Add support for options IPSEC_NAT_T (RFC 3947 and 3948) for fast_ipsec(4).
No objection on tech-net@
This commit is contained in:
parent
f4e11163b6
commit
4ddfe916ff
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp_usrreq.c,v 1.159 2007/05/12 02:03:15 dyoung Exp $ */
|
||||
/* $NetBSD: udp_usrreq.c,v 1.160 2007/06/27 20:38:32 degroote Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -61,7 +61,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.159 2007/05/12 02:03:15 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.160 2007/06/27 20:38:32 degroote Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -1528,7 +1528,7 @@ udp4_espinudp(struct mbuf **mp, int off, struct sockaddr *src,
|
||||
m_tag_prepend(n, tag);
|
||||
|
||||
#ifdef FAST_IPSEC
|
||||
ipsec4_common_input(n, iphdrlen);
|
||||
ipsec4_common_input(n, iphdrlen, IPPROTO_ESP);
|
||||
#else
|
||||
esp4_input(n, iphdrlen);
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ipsec_input.c,v 1.16 2007/03/04 21:17:54 degroote Exp $ */
|
||||
/* $NetBSD: ipsec_input.c,v 1.17 2007/06/27 20:38:33 degroote Exp $ */
|
||||
/* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec_input.c,v 1.2.4.2 2003/03/28 20:32:53 sam Exp $ */
|
||||
/* $OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $ */
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.16 2007/03/04 21:17:54 degroote Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.17 2007/06/27 20:38:33 degroote Exp $");
|
||||
|
||||
/*
|
||||
* IPsec input processing.
|
||||
@ -116,7 +116,12 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
||||
union sockaddr_union dst_address;
|
||||
struct secasvar *sav;
|
||||
u_int32_t spi;
|
||||
u_int16_t sport = 0;
|
||||
u_int16_t dport = 0;
|
||||
int s, error;
|
||||
#ifdef IPSEC_NAT_T
|
||||
struct m_tag * tag = NULL;
|
||||
#endif
|
||||
|
||||
IPSEC_ISTAT(sproto, espstat.esps_input, ahstat.ahs_input,
|
||||
ipcompstat.ipcomps_input);
|
||||
@ -149,7 +154,19 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
||||
u_int16_t cpi;
|
||||
m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t), &cpi);
|
||||
spi = ntohl(htons(cpi));
|
||||
} else {
|
||||
panic("ipsec_common_input called with bad protocol number :"
|
||||
"%d\n", sproto);
|
||||
}
|
||||
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/* find the source port for NAT-T */
|
||||
if ((tag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL))) {
|
||||
sport = ((u_int16_t *)(tag + 1))[0];
|
||||
dport = ((u_int16_t *)(tag + 1))[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find the SA and (indirectly) call the appropriate
|
||||
@ -187,12 +204,12 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
||||
s = splsoftnet();
|
||||
|
||||
/* NB: only pass dst since key_allocsa follows RFC2401 */
|
||||
sav = KEY_ALLOCSA(&dst_address, sproto, spi);
|
||||
sav = KEY_ALLOCSA(&dst_address, sproto, spi, sport, dport);
|
||||
if (sav == NULL) {
|
||||
DPRINTF(("ipsec_common_input: no key association found for"
|
||||
" SA %s/%08lx/%u\n",
|
||||
" SA %s/%08lx/%u/%u\n",
|
||||
ipsec_address(&dst_address),
|
||||
(u_long) ntohl(spi), sproto));
|
||||
(u_long) ntohl(spi), sproto, ntohs(dport)));
|
||||
IPSEC_ISTAT(sproto, espstat.esps_notdb, ahstat.ahs_notdb,
|
||||
ipcompstat.ipcomps_notdb);
|
||||
splx(s);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ipsec_netbsd.c,v 1.26 2007/04/11 22:21:41 degroote Exp $ */
|
||||
/* $NetBSD: ipsec_netbsd.c,v 1.27 2007/06/27 20:38:33 degroote Exp $ */
|
||||
/* $KAME: esp_input.c,v 1.60 2001/09/04 08:43:19 itojun Exp $ */
|
||||
/* $KAME: ah_input.c,v 1.64 2001/09/04 08:43:19 itojun Exp $ */
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_netbsd.c,v 1.26 2007/04/11 22:21:41 degroote Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_netbsd.c,v 1.27 2007/06/27 20:38:33 degroote Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -112,7 +112,7 @@ ah4_ctlinput(cmd, sa, v)
|
||||
*/
|
||||
ah = (struct ah *)((char *)ip + (ip->ip_hl << 2));
|
||||
sav = KEY_ALLOCSA((const union sockaddr_union *)sa,
|
||||
IPPROTO_AH, ah->ah_spi);
|
||||
IPPROTO_AH, ah->ah_spi, 0, 0);
|
||||
|
||||
if (sav) {
|
||||
if (sav->state == SADB_SASTATE_MATURE ||
|
||||
@ -163,7 +163,7 @@ esp4_ctlinput(cmd, sa, v)
|
||||
*/
|
||||
esp = (struct esp *)((char *)ip + (ip->ip_hl << 2));
|
||||
sav = KEY_ALLOCSA((const union sockaddr_union *)sa,
|
||||
IPPROTO_ESP, esp->esp_spi);
|
||||
IPPROTO_ESP, esp->esp_spi, 0, 0);
|
||||
|
||||
if (sav) {
|
||||
if (sav->state == SADB_SASTATE_MATURE ||
|
||||
@ -249,7 +249,7 @@ ah6_ctlinput(cmd, sa, d)
|
||||
* to the address in the ICMP message payload.
|
||||
*/
|
||||
sav = KEY_ALLOCSA((const union sockaddr_union*)sa,
|
||||
IPPROTO_AH, ahp->ah_spi);
|
||||
IPPROTO_AH, ahp->ah_spi, 0, 0);
|
||||
|
||||
if (sav) {
|
||||
if (sav->state == SADB_SASTATE_MATURE ||
|
||||
@ -357,7 +357,7 @@ esp6_ctlinput(cmd, sa, d)
|
||||
*/
|
||||
|
||||
sav = KEY_ALLOCSA((const union sockaddr_union*)sa,
|
||||
IPPROTO_ESP, espp->esp_spi);
|
||||
IPPROTO_ESP, espp->esp_spi, 0, 0);
|
||||
|
||||
if (sav) {
|
||||
if (sav->state == SADB_SASTATE_MATURE ||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ipsec_output.c,v 1.21 2007/02/10 09:43:05 degroote Exp $ */
|
||||
/* $NetBSD: ipsec_output.c,v 1.22 2007/06/27 20:38:33 degroote Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
|
||||
@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.21 2007/02/10 09:43:05 degroote Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.22 2007/06/27 20:38:33 degroote Exp $");
|
||||
|
||||
/*
|
||||
* IPsec output processing.
|
||||
@ -72,6 +72,9 @@ __KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.21 2007/02/10 09:43:05 degroote E
|
||||
#ifdef INET6
|
||||
#include <netinet/icmp6.h>
|
||||
#endif
|
||||
#ifdef IPSEC_NAT_T
|
||||
#include <netinet/udp.h>
|
||||
#endif
|
||||
|
||||
#include <netipsec/ipsec.h>
|
||||
#include <netipsec/ipsec_var.h>
|
||||
@ -99,6 +102,18 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
|
||||
struct secasvar *sav;
|
||||
struct secasindex *saidx;
|
||||
int error;
|
||||
#ifdef INET
|
||||
struct ip * ip;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
struct ip6_hdr * ip6;
|
||||
#endif /* INET6 */
|
||||
#ifdef IPSEC_NAT_T
|
||||
struct mbuf * mo;
|
||||
struct udphdr *udp = NULL;
|
||||
uint64_t * data = NULL;
|
||||
int hlen, roff;
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
IPSEC_SPLASSERT_SOFTNET("ipsec_process_done");
|
||||
|
||||
@ -109,11 +124,57 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
|
||||
IPSEC_ASSERT(sav->sah != NULL, ("ipsec_process_done: null SAH"));
|
||||
|
||||
saidx = &sav->sah->saidx;
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
if(sav->natt_type != 0) {
|
||||
ip = mtod(m, struct ip *);
|
||||
|
||||
hlen = sizeof(struct udphdr);
|
||||
if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE)
|
||||
hlen += sizeof(uint64_t);
|
||||
|
||||
mo = m_makespace(m, sizeof(struct ip), hlen, &roff);
|
||||
if (mo == NULL) {
|
||||
DPRINTF(("ipsec_process_done : failed to inject"
|
||||
"%u byte UDP for SA %s/%08lx\n",
|
||||
hlen, ipsec_address(&saidx->dst),
|
||||
(u_long) ntohl(sav->spi)));
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
udp = (struct udphdr*) (mtod(mo, char*) + roff);
|
||||
data = (uint64_t*) (udp + 1);
|
||||
|
||||
if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE)
|
||||
*data = 0; /* NON-IKE Marker */
|
||||
|
||||
if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE)
|
||||
udp->uh_sport = htons(UDP_ENCAP_ESPINUDP_PORT);
|
||||
else
|
||||
udp->uh_sport = key_portfromsaddr(&saidx->src);
|
||||
|
||||
udp->uh_dport = key_portfromsaddr(&saidx->dst);
|
||||
udp->uh_sum = 0;
|
||||
#ifdef _IP_VHL
|
||||
udp->uh_ulen = htons(m->m_pkthdr.len -
|
||||
(IP_VHL_HL(ip->ip_vhl) << 2));
|
||||
#else
|
||||
udp->uh_ulen = htons(m->m_pkthdr.len - (ip->ip_hl << 2));
|
||||
#endif
|
||||
}
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
switch (saidx->dst.sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
/* Fix the header length, for AH processing. */
|
||||
mtod(m, struct ip *)->ip_len = htons(m->m_pkthdr.len);
|
||||
ip = mtod(m, struct ip *);
|
||||
ip->ip_len = htons(m->m_pkthdr.len);
|
||||
#ifdef IPSEC_NAT_T
|
||||
if (sav->natt_type != 0)
|
||||
ip->ip_p = IPPROTO_UDP;
|
||||
#endif /* IPSEC_NAT_T */
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
@ -128,8 +189,12 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
|
||||
error = ENXIO; /*?*/
|
||||
goto bad;
|
||||
}
|
||||
mtod(m, struct ip6_hdr *)->ip6_plen =
|
||||
htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
|
||||
#ifdef IPSEC_NAT_T
|
||||
if (sav->natt_type != 0)
|
||||
ip6->ip6_nxt = IPPROTO_UDP;
|
||||
#endif /* IPSEC_NAT_T */
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
default:
|
||||
@ -190,7 +255,6 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
|
||||
*/
|
||||
switch (saidx->dst.sa.sa_family) {
|
||||
#ifdef INET
|
||||
struct ip *ip;
|
||||
case AF_INET:
|
||||
ip = mtod(m, struct ip *);
|
||||
#ifdef __FreeBSD__
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: key.c,v 1.47 2007/05/08 14:03:05 degroote Exp $ */
|
||||
/* $NetBSD: key.c,v 1.48 2007/06/27 20:38:33 degroote Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */
|
||||
/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.47 2007/05/08 14:03:05 degroote Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.48 2007/06/27 20:38:33 degroote Exp $");
|
||||
|
||||
/*
|
||||
* This code is referd to RFC 2367
|
||||
@ -353,16 +353,10 @@ do { \
|
||||
* set parameters into secasindex buffer.
|
||||
* Must allocate secasindex buffer before calling this function.
|
||||
*/
|
||||
#define KEY_SETSECASIDX(p, m, r, s, d, idx) \
|
||||
do { \
|
||||
bzero((idx), sizeof(struct secasindex)); \
|
||||
(idx)->proto = (p); \
|
||||
(idx)->mode = (m); \
|
||||
(idx)->reqid = (r); \
|
||||
bcopy((s), &(idx)->src, ((const struct sockaddr *)(s))->sa_len); \
|
||||
bcopy((d), &(idx)->dst, ((const struct sockaddr *)(d))->sa_len); \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
key_setsecasidx __P((int, int, int, const struct sadb_address *,
|
||||
const struct sadb_address *, struct secasindex *));
|
||||
|
||||
/* key statistics */
|
||||
struct _keystat {
|
||||
u_long getspi_count; /* the avarage of count to try to get new SPI */
|
||||
@ -399,6 +393,10 @@ static int key_spddump __P((struct socket *, struct mbuf *,
|
||||
const struct sadb_msghdr *));
|
||||
static struct mbuf * key_setspddump __P((int *errorp, pid_t));
|
||||
static struct mbuf * key_setspddump_chain __P((int *errorp, int *lenp, pid_t pid));
|
||||
#ifdef IPSEC_NAT_T
|
||||
static int key_nat_map __P((struct socket *, struct mbuf *,
|
||||
const struct sadb_msghdr *));
|
||||
#endif
|
||||
static struct mbuf *key_setdumpsp __P((struct secpolicy *,
|
||||
u_int8_t, u_int32_t, pid_t));
|
||||
static u_int key_getspreqmsglen __P((struct secpolicy *));
|
||||
@ -419,6 +417,12 @@ static int key_setsaval __P((struct secasvar *, struct mbuf *,
|
||||
static int key_mature __P((struct secasvar *));
|
||||
static struct mbuf *key_setdumpsa __P((struct secasvar *, u_int8_t,
|
||||
u_int8_t, u_int32_t, u_int32_t));
|
||||
#ifdef IPSEC_NAT_T
|
||||
static struct mbuf *key_setsadbxport __P((u_int16_t, u_int16_t));
|
||||
static struct mbuf *key_setsadbxtype __P((u_int16_t));
|
||||
#endif
|
||||
static void key_porttosaddr __P((union sockaddr_union *, u_int16_t));
|
||||
static int key_checksalen __P((const union sockaddr_union *));
|
||||
static struct mbuf *key_setsadbmsg __P((u_int8_t, u_int16_t, u_int8_t,
|
||||
u_int32_t, pid_t, u_int16_t));
|
||||
static struct mbuf *key_setsadbsa __P((struct secasvar *));
|
||||
@ -454,6 +458,10 @@ static int key_getspi __P((struct socket *, struct mbuf *,
|
||||
const struct sadb_msghdr *));
|
||||
static u_int32_t key_do_getnewspi __P((struct sadb_spirange *,
|
||||
struct secasindex *));
|
||||
#ifdef IPSEC_NAT_T
|
||||
static int key_handle_natt_info __P((struct secasvar *,
|
||||
const struct sadb_msghdr *));
|
||||
#endif
|
||||
static int key_update __P((struct socket *, struct mbuf *,
|
||||
const struct sadb_msghdr *));
|
||||
#ifdef IPSEC_DOSEQCHECK
|
||||
@ -1037,24 +1045,34 @@ key_do_allocsa_policy(struct secashead *sah, u_int state)
|
||||
* Note that, however, we do need to keep source address in IPsec SA.
|
||||
* IKE specification and PF_KEY specification do assume that we
|
||||
* keep source address in IPsec SA. We see a tricky situation here.
|
||||
*
|
||||
* sport and dport are used for NAT-T. network order is always used.
|
||||
*/
|
||||
struct secasvar *
|
||||
key_allocsa(
|
||||
const union sockaddr_union *dst,
|
||||
u_int proto,
|
||||
u_int32_t spi,
|
||||
u_int16_t sport,
|
||||
u_int16_t dport,
|
||||
const char* where, int tag)
|
||||
{
|
||||
struct secashead *sah;
|
||||
struct secasvar *sav;
|
||||
u_int stateidx, state;
|
||||
int s;
|
||||
int chkport = 0;
|
||||
|
||||
int must_check_spi = 1;
|
||||
int must_check_alg = 0;
|
||||
u_int16_t cpi = 0;
|
||||
u_int8_t algo = 0;
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
if ((sport != 0) && (dport != 0))
|
||||
chkport = 1;
|
||||
#endif
|
||||
|
||||
IPSEC_ASSERT(dst != NULL, ("key_allocsa: null dst address"));
|
||||
|
||||
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
|
||||
@ -1108,12 +1126,16 @@ key_allocsa(
|
||||
continue;
|
||||
|
||||
#if 0 /* don't check src */
|
||||
/* Fix port in src->sa */
|
||||
|
||||
/* check src address */
|
||||
if (key_sockaddrcmp(&src->sa, &sav->sah->saidx.src.sa, 0) != 0)
|
||||
continue;
|
||||
#endif
|
||||
/* fix port of dst address XXX*/
|
||||
key_porttosaddr(__UNCONST(dst), dport);
|
||||
/* check dst address */
|
||||
if (key_sockaddrcmp(&dst->sa, &sav->sah->saidx.dst.sa, 0) != 0)
|
||||
if (key_sockaddrcmp(&dst->sa, &sav->sah->saidx.dst.sa, chkport) != 0)
|
||||
continue;
|
||||
SA_ADDREF(sav);
|
||||
goto done;
|
||||
@ -2546,6 +2568,68 @@ key_spddump(so, m0, mhp)
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/*
|
||||
* SADB_X_NAT_T_NEW_MAPPING. Unused by racoon as of 2005/04/23
|
||||
*/
|
||||
static int
|
||||
key_nat_map(so, m, mhp)
|
||||
struct socket *so;
|
||||
struct mbuf *m;
|
||||
const struct sadb_msghdr *mhp;
|
||||
{
|
||||
struct sadb_x_nat_t_type *type;
|
||||
struct sadb_x_nat_t_port *sport;
|
||||
struct sadb_x_nat_t_port *dport;
|
||||
struct sadb_address *addr;
|
||||
struct sadb_x_nat_t_frag *frag;
|
||||
|
||||
/* sanity check */
|
||||
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
|
||||
panic("key_nat_map: NULL pointer is passed.");
|
||||
|
||||
if (mhp->ext[SADB_X_EXT_NAT_T_TYPE] == NULL ||
|
||||
mhp->ext[SADB_X_EXT_NAT_T_SPORT] == NULL ||
|
||||
mhp->ext[SADB_X_EXT_NAT_T_DPORT] == NULL) {
|
||||
ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n"));
|
||||
return key_senderror(so, m, EINVAL);
|
||||
}
|
||||
if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) ||
|
||||
(mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) ||
|
||||
(mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) {
|
||||
ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n"));
|
||||
return key_senderror(so, m, EINVAL);
|
||||
}
|
||||
|
||||
if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) &&
|
||||
(mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) {
|
||||
ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n"));
|
||||
return key_senderror(so, m, EINVAL);
|
||||
}
|
||||
|
||||
if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) &&
|
||||
(mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) {
|
||||
ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n"));
|
||||
return key_senderror(so, m, EINVAL);
|
||||
}
|
||||
|
||||
type = (struct sadb_x_nat_t_type *)mhp->ext[SADB_X_EXT_NAT_T_TYPE];
|
||||
sport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_SPORT];
|
||||
dport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_DPORT];
|
||||
addr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OA];
|
||||
frag = (struct sadb_x_nat_t_frag *) mhp->ext[SADB_X_EXT_NAT_T_FRAG];
|
||||
|
||||
printf("sadb_nat_map called\n");
|
||||
|
||||
/*
|
||||
* XXX handle that, it should also contain a SA, or anything
|
||||
* that enable to update the SA information.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
static struct mbuf *
|
||||
key_setdumpsp(sp, type, seq, pid)
|
||||
struct secpolicy *sp;
|
||||
@ -3128,6 +3212,10 @@ key_setsaval(sav, m, mhp)
|
||||
sav->tdb_encalgxform = NULL; /* encoding algorithm */
|
||||
sav->tdb_authalgxform = NULL; /* authentication algorithm */
|
||||
sav->tdb_compalgxform = NULL; /* compression algorithm */
|
||||
#ifdef IPSEC_NAT_T
|
||||
sav->natt_type = 0;
|
||||
sav->esp_frag = 0;
|
||||
#endif
|
||||
|
||||
/* SA */
|
||||
if (mhp->ext[SADB_EXT_SA] != NULL) {
|
||||
@ -3463,6 +3551,12 @@ key_setdumpsa(sav, type, satype, seq, pid)
|
||||
SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH,
|
||||
SADB_EXT_KEY_ENCRYPT, SADB_EXT_IDENTITY_SRC,
|
||||
SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY,
|
||||
#ifdef IPSEC_NAT_T
|
||||
SADB_X_EXT_NAT_T_TYPE, SADB_X_EXT_NAT_T_SPORT,
|
||||
SADB_X_EXT_NAT_T_DPORT, SADB_X_EXT_NAT_T_OA,
|
||||
SADB_X_EXT_NAT_T_FRAG,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt);
|
||||
@ -3539,6 +3633,31 @@ key_setdumpsa(sav, type, satype, seq, pid)
|
||||
p = sav->lft_s;
|
||||
break;
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
case SADB_X_EXT_NAT_T_TYPE:
|
||||
if ((m = key_setsadbxtype(sav->natt_type)) == NULL)
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case SADB_X_EXT_NAT_T_DPORT:
|
||||
if ((m = key_setsadbxport(
|
||||
key_portfromsaddr(&sav->sah->saidx.dst),
|
||||
SADB_X_EXT_NAT_T_DPORT)) == NULL)
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case SADB_X_EXT_NAT_T_SPORT:
|
||||
if ((m = key_setsadbxport(
|
||||
key_portfromsaddr(&sav->sah->saidx.src),
|
||||
SADB_X_EXT_NAT_T_SPORT)) == NULL)
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case SADB_X_EXT_NAT_T_OA:
|
||||
case SADB_X_EXT_NAT_T_FRAG:
|
||||
continue;
|
||||
#endif
|
||||
|
||||
case SADB_EXT_ADDRESS_PROXY:
|
||||
case SADB_EXT_IDENTITY_SRC:
|
||||
case SADB_EXT_IDENTITY_DST:
|
||||
@ -3592,6 +3711,155 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/*
|
||||
* set a type in sadb_x_nat_t_type
|
||||
*/
|
||||
static struct mbuf *
|
||||
key_setsadbxtype(type)
|
||||
u_int16_t type;
|
||||
{
|
||||
struct mbuf *m;
|
||||
size_t len;
|
||||
struct sadb_x_nat_t_type *p;
|
||||
|
||||
len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_type));
|
||||
|
||||
m = key_alloc_mbuf(len);
|
||||
if (!m || m->m_next) { /*XXX*/
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = mtod(m, struct sadb_x_nat_t_type *);
|
||||
|
||||
bzero(p, len);
|
||||
p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
|
||||
p->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
|
||||
p->sadb_x_nat_t_type_type = type;
|
||||
|
||||
return m;
|
||||
}
|
||||
/*
|
||||
* set a port in sadb_x_nat_t_port. port is in network order
|
||||
*/
|
||||
static struct mbuf *
|
||||
key_setsadbxport(port, type)
|
||||
u_int16_t port;
|
||||
u_int16_t type;
|
||||
{
|
||||
struct mbuf *m;
|
||||
size_t len;
|
||||
struct sadb_x_nat_t_port *p;
|
||||
|
||||
len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_port));
|
||||
|
||||
m = key_alloc_mbuf(len);
|
||||
if (!m || m->m_next) { /*XXX*/
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = mtod(m, struct sadb_x_nat_t_port *);
|
||||
|
||||
bzero(p, len);
|
||||
p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
|
||||
p->sadb_x_nat_t_port_exttype = type;
|
||||
p->sadb_x_nat_t_port_port = port;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get port from sockaddr, port is in network order
|
||||
*/
|
||||
u_int16_t
|
||||
key_portfromsaddr(saddr)
|
||||
const union sockaddr_union *saddr;
|
||||
{
|
||||
u_int16_t port;
|
||||
|
||||
switch (saddr->sa.sa_family) {
|
||||
case AF_INET: {
|
||||
port = saddr->sin.sin_port;
|
||||
break;
|
||||
}
|
||||
#ifdef INET6
|
||||
case AF_INET6: {
|
||||
port = saddr->sin6.sin6_port;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
printf("key_portfromsaddr: unexpected address family\n");
|
||||
port = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
/*
|
||||
* Set port is struct sockaddr. port is in network order
|
||||
*/
|
||||
static void
|
||||
key_porttosaddr(saddr, port)
|
||||
union sockaddr_union *saddr;
|
||||
u_int16_t port;
|
||||
{
|
||||
switch (saddr->sa.sa_family) {
|
||||
case AF_INET: {
|
||||
saddr->sin.sin_port = port;
|
||||
break;
|
||||
}
|
||||
#ifdef INET6
|
||||
case AF_INET6: {
|
||||
saddr->sin6.sin6_port = port;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
printf("key_porttosaddr: unexpected address family %d\n",
|
||||
saddr->sa.sa_family);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Safety check sa_len
|
||||
*/
|
||||
static int
|
||||
key_checksalen(saddr)
|
||||
const union sockaddr_union *saddr;
|
||||
{
|
||||
switch (saddr->sa.sa_family) {
|
||||
case AF_INET:
|
||||
if (saddr->sa.sa_len != sizeof(struct sockaddr_in))
|
||||
return -1;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (saddr->sa.sa_len != sizeof(struct sockaddr_in6))
|
||||
return -1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("key_checksalen: unexpected sa_family %d\n",
|
||||
saddr->sa.sa_family);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set data into sadb_msg.
|
||||
*/
|
||||
@ -3961,6 +4229,8 @@ key_cmpsaidx(
|
||||
const struct secasindex *saidx1,
|
||||
int flag)
|
||||
{
|
||||
int chkport = 0;
|
||||
|
||||
/* sanity */
|
||||
if (saidx0 == NULL && saidx1 == NULL)
|
||||
return 1;
|
||||
@ -3998,10 +4268,20 @@ key_cmpsaidx(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (key_sockaddrcmp(&saidx0->src.sa, &saidx1->src.sa, 0) != 0) {
|
||||
/*
|
||||
* If NAT-T is enabled, check ports for tunnel mode.
|
||||
* Don't do it for transport mode, as there is no
|
||||
* port information available in the SP.
|
||||
*/
|
||||
#ifdef IPSEC_NAT_T
|
||||
if (saidx1->mode == IPSEC_MODE_TUNNEL)
|
||||
chkport = 1;
|
||||
#endif
|
||||
|
||||
if (key_sockaddrcmp(&saidx0->src.sa, &saidx1->src.sa, chkport) != 0) {
|
||||
return 0;
|
||||
}
|
||||
if (key_sockaddrcmp(&saidx0->dst.sa, &saidx1->dst.sa, 0) != 0) {
|
||||
if (key_sockaddrcmp(&saidx0->dst.sa, &saidx1->dst.sa, chkport) != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -4597,6 +4877,40 @@ key_proto2satype(proto)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static int
|
||||
key_setsecasidx(proto, mode, reqid, src, dst, saidx)
|
||||
int proto;
|
||||
int mode;
|
||||
int reqid;
|
||||
const struct sadb_address * src;
|
||||
const struct sadb_address * dst;
|
||||
struct secasindex * saidx;
|
||||
{
|
||||
const union sockaddr_union * src_u =
|
||||
(const union sockaddr_union *) src;
|
||||
const union sockaddr_union * dst_u =
|
||||
(const union sockaddr_union *) dst;
|
||||
|
||||
/* sa len safety check */
|
||||
if (key_checksalen(src_u) != 0)
|
||||
return -1;
|
||||
if (key_checksalen(dst_u) != 0)
|
||||
return -1;
|
||||
|
||||
memset(saidx, 0, sizeof(*saidx));
|
||||
saidx->proto = proto;
|
||||
saidx->mode = mode;
|
||||
saidx->reqid = reqid;
|
||||
memcpy(&saidx->src, src_u, src_u->sa.sa_len);
|
||||
memcpy(&saidx->dst, dst_u, dst_u->sa.sa_len);
|
||||
|
||||
#ifndef IPSEC_NAT_T
|
||||
key_porttosaddr(&((saidx)->src),0); \
|
||||
key_porttosaddr(&((saidx)->dst),0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* %%% PF_KEY */
|
||||
/*
|
||||
* SADB_GETSPI processing is to receive
|
||||
@ -4657,42 +4971,10 @@ key_getspi(so, m, mhp)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
}
|
||||
|
||||
/* make sure if port number is zero. */
|
||||
switch (((struct sockaddr *)(src0 + 1))->sa_family) {
|
||||
case AF_INET:
|
||||
if (((struct sockaddr *)(src0 + 1))->sa_len !=
|
||||
sizeof(struct sockaddr_in))
|
||||
return key_senderror(so, m, EINVAL);
|
||||
((struct sockaddr_in *)(src0 + 1))->sin_port = 0;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (((struct sockaddr *)(src0 + 1))->sa_len !=
|
||||
sizeof(struct sockaddr_in6))
|
||||
return key_senderror(so, m, EINVAL);
|
||||
((struct sockaddr_in6 *)(src0 + 1))->sin6_port = 0;
|
||||
break;
|
||||
default:
|
||||
; /*???*/
|
||||
}
|
||||
switch (((struct sockaddr *)(dst0 + 1))->sa_family) {
|
||||
case AF_INET:
|
||||
if (((struct sockaddr *)(dst0 + 1))->sa_len !=
|
||||
sizeof(struct sockaddr_in))
|
||||
return key_senderror(so, m, EINVAL);
|
||||
((struct sockaddr_in *)(dst0 + 1))->sin_port = 0;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (((struct sockaddr *)(dst0 + 1))->sa_len !=
|
||||
sizeof(struct sockaddr_in6))
|
||||
return key_senderror(so, m, EINVAL);
|
||||
((struct sockaddr_in6 *)(dst0 + 1))->sin6_port = 0;
|
||||
break;
|
||||
default:
|
||||
; /*???*/
|
||||
}
|
||||
|
||||
/* XXX boundary check against sa_len */
|
||||
KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx);
|
||||
if ((error = key_setsecasidx(proto, mode, reqid, src0 + 1,
|
||||
dst0 + 1, &saidx)) != 0)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
|
||||
/* SPI allocation */
|
||||
spi = key_do_getnewspi((struct sadb_spirange *)mhp->ext[SADB_EXT_SPIRANGE],
|
||||
@ -4872,6 +5154,76 @@ key_do_getnewspi(spirange, saidx)
|
||||
return newspi;
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/* Handle IPSEC_NAT_T info if present */
|
||||
static int
|
||||
key_handle_natt_info(sav,mhp)
|
||||
struct secasvar *sav;
|
||||
const struct sadb_msghdr *mhp;
|
||||
{
|
||||
|
||||
if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL)
|
||||
printf("update: NAT-T OA present\n");
|
||||
|
||||
if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) &&
|
||||
(mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) &&
|
||||
(mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) {
|
||||
struct sadb_x_nat_t_type *type;
|
||||
struct sadb_x_nat_t_port *sport;
|
||||
struct sadb_x_nat_t_port *dport;
|
||||
struct sadb_address *addr;
|
||||
struct sadb_x_nat_t_frag *frag;
|
||||
|
||||
if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) ||
|
||||
(mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) ||
|
||||
(mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) {
|
||||
ipseclog((LOG_DEBUG, "key_update: "
|
||||
"invalid message.\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) &&
|
||||
(mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) {
|
||||
ipseclog((LOG_DEBUG, "key_update: invalid message\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) &&
|
||||
(mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) {
|
||||
ipseclog((LOG_DEBUG, "key_update: invalid message\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
type = (struct sadb_x_nat_t_type *)
|
||||
mhp->ext[SADB_X_EXT_NAT_T_TYPE];
|
||||
sport = (struct sadb_x_nat_t_port *)
|
||||
mhp->ext[SADB_X_EXT_NAT_T_SPORT];
|
||||
dport = (struct sadb_x_nat_t_port *)
|
||||
mhp->ext[SADB_X_EXT_NAT_T_DPORT];
|
||||
addr = (struct sadb_address *)
|
||||
mhp->ext[SADB_X_EXT_NAT_T_OA];
|
||||
frag = (struct sadb_x_nat_t_frag *)
|
||||
mhp->ext[SADB_X_EXT_NAT_T_FRAG];
|
||||
|
||||
if (type)
|
||||
sav->natt_type = type->sadb_x_nat_t_type_type;
|
||||
if (sport)
|
||||
key_porttosaddr(&sav->sah->saidx.src,
|
||||
sport->sadb_x_nat_t_port_port);
|
||||
if (dport)
|
||||
key_porttosaddr(&sav->sah->saidx.dst,
|
||||
dport->sadb_x_nat_t_port_port);
|
||||
if (frag)
|
||||
sav->esp_frag = frag->sadb_x_nat_t_frag_fraglen;
|
||||
else
|
||||
sav->esp_frag = IP_MAXPACKET;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* SADB_UPDATE processing
|
||||
* receive
|
||||
@ -4944,8 +5296,10 @@ key_update(so, m, mhp)
|
||||
src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
|
||||
dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
|
||||
|
||||
/* XXX boundary check against sa_len */
|
||||
KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx);
|
||||
if ((error = key_setsecasidx(proto, mode, reqid, src0 + 1,
|
||||
dst0 + 1, &saidx)) != 0)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
|
||||
|
||||
/* get a SA header */
|
||||
if ((sah = key_getsah(&saidx)) == NULL) {
|
||||
@ -5013,6 +5367,11 @@ key_update(so, m, mhp)
|
||||
return key_senderror(so, m, 0);
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
if ((error = key_handle_natt_info(sav,mhp)) != 0)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
{
|
||||
struct mbuf *n;
|
||||
|
||||
@ -5139,8 +5498,9 @@ key_add(so, m, mhp)
|
||||
src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
|
||||
dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
|
||||
|
||||
/* XXX boundary check against sa_len */
|
||||
KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx);
|
||||
if ((error = key_setsecasidx(proto, mode, reqid, src0 + 1,
|
||||
dst0 + 1, &saidx)) != 0)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
|
||||
/* get a SA header */
|
||||
if ((newsah = key_getsah(&saidx)) == NULL) {
|
||||
@ -5175,6 +5535,11 @@ key_add(so, m, mhp)
|
||||
return key_senderror(so, m, error);
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
if ((error = key_handle_natt_info(newsav, mhp)) != 0)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
/*
|
||||
* don't call key_freesav() here, as we would like to keep the SA
|
||||
* in the database on success.
|
||||
@ -5326,6 +5691,7 @@ key_delete(so, m, mhp)
|
||||
struct secashead *sah;
|
||||
struct secasvar *sav = NULL;
|
||||
u_int16_t proto;
|
||||
int error;
|
||||
|
||||
/* sanity check */
|
||||
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
|
||||
@ -5366,8 +5732,9 @@ key_delete(so, m, mhp)
|
||||
src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
|
||||
dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
|
||||
|
||||
/* XXX boundary check against sa_len */
|
||||
KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
|
||||
if ((error = key_setsecasidx(proto, IPSEC_MODE_ANY, 0, src0 + 1,
|
||||
dst0 + 1, &saidx)) != 0)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
|
||||
/* get a SA header */
|
||||
LIST_FOREACH(sah, &sahtree, chain) {
|
||||
@ -5428,12 +5795,14 @@ key_delete_all(so, m, mhp, proto)
|
||||
struct secashead *sah;
|
||||
struct secasvar *sav, *nextsav;
|
||||
u_int stateidx, state;
|
||||
int error;
|
||||
|
||||
src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
|
||||
dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
|
||||
|
||||
/* XXX boundary check against sa_len */
|
||||
KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
|
||||
if ((error = key_setsecasidx(proto, IPSEC_MODE_ANY, 0, src0 + 1,
|
||||
dst0 + 1, &saidx)) != 0)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
|
||||
LIST_FOREACH(sah, &sahtree, chain) {
|
||||
if (sah->state == SADB_SASTATE_DEAD)
|
||||
@ -5513,6 +5882,7 @@ key_get(so, m, mhp)
|
||||
struct secashead *sah;
|
||||
struct secasvar *sav = NULL;
|
||||
u_int16_t proto;
|
||||
int error;
|
||||
|
||||
/* sanity check */
|
||||
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
|
||||
@ -5541,8 +5911,10 @@ key_get(so, m, mhp)
|
||||
src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
|
||||
dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
|
||||
|
||||
/* XXX boundary check against sa_len */
|
||||
KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
|
||||
|
||||
if ((error = key_setsecasidx(proto, IPSEC_MODE_ANY, 0, src0 + 1,
|
||||
dst0 + 1, &saidx)) != 0)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
|
||||
/* get a SA header */
|
||||
LIST_FOREACH(sah, &sahtree, chain) {
|
||||
@ -6225,8 +6597,9 @@ key_acquire2(so, m, mhp)
|
||||
src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
|
||||
dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
|
||||
|
||||
/* XXX boundary check against sa_len */
|
||||
KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
|
||||
if ((error = key_setsecasidx(proto, IPSEC_MODE_ANY, 0, src0 + 1,
|
||||
dst0 + 1, &saidx)) != 0)
|
||||
return key_senderror(so, m, EINVAL);
|
||||
|
||||
/* get a SA index */
|
||||
LIST_FOREACH(sah, &sahtree, chain) {
|
||||
@ -6913,7 +7286,9 @@ static int (*key_typesw[]) __P((struct socket *, struct mbuf *,
|
||||
key_spdadd, /* SADB_X_SPDSETIDX */
|
||||
NULL, /* SADB_X_SPDEXPIRE */
|
||||
key_spddelete2, /* SADB_X_SPDDELETE2 */
|
||||
NULL, /* SADB_X_NAT_T_NEW_MAPPING */
|
||||
#ifdef IPSEC_NAT_T
|
||||
key_nat_map, /* SADB_X_NAT_T_NEW_MAPPING */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@ -7255,6 +7630,13 @@ key_align(m, mhp)
|
||||
case SADB_EXT_SPIRANGE:
|
||||
case SADB_X_EXT_POLICY:
|
||||
case SADB_X_EXT_SA2:
|
||||
#ifdef IPSEC_NAT_T
|
||||
case SADB_X_EXT_NAT_T_TYPE:
|
||||
case SADB_X_EXT_NAT_T_SPORT:
|
||||
case SADB_X_EXT_NAT_T_DPORT:
|
||||
case SADB_X_EXT_NAT_T_OA:
|
||||
case SADB_X_EXT_NAT_T_FRAG:
|
||||
#endif
|
||||
/* duplicate check */
|
||||
/*
|
||||
* XXX Are there duplication payloads of either
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: key.h,v 1.6 2007/03/04 06:03:29 christos Exp $ */
|
||||
/* $NetBSD: key.h,v 1.7 2007/06/27 20:38:33 degroote Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/key.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
|
||||
/* $KAME: key.h,v 1.21 2001/07/27 03:51:30 itojun Exp $ */
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
struct secpolicy;
|
||||
struct secpolicyindex;
|
||||
struct ipsecrequest;
|
||||
@ -78,11 +80,11 @@ extern void _key_freesp(struct secpolicy **, const char*, int);
|
||||
_key_freesp(spp, __FILE__, __LINE__)
|
||||
|
||||
extern struct secasvar *key_allocsa(const union sockaddr_union *,
|
||||
u_int, u_int32_t,const char*, int);
|
||||
u_int, u_int32_t, u_int16_t, u_int16_t, const char*, int);
|
||||
extern void key_freesav(struct secasvar **, const char*, int);
|
||||
|
||||
#define KEY_ALLOCSA(dst, proto, spi) \
|
||||
key_allocsa(dst, proto, spi, __FILE__, __LINE__)
|
||||
#define KEY_ALLOCSA(dst, proto, spi, sport, dport) \
|
||||
key_allocsa(dst, proto, spi, sport, dport, __FILE__, __LINE__)
|
||||
#define KEY_FREESAV(psav) \
|
||||
key_freesav(psav, __FILE__, __LINE__)
|
||||
|
||||
@ -111,6 +113,12 @@ extern void key_sa_recordxfer __P((struct secasvar *, struct mbuf *));
|
||||
extern void key_sa_routechange __P((struct sockaddr *));
|
||||
extern void key_sa_stir_iv __P((struct secasvar *));
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
u_int16_t key_portfromsaddr __P((const union sockaddr_union *));
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_SECA);
|
||||
#endif /* MALLOC_DECLARE */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: keydb.h,v 1.4 2007/03/04 19:54:49 degroote Exp $ */
|
||||
/* $NetBSD: keydb.h,v 1.5 2007/06/27 20:38:33 degroote Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/keydb.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
|
||||
/* $KAME: keydb.h,v 1.14 2000/08/02 17:58:26 sakane Exp $ */
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
#include <netipsec/key_var.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
@ -125,6 +127,11 @@ struct secasvar {
|
||||
struct auth_hash *tdb_authalgxform; /* authentication algorithm */
|
||||
struct comp_algo *tdb_compalgxform; /* compression algorithm */
|
||||
u_int64_t tdb_cryptoid; /* crypto session id */
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
u_int16_t natt_type;
|
||||
u_int16_t esp_frag;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* replay prevention */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: xform_ah.c,v 1.17 2007/03/25 22:11:18 degroote Exp $ */
|
||||
/* $NetBSD: xform_ah.c,v 1.18 2007/06/27 20:38:33 degroote Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
|
||||
/* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
|
||||
/*
|
||||
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.17 2007/03/25 22:11:18 degroote Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.18 2007/06/27 20:38:33 degroote Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#ifdef __FreeBSD__
|
||||
@ -794,6 +794,11 @@ ah_input_cb(struct cryptop *crp)
|
||||
u_int8_t nxt;
|
||||
char *ptr;
|
||||
int s, authsize;
|
||||
u_int16_t dport = 0;
|
||||
u_int16_t sport = 0;
|
||||
#ifdef IPSEC_NAT_T
|
||||
struct m_tag * tag = NULL;
|
||||
#endif
|
||||
|
||||
crd = crp->crp_desc;
|
||||
|
||||
@ -805,9 +810,18 @@ ah_input_cb(struct cryptop *crp)
|
||||
mtag = (struct m_tag *) tc->tc_ptr;
|
||||
m = (struct mbuf *) crp->crp_buf;
|
||||
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/* find the source port for NAT-T */
|
||||
if ((tag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL))) {
|
||||
sport = ((u_int16_t *)(tag + 1))[0];
|
||||
dport = ((u_int16_t *)(tag + 1))[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
s = splsoftnet();
|
||||
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, sport, dport);
|
||||
if (sav == NULL) {
|
||||
ahstat.ahs_notdb++;
|
||||
DPRINTF(("ah_input_cb: SA expired while in crypto\n"));
|
||||
@ -1208,7 +1222,7 @@ ah_output_cb(struct cryptop *crp)
|
||||
s = splsoftnet();
|
||||
|
||||
isr = tc->tc_isr;
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, 0, 0);
|
||||
if (sav == NULL) {
|
||||
ahstat.ahs_notdb++;
|
||||
DPRINTF(("ah_output_cb: SA expired while in crypto\n"));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: xform_esp.c,v 1.15 2007/03/04 21:17:55 degroote Exp $ */
|
||||
/* $NetBSD: xform_esp.c,v 1.16 2007/06/27 20:38:33 degroote Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $ */
|
||||
/* $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.15 2007/03/04 21:17:55 degroote Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.16 2007/06/27 20:38:33 degroote Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#ifdef __FreeBSD__
|
||||
@ -469,6 +469,11 @@ esp_input_cb(struct cryptop *crp)
|
||||
struct secasvar *sav;
|
||||
struct secasindex *saidx;
|
||||
void *ptr;
|
||||
u_int16_t dport = 0;
|
||||
u_int16_t sport = 0;
|
||||
#ifdef IPSEC_NAT_T
|
||||
struct m_tag * tag = NULL;
|
||||
#endif
|
||||
|
||||
crd = crp->crp_desc;
|
||||
IPSEC_ASSERT(crd != NULL, ("esp_input_cb: null crypto descriptor!"));
|
||||
@ -480,9 +485,17 @@ esp_input_cb(struct cryptop *crp)
|
||||
mtag = (struct m_tag *) tc->tc_ptr;
|
||||
m = (struct mbuf *) crp->crp_buf;
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/* find the source port for NAT-T */
|
||||
if ((tag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL))) {
|
||||
sport = ((u_int16_t *)(tag + 1))[0];
|
||||
dport = ((u_int16_t *)(tag + 1))[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
s = splsoftnet();
|
||||
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, sport, dport);
|
||||
if (sav == NULL) {
|
||||
espstat.esps_notdb++;
|
||||
DPRINTF(("esp_input_cb: SA expired while in crypto "
|
||||
@ -920,7 +933,7 @@ esp_output_cb(struct cryptop *crp)
|
||||
s = splsoftnet();
|
||||
|
||||
isr = tc->tc_isr;
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, 0, 0);
|
||||
if (sav == NULL) {
|
||||
espstat.esps_notdb++;
|
||||
DPRINTF(("esp_output_cb: SA expired while in crypto "
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: xform_ipcomp.c,v 1.13 2007/03/04 21:17:55 degroote Exp $ */
|
||||
/* $NetBSD: xform_ipcomp.c,v 1.14 2007/06/27 20:38:33 degroote Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/xform_ipcomp.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
|
||||
/* $OpenBSD: ip_ipcomp.c,v 1.1 2001/07/05 12:08:52 jjbg Exp $ */
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.13 2007/03/04 21:17:55 degroote Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.14 2007/06/27 20:38:33 degroote Exp $");
|
||||
|
||||
/* IP payload compression protocol (IPComp), see RFC 2393 */
|
||||
#include "opt_inet.h"
|
||||
@ -226,6 +226,11 @@ ipcomp_input_cb(struct cryptop *crp)
|
||||
int s, hlen = IPCOMP_HLENGTH, error, clen;
|
||||
u_int8_t nproto;
|
||||
void *addr;
|
||||
u_int16_t dport = 0;
|
||||
u_int16_t sport = 0;
|
||||
#ifdef IPSEC_NAT_T
|
||||
struct m_tag * tag = NULL;
|
||||
#endif
|
||||
|
||||
crd = crp->crp_desc;
|
||||
|
||||
@ -236,9 +241,17 @@ ipcomp_input_cb(struct cryptop *crp)
|
||||
mtag = (struct mtag *) tc->tc_ptr;
|
||||
m = (struct mbuf *) crp->crp_buf;
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/* find the source port for NAT-T */
|
||||
if ((tag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL))) {
|
||||
sport = ((u_int16_t *)(tag + 1))[0];
|
||||
dport = ((u_int16_t *)(tag + 1))[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
s = splsoftnet();
|
||||
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, sport, dport);
|
||||
if (sav == NULL) {
|
||||
ipcompstat.ipcomps_notdb++;
|
||||
DPRINTF(("ipcomp_input_cb: SA expired while in crypto\n"));
|
||||
@ -491,7 +504,7 @@ ipcomp_output_cb(struct cryptop *crp)
|
||||
s = splsoftnet();
|
||||
|
||||
isr = tc->tc_isr;
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, 0, 0);
|
||||
if (sav == NULL) {
|
||||
ipcompstat.ipcomps_notdb++;
|
||||
DPRINTF(("ipcomp_output_cb: SA expired while in crypto\n"));
|
||||
|
Loading…
Reference in New Issue
Block a user