[PATCH] Add VPN tunnel support for Darwin's utun device.
rcmuir at gmail.com
rcmuir at gmail.com
Tue Dec 27 07:33:47 AEDT 2016
From: Robert Muir <rcmuir at gmail.com>
This tunnel device is available out of box since OS X 10.6. I found a previous
discussion [1] but no patches anywhere yet.
[1] http://lists.mindrot.org/pipermail/openssh-unix-dev/2014-October/033012.html
---
configure.ac | 9 ++++++-
openbsd-compat/port-tun.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++
openbsd-compat/port-tun.h | 3 ++-
3 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index eb9f45dc..74a1e0bd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -618,7 +618,14 @@ 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_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])
+ fi
AC_DEFINE([SSH_TUN_COMPAT_AF], [1],
[Use tunnel device compatibility to OpenBSD])
AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
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