|
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 |
/* |