]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Add TUNIDX for Windows vpnc-script
authorDavid Woodhouse <David.Woodhouse@intel.com>
Fri, 23 Sep 2016 23:09:07 +0000 (00:09 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Fri, 23 Sep 2016 23:09:07 +0000 (00:09 +0100)
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
configure.ac
library.c
openconnect-internal.h
tun-win32.c
www/changelog.xml

index 118a740a8c229b7efaad090c8752a200842c4096..fcb2bad9d8ef7bcd39ccb910c27288e795a5c278 100644 (file)
@@ -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
index 5e22a6d92172eacc397c173145a7bd23ddbf0d7d..9cce027e8a185207c09779b381048ef334781470 100644 (file)
--- 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)
index 10cc909af108788680e4deea2c371a68018083ec..e44a549c6ccb50647698be6cf8a5e40649d2fac9 100644 (file)
@@ -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
index b5f6f83cc6bd481a72ef2124e3fe411e875dd122..9bc988156d3e18bcd691856a4eac61f45a04c9cc 100644 (file)
@@ -20,6 +20,7 @@
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <winioctl.h>
+#include <iphlpapi.h>
 
 #include <errno.h>
 #include <stdio.h>
@@ -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;
 }
 
index e9e8fa69faff3f42b4d9be4ab97c9960caa1a884..fc264d70e404082204539ee914e85c12f7c997b7 100644 (file)
@@ -15,6 +15,7 @@
 <ul>
    <li><b>OpenConnect HEAD</b>
      <ul>
+       <li>Add <tt>TUNIDX</tt> environment variable on Windows.</li>
        <li>Fix compatibility with Pulse Secure 8.2R5.</li>
        <li>Fix IPv6 support in Solaris.</li>
        <li>Support DTLS automatic negotiation.</li>