View | Details | Raw Unified | Return to bug 146190
Collapse All | Expand All

(-)esp_var.h (+2 lines)
Lines 76-80 Link Here
76
#define	V_esp_enable	VNET(esp_enable)
76
#define	V_esp_enable	VNET(esp_enable)
77
VNET_DECLARE(struct espstat, espstat);
77
VNET_DECLARE(struct espstat, espstat);
78
#define	V_espstat	VNET(espstat)
78
#define	V_espstat	VNET(espstat)
79
VNET_DECLARE(int, esp_ignore_natt_cksum);
80
#define V_esp_ignore_natt_cksum	    VNET(esp_ignore_natt_cksum)
79
#endif /* _KERNEL */
81
#endif /* _KERNEL */
80
#endif /*_NETIPSEC_ESP_VAR_H_*/
82
#endif /*_NETIPSEC_ESP_VAR_H_*/
(-)ipsec.c (-1 / +1 lines)
Lines 592-598 Link Here
592
	IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),("packet too short"));
592
	IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),("packet too short"));
593
593
594
	/* NB: ip_input() flips it into host endian. XXX Need more checking. */
594
	/* NB: ip_input() flips it into host endian. XXX Need more checking. */
595
	if (m->m_len < sizeof (struct ip)) {
595
	if (m->m_len >= sizeof (struct ip)) {
596
		struct ip *ip = mtod(m, struct ip *);
596
		struct ip *ip = mtod(m, struct ip *);
597
		if (ip->ip_off & (IP_MF | IP_OFFMASK))
597
		if (ip->ip_off & (IP_MF | IP_OFFMASK))
598
			goto done;
598
			goto done;
(-)ipsec_input.c (+33 lines)
Lines 76-81 Link Here
76
#include <netinet/icmp6.h>
76
#include <netinet/icmp6.h>
77
#endif
77
#endif
78
78
79
#ifdef IPSEC_NAT_T
80
#include <netinet/tcp.h>
81
#include <netinet/udp.h>
82
#endif
83
79
#include <netipsec/ipsec.h>
84
#include <netipsec/ipsec.h>
80
#ifdef INET6
85
#ifdef INET6
81
#include <netipsec/ipsec6.h>
86
#include <netipsec/ipsec6.h>
Lines 347-352 Link Here
347
	}
352
	}
348
	prot = ip->ip_p;
353
	prot = ip->ip_p;
349
354
355
#ifdef IPSEC_NAT_T
356
	if (saidx->mode == IPSEC_MODE_TRANSPORT && sproto == IPPROTO_ESP &&
357
	    sav->natt_cksum != 0) {
358
		if (V_esp_ignore_natt_cksum != 0) {
359
			/* Ignore checksum of packet protected by ESP.  */
360
			if (prot == IPPROTO_TCP || prot == IPPROTO_UDP) {
361
				m->m_pkthdr.csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
362
				m->m_pkthdr.csum_data = 0xffff;
363
364
			}
365
		} else {
366
			if (prot == IPPROTO_TCP || prot == IPPROTO_UDP) {
367
				u_int16_t proto_cksum;
368
				int off = sizeof(struct ip);
369
				if (prot == IPPROTO_TCP) {
370
					off += offsetof(struct tcphdr, th_sum);
371
				} else if (prot == IPPROTO_UDP) {
372
					off += offsetof(struct udphdr, uh_sum);
373
				}
374
				m_copydata(m, off, sizeof(u_int16_t), (caddr_t)&proto_cksum);
375
				proto_cksum = in_addword(sav->natt_cksum, ~ntohs(proto_cksum));
376
				proto_cksum = ~htons(proto_cksum);
377
				m_copyback(m, off, sizeof(u_int16_t), (caddr_t)&proto_cksum);
378
			}
379
		}
380
	}
381
#endif
382
350
#ifdef notyet
383
#ifdef notyet
351
	/* IP-in-IP encapsulation */
