Add support for IPsec Network Address Translator traversal (NAT-T), as
described by RFC 3947 and 3948.
This commit is contained in:
parent
a8f0ad3c37
commit
5c217c1a67
|
@ -1,4 +1,4 @@
|
|||
LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.423 $>
|
||||
LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.424 $>
|
||||
|
||||
|
||||
[Note: This file does not mention every change made to the NetBSD source tree.
|
||||
|
@ -214,3 +214,4 @@ Changes from NetBSD 2.0 to NetBSD 3.0:
|
|||
groupadd(8): Add the -r option, used to specify a gid range in which
|
||||
groups can be created. [jmmv 20050205]
|
||||
ipf(8): updated to version 4.1.5. [martti 20050208]
|
||||
ipsec(4): Add support for IPsec NAT-T [manu 20050212]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: ipsec.4,v 1.25 2003/10/21 08:44:04 itojun Exp $
|
||||
.\" $NetBSD: ipsec.4,v 1.26 2005/02/12 12:31:07 manu Exp $
|
||||
.\" $KAME: ipsec.4,v 1.17 2001/06/27 15:25:10 itojun Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -41,6 +41,7 @@
|
|||
.Pp
|
||||
.Cd options IPSEC
|
||||
.Cd options IPSEC_ESP
|
||||
.Cd options IPSEC_NAT_T
|
||||
.Cd options IPSEC_DEBUG
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
|
@ -112,6 +113,15 @@ will enable source code that is subject to export control in some countries
|
|||
and compiled kernel binary will be subject to certain restriction.
|
||||
This option assumes
|
||||
.Em IPSEC .
|
||||
.It Cd options IPSEC_NAT_T
|
||||
Includes support for
|
||||
.Tn IPsec
|
||||
Network Address Translator traversal (NAT-T), as described in RFC 3947
|
||||
and 3948. This feature might be patent-encumbered in some countries.
|
||||
This option assumes
|
||||
.Em IPSEC
|
||||
and
|
||||
.Em IPSEC_ESP .
|
||||
.El
|
||||
.\"
|
||||
.Ss Kernel interface
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: options.4,v 1.265 2005/01/25 01:59:07 wiz Exp $
|
||||
.\" $NetBSD: options.4,v 1.266 2005/02/12 12:31:07 manu Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1996
|
||||
.\" Perry E. Metzger. All rights reserved.
|
||||
|
@ -1517,6 +1517,12 @@ protocol.
|
|||
See
|
||||
.Xr ipsec 4
|
||||
for details.
|
||||
.It Cd options IPSEC_NAT_T
|
||||
Includes support for
|
||||
.Tn IPsec
|
||||
Network Address Translator traversal (NAT-T), as described in RFC 3947
|
||||
and 3948. This feature might be
|
||||
patent-encumbered in some countries.
|
||||
.It Cd options ALTQ
|
||||
Enabled ALTQ (Alternate Queueing).
|
||||
For simple rate-limiting, use
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pfkeyv2.h,v 1.18 2005/01/14 04:11:55 itojun Exp $ */
|
||||
/* $NetBSD: pfkeyv2.h,v 1.19 2005/02/12 12:31:07 manu Exp $ */
|
||||
/* $KAME: pfkeyv2.h,v 1.36 2003/07/25 09:33:37 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -75,7 +75,8 @@ you leave this credit intact on any copies of this file.
|
|||
#define SADB_X_SPDSETIDX 20
|
||||
#define SADB_X_SPDEXPIRE 21 /* not yet */
|
||||
#define SADB_X_SPDDELETE2 22 /* by policy id */
|
||||
#define SADB_MAX 22
|
||||
#define SADB_X_NAT_T_NEW_MAPPING 23
|
||||
#define SADB_MAX 23
|
||||
|
||||
struct sadb_msg {
|
||||
u_int8_t sadb_msg_version;
|
||||
|
@ -255,6 +256,34 @@ struct sadb_x_ipsecrequest {
|
|||
*/
|
||||
};
|
||||
|
||||
/* NAT traversal type, see draft-ietf-ipsec-udp-encaps-06 */
|
||||
/* sizeof(struct sadb_x_nat_t_type) == 8 */
|
||||
struct sadb_x_nat_t_type {
|
||||
u_int16_t sadb_x_nat_t_type_len;
|
||||
u_int16_t sadb_x_nat_t_type_exttype;
|
||||
u_int8_t sadb_x_nat_t_type_type;
|
||||
u_int8_t sadb_x_nat_t_type_reserved[3];
|
||||
};
|
||||
|
||||
/* NAT traversal source or destination port */
|
||||
/* sizeof(struct sadb_x_nat_t_port) == 8 */
|
||||
struct sadb_x_nat_t_port {
|
||||
u_int16_t sadb_x_nat_t_port_len;
|
||||
u_int16_t sadb_x_nat_t_port_exttype;
|
||||
u_int16_t sadb_x_nat_t_port_port;
|
||||
u_int16_t sadb_x_nat_t_port_reserved;
|
||||
};
|
||||
|
||||
/* ESP fragmentation size */
|
||||
/* sizeof(struct sadb_x_nat_t_frag) == 8 */
|
||||
struct sadb_x_nat_t_frag {
|
||||
u_int16_t sadb_x_nat_t_frag_len;
|
||||
u_int16_t sadb_x_nat_t_frag_exttype;
|
||||
u_int16_t sadb_x_nat_t_frag_fraglen;
|
||||
u_int16_t sadb_x_nat_t_frag_reserved;
|
||||
};
|
||||
|
||||
|
||||
#define SADB_EXT_RESERVED 0
|
||||
#define SADB_EXT_SA 1
|
||||
#define SADB_EXT_LIFETIME_CURRENT 2
|
||||
|
@ -275,7 +304,12 @@ struct sadb_x_ipsecrequest {
|
|||
#define SADB_X_EXT_KMPRIVATE 17
|
||||
#define SADB_X_EXT_POLICY 18
|
||||
#define SADB_X_EXT_SA2 19
|
||||
#define SADB_EXT_MAX 19
|
||||
#define SADB_X_EXT_NAT_T_TYPE 20
|
||||
#define SADB_X_EXT_NAT_T_SPORT 21
|
||||
#define SADB_X_EXT_NAT_T_DPORT 22
|
||||
#define SADB_X_EXT_NAT_T_OA 23
|
||||
#define SADB_X_EXT_NAT_T_FRAG 24
|
||||
#define SADB_EXT_MAX 24
|
||||
|
||||
#define SADB_SATYPE_UNSPEC 0
|
||||
#define SADB_SATYPE_AH 2
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in_pcb.h,v 1.38 2004/04/21 17:49:46 itojun Exp $ */
|
||||
/* $NetBSD: in_pcb.h,v 1.39 2005/02/12 12:31:07 manu Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -105,8 +105,12 @@ struct inpcb {
|
|||
#define INP_LOWPORT 0x20 /* user wants "low" port binding */
|
||||
#define INP_ANONPORT 0x40 /* port chosen for user */
|
||||
#define INP_RECVIF 0x80 /* receive incoming interface */
|
||||
/* XXX should move to an UDP control block */
|
||||
#define INP_ESPINUDP 0x100 /* ESP over UDP for NAT-T */
|
||||
#define INP_ESPINUDP_NON_IKE 0x200 /* ESP over UDP for NAT-T */
|
||||
#define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
|
||||
INP_RECVIF)
|
||||
#define INP_ESPINUDP_ALL (INP_ESPINUDP|INP_ESPINUDP_NON_IKE)
|
||||
|
||||
#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in_proto.c,v 1.67 2005/01/31 23:49:36 kim Exp $ */
|
||||
/* $NetBSD: in_proto.c,v 1.68 2005/02/12 12:31:07 manu Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -61,7 +61,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.67 2005/01/31 23:49:36 kim Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.68 2005/02/12 12:31:07 manu Exp $");
|
||||
|
||||
#include "opt_mrouting.h"
|
||||
#include "opt_eon.h" /* ISO CLNL over IP */
|
||||
|
@ -157,7 +157,7 @@ const struct protosw inetsw[] = {
|
|||
ip_init, 0, ip_slowtimo, ip_drain, NULL
|
||||
},
|
||||
{ SOCK_DGRAM, &inetdomain, IPPROTO_UDP, PR_ATOMIC|PR_ADDR,
|
||||
udp_input, 0, udp_ctlinput, ip_ctloutput,
|
||||
udp_input, 0, udp_ctlinput, udp_ctloutput,
|
||||
udp_usrreq,
|
||||
udp_init, 0, 0, 0, NULL
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip_output.c,v 1.140 2005/02/03 23:13:20 perry Exp $ */
|
||||
/* $NetBSD: ip_output.c,v 1.141 2005/02/12 12:31:07 manu Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -98,7 +98,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.140 2005/02/03 23:13:20 perry Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.141 2005/02/12 12:31:07 manu Exp $");
|
||||
|
||||
#include "opt_pfil_hooks.h"
|
||||
#include "opt_inet.h"
|
||||
|
@ -139,6 +139,9 @@ __KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.140 2005/02/03 23:13:20 perry Exp $"
|
|||
#include <netinet6/ipsec.h>
|
||||
#include <netkey/key.h>
|
||||
#include <netkey/key_debug.h>
|
||||
#ifdef IPSEC_NAT_T
|
||||
#include <netinet/udp.h>
|
||||
#endif
|
||||
#endif /*IPSEC*/
|
||||
|
||||
#ifdef FAST_IPSEC
|
||||
|
@ -182,6 +185,9 @@ ip_output(struct mbuf *m0, ...)
|
|||
va_list ap;
|
||||
#ifdef IPSEC
|
||||
struct secpolicy *sp = NULL;
|
||||
#ifdef IPSEC_NAT_T
|
||||
int natt_frag = 0;
|
||||
#endif
|
||||
#endif /*IPSEC*/
|
||||
#ifdef FAST_IPSEC
|
||||
struct inpcb *inp;
|
||||
|
@ -504,6 +510,22 @@ sendit:
|
|||
printf("ip_output: Invalid policy found. %d\n", sp->policy);
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/*
|
||||
* NAT-T ESP fragmentation: don't do IPSec processing now,
|
||||
* we'll do it on each fragmented packet.
|
||||
*/
|
||||
if (sp->req->sav &&
|
||||
((sp->req->sav->natt_type & UDP_ENCAP_ESPINUDP) ||
|
||||
(sp->req->sav->natt_type & UDP_ENCAP_ESPINUDP_NON_IKE))) {
|
||||
if (ntohs(ip->ip_len) > sp->req->sav->esp_frag) {
|
||||
natt_frag = 1;
|
||||
mtu = sp->req->sav->esp_frag;
|
||||
goto skip_ipsec;
|
||||
}
|
||||
}
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
/*
|
||||
* ipsec4_output() expects ip_len and ip_off in network
|
||||
* order. They have been set to network order above.
|
||||
|
@ -828,11 +850,26 @@ spd_done:
|
|||
#ifdef IPSEC
|
||||
/* clean ipsec history once it goes out of the node */
|
||||
ipsec_delaux(m);
|
||||
#endif
|
||||
KASSERT((m->m_pkthdr.csum_flags &
|
||||
(M_CSUM_UDPv4 | M_CSUM_TCPv4)) == 0);
|
||||
error = (*ifp->if_output)(ifp, m, sintosa(dst),
|
||||
ro->ro_rt);
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/*
|
||||
* If we get there, the packet has not been handeld by
|
||||
* IPSec whereas it should have. Now that it has been
|
||||
* fragmented, re-inject it in ip_output so that IPsec
|
||||
* processing can occur.
|
||||
*/
|
||||
if (natt_frag) {
|
||||
error = ip_output(m, opt,
|
||||
ro, flags, imo, so, mtu_p);
|
||||
} else
|
||||
#endif /* IPSEC_NAT_T */
|
||||
#endif /* IPSEC */
|
||||
{
|
||||
KASSERT((m->m_pkthdr.csum_flags &
|
||||
(M_CSUM_UDPv4 | M_CSUM_TCPv4)) == 0);
|
||||
error = (*ifp->if_output)(ifp, m, sintosa(dst),
|
||||
ro->ro_rt);
|
||||
}
|
||||
} else
|
||||
m_freem(m);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: udp.h,v 1.10 2003/08/07 16:33:20 agc Exp $ */
|
||||
/* $NetBSD: udp.h,v 1.11 2005/02/12 12:31:07 manu Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
|
@ -45,4 +45,17 @@ struct udphdr {
|
|||
u_int16_t uh_sum; /* udp checksum */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/* socket options for UDP */
|
||||
#define UDP_ENCAP 100
|
||||
|
||||
/* Encapsulation types */
|
||||
#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
|
||||
#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
|
||||
|
||||
/* Default encapsulation port */
|
||||
#define UDP_ENCAP_ESPINUDP_PORT 500
|
||||
|
||||
/* Maximum UDP fragment size for ESP over UDP */
|
||||
#define UDP_ENCAP_ESPINUDP_MAXFRAGLEN 552
|
||||
|
||||
#endif /* _NETINET_UDP_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: udp_usrreq.c,v 1.129 2004/12/21 05:51:32 yamt Exp $ */
|
||||
/* $NetBSD: udp_usrreq.c,v 1.130 2005/02/12 12:31:07 manu 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.129 2004/12/21 05:51:32 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.130 2005/02/12 12:31:07 manu Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -95,6 +95,11 @@ __KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.129 2004/12/21 05:51:32 yamt Exp $"
|
|||
#include <netinet/udp.h>
|
||||
#include <netinet/udp_var.h>
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
#include <netinet6/ipsec.h>
|
||||
#include <netinet6/esp.h>
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/icmp6.h>
|
||||
|
@ -147,6 +152,10 @@ struct inpcbtable udbtable;
|
|||
struct udpstat udpstat;
|
||||
|
||||
#ifdef INET
|
||||
#ifdef IPSEC_NAT_T
|
||||
static int udp4_espinudp (struct mbuf *, int, struct sockaddr *,
|
||||
struct socket *);
|
||||
#endif
|
||||
static void udp4_sendup (struct mbuf *, int, struct sockaddr *,
|
||||
struct socket *);
|
||||
static int udp4_realinput (struct sockaddr_in *, struct sockaddr_in *,
|
||||
|
@ -740,6 +749,20 @@ udp4_realinput(struct sockaddr_in *src, struct sockaddr_in *dst,
|
|||
return rcvcnt;
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/* Handle ESP over UDP */
|
||||
if (inp->inp_flags & INP_ESPINUDP_ALL) {
|
||||
struct sockaddr *sa = (struct sockaddr *)src;
|
||||
|
||||
if (udp4_espinudp(m, off, sa, inp->inp_socket) != 0) {
|
||||
rcvcnt++;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Normal UDP processing will take place */
|
||||
}
|
||||
#endif
|
||||
|
||||
udp4_sendup(m, off, (struct sockaddr *)src, inp->inp_socket);
|
||||
rcvcnt++;
|
||||
}
|
||||
|
@ -908,6 +931,100 @@ udp_ctlinput(int cmd, struct sockaddr *sa, void *v)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
udp_ctloutput(op, so, level, optname, mp)
|
||||
int op;
|
||||
struct socket *so;
|
||||
int level, optname;
|
||||
struct mbuf **mp;
|
||||
{
|
||||
int s;
|
||||
int error = 0;
|
||||
struct mbuf *m;
|
||||
struct inpcb *inp;
|
||||
int family;
|
||||
|
||||
family = so->so_proto->pr_domain->dom_family;
|
||||
|
||||
s = splsoftnet();
|
||||
switch (family) {
|
||||
#ifdef INET
|
||||
case PF_INET:
|
||||
if (level != IPPROTO_UDP) {
|
||||
error = ip_ctloutput(op, so, level, optname, mp);
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case PF_INET6:
|
||||
if (level != IPPROTO_UDP) {
|
||||
error = ip6_ctloutput(op, so, level, optname, mp);
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error = EAFNOSUPPORT;
|
||||
goto end;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch (op) {
|
||||
case PRCO_SETOPT:
|
||||
m = *mp;
|
||||
inp = sotoinpcb(so);
|
||||
|
||||
switch (optname) {
|
||||
case UDP_ENCAP:
|
||||
if (m == NULL || m->m_len < sizeof (int)) {
|
||||
error = EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch(*mtod(m, int *)) {
|
||||
#ifdef IPSEC_NAT_T
|
||||
case 0:
|
||||
inp->inp_flags &= ~INP_ESPINUDP_ALL;
|
||||
break;
|
||||
|
||||
case UDP_ENCAP_ESPINUDP:
|
||||
inp->inp_flags &= ~INP_ESPINUDP_ALL;
|
||||
inp->inp_flags |= INP_ESPINUDP;
|
||||
break;
|
||||
|
||||
case UDP_ENCAP_ESPINUDP_NON_IKE:
|
||||
inp->inp_flags &= ~INP_ESPINUDP_ALL;
|
||||
inp->inp_flags |= INP_ESPINUDP_NON_IKE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error = EINVAL;
|
||||
goto end;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ENOPROTOOPT;
|
||||
goto end;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
goto end;
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
udp_output(struct mbuf *m, ...)
|
||||
{
|
||||
|
@ -1219,3 +1336,113 @@ SYSCTL_SETUP(sysctl_net_inet_udp_setup, "sysctl net.inet.udp subtree setup")
|
|||
CTL_EOL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined INET && defined IPSEC_NAT_T)
|
||||
/*
|
||||
* Returns:
|
||||
* 1 if the packet was processed
|
||||
* 0 if normal UDP processing should take place
|
||||
*/
|
||||
static int
|
||||
udp4_espinudp(m, off, src, so)
|
||||
struct mbuf *m;
|
||||
int off;
|
||||
struct sockaddr *src;
|
||||
struct socket *so;
|
||||
{
|
||||
size_t len;
|
||||
caddr_t data;
|
||||
struct inpcb *inp;
|
||||
size_t skip = 0;
|
||||
size_t minlen;
|
||||
size_t iphdrlen;
|
||||
struct ip *ip;
|
||||
struct mbuf *n;
|
||||
|
||||
/*
|
||||
* Collapse the mbuf chain if the first mbuf is too short
|
||||
* The longest case is: UDP + non ESP marker + ESP
|
||||
*/
|
||||
minlen = off + sizeof(u_int64_t) + sizeof(struct esp);
|
||||
if (minlen > m->m_pkthdr.len)
|
||||
minlen = m->m_pkthdr.len;
|
||||
|
||||
if (m->m_len < minlen) {
|
||||
if ((m = m_pullup(m, minlen)) == NULL) {
|
||||
printf("udp4_espinudp: m_pullup failed\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
len = m->m_len - off;
|
||||
data = mtod(m, caddr_t) + off;
|
||||
inp = sotoinpcb(so);
|
||||
|
||||
/* Ignore keepalive packets */
|
||||
if ((len == 1) && (data[0] == '\xff')) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the payload is long enough to hold
|
||||
* an ESP header and compute the length of encapsulation
|
||||
* header to remove
|
||||
*/
|
||||
if (inp->inp_flags & INP_ESPINUDP) {
|
||||
u_int32_t *st = (u_int32_t *)data;
|
||||
|
||||
if ((len <= sizeof(struct esp)) || (*st == 0))
|
||||
return 0; /* Normal UDP processing */
|
||||
|
||||
skip = sizeof(struct udphdr);
|
||||
}
|
||||
|
||||
if (inp->inp_flags & INP_ESPINUDP_NON_IKE) {
|
||||
u_int64_t *st = (u_int64_t *)data;
|
||||
|
||||
if ((len <= sizeof(u_int64_t) + sizeof(struct esp))
|
||||
|| (*st != 0))
|
||||
return 0; /* Normal UDP processing */
|
||||
|
||||
skip = sizeof(struct udphdr) + sizeof(u_int64_t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the UDP header (and possibly the non ESP marker)
|
||||
* IP header lendth is iphdrlen
|
||||
* Before:
|
||||
* <--- off --->
|
||||
* +----+------+-----+
|
||||
* | IP | UDP | ESP |
|
||||
* +----+------+-----+
|
||||
* <-skip->
|
||||
* After:
|
||||
* +----+-----+
|
||||
* | IP | ESP |
|
||||
* +----+-----+
|
||||
* <-skip->
|
||||
*/
|
||||
iphdrlen = off - sizeof(struct udphdr);
|
||||
memmove(mtod(m, caddr_t) + skip, mtod(m, caddr_t), iphdrlen);
|
||||
m_adj(m, skip);
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
ip->ip_len = htons(ntohs(ip->ip_len) - skip);
|
||||
ip->ip_p = IPPROTO_ESP;
|
||||
|
||||
/*
|
||||
* Copy the mbuf to avoid multiple free, as both
|
||||
* esp4_input (which we call) and udp_input (which
|
||||
* called us) free the mbuf.
|
||||
*/
|
||||
if ((n = m_dup(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
|
||||
printf("udp4_espinudp: m_dup failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
esp4_input(n, iphdrlen);
|
||||
|
||||
/* We handled it, it shoudln't be handled by UDP */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: udp_var.h,v 1.26 2004/12/21 05:51:33 yamt Exp $ */
|
||||
/* $NetBSD: udp_var.h,v 1.27 2005/02/12 12:31:08 manu Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
|
@ -94,6 +94,7 @@ extern int udp_do_loopback_cksum;
|
|||
#endif
|
||||
|
||||
void *udp_ctlinput(int, struct sockaddr *, void *);
|
||||
int udp_ctloutput(int, struct socket *, int, int, struct mbuf **);
|
||||
void udp_init(void);
|
||||
void udp_input(struct mbuf *, ...);
|
||||
int udp_output(struct mbuf *, ...);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: esp_output.c,v 1.18 2003/09/07 15:59:36 itojun Exp $ */
|
||||
/* $NetBSD: esp_output.c,v 1.19 2005/02/12 12:31:08 manu Exp $ */
|
||||
/* $KAME: esp_output.c,v 1.44 2001/07/26 06:53:15 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: esp_output.c,v 1.18 2003/09/07 15:59:36 itojun Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: esp_output.c,v 1.19 2005/02/12 12:31:08 manu Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
|
@ -59,6 +59,9 @@ __KERNEL_RCSID(0, "$NetBSD: esp_output.c,v 1.18 2003/09/07 15:59:36 itojun Exp $
|
|||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/in_var.h>
|
||||
#ifdef IPSEC_NAT_T
|
||||
#include <netinet/udp.h>
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
#include <netinet/ip6.h>
|
||||
|
@ -136,6 +139,17 @@ esp_hdrsiz(isr)
|
|||
esp_max_padbound() - 1 + 2 + authlen;
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/*
|
||||
* If NAT-T is enabled, add the space for UDP encapsulation
|
||||
*/
|
||||
if (sav->natt_type != 0) {
|
||||
hdrsiz += sizeof(struct udphdr);
|
||||
if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE)
|
||||
hdrsiz += sizeof(u_int64_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
return hdrsiz;
|
||||
|
||||
estimate:
|
||||
|
@ -147,9 +161,15 @@ esp_hdrsiz(isr)
|
|||
* maximum padding length without random padding length
|
||||
* 2 = (Pad Length field) + (Next Header field).
|
||||
* AH_MAXSUMSIZE = maximum ICV we support.
|
||||
* sizeof(u_int64_t) = non IKE marker (NAT-T)
|
||||
* sizeof(struct udphdr) = UDP encapsulation (NAT-T)
|
||||
*/
|
||||
return sizeof(struct newesp) + esp_max_ivlen() +
|
||||
esp_max_padbound() - 1 + 2 + AH_MAXSUMSIZE;
|
||||
esp_max_padbound() - 1 + 2 + AH_MAXSUMSIZE +
|
||||
#ifdef IPSEC_NAT_T
|
||||
sizeof(u_int64_t) + sizeof(struct udphdr) +
|
||||
#endif
|
||||
0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -195,6 +215,9 @@ esp_output(m, nexthdrp, md, isr, af)
|
|||
size_t extendsiz;
|
||||
int error = 0;
|
||||
struct ipsecstat *stat;
|
||||
#ifdef IPSEC_NAT_T
|
||||
struct udphdr *udp = NULL;
|
||||
#endif
|
||||
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
|
@ -329,10 +352,25 @@ esp_output(m, nexthdrp, md, isr, af)
|
|||
|
||||
espoff = m->m_pkthdr.len - plen;
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
if (sav->natt_type != 0) {
|
||||
esphlen += sizeof(struct udphdr);
|
||||
espoff += sizeof(struct udphdr);
|
||||
|
||||
if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) {
|
||||
/* NON-IKE marker */
|
||||
esphlen += sizeof(u_int64_t);
|
||||
espoff += sizeof(u_int64_t);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* grow the mbuf to accomodate ESP header.
|
||||
* before: IP ... payload
|
||||
* after: IP ... ESP IV payload
|
||||
* after (without NAT-T): IP ... ESP IV payload
|
||||
* after (with older NAT-T): IP ... UDP non-IKE-marker ESP IV payload
|
||||
* after (with newer NAT-T): IP ... UDP ESP IV payload
|
||||
*/
|
||||
if (M_LEADINGSPACE(md) < esphlen || (md->m_flags & M_EXT) != 0) {
|
||||
MGET(n, M_DONTWAIT, MT_DATA);
|
||||
|
@ -345,6 +383,7 @@ esp_output(m, nexthdrp, md, isr, af)
|
|||
mprev->m_next = n;
|
||||
n->m_next = md;
|
||||
m->m_pkthdr.len += esphlen;
|
||||
|
||||
esp = mtod(n, struct esp *);
|
||||
} else {
|
||||
md->m_len += esphlen;
|
||||
|
@ -353,6 +392,20 @@ esp_output(m, nexthdrp, md, isr, af)
|
|||
esp = mtod(md, struct esp *);
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
if (sav->natt_type != 0) {
|
||||
udp = (struct udphdr *)esp;
|
||||
esp = (struct esp *)(udp + 1);
|
||||
|
||||
if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) {
|
||||
u_int64_t *data = (u_int64_t *)esp;
|
||||
|
||||
*data = 0; /* NON-IKE marker */
|
||||
esp = (struct esp *)(data + 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nxt = *nexthdrp;
|
||||
*nexthdrp = IPPROTO_ESP;
|
||||
switch (af) {
|
||||
|
@ -469,6 +522,26 @@ esp_output(m, nexthdrp, md, isr, af)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
if (sav->natt_type != 0) {
|
||||
*nexthdrp = IPPROTO_UDP;
|
||||
|
||||
/*
|
||||
* Create the UDP encapsulation header for NAT-T
|
||||
* uh_len is set later, when the size is known.
|
||||
*/
|
||||
if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE)
|
||||
udp->uh_sport = htons(UDP_ENCAP_ESPINUDP_PORT);
|
||||
else
|
||||
udp->uh_sport = htons(sav->local_ike_port);
|
||||
|
||||
udp->uh_dport = htons(sav->remote_ike_port);
|
||||
udp->uh_sum = 0;
|
||||
} else {
|
||||
*nexthdrp = IPPROTO_ESP;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* initialize esp trailer. */
|
||||
esptail = (struct esptail *)
|
||||
(mtod(n, u_int8_t *) + n->m_len - sizeof(struct esptail));
|
||||
|
@ -612,6 +685,20 @@ esp_output(m, nexthdrp, md, isr, af)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
if (sav->natt_type != 0) {
|
||||
struct ip *ip;
|
||||
ip = mtod(m, struct ip *);
|
||||
#ifdef _IP_VHL
|
||||
udp->uh_ulen =
|
||||
htons(ntohs(ip->ip_len) - (IP_VHL_HL(ip->ip_vhl) << 2));
|
||||
#else
|
||||
udp->uh_ulen = htons(ntohs(ip->ip_len) - (ip->ip_hl << 2));
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
noantireplay:
|
||||
if (!m) {
|
||||
ipseclog((LOG_ERR,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: key.c,v 1.20 2004/06/10 01:28:25 jonathan Exp $ */
|
||||
/* $NetBSD: key.c,v 1.21 2005/02/12 12:31:08 manu 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 $ */
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.20 2004/06/10 01:28:25 jonathan Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.21 2005/02/12 12:31:08 manu Exp $");
|
||||
|
||||
/*
|
||||
* This code is referd to RFC 2367
|
||||
|
@ -183,6 +183,11 @@ static const int minsize[] = {
|
|||
0, /* SADB_X_EXT_KMPRIVATE */
|
||||
sizeof(struct sadb_x_policy), /* SADB_X_EXT_POLICY */
|
||||
sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */
|
||||
sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */
|
||||
sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */
|
||||
sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */
|
||||
sizeof(struct sadb_x_nat_t_oa), /* SADB_X_EXT_NAT_T_OA */
|
||||
sizeof(struct sadb_x_nat_t_frag), /* SADB_X_EXT_NAT_T_FRAG */
|
||||
};
|
||||
static const int maxsize[] = {
|
||||
sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */
|
||||
|
@ -205,6 +210,11 @@ static const int maxsize[] = {
|
|||
0, /* SADB_X_EXT_KMPRIVATE */
|
||||
0, /* SADB_X_EXT_POLICY */
|
||||
sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */
|
||||
sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */
|
||||
sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */
|
||||
sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */
|
||||
sizeof(struct sadb_x_nat_t_oa), /* SADB_X_EXT_NAT_T_OA */
|
||||
sizeof(struct sadb_x_nat_t_frag), /* SADB_X_EXT_NAT_T_FRAG */
|
||||
};
|
||||
|
||||
static int ipsec_esp_keymin = 256;
|
||||
|
@ -6892,6 +6902,7 @@ 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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
213
sys/netkey/key.c
213
sys/netkey/key.c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: key.c,v 1.127 2005/01/11 01:30:17 itojun Exp $ */
|
||||
/* $NetBSD: key.c,v 1.128 2005/02/12 12:31:08 manu Exp $ */
|
||||
/* $KAME: key.c,v 1.310 2003/09/08 02:23:44 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.127 2005/01/11 01:30:17 itojun Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.128 2005/02/12 12:31:08 manu Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -191,6 +191,11 @@ static const int minsize[] = {
|
|||
0, /* SADB_X_EXT_KMPRIVATE */
|
||||
sizeof(struct sadb_x_policy), /* SADB_X_EXT_POLICY */
|
||||
sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */
|
||||
sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */
|
||||
sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */
|
||||
sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */
|
||||
sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OA */
|
||||
sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */
|
||||
#ifdef SADB_X_EXT_TAG
|
||||
sizeof(struct sadb_x_tag), /* SADB_X_TAG */
|
||||
#endif
|
||||
|
@ -216,6 +221,11 @@ static const int maxsize[] = {
|
|||
0, /* SADB_X_EXT_KMPRIVATE */
|
||||
0, /* SADB_X_EXT_POLICY */
|
||||
sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */
|
||||
sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */
|
||||
sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */
|
||||
sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */
|
||||
0, /* SADB_X_EXT_NAT_T_OA */
|
||||
sizeof(struct sadb_x_nat_t_frag), /* SADB_X_EXT_NAT_T_FRAG */
|
||||
#ifdef SADB_X_EXT_TAG
|
||||
sizeof(struct sadb_x_tag), /* SADB_X_TAG */
|
||||
#endif
|
||||
|
@ -340,6 +350,10 @@ static int key_spdflush __P((struct socket *, struct mbuf *,
|
|||
const struct sadb_msghdr *));
|
||||
static int key_spddump __P((struct socket *, struct mbuf *,
|
||||
const struct sadb_msghdr *));
|
||||
#ifdef IPSEC_NAT_T
|
||||
static int key_nat_map __P((struct socket *, struct mbuf *,
|
||||
const struct sadb_msghdr *));
|
||||
#endif
|
||||
static struct mbuf *key_setspddump __P((int *));
|
||||
static u_int key_getspreqmsglen __P((struct secpolicy *));
|
||||
static int key_spdexpire __P((struct secpolicy *));
|
||||
|
@ -2347,6 +2361,71 @@ key_spddump(so, m, mhp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/*
|
||||
* SADB_X_NAT_T_NEW_MAPPING
|
||||
*/
|
||||
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: type %d, sport = %d, dport = %d\n",
|
||||
type->sadb_x_nat_t_type_type,
|
||||
sport->sadb_x_nat_t_port_port,
|
||||
dport->sadb_x_nat_t_port_port);
|
||||
|
||||
/*
|
||||
* 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_setspddump(errorp)
|
||||
int *errorp;
|
||||
|
@ -2961,6 +3040,10 @@ key_setsaval(sav, m, mhp)
|
|||
sav->lft_c = NULL;
|
||||
sav->lft_h = NULL;
|
||||
sav->lft_s = NULL;
|
||||
#ifdef IPSEC_NAT_T
|
||||
sav->natt_type = 0;
|
||||
sav->remote_ike_port = 0;
|
||||
#endif
|
||||
|
||||
/* SA */
|
||||
if (mhp->ext[SADB_EXT_SA] != NULL) {
|
||||
|
@ -5106,6 +5189,63 @@ key_update(so, m, mhp)
|
|||
return key_senderror(so, m, error);
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/*
|
||||
* Handle NAT-T info if present
|
||||
*/
|
||||
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 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_update: 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_update: 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];
|
||||
|
||||
sav->natt_type = type->sadb_x_nat_t_type_type;
|
||||
sav->remote_ike_port = ntohs(dport->sadb_x_nat_t_port_port);
|
||||
sav->local_ike_port = ntohs(sport->sadb_x_nat_t_port_port);
|
||||
if (frag)
|
||||
sav->esp_frag = frag->sadb_x_nat_t_frag_fraglen;
|
||||
else
|
||||
sav->esp_frag = IP_MAXPACKET;
|
||||
}
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
{
|
||||
struct mbuf *n;
|
||||
|
||||
|
@ -5261,6 +5401,63 @@ key_add(so, m, mhp)
|
|||
return key_senderror(so, m, error);
|
||||
}
|
||||
|
||||
#ifdef IPSEC_NAT_T
|
||||
/*
|
||||
* Handle NAT-T info if present
|
||||
*/
|
||||
if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL)
|
||||
printf("add: 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_add: "
|
||||
"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_add: 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_update: 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];
|
||||
|
||||
newsav->natt_type = type->sadb_x_nat_t_type_type;
|
||||
newsav->local_ike_port = ntohs(sport->sadb_x_nat_t_port_port);
|
||||
newsav->remote_ike_port = ntohs(dport->sadb_x_nat_t_port_port);
|
||||
if (frag)
|
||||
newsav->esp_frag = frag->sadb_x_nat_t_frag_fraglen;
|
||||
else
|
||||
newsav->esp_frag = IP_MAXPACKET;
|
||||
}
|
||||
#endif /* IPSEC_NAT_T */
|
||||
|
||||
/*
|
||||
* don't call key_freesav() here, as we would like to keep the SA
|
||||
* in the database on success.
|
||||
|
@ -7068,6 +7265,11 @@ static int (*key_typesw[]) __P((struct socket *, struct mbuf *,
|
|||
key_spdadd, /* SADB_X_SPDSETIDX */
|
||||
NULL, /* SADB_X_SPDEXPIRE */
|
||||
key_spddelete2, /* SADB_X_SPDDELETE2 */
|
||||
#ifdef IPSEC_NAT_T
|
||||
key_nat_map, /* SADB_X_NAT_T_NEW_MAPPING */
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -7404,6 +7606,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
|
||||
#ifdef SADB_X_EXT_TAG
|
||||
case SADB_X_EXT_TAG:
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: keydb.h,v 1.21 2004/12/06 08:05:26 itojun Exp $ */
|
||||
/* $NetBSD: keydb.h,v 1.22 2005/02/12 12:31:08 manu Exp $ */
|
||||
/* $KAME: keydb.h,v 1.23 2003/09/07 05:25:20 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -107,6 +107,11 @@ struct secasvar {
|
|||
struct secashead *sah; /* back pointer to the secashead */
|
||||
|
||||
u_int32_t id; /* SA id */
|
||||
/* Nat-Traversal state */
|
||||
u_int16_t natt_type;
|
||||
u_int16_t remote_ike_port;
|
||||
u_int16_t local_ike_port;
|
||||
u_int16_t esp_frag;
|
||||
};
|
||||
|
||||
/* replay prevention */
|
||||
|
|
Loading…
Reference in New Issue