diff --git a/edge.c b/edge.c index 088e67a..12843f3 100644 --- a/edge.c +++ b/edge.c @@ -173,6 +173,11 @@ static void help() { printf("\nEnvironment variables:\n"); printf(" N2N_KEY | Encryption key (ASCII). Not with -k.\n"); +#ifdef WIN32 + printf("\nAvailable TAP adapters:\n"); + win_print_available_adapters(); +#endif + exit(0); } diff --git a/win32/wintap.c b/win32/wintap.c index 3321675..b1296df 100644 --- a/win32/wintap.c +++ b/win32/wintap.c @@ -5,6 +5,8 @@ #include "../n2n.h" #include "n2n_win32.h" +/* ***************************************************** */ + void initWin32() { WSADATA wsaData; int err; @@ -18,29 +20,24 @@ void initWin32() { } } -int open_wintap(struct tuntap_dev *device, - const char * devname, - const char * address_mode, /* "static" or "dhcp" */ - char *device_ip, - char *device_mask, - const char *device_mac, - int mtu) { - HKEY key, key2; - LONG rc; - char regpath[1024], cmd[256]; +struct win_adapter_info { + HANDLE handle; char adapterid[1024]; char adaptername[1024]; +}; + +/* ***************************************************** */ + +static void iterate_win_network_adapters( + int (*callback)(struct win_adapter_info*, struct tuntap_dev *), + void *userdata) { + HKEY key, key2; + char regpath[1024]; char tapname[1024]; - long len; + long len, rc; int found = 0; int err, i; - ULONG status = TRUE; - - memset(device, 0, sizeof(struct tuntap_dev)); - device->device_handle = INVALID_HANDLE_VALUE; - device->device_name = devname[0] ? devname : NULL; - device->ifName = NULL; - device->ip_addr = inet_addr(device_ip); + struct win_adapter_info adapter; /* Open registry and look for network adapters */ if((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key))) { @@ -53,79 +50,104 @@ int open_wintap(struct tuntap_dev *device, } for (i = 0; ; i++) { - len = sizeof(adapterid); - if(RegEnumKeyEx(key, i, (LPTSTR)adapterid, &len, 0, 0, 0, NULL)) + len = sizeof(adapter.adapterid); + if(RegEnumKeyEx(key, i, (LPTSTR)adapter.adapterid, &len, 0, 0, 0, NULL)) break; /* Find out more about this adapter */ - _snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); + _snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapter.adapterid); if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)regpath, 0, KEY_READ, &key2)) continue; - len = sizeof(adaptername); - err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); + len = sizeof(adapter.adaptername); + err = RegQueryValueEx(key2, "Name", 0, 0, adapter.adaptername, &len); RegCloseKey(key2); if(err) continue; - if(device->device_name) { - if(!strcmp(device->device_name, adapterid)) { - found = 1; - break; - } else - continue; - } - - if(device->ifName) { - if(!strcmp(device->ifName, adaptername)) { - found = 1; - break; - } else - continue; - } - - _snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); - device->device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, - 0, /* Don't let other processes share or open - the resource until the handle's been closed */ - 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); - if(device->device_handle != INVALID_HANDLE_VALUE) { - found = 1; - break; + _snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapter.adapterid); + adapter.handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, + 0, /* Don't let other processes share or open + the resource until the handle's been closed */ + 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + if(adapter.handle != INVALID_HANDLE_VALUE) { + /* Valid device, use the callback */ + if(!callback(&adapter, userdata)) + break; + else + CloseHandle(adapter.handle); + /* continue */ } } RegCloseKey(key); +} - if(!found) { - printf("No Windows tap device found!\n"); - exit(0); - } +/* ***************************************************** */ - /* ************************************** */ +static int print_adapter_callback(struct win_adapter_info *adapter, void *userdata) { + printf(" %s - %s\n", adapter->adapterid, adapter->adaptername); +} - if(!device->device_name) - device->device_name = _strdup(adapterid); +void win_print_available_adapters() { + iterate_win_network_adapters(print_adapter_callback, NULL); +} - if(!device->ifName) - device->ifName = _strdup(adaptername); +/* ***************************************************** */ - /* Try to open the corresponding tap device->device_name */ +static int choose_adapter_callback(struct win_adapter_info *adapter, void *userdata) { + struct tuntap_dev *device = (struct tuntap_dev *)userdata; - if(device->device_handle == INVALID_HANDLE_VALUE) { - _snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device->device_name); - device->device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, - OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); - } + if(device->device_name) { + /* A device name filter was set, name must match */ + if(strcmp(device->device_name, adapter->adapterid) && + strcmp(device->device_name, adapter->adaptername)) { + /* Not found, continue */ + return(1); + } + } /* otherwise just pick the first available adapter */ + + /* Adapter found, break */ + device->device_handle = adapter->handle; + device->device_name = _strdup(adapter->adapterid); + device->ifName = _strdup(adapter->adaptername); + return(0); +} + +/* ***************************************************** */ + +int open_wintap(struct tuntap_dev *device, + const char * devname, + const char * address_mode, /* "static" or "dhcp" */ + char *device_ip, + char *device_mask, + const char *device_mac, + int mtu) { + char cmd[256]; + int len; + ULONG status = TRUE; + + memset(device, 0, sizeof(struct tuntap_dev)); + device->device_handle = INVALID_HANDLE_VALUE; + device->device_name = devname[0] ? devname : NULL; + device->ifName = NULL; + device->ip_addr = inet_addr(device_ip); + + iterate_win_network_adapters(choose_adapter_callback, device); if(device->device_handle == INVALID_HANDLE_VALUE) { - printf("%s (%s) is not a usable Windows tap device\n", device->device_name, device->ifName); - exit(-1); + if(!devname) + printf("No Windows tap devices found, did you run tapinstall.exe?\n"); + else + printf("Cannot find tap device \"%s\"\n", devname); + exit(0); } + /* ************************************** */ + /* Get MAC address from tap device->device_name */ if(!DeviceIoControl(device->device_handle, TAP_IOCTL_GET_MAC, diff --git a/win32/wintap.h b/win32/wintap.h index 0eef8f0..ef44b0e 100644 --- a/win32/wintap.h +++ b/win32/wintap.h @@ -63,5 +63,6 @@ #define TAP_COMPONENT_ID "tap0801" extern void initWin32(); +extern void win_print_available_adapters(); #endif \ No newline at end of file