diff --git a/CHANGELOG b/CHANGELOG index 3b9a66a..1336843 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,7 @@ CHANGES: 20xx-xx-xx: x.y.z - Fixed tunnel not working on Windows. - Any device name is now supported on Windows, fixes #47. + - Multiple installed TAP32 interfaces are now supported, fixes #46. 2009-06-01: 0.5.2 "WifiFree" - Fixed client segfault on OS X, #57 diff --git a/README-win32.txt b/README-win32.txt index 29c356d..250893e 100644 --- a/README-win32.txt +++ b/README-win32.txt @@ -13,14 +13,14 @@ Extra README file for Win32 related stuff choose OpenVPN 2.0.9 Windows Installer, when installing you can select to install only the TAP driver. -2. Have one TAP32 interface installed +2. Make sure the interface you want to use does not have a default gateway set. + Use -d to specify the interface, use double quotes to include spaces, example + iodine.exe -d "Local Area Connection 4" abc.ab -3. Make sure the interface does not have a default gateway set - -4. Run iodine/iodined as normal (see the main README file). +3. Run iodine/iodined as normal (see the main README file). You may have to run it as administrator depending on user privileges. -5. Enjoy! +4. Enjoy! == Building on Windows: @@ -47,7 +47,6 @@ cross-compile. == Results of crappy Win32 API: The following fixable limitations apply: -- Exactly one TAP32 interface must be installed - Server cannot read packet destination address The following (probably) un-fixable limitations apply: diff --git a/src/tun.c b/src/tun.c index 01add71..306a892 100644 --- a/src/tun.c +++ b/src/tun.c @@ -32,6 +32,8 @@ HANDLE dev_handle; struct tun_data data; +static void get_name(char *ifname, int namelen, char *dev_name); + #define TAP_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) #define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE(10, METHOD_BUFFERED) #define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE(6, METHOD_BUFFERED) @@ -160,7 +162,7 @@ open_tun(const char *tun_device) #endif /* !LINUX */ #else /* WINDOWS32 */ static void -get_device(char *device, int device_len) +get_device(char *device, int device_len, const char *wanted_dev) { LONG status; HKEY adapter_key; @@ -216,7 +218,18 @@ get_device(char *device, int device_len) if (status != ERROR_SUCCESS || datatype != REG_SZ) { warnx("Error reading registry key %s\\%s on TAP device", unit, iid_string); } else { - /* Done getting name of TAP device */ + /* Done getting GUID of TAP device, + * now check if the name is the requested one */ + if (wanted_dev) { + char name[250]; + get_name(name, sizeof(name), device); + if (strncmp(name, wanted_dev, strlen(wanted_dev))) { + /* Skip if name mismatch */ + goto next; + } + } + /* Get the if name */ + get_name(if_name, sizeof(if_name), device); RegCloseKey(device_key); return; } @@ -229,7 +242,7 @@ next: } static void -get_name(char *dev_name) +get_name(char *ifname, int namelen, char *dev_name) { char path[256]; char name_str[256] = "Name"; @@ -238,18 +251,17 @@ get_name(char *dev_name) DWORD len; DWORD datatype; - memset(if_name, 0, sizeof(if_name)); + memset(ifname, 0, namelen); snprintf(path, sizeof(path), NETWORK_KEY "\\%s\\Connection", dev_name); status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &conn_key); - printf("%s ?? %s\n", path, dev_name); if (status != ERROR_SUCCESS) { fprintf(stderr, "Could not look up name of interface %s: error opening key\n", dev_name); RegCloseKey(conn_key); return; } - len = sizeof(if_name); - status = RegQueryValueEx(conn_key, name_str, NULL, &datatype, (LPBYTE)if_name, &len); + len = namelen; + status = RegQueryValueEx(conn_key, name_str, NULL, &datatype, (LPBYTE)ifname, &len); if (status != ERROR_SUCCESS || datatype != REG_SZ) { fprintf(stderr, "Could not look up name of interface %s: error reading value\n", dev_name); RegCloseKey(conn_key); @@ -295,8 +307,8 @@ open_tun(const char *tun_device) in_addr_t local; memset(adapter, 0, sizeof(adapter)); - get_device(adapter, sizeof(adapter)); - get_name(adapter); /* Copies interface 'human name' to if_name */ + get_device(adapter, sizeof(adapter), tun_device); + get_name(if_name, sizeof(if_name), adapter); if (strlen(adapter) == 0 || strlen(if_name) == 0) { warnx("No TAP adapters found. See README-win32.txt for help.\n"); @@ -304,7 +316,7 @@ open_tun(const char *tun_device) } snprintf(tapfile, sizeof(tapfile), "%s%s.tap", TAP_DEVICE_SPACE, adapter); - fprintf(stderr, "Opening device %s\n", tapfile); + fprintf(stderr, "Opening device %s\n", if_name); dev_handle = CreateFile(tapfile, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, NULL); if (dev_handle == INVALID_HANDLE_VALUE) { return -1;