diff --git a/configure.ac b/configure.ac index 1705862..042b0d0 100644 --- a/configure.ac +++ b/configure.ac @@ -260,6 +260,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) ;; *-*-freebsd*) check_for_libcrypt_later=1 + AC_DEFINE([HAVE_FREEBSD_NATT], [1], [Use FreeBSD's NAT-T support]) ;; *-*-openbsd*) echo "Please use -current" diff --git a/iked/pfkey.c b/iked/pfkey.c index a3e876b..4b808f0 100644 --- a/iked/pfkey.c +++ b/iked/pfkey.c @@ -29,6 +29,8 @@ #if defined(__OpenBSD__) #include #include +#elif defined(HAVE_FREEBSD_NATT) +#include #endif #include @@ -657,6 +659,11 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, struct iked_childsa *sa) #if defined(HAVE_APPLE_NATT) struct sadb_sa_natt natt; #endif +#if defined(HAVE_FREEBSD_NATT) + struct sadb_x_nat_t_type nat_type; + struct sadb_x_nat_t_port nat_port_src; + struct sadb_x_nat_t_port nat_port_dst; +#endif #endif struct sockaddr_storage ssrc, sdst; struct sadb_ident *sa_srcid, *sa_dstid; @@ -731,6 +738,10 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, struct iked_childsa *sa) bzero(&udpencap, sizeof udpencap); #elif defined(HAVE_APPLE_NATT) bzero(&natt, sizeof(natt)); +#elif defined(HAVE_FREEBSD_NATT) + bzero(&nat_type, sizeof(nat_type)); + bzero(&nat_port_src, sizeof(nat_port_src)); + bzero(&nat_port_dst, sizeof(nat_port_dst)); #endif bzero(&sa_ltime_hard, sizeof(sa_ltime_hard)); bzero(&sa_ltime_soft, sizeof(sa_ltime_soft)); @@ -784,6 +795,23 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, struct iked_childsa *sa) sadb.sadb_sa_flags |= SADB_X_EXT_NATT_DETECTED_PEER; natt.sadb_sa_natt_port = ntohs(sa->csa_ikesa->sa_peer.addr_port); +#elif defined(HAVE_FREEBSD_NATT) + nat_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; + nat_type.sadb_x_nat_t_type_len = sizeof(nat_type) / 8; + nat_type.sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP; + + nat_port_src.sadb_x_nat_t_port_exttype + = SADB_X_EXT_NAT_T_SPORT; + nat_port_src.sadb_x_nat_t_port_len + = sizeof(nat_port_src) / 8; + nat_port_src.sadb_x_nat_t_port_port = htons(4500); + + nat_port_dst.sadb_x_nat_t_port_exttype + = SADB_X_EXT_NAT_T_DPORT; + nat_port_dst.sadb_x_nat_t_port_len + = sizeof(nat_port_dst) / 8; + nat_port_dst.sadb_x_nat_t_port_port + = sa->csa_ikesa->sa_peer.addr_port; #else #warning PFKEYv2 NAT-T not supported #endif @@ -923,6 +951,25 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, struct iked_childsa *sa) } #endif +#if defined(HAVE_FREEBSD_NATT) + if (nat_type.sadb_x_nat_t_type_len) { + iov[iov_cnt].iov_base = &nat_type; + iov[iov_cnt].iov_len = sizeof(nat_type); + smsg.sadb_msg_len += nat_type.sadb_x_nat_t_type_len; + iov_cnt++; + + iov[iov_cnt].iov_base = &nat_port_src; + iov[iov_cnt].iov_len = sizeof(nat_port_src); + smsg.sadb_msg_len += nat_port_src.sadb_x_nat_t_port_len; + iov_cnt++; + + iov[iov_cnt].iov_base = &nat_port_dst; + iov[iov_cnt].iov_len = sizeof(nat_port_dst); + smsg.sadb_msg_len += nat_port_dst.sadb_x_nat_t_port_len; + iov_cnt++; + } +#endif + if (sa_enckey.sadb_key_len) { /* encryption key */ iov[iov_cnt].iov_base = &sa_enckey;