[PATCH] Add VPN tunnel support for Darwin's utun device.
rcmuir at gmail.com
rcmuir at gmail.com
Tue Dec 27 08:59:52 AEDT 2016
From: Robert Muir <rcmuir at gmail.com>
My patch had a mistake in the configure.ac, corrected version here.
Cheers,
Robert
---
configure.ac | 17 ++++++++++----
openbsd-compat/port-tun.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++
openbsd-compat/port-tun.h | 3 ++-
3 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index eb9f45dc..7f2fd418 100644
--- a/configure.ac
+++ b/configure.ac
@@ -618,11 +618,18 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_DEFINE([BROKEN_GLOB], [1], [OS X glob does not do what we expect])
AC_DEFINE_UNQUOTED([BIND_8_COMPAT], [1],
[Define if your resolver libs need this for getrrsetbyname])
- AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
- AC_DEFINE([SSH_TUN_COMPAT_AF], [1],
- [Use tunnel device compatibility to OpenBSD])
- AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
- [Prepend the address family to IP tunnel traffic])
+ AC_CHECK_HEADERS([net/if_utun.h])
+ if test "x$ac_cv_header_net_if_utun_h" = "xyes" ; then
+ AC_DEFINE([SSH_TUN_DARWIN], [1],
+ [Open tunnel devices the Darwin way])
+ else
+ AC_DEFINE([SSH_TUN_FREEBSD], [1],
+ [Open tunnel devices the FreeBSD way])
+ AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
+ [Prepend the address family to IP tunnel traffic])
+ AC_DEFINE([SSH_TUN_COMPAT_AF], [1],
+ [Use tunnel device compatibility to OpenBSD])
+ fi
m4_pattern_allow([AU_IPv])
AC_CHECK_DECL([AU_IPv4], [],
AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
diff --git a/openbsd-compat/port-tun.c b/openbsd-compat/port-tun.c
index a444adf1..7eac9a70 100644
--- a/openbsd-compat/port-tun.c
+++ b/openbsd-compat/port-tun.c
@@ -43,6 +43,7 @@
*
* SSH_TUN_LINUX Use the (newer) Linux tun/tap device
* SSH_TUN_FREEBSD Use the FreeBSD tun/tap device
+ * SSH_TUN_DARWIN Use the Darwin utun device
* SSH_TUN_COMPAT_AF Translate the OpenBSD address family
* SSH_TUN_PREPEND_AF Prepend/remove the address family
*/
@@ -194,6 +195,65 @@ sys_tun_open(int tun, int mode)
}
#endif /* SSH_TUN_FREEBSD */
+#ifdef SSH_TUN_DARWIN
+#include <sys/sys_domain.h>
+#include <sys/kern_control.h>
+#include <net/if_utun.h>
+
+int
+sys_tun_open(int tun, int mode)
+{
+ struct ctl_info info;
+ struct sockaddr_ctl addr;
+ int fd;
+
+ if (tun != SSH_TUNID_ANY && tun > SSH_TUNID_MAX) {
+ debug("%s: invalid tunnel %u", __func__, tun);
+ return (-1);
+ }
+
+ if (mode == SSH_TUNMODE_ETHERNET) {
+ debug("%s: no layer 2 tunnelling support", __func__);
+ return (-1);
+ }
+
+ fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
+ if (fd == -1) {
+ debug("%s: failed to create control socket: %s",
+ __func__, strerror(errno));
+ return (-1);
+ }
+
+ bzero(&info, sizeof(info));
+ strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name));
+ if (ioctl(fd, CTLIOCGINFO, &info) == -1) {
+ debug("%s: failed to lookup utun control id: %s",
+ __func__, strerror(errno));
+ goto failed;
+ }
+
+ bzero(&addr, sizeof(addr));
+ addr.sc_id = info.ctl_id;
+ addr.sc_len = sizeof(addr);
+ addr.sc_family = AF_SYSTEM;
+ addr.ss_sysaddr = AF_SYS_CONTROL;
+ if (tun != SSH_TUNID_ANY)
+ addr.sc_unit = tun + 1;
+
+ if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+ debug("%s: failed to connect to utun device: %s",
+ __func__, strerror(errno));
+ goto failed;
+ }
+
+ return (fd);
+
+ failed:
+ close(fd);
+ return (-1);
+}
+#endif /* SSH_TUN_DARWIN */
+
/*
* System-specific channel filters
*/
diff --git a/openbsd-compat/port-tun.h b/openbsd-compat/port-tun.h
index c53df01f..e2a51f15 100644
--- a/openbsd-compat/port-tun.h
+++ b/openbsd-compat/port-tun.h
@@ -19,7 +19,8 @@
struct Channel;
-#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD)
+#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) || \
+ defined(SSH_TUN_DARWIN)
# define CUSTOM_SYS_TUN_OPEN
int sys_tun_open(int, int);
#endif
--
2.11.0
More information about the openssh-unix-dev
mailing list