From 6096fb0e49e6dfed4f6a0f3363d4873e528eabef Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 Sep 2016 00:09:07 +0100 Subject: [PATCH] Add TUNIDX for Windows vpnc-script Signed-off-by: David Woodhouse --- configure.ac | 2 +- library.c | 4 +++ openconnect-internal.h | 2 +- tun-win32.c | 62 ++++++++++++++++++++++++++++++++++++++++++ www/changelog.xml | 1 + 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 118a740a..fcb2bad9 100644 --- a/configure.ac +++ b/configure.ac @@ -170,7 +170,7 @@ AC_SUBST(WFLAGS, [$WFLAGS]) if test "$have_win" = yes; then # Checking "properly" for __attribute__((dllimport,stdcall)) functions is non-trivial - LIBS="$LIBS -lws2_32 -lshlwapi -lsecur32" + LIBS="$LIBS -lws2_32 -lshlwapi -lsecur32 -liphlpapi" else AC_CHECK_FUNC(socket, [], AC_CHECK_LIB(socket, socket, [], AC_ERROR(Cannot find socket() function))) fi diff --git a/library.c b/library.c index 5e22a6d9..9cce027e 100644 --- a/library.c +++ b/library.c @@ -840,6 +840,10 @@ int openconnect_setup_tun_device(struct openconnect_info *vpninfo, if (tun_fd < 0) return tun_fd; +#ifdef _WIN32 + if (vpninfo->tun_idx != -1) + script_setenv_int(vpninfo, "TUNIDX", vpninfo->tun_idx); +#endif legacy_ifname = openconnect_utf8_to_legacy(vpninfo, vpninfo->ifname); script_setenv(vpninfo, "TUNDEV", legacy_ifname, 0); if (legacy_ifname != vpninfo->ifname) diff --git a/openconnect-internal.h b/openconnect-internal.h index 10cc909a..e44a549c 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -589,7 +589,7 @@ struct openconnect_info { #ifdef _WIN32 HANDLE tun_fh; OVERLAPPED tun_rd_overlap, tun_wr_overlap; - int tun_rd_pending; + int tun_idx, tun_rd_pending; #else int tun_fd; #endif diff --git a/tun-win32.c b/tun-win32.c index b5f6f83c..9bc98815 100644 --- a/tun-win32.c +++ b/tun-win32.c @@ -20,6 +20,7 @@ #define WIN32_LEAN_AND_MEAN #include #include +#include #include #include @@ -155,6 +156,65 @@ static intptr_t search_taps(struct openconnect_info *vpninfo, tap_callback *cb, return ret; } +static int get_adapter_index(struct openconnect_info *vpninfo, char *guid) +{ + struct oc_text_buf *buf = buf_alloc(); + IP_ADAPTER_INFO *adapter; + void *adapters_buf; + ULONG idx; + DWORD status; + int ret = -EINVAL; + + vpninfo->tun_idx = -1; + + buf_append_utf16le(buf, "\\device\\tcpip_"); + buf_append_utf16le(buf, guid); + if (buf_error(buf)) { + /* If we didn't manage to malloc for this, we're never + * going to manage for GetAdaptersInfo(). Give up. */ + return buf_free(buf); + } + + status = GetAdapterIndex((void *)buf->data, &idx); + buf_free(buf); + if (status == NO_ERROR) { + vpninfo->tun_idx = idx; + return 0; + } else { + char *errstr = openconnect__win32_strerror(status); + vpn_progress(vpninfo, PRG_INFO, + _("GetAdapterIndex() failed: %s\nFalling back to GetAdaptersInfo()\n"), + errstr); + free(errstr); + } + idx = 0; + status = GetAdaptersInfo(NULL, &idx); + if (status != ERROR_BUFFER_OVERFLOW) + return -EIO; + adapters_buf = malloc(idx); + if (!adapters_buf) + return -ENOMEM; + status = GetAdaptersInfo(adapters_buf, &idx); + if (status != NO_ERROR) { + char *errstr = openconnect__win32_strerror(status); + vpn_progress(vpninfo, PRG_ERR, _("GetAdaptersInfo() failed: %s\n"), errstr); + free(errstr); + free(adapters_buf); + return -EIO; + } + + for (adapter = adapters_buf; adapter; adapter = adapter->Next) { + if (!strcmp(adapter->AdapterName, guid)) { + vpninfo->tun_idx = adapter->Index; + ret = 0; + break; + } + } + + free(adapters_buf); + return ret; +} + static intptr_t open_tun(struct openconnect_info *vpninfo, char *guid, char *name) { char devname[80]; @@ -227,6 +287,8 @@ static intptr_t open_tun(struct openconnect_info *vpninfo, char *guid, char *nam if (!vpninfo->ifname) vpninfo->ifname = strdup(name); + get_adapter_index(vpninfo, guid); + return (intptr_t)tun_fh; } diff --git a/www/changelog.xml b/www/changelog.xml index e9e8fa69..fc264d70 100644 --- a/www/changelog.xml +++ b/www/changelog.xml @@ -15,6 +15,7 @@
  • OpenConnect HEAD
      +
    • Add TUNIDX environment variable on Windows.
    • Fix compatibility with Pulse Secure 8.2R5.
    • Fix IPv6 support in Solaris.
    • Support DTLS automatic negotiation.