384
	/* IP-in-IP encapsulation */
352
	if (prot == IPPROTO_IPIP) {
385
	if (prot == IPPROTO_IPIP) {
(-)key.c (-3 / +112 lines)
Lines 459-464 Link Here
459
#ifdef IPSEC_NAT_T
459
#ifdef IPSEC_NAT_T
460
static struct mbuf *key_setsadbxport(u_int16_t, u_int16_t);
460
static struct mbuf *key_setsadbxport(u_int16_t, u_int16_t);
461
static struct mbuf *key_setsadbxtype(u_int16_t);
461
static struct mbuf *key_setsadbxtype(u_int16_t);
462
static u_int16_t key_compute_natt_cksum(struct sockaddr*, 
463
	struct sockaddr*, struct sockaddr*, struct sockaddr*);
462
#endif
464
#endif
463
static void key_porttosaddr(struct sockaddr *, u_int16_t);
465
static void key_porttosaddr(struct sockaddr *, u_int16_t);
464
#define	KEY_PORTTOSADDR(saddr, port)				\
466
#define	KEY_PORTTOSADDR(saddr, port)				\
Lines 3083-3088 Link Here
3083
	/*  Initialize even if NAT-T not compiled in: */
3085
	/*  Initialize even if NAT-T not compiled in: */
3084
	sav->natt_type = 0;
3086
	sav->natt_type = 0;
3085
	sav->natt_esp_frag_len = 0;
3087
	sav->natt_esp_frag_len = 0;
3088
	sav->natt_cksum = 0;
3086
3089
3087
	/* SA */
3090
	/* SA */
3088
	if (mhp->ext[SADB_EXT_SA] != NULL) {
3091
	if (mhp->ext[SADB_EXT_SA] != NULL) {
Lines 3505-3511 Link Here
3505
			break;
3508
			break;
3506
3509
3507
		case SADB_X_EXT_NAT_T_OAI:
3510
		case SADB_X_EXT_NAT_T_OAI:
3511
			m = key_setsadbaddr(SADB_X_EXT_NAT_T_OAI,
3512
			    &sav->natt_oa_src.sa,
3513
			    FULLMASK, IPSEC_ULPROTO_ANY);
3514
			if (!m)
3515
				goto fail;
3516
			break;
3508
		case SADB_X_EXT_NAT_T_OAR:
3517
		case SADB_X_EXT_NAT_T_OAR:
3518
			m = key_setsadbaddr(SADB_X_EXT_NAT_T_OAR,
3519
			    &sav->natt_oa_dst.sa,
3520
			    FULLMASK, IPSEC_ULPROTO_ANY);
3521
			if (!m)
3522
				goto fail;
3523
			break;
3509
		case SADB_X_EXT_NAT_T_FRAG:
3524
		case SADB_X_EXT_NAT_T_FRAG:
3510
			/* We do not (yet) support those. */
3525
			/* We do not (yet) support those. */
3511
			continue;
3526
			continue;
Lines 3786-3791 Link Here
3786
			__func__, sa->sa_family));
3801
			__func__, sa->sa_family));
3787
	return (0);
3802
	return (0);
3788
}
3803
}
3804
3805
/* 
3806
 * Compute checksum delta to be applied to incoming TCP/UDP packet
3807
 * after packet has been decrypted
3808
 */
3809
static u_int16_t
3810
key_compute_natt_cksum(struct sockaddr *src, struct sockaddr *dst,
3811
	struct sockaddr *natt_src, struct sockaddr *natt_dst)
3812
{
3813
	u_int32_t total_sum = 0;
3814
	u_int32_t sum_old, sum_new;
3815
	if (natt_src && key_sockaddrcmp(src, natt_src, 0)) {
3816
		IPSEC_ASSERT(src->sa.sa_family == AF_INET, ("bad address family"));
3817
		sum_old = *(u_int32_t*)(&((struct sockaddr_in*)src)->sin_addr);
3818
		sum_old = ntohl(sum_old);
3819
		sum_old = (sum_old & 0xFFFF) + (sum_old >> 16);
3820
		sum_old = (sum_old & 0xFFFF) + (sum_old >> 16);
3821
3822
		sum_new = *(u_int32_t*)(&((struct sockaddr_in*)natt_src)->sin_addr);
3823
		sum_new = ntohl(sum_new);
3824
		sum_new = (sum_new & 0xFFFF) + (sum_new >> 16);
3825
		sum_new = (sum_new & 0xFFFF) + (sum_new >> 16);
3826
3827
		if (sum_new < sum_old)
3828
			sum_new--;
3829
3830
		total_sum += sum_new - sum_old;
3831
	}
3832
	if (natt_dst && key_sockaddrcmp(dst, natt_dst, 0)) {
3833
		IPSEC_ASSERT(dst->sa.sa_family == AF_INET, ("bad address family"));
3834
		sum_old = *(u_int32_t*)(&((struct sockaddr_in*)natt_dst)->sin_addr);
3835
		sum_old = ntohl(sum_old);
3836
		sum_old = (sum_old & 0xFFFF) + (sum_old >> 16);
3837
		sum_old = (sum_old & 0xFFFF) + (sum_old >> 16);
3838
3839
		sum_new = *(u_int32_t*)(&((struct sockaddr_in*)dst)->sin_addr);
3840
		sum_new = ntohl(sum_new);
3841
		sum_new = (sum_new & 0xFFFF) + (sum_new >> 16);
3842
		sum_new = (sum_new & 0xFFFF) + (sum_new >> 16);
3843
3844
		if (sum_new < sum_old)
3845
			sum_new--;
3846
3847
		total_sum += sum_new - sum_old;
3848
	}
3849
	total_sum = (total_sum & 0xFFFF) + (total_sum >> 16);
3850
	total_sum = (total_sum & 0xFFFF) + (total_sum >> 16);
3851
	return (u_int16_t)total_sum;
3852
}
3853
3789
#endif /* IPSEC_NAT_T */
3854
#endif /* IPSEC_NAT_T */
3790
3855
3791
/*
3856
/*
Lines 4656-4662 Link Here
4656
	struct mbuf *m;
4721
	struct mbuf *m;
4657
	const struct sadb_msghdr *mhp;
4722
	const struct sadb_msghdr *mhp;
4658
{
4723
{
4659
	struct sadb_address *src0, *dst0;
4724
	struct sadb_address *src0, *dst0, *iaddr, *raddr;
4660
	struct secasindex saidx;
4725
	struct secasindex saidx;
4661
	struct secashead *newsah;
4726
	struct secashead *newsah;
4662
	struct secasvar *newsav;
4727
	struct secasvar *newsav;
Lines 4747-4756 Link Here
4747
	 * We made sure the port numbers are zero above, so we do
4812
	 * We made sure the port numbers are zero above, so we do
4748
	 * not have to worry in case we do not update them.
4813
	 * not have to worry in case we do not update them.
4749
	 */
4814
	 */
4750
	if (mhp->ext[SADB_X_EXT_NAT_T_OAI] != NULL)
4815
	if (mhp->ext[SADB_X_EXT_NAT_T_OAI] != NULL) {
4751
		ipseclog((LOG_DEBUG, "%s: NAT-T OAi present\n", __func__));
4816
		ipseclog((LOG_DEBUG, "%s: NAT-T OAi present\n", __func__));
4752
	if (mhp->ext[SADB_X_EXT_NAT_T_OAR] != NULL)
4817
		if (mhp->extlen[SADB_X_EXT_NAT_T_OAI] < sizeof(struct sadb_address)) {
4818
			ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n",
4819
			    __func__));
4820
			return key_senderror(so, m, EINVAL);
4821
		}
4822
		iaddr = (struct sadb_address *)(mhp->ext[SADB_X_EXT_NAT_T_OAI]);
4823
	}
4824
	if (mhp->ext[SADB_X_EXT_NAT_T_OAR] != NULL) {
4753
		ipseclog((LOG_DEBUG, "%s: NAT-T OAr present\n", __func__));
4825
		ipseclog((LOG_DEBUG, "%s: NAT-T OAr present\n", __func__));
4826
		if (mhp->extlen[SADB_X_EXT_NAT_T_OAR] < sizeof(struct sadb_address)) {
4827
			ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n",
4828
			    __func__));
4829
			return key_senderror(so, m, EINVAL);
4830
		}
4831
		raddr = (struct sadb_address *)(mhp->ext[SADB_X_EXT_NAT_T_OAR]);
4832
	}
4754
4833
4755
	if (mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL &&
4834
	if (mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL &&
4756
	    mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL &&
4835
	    mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL &&
Lines 5081-5086 Link Here
5081
		iaddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAI];
5160
		iaddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAI];
5082
		raddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAR];
5161
		raddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAR];
5083
		ipseclog((LOG_DEBUG, "%s: NAT-T OAi/r present\n", __func__));
5162
		ipseclog((LOG_DEBUG, "%s: NAT-T OAi/r present\n", __func__));
5163
	} else if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) {
5164
	    iaddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OA];
5165
	    raddr = NULL;
5166
	    ipseclog((LOG_DEBUG, "%s: NAT-T OA present\n", __func__));
5167
5084
	} else {
5168
	} else {
5085
		iaddr = raddr = NULL;
5169
		iaddr = raddr = NULL;
5086
	}
5170
	}
Lines 5177-5182 Link Here
5177
	if (dport)
5261
	if (dport)
5178
		KEY_PORTTOSADDR(&sav->sah->saidx.dst,
5262
		KEY_PORTTOSADDR(&sav->sah->saidx.dst,
5179
		    dport->sadb_x_nat_t_port_port);
5263
		    dport->sadb_x_nat_t_port_port);
5264
	if (iaddr)
5265
		bcopy(iaddr + 1, &sav->natt_oa_src, ((const struct sockaddr *)(iaddr + 1))->sa_len);
5266
	if (raddr)
5267
		bcopy(raddr + 1, &sav->natt_oa_dst, ((const struct sockaddr *)(raddr + 1))->sa_len);
5268
	if (sav->sah->saidx.src.sa.sa_family == AF_INET) {
5269
		struct sockaddr *natt_src_sa = iaddr ? &sav->natt_oa_src.sa : NULL;
5270
		struct sockaddr *natt_dst_sa = raddr ? &sav->natt_oa_dst.sa : NULL;
5271
		sav->natt_cksum = key_compute_natt_cksum(&sav->sah->saidx.src.sa,
5272
		    &sav->sah->saidx.dst.sa, natt_src_sa, natt_dst_sa);
5273
	}
5180
5274
5181
#if 0
5275
#if 0
5182
	/*
5276
	/*
Lines 5377-5382 Link Here
5377
		iaddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAI];
5471
		iaddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAI];
5378
		raddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAR];
5472
		raddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAR];
5379
		ipseclog((LOG_DEBUG, "%s: NAT-T OAi/r present\n", __func__));
5473
		ipseclog((LOG_DEBUG, "%s: NAT-T OAi/r present\n", __func__));
5474
	} else if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) {
5475
		iaddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAI];
5476
		raddr = NULL;
5477
		ipseclog((LOG_DEBUG, "%s: NAT-T OA present\n", __func__));
5478
5380
	} else {
5479
	} else {
5381
		iaddr = raddr = NULL;
5480
		iaddr = raddr = NULL;
5382
	}
5481
	}
Lines 5436-5441 Link Here
5436
	 */
5535
	 */
5437
	if (type)
5536
	if (type)
5438
		newsav->natt_type = type->sadb_x_nat_t_type_type;
5537
		newsav->natt_type = type->sadb_x_nat_t_type_type;
5538
	if (iaddr)
5539
		bcopy(iaddr + 1, &newsav->natt_oa_src, ((const struct sockaddr *)(iaddr + 1))->sa_len);
5540
	if (raddr)
5541
		bcopy(raddr + 1, &newsav->natt_oa_dst, ((const struct sockaddr *)(raddr + 1))->sa_len);
5542
	if (newsav->sah->saidx.src.sa.sa_family == AF_INET) {
5543
		struct sockaddr *natt_src_sa = iaddr ? &newsav->natt_oa_src.sa : NULL;
5544
		struct sockaddr *natt_dst_sa = raddr ? &newsav->natt_oa_dst.sa : NULL;
5545
		newsav->natt_cksum = key_compute_natt_cksum(&newsav->sah->saidx.src.sa,
5546
		    &newsav->sah->saidx.dst.sa, natt_src_sa, natt_dst_sa);
5547
	}
5439
5548
5440
#if 0
5549
#if 0
5441
	/*
5550
	/*
(-)keydb.h (+3 lines)
Lines 157-162 Link Here
157
	 */
157
	 */
158
	u_int16_t natt_type;		/* IKE/ESP-marker in output. */
158
	u_int16_t natt_type;		/* IKE/ESP-marker in output. */
159
	u_int16_t natt_esp_frag_len;	/* MTU for payload fragmentation. */
159
	u_int16_t natt_esp_frag_len;	/* MTU for payload fragmentation. */
160
	union sockaddr_union natt_oa_src; /* NATT source address */
161
	union sockaddr_union natt_oa_dst; /* NATT destination address */
162
	u_int16_t natt_cksum;             /* checksum delta for inbound packets */
160
};
163
};
161
164
162
#define	SECASVAR_LOCK_INIT(_sav) \
165
#define	SECASVAR_LOCK_INIT(_sav) \
(-)xform_esp.c (+4 lines)
Lines 78-89 Link Here
78
78
79
VNET_DEFINE(int, esp_enable) = 1;
79
VNET_DEFINE(int, esp_enable) = 1;
80
VNET_DEFINE(struct espstat, espstat);
80
VNET_DEFINE(struct espstat, espstat);
81
VNET_DEFINE(int, esp_ignore_natt_cksum) = 0;
81
82
82
SYSCTL_DECL(_net_inet_esp);
83
SYSCTL_DECL(_net_inet_esp);
83
SYSCTL_VNET_INT(_net_inet_esp, OID_AUTO,
84
SYSCTL_VNET_INT(_net_inet_esp, OID_AUTO,
84
	esp_enable,	CTLFLAG_RW,	&VNET_NAME(esp_enable),	0, "");
85
	esp_enable,	CTLFLAG_RW,	&VNET_NAME(esp_enable),	0, "");
85
SYSCTL_VNET_STRUCT(_net_inet_esp, IPSECCTL_STATS,
86
SYSCTL_VNET_STRUCT(_net_inet_esp, IPSECCTL_STATS,
86
	stats,		CTLFLAG_RD,	&VNET_NAME(espstat),	espstat, "");
87
	stats,		CTLFLAG_RD,	&VNET_NAME(espstat),	espstat, "");
88
SYSCTL_VNET_INT(_net_inet_esp, OID_AUTO,
89
	esp_ignore_natt_cksum,	CTLFLAG_RW,	&VNET_NAME(esp_ignore_natt_cksum), 0, 
90
	"Do not validate checksums of ESP protected packets in case of NAT-T");
87
91
88
/* max iv length over all algorithms */
92
/* max iv length over all algorithms */
89
static VNET_DEFINE(int, esp_max_ivlen) = 0;
93
static VNET_DEFINE(int, esp_max_ivlen) = 0;

Return to bug 146190