From 07af8773aac5d6861d0efae50d4af454e2149969 Mon Sep 17 00:00:00 2001 From: siten Date: Mon, 25 Feb 2019 13:14:08 +0800 Subject: [PATCH 1/2] openvpn 2.4.7-I603 read write tap device change 2.4.7 tap device read write need LPOVERLAPPED parameter. --- tuntap-windows.c | 510 +++++++++++++++++++++++++++-------------------- 1 file changed, 295 insertions(+), 215 deletions(-) diff --git a/tuntap-windows.c b/tuntap-windows.c index 7823d63..34daa01 100644 --- a/tuntap-windows.c +++ b/tuntap-windows.c @@ -26,7 +26,7 @@ #include "tuntap.h" #include "private.h" -/* From OpenVPN tap driver, common.h */ + /* From OpenVPN tap driver, common.h */ #define TAP_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) #define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) #define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) @@ -47,6 +47,9 @@ /* From OpenVPN tap driver, proto.h */ typedef unsigned long IPADDR; +OVERLAPPED g_olw = { 0 }; +OVERLAPPED g_olr = { 0 }; + /* This one is from Fabien Pichot, in the tNETacle source code */ static LPWSTR formated_error(LPWSTR pMessage, DWORD m, ...) { @@ -56,13 +59,13 @@ formated_error(LPWSTR pMessage, DWORD m, ...) { va_start(args, pMessage); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ALLOCATE_BUFFER, - pMessage, - m, - 0, - (LPSTR)&pBuffer, - 0, - &args); + FORMAT_MESSAGE_ALLOCATE_BUFFER, + pMessage, + m, + 0, + (LPSTR)&pBuffer, + 0, + &args); va_end(args); @@ -72,303 +75,380 @@ formated_error(LPWSTR pMessage, DWORD m, ...) { /* TODO: Rework to be more generic and allow arbitrary key modification (MTU and stuff) */ static char * reg_query(char *key_name) { - HKEY adapters, adapter; - DWORD i, ret, len; - char *deviceid = NULL; - DWORD sub_keys = 0; - - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(key_name), 0, KEY_READ, &adapters); - if (ret != ERROR_SUCCESS) { - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", ret)); - return NULL; - } - - ret = RegQueryInfoKey(adapters, NULL, NULL, NULL, &sub_keys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if (ret != ERROR_SUCCESS) { - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", ret)); - return NULL; - } - - if (sub_keys <= 0) { - tuntap_log(TUNTAP_LOG_DEBUG, "Wrong registry key"); - return NULL; - } - - /* Walk througt all adapters */ + HKEY adapters, adapter; + DWORD i, ret, len; + char *deviceid = NULL; + DWORD sub_keys = 0; + + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &adapters); + if (ret != ERROR_SUCCESS) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", ret)); + return NULL; + } + + ret = RegQueryInfoKey(adapters, NULL, NULL, NULL, &sub_keys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if (ret != ERROR_SUCCESS) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", ret)); + return NULL; + } + + if (sub_keys <= 0) { + tuntap_log(TUNTAP_LOG_DEBUG, "Wrong registry key"); + return NULL; + } + + /* Walk througt all adapters */ for (i = 0; i < sub_keys; i++) { - char new_key[MAX_KEY_LENGTH]; - char data[256]; - TCHAR key[MAX_KEY_LENGTH]; - DWORD keylen = MAX_KEY_LENGTH; - - /* Get the adapter key name */ - ret = RegEnumKeyEx(adapters, i, key, &keylen, NULL, NULL, NULL, NULL); - if (ret != ERROR_SUCCESS) { - continue; - } - - /* Append it to NETWORK_ADAPTERS and open it */ - snprintf(new_key, sizeof new_key, "%s\\%s", key_name, key); - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(new_key), 0, KEY_READ, &adapter); - if (ret != ERROR_SUCCESS) { - continue; - } - - /* Check its values */ - len = sizeof data; - ret = RegQueryValueEx(adapter, "ComponentId", NULL, NULL, (LPBYTE)data, &len); - if (ret != ERROR_SUCCESS) { - /* This value doesn't exist in this adaptater tree */ - goto clean; - } - /* If its a tap adapter, its all good */ - if (strncmp(data, "tap", 3) == 0) { - DWORD type; - - len = sizeof data; - ret = RegQueryValueEx(adapter, "NetCfgInstanceId", NULL, &type, (LPBYTE)data, &len); - if (ret != ERROR_SUCCESS) { - tuntap_log(TUNTAP_LOG_INFO, (const char *)formated_error(L"%1", ret)); - goto clean; - } - deviceid = strdup(data); - break; - } -clean: - RegCloseKey(adapter); - } - RegCloseKey(adapters); - return deviceid; + char new_key[MAX_KEY_LENGTH]; + char data[256]; + TCHAR key[MAX_KEY_LENGTH]; + DWORD keylen = MAX_KEY_LENGTH; + + /* Get the adapter key name */ + ret = RegEnumKeyEx(adapters, i, key, &keylen, NULL, NULL, NULL, NULL); + if (ret != ERROR_SUCCESS) { + continue; + } + + /* Append it to NETWORK_ADAPTERS and open it */ + snprintf(new_key, sizeof new_key, "%s\\%s", key_name, key); + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, new_key, 0, KEY_READ, &adapter); + if (ret != ERROR_SUCCESS) { + continue; + } + + /* Check its values */ + len = sizeof data; + ret = RegQueryValueEx(adapter, "ComponentId", NULL, NULL, (LPBYTE)data, &len); + if (ret != ERROR_SUCCESS) { + /* This value doesn't exist in this adaptater tree */ + goto clean; + } + /* If its a tap adapter, its all good */ + if (strncmp(data, "tap", 3) == 0) { + DWORD type; + + len = sizeof data; + ret = RegQueryValueEx(adapter, "NetCfgInstanceId", NULL, &type, (LPBYTE)data, &len); + if (ret != ERROR_SUCCESS) { + tuntap_log(TUNTAP_LOG_INFO, (const char *)formated_error(L"%1", ret)); + goto clean; + } + deviceid = strdup(data); + break; + } + clean: + RegCloseKey(adapter); + } + RegCloseKey(adapters); + return deviceid; } void tuntap_sys_destroy(struct device *dev) { - (void)dev; - return; + (void)dev; + return; } int tuntap_start(struct device *dev, int mode, int tun) { - HANDLE tun_fd; - char *deviceid; - char buf[60]; - - /* Don't re-initialise a previously started device */ - if (dev->tun_fd != TUNFD_INVALID_VALUE) { - return -1; - } - - /* Shift the persistence bit */ - if (mode & TUNTAP_MODE_PERSIST) { - mode &= ~TUNTAP_MODE_PERSIST; - } - - if (mode == TUNTAP_MODE_TUNNEL) { - tuntap_log(TUNTAP_LOG_NOTICE, "Layer 3 tunneling is not implemented"); - return -1; - } - else if (mode != TUNTAP_MODE_ETHERNET) { - tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'mode'"); - return -1; - } - - deviceid = reg_query(NETWORK_ADAPTERS); - snprintf(buf, sizeof buf, "\\\\.\\Global\\%s.tap", deviceid); - tun_fd = CreateFile(buf, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED, 0); - if (tun_fd == TUNFD_INVALID_VALUE) { - int errcode = GetLastError(); - - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; - } - - dev->tun_fd = tun_fd; - return 0; + HANDLE tun_fd; + char *deviceid; + char buf[60]; + + /* Don't re-initialise a previously started device */ + if (dev->tun_fd != TUNFD_INVALID_VALUE) { + return -1; + } + + /* Shift the persistence bit */ + if (mode & TUNTAP_MODE_PERSIST) { + mode &= ~TUNTAP_MODE_PERSIST; + } + + if (mode == TUNTAP_MODE_TUNNEL) { + tuntap_log(TUNTAP_LOG_NOTICE, "Layer 3 tunneling is not implemented"); + return -1; + } + else if (mode != TUNTAP_MODE_ETHERNET) { + tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'mode'"); + return -1; + } + + g_olw.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (NULL == g_olw.hEvent) { + return -1; + } + g_olr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (NULL == g_olr.hEvent) { + CloseHandle(g_olw.hEvent); + g_olw.hEvent = NULL; + return -1; + } + + deviceid = reg_query(NETWORK_ADAPTERS); + snprintf(buf, sizeof buf, "\\\\.\\Global\\%s.tap", deviceid); + tun_fd = CreateFile(buf, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + if (tun_fd == TUNFD_INVALID_VALUE) { + int errcode = GetLastError(); + + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; + } + + dev->tun_fd = tun_fd; + return 0; } void tuntap_release(struct device *dev) { - (void)CloseHandle(dev->tun_fd); - free(dev); + (void)CloseHandle(dev->tun_fd); + if (g_olw.hEvent) { + CloseHandle(g_olw.hEvent); + g_olw.hEvent = NULL; + } + if (g_olr.hEvent) { + CloseHandle(g_olr.hEvent); + g_olr.hEvent = NULL; + } + free(dev); } char * tuntap_get_hwaddr(struct device *dev) { - static unsigned char hwaddr[ETHER_ADDR_LEN]; - DWORD len; + static unsigned char hwaddr[ETHER_ADDR_LEN]; + DWORD len; if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_GET_MAC, &hwaddr, sizeof(hwaddr), &hwaddr, sizeof(hwaddr), &len, NULL) == 0) { - int errcode = GetLastError(); - - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return NULL; - } else { - char buf[128]; - - (void)_snprintf_s(buf, sizeof buf, sizeof buf, "MAC address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", - hwaddr[0],hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]); - tuntap_log(TUNTAP_LOG_DEBUG, buf); - } - return (char *)hwaddr; + int errcode = GetLastError(); + + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return NULL; + } + else { + char buf[128]; + + (void)_snprintf_s(buf, sizeof buf, sizeof buf, "MAC address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); + tuntap_log(TUNTAP_LOG_DEBUG, buf); + } + return (char *)hwaddr; } int tuntap_set_hwaddr(struct device *dev, const char *hwaddr) { - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_hwaddr()"); - return -1; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_hwaddr()"); + return -1; } static int tuntap_sys_set_updown(struct device *dev, ULONG flag) { - DWORD len; + DWORD len; - if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_SET_MEDIA_STATUS, &flag, sizeof(flag), &flag, sizeof(flag), &len, NULL) == 0) { - int errcode = GetLastError(); + if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_SET_MEDIA_STATUS, &flag, sizeof(flag), &flag, sizeof(flag), &len, NULL) == 0) { + int errcode = GetLastError(); - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; - } else { - char buf[32]; + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; + } + else { + char buf[32]; - (void)_snprintf_s(buf, sizeof buf, sizeof buf, "Status: %s", flag ? "Up" : "Down"); - tuntap_log(TUNTAP_LOG_DEBUG, buf); - return 0; - } + (void)_snprintf_s(buf, sizeof buf, sizeof buf, "Status: %s", flag ? "Up" : "Down"); + tuntap_log(TUNTAP_LOG_DEBUG, buf); + return 0; + } } int tuntap_up(struct device *dev) { - ULONG flag; + ULONG flag; - flag = 1; - return tuntap_sys_set_updown(dev, flag); + flag = 1; + return tuntap_sys_set_updown(dev, flag); } int tuntap_down(struct device *dev) { - ULONG flag; + ULONG flag; - flag = 0; - return tuntap_sys_set_updown(dev, flag); + flag = 0; + return tuntap_sys_set_updown(dev, flag); } int tuntap_get_mtu(struct device *dev) { - ULONG mtu; - DWORD len; + ULONG mtu; + DWORD len; - if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_GET_MTU, &mtu, sizeof(mtu), &mtu, sizeof(mtu), &len, NULL) == 0) { - int errcode = GetLastError(); + if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_GET_MTU, &mtu, sizeof(mtu), &mtu, sizeof(mtu), &len, NULL) == 0) { + int errcode = GetLastError(); - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; } - return 0; + return 0; } int tuntap_set_mtu(struct device *dev, int mtu) { - (void)dev; - (void)mtu; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_mtu()"); - return -1; + (void)dev; + (void)mtu; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_mtu()"); + return -1; } int tuntap_sys_set_ipv4(struct device *dev, t_tun_in_addr *s, uint32_t mask) { - IPADDR psock[4]; - DWORD len; - - /* Address + Netmask */ - psock[0] = s->S_un.S_addr; - psock[1] = mask; - /* DHCP server address (We don't want it) */ - psock[2] = 0; - /* DHCP lease time */ - psock[3] = 0; - - if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_CONFIG_DHCP_MASQ, &psock, sizeof(psock), &psock, sizeof(psock), &len, NULL) == 0) { - int errcode = GetLastError(); - - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; + IPADDR psock[4]; + DWORD len; + + /* Address + Netmask */ + psock[0] = s->S_un.S_addr; + psock[1] = mask; + /* DHCP server address (We don't want it) */ + psock[2] = 0; + /* DHCP lease time */ + psock[3] = 0; + + if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_CONFIG_DHCP_MASQ, &psock, sizeof(psock), &psock, sizeof(psock), &len, NULL) == 0) { + int errcode = GetLastError(); + + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; } - return 0; + return 0; } int tuntap_sys_set_ipv6(struct device *dev, t_tun_in6_addr *s, uint32_t mask) { - (void)dev; - (void)s; - (void)mask; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_sys_set_ipv6()"); - return -1; + (void)dev; + (void)s; + (void)mask; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_sys_set_ipv6()"); + return -1; } int tuntap_read(struct device *dev, void *buf, size_t size) { - DWORD len; - - if (ReadFile(dev->tun_fd, buf, (DWORD)size, &len, NULL) == 0) { - int errcode = GetLastError(); - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; - } + DWORD len; + int ret = 0; + ResetEvent(g_olr.hEvent); + + if (!ReadFile(dev->tun_fd, buf, (DWORD)size, &len, &g_olr)) + { + if (GetLastError() != ERROR_IO_PENDING) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + } + else + { + switch (WaitForSingleObject(g_olr.hEvent, INFINITE)) + { + case WAIT_OBJECT_0: + if (!GetOverlappedResult(dev->tun_fd, &g_olr, &len, FALSE)) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + } + else { + ret = 0; //read ok + } + break; + default: + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + break; + } + } + } - return 0; + if (0 == ret) { + return len; + } + else { + return -1; + } } int tuntap_write(struct device *dev, void *buf, size_t size) { - DWORD len; - if (WriteFile(dev->tun_fd, buf, (DWORD)size, &len, NULL) == 0) { - int errcode = GetLastError(); - - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; - } + DWORD len; + int ret = 0; + ResetEvent(g_olw.hEvent); + + if (!WriteFile(dev->tun_fd, buf, (DWORD)size, &len, &g_olw)) + { + if (GetLastError() != ERROR_IO_PENDING) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + } + else + { + switch (WaitForSingleObject(g_olw.hEvent, INFINITE)) + { + case WAIT_OBJECT_0: + if (!GetOverlappedResult(dev->tun_fd, &g_olw, &len, FALSE)) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + } + else { + ret = 0; //write ok + } + break; + default: + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + break; + } + } + } - return 0; + if (0 == ret) { + return len; + } + else { + return -1; + } } int tuntap_get_readable(struct device *dev) { - (void)dev; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_get_readable()"); - return -1; + (void)dev; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_get_readable()"); + return -1; } int tuntap_set_nonblocking(struct device *dev, int set) { - (void)dev; - (void)set; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_nonblocking()"); - return -1; + (void)dev; + (void)set; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_nonblocking()"); + return -1; } int tuntap_set_debug(struct device *dev, int set) { - (void)dev; - (void)set; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_debug()"); - return -1; + (void)dev; + (void)set; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_debug()"); + return -1; } int tuntap_set_descr(struct device *dev, const char *descr) { - (void)dev; - (void)descr; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_descr()"); - return -1; + (void)dev; + (void)descr; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_descr()"); + return -1; } int tuntap_set_ifname(struct device *dev, const char *name) { - /* TODO: Check Windows API to know how to rename an interface */ - (void)dev; - (void)name; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_ifname()"); - return -1; + /* TODO: Check Windows API to know how to rename an interface */ + (void)dev; + (void)name; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_ifname()"); + return -1; } From 0946177d2dd3f776abee9e38885b014e96671963 Mon Sep 17 00:00:00 2001 From: siten Date: Wed, 27 Feb 2019 16:33:43 +0800 Subject: [PATCH 2/2] openvpn 2.4.7-I603 read write tap device change 2.4.7 tap device read write need LPOVERLAPPED parameter. and set dhcp lease time not 0. --- tuntap-windows.c | 608 +++++++++++++++++++++++------------------------ 1 file changed, 304 insertions(+), 304 deletions(-) diff --git a/tuntap-windows.c b/tuntap-windows.c index 34daa01..8eed1a2 100644 --- a/tuntap-windows.c +++ b/tuntap-windows.c @@ -53,402 +53,402 @@ OVERLAPPED g_olr = { 0 }; /* This one is from Fabien Pichot, in the tNETacle source code */ static LPWSTR formated_error(LPWSTR pMessage, DWORD m, ...) { - LPWSTR pBuffer = NULL; + LPWSTR pBuffer = NULL; - va_list args = NULL; - va_start(args, pMessage); + va_list args = NULL; + va_start(args, pMessage); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ALLOCATE_BUFFER, - pMessage, - m, - 0, - (LPSTR)&pBuffer, - 0, - &args); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER, + pMessage, + m, + 0, + (LPSTR)&pBuffer, + 0, + &args); - va_end(args); + va_end(args); - return pBuffer; + return pBuffer; } /* TODO: Rework to be more generic and allow arbitrary key modification (MTU and stuff) */ static char * reg_query(char *key_name) { - HKEY adapters, adapter; - DWORD i, ret, len; - char *deviceid = NULL; - DWORD sub_keys = 0; - - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &adapters); - if (ret != ERROR_SUCCESS) { - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", ret)); - return NULL; - } - - ret = RegQueryInfoKey(adapters, NULL, NULL, NULL, &sub_keys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if (ret != ERROR_SUCCESS) { - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", ret)); - return NULL; - } - - if (sub_keys <= 0) { - tuntap_log(TUNTAP_LOG_DEBUG, "Wrong registry key"); - return NULL; - } - - /* Walk througt all adapters */ - for (i = 0; i < sub_keys; i++) { - char new_key[MAX_KEY_LENGTH]; - char data[256]; - TCHAR key[MAX_KEY_LENGTH]; - DWORD keylen = MAX_KEY_LENGTH; - - /* Get the adapter key name */ - ret = RegEnumKeyEx(adapters, i, key, &keylen, NULL, NULL, NULL, NULL); - if (ret != ERROR_SUCCESS) { - continue; - } - - /* Append it to NETWORK_ADAPTERS and open it */ - snprintf(new_key, sizeof new_key, "%s\\%s", key_name, key); - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, new_key, 0, KEY_READ, &adapter); - if (ret != ERROR_SUCCESS) { - continue; - } - - /* Check its values */ - len = sizeof data; - ret = RegQueryValueEx(adapter, "ComponentId", NULL, NULL, (LPBYTE)data, &len); - if (ret != ERROR_SUCCESS) { - /* This value doesn't exist in this adaptater tree */ - goto clean; - } - /* If its a tap adapter, its all good */ - if (strncmp(data, "tap", 3) == 0) { - DWORD type; - - len = sizeof data; - ret = RegQueryValueEx(adapter, "NetCfgInstanceId", NULL, &type, (LPBYTE)data, &len); - if (ret != ERROR_SUCCESS) { - tuntap_log(TUNTAP_LOG_INFO, (const char *)formated_error(L"%1", ret)); - goto clean; - } - deviceid = strdup(data); - break; - } - clean: - RegCloseKey(adapter); - } - RegCloseKey(adapters); - return deviceid; + HKEY adapters, adapter; + DWORD i, ret, len; + char *deviceid = NULL; + DWORD sub_keys = 0; + + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &adapters); + if (ret != ERROR_SUCCESS) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", ret)); + return NULL; + } + + ret = RegQueryInfoKey(adapters, NULL, NULL, NULL, &sub_keys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if (ret != ERROR_SUCCESS) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", ret)); + return NULL; + } + + if (sub_keys <= 0) { + tuntap_log(TUNTAP_LOG_DEBUG, "Wrong registry key"); + return NULL; + } + + /* Walk througt all adapters */ + for (i = 0; i < sub_keys; i++) { + char new_key[MAX_KEY_LENGTH]; + char data[256]; + TCHAR key[MAX_KEY_LENGTH]; + DWORD keylen = MAX_KEY_LENGTH; + + /* Get the adapter key name */ + ret = RegEnumKeyEx(adapters, i, key, &keylen, NULL, NULL, NULL, NULL); + if (ret != ERROR_SUCCESS) { + continue; + } + + /* Append it to NETWORK_ADAPTERS and open it */ + snprintf(new_key, sizeof new_key, "%s\\%s", key_name, key); + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, new_key, 0, KEY_READ, &adapter); + if (ret != ERROR_SUCCESS) { + continue; + } + + /* Check its values */ + len = sizeof data; + ret = RegQueryValueEx(adapter, "ComponentId", NULL, NULL, (LPBYTE)data, &len); + if (ret != ERROR_SUCCESS) { + /* This value doesn't exist in this adaptater tree */ + goto clean; + } + /* If its a tap adapter, its all good */ + if (strncmp(data, "tap", 3) == 0) { + DWORD type; + + len = sizeof data; + ret = RegQueryValueEx(adapter, "NetCfgInstanceId", NULL, &type, (LPBYTE)data, &len); + if (ret != ERROR_SUCCESS) { + tuntap_log(TUNTAP_LOG_INFO, (const char *)formated_error(L"%1", ret)); + goto clean; + } + deviceid = strdup(data); + break; + } + clean: + RegCloseKey(adapter); + } + RegCloseKey(adapters); + return deviceid; } void tuntap_sys_destroy(struct device *dev) { - (void)dev; - return; + (void)dev; + return; } int tuntap_start(struct device *dev, int mode, int tun) { - HANDLE tun_fd; - char *deviceid; - char buf[60]; - - /* Don't re-initialise a previously started device */ - if (dev->tun_fd != TUNFD_INVALID_VALUE) { - return -1; - } - - /* Shift the persistence bit */ - if (mode & TUNTAP_MODE_PERSIST) { - mode &= ~TUNTAP_MODE_PERSIST; - } - - if (mode == TUNTAP_MODE_TUNNEL) { - tuntap_log(TUNTAP_LOG_NOTICE, "Layer 3 tunneling is not implemented"); - return -1; - } - else if (mode != TUNTAP_MODE_ETHERNET) { - tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'mode'"); - return -1; - } - - g_olw.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (NULL == g_olw.hEvent) { - return -1; - } - g_olr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (NULL == g_olr.hEvent) { - CloseHandle(g_olw.hEvent); - g_olw.hEvent = NULL; - return -1; - } - - deviceid = reg_query(NETWORK_ADAPTERS); - snprintf(buf, sizeof buf, "\\\\.\\Global\\%s.tap", deviceid); - tun_fd = CreateFile(buf, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); - if (tun_fd == TUNFD_INVALID_VALUE) { - int errcode = GetLastError(); - - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; - } - - dev->tun_fd = tun_fd; - return 0; + HANDLE tun_fd; + char *deviceid; + char buf[60]; + + /* Don't re-initialise a previously started device */ + if (dev->tun_fd != TUNFD_INVALID_VALUE) { + return -1; + } + + /* Shift the persistence bit */ + if (mode & TUNTAP_MODE_PERSIST) { + mode &= ~TUNTAP_MODE_PERSIST; + } + + if (mode == TUNTAP_MODE_TUNNEL) { + tuntap_log(TUNTAP_LOG_NOTICE, "Layer 3 tunneling is not implemented"); + return -1; + } + else if (mode != TUNTAP_MODE_ETHERNET) { + tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'mode'"); + return -1; + } + + g_olw.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (NULL == g_olw.hEvent) { + return -1; + } + g_olr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (NULL == g_olr.hEvent) { + CloseHandle(g_olw.hEvent); + g_olw.hEvent = NULL; + return -1; + } + + deviceid = reg_query(NETWORK_ADAPTERS); + snprintf(buf, sizeof buf, "\\\\.\\Global\\%s.tap", deviceid); + tun_fd = CreateFile(buf, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + if (tun_fd == TUNFD_INVALID_VALUE) { + int errcode = GetLastError(); + + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; + } + + dev->tun_fd = tun_fd; + return 0; } void tuntap_release(struct device *dev) { - (void)CloseHandle(dev->tun_fd); - if (g_olw.hEvent) { - CloseHandle(g_olw.hEvent); - g_olw.hEvent = NULL; - } - if (g_olr.hEvent) { - CloseHandle(g_olr.hEvent); - g_olr.hEvent = NULL; - } - free(dev); + (void)CloseHandle(dev->tun_fd); + if (g_olw.hEvent) { + CloseHandle(g_olw.hEvent); + g_olw.hEvent = NULL; + } + if (g_olr.hEvent) { + CloseHandle(g_olr.hEvent); + g_olr.hEvent = NULL; + } + free(dev); } char * tuntap_get_hwaddr(struct device *dev) { - static unsigned char hwaddr[ETHER_ADDR_LEN]; - DWORD len; - - if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_GET_MAC, &hwaddr, sizeof(hwaddr), &hwaddr, sizeof(hwaddr), &len, NULL) == 0) { - int errcode = GetLastError(); - - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return NULL; - } - else { - char buf[128]; - - (void)_snprintf_s(buf, sizeof buf, sizeof buf, "MAC address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", - hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); - tuntap_log(TUNTAP_LOG_DEBUG, buf); - } - return (char *)hwaddr; + static unsigned char hwaddr[ETHER_ADDR_LEN]; + DWORD len; + + if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_GET_MAC, &hwaddr, sizeof(hwaddr), &hwaddr, sizeof(hwaddr), &len, NULL) == 0) { + int errcode = GetLastError(); + + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return NULL; + } + else { + char buf[128]; + + (void)_snprintf_s(buf, sizeof buf, sizeof buf, "MAC address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); + tuntap_log(TUNTAP_LOG_DEBUG, buf); + } + return (char *)hwaddr; } int tuntap_set_hwaddr(struct device *dev, const char *hwaddr) { - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_hwaddr()"); - return -1; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_hwaddr()"); + return -1; } static int tuntap_sys_set_updown(struct device *dev, ULONG flag) { - DWORD len; + DWORD len; - if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_SET_MEDIA_STATUS, &flag, sizeof(flag), &flag, sizeof(flag), &len, NULL) == 0) { - int errcode = GetLastError(); + if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_SET_MEDIA_STATUS, &flag, sizeof(flag), &flag, sizeof(flag), &len, NULL) == 0) { + int errcode = GetLastError(); - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; - } - else { - char buf[32]; + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; + } + else { + char buf[32]; - (void)_snprintf_s(buf, sizeof buf, sizeof buf, "Status: %s", flag ? "Up" : "Down"); - tuntap_log(TUNTAP_LOG_DEBUG, buf); - return 0; - } + (void)_snprintf_s(buf, sizeof buf, sizeof buf, "Status: %s", flag ? "Up" : "Down"); + tuntap_log(TUNTAP_LOG_DEBUG, buf); + return 0; + } } int tuntap_up(struct device *dev) { - ULONG flag; + ULONG flag; - flag = 1; - return tuntap_sys_set_updown(dev, flag); + flag = 1; + return tuntap_sys_set_updown(dev, flag); } int tuntap_down(struct device *dev) { - ULONG flag; + ULONG flag; - flag = 0; - return tuntap_sys_set_updown(dev, flag); + flag = 0; + return tuntap_sys_set_updown(dev, flag); } int tuntap_get_mtu(struct device *dev) { - ULONG mtu; - DWORD len; + ULONG mtu; + DWORD len; - if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_GET_MTU, &mtu, sizeof(mtu), &mtu, sizeof(mtu), &len, NULL) == 0) { - int errcode = GetLastError(); + if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_GET_MTU, &mtu, sizeof(mtu), &mtu, sizeof(mtu), &len, NULL) == 0) { + int errcode = GetLastError(); - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; - } - return 0; + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; + } + return 0; } int tuntap_set_mtu(struct device *dev, int mtu) { - (void)dev; - (void)mtu; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_mtu()"); - return -1; + (void)dev; + (void)mtu; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_mtu()"); + return -1; } int tuntap_sys_set_ipv4(struct device *dev, t_tun_in_addr *s, uint32_t mask) { - IPADDR psock[4]; - DWORD len; - - /* Address + Netmask */ - psock[0] = s->S_un.S_addr; - psock[1] = mask; - /* DHCP server address (We don't want it) */ - psock[2] = 0; - /* DHCP lease time */ - psock[3] = 0; - - if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_CONFIG_DHCP_MASQ, &psock, sizeof(psock), &psock, sizeof(psock), &len, NULL) == 0) { - int errcode = GetLastError(); - - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); - return -1; - } - return 0; + IPADDR psock[4]; + DWORD len; + + /* Address + Netmask */ + psock[0] = s->S_un.S_addr; + psock[1] = mask; + /* DHCP server address (We don't want it) */ + psock[2] = 0; + /* DHCP lease time in seconds */ + psock[3] = 60 * 5; + + if (DeviceIoControl(dev->tun_fd, TAP_IOCTL_CONFIG_DHCP_MASQ, &psock, sizeof(psock), &psock, sizeof(psock), &len, NULL) == 0) { + int errcode = GetLastError(); + + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; + } + return 0; } int tuntap_sys_set_ipv6(struct device *dev, t_tun_in6_addr *s, uint32_t mask) { - (void)dev; - (void)s; - (void)mask; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_sys_set_ipv6()"); - return -1; + (void)dev; + (void)s; + (void)mask; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_sys_set_ipv6()"); + return -1; } int tuntap_read(struct device *dev, void *buf, size_t size) { - DWORD len; - int ret = 0; - ResetEvent(g_olr.hEvent); - - if (!ReadFile(dev->tun_fd, buf, (DWORD)size, &len, &g_olr)) - { - if (GetLastError() != ERROR_IO_PENDING) { - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); - ret = -1; - } - else - { - switch (WaitForSingleObject(g_olr.hEvent, INFINITE)) - { - case WAIT_OBJECT_0: - if (!GetOverlappedResult(dev->tun_fd, &g_olr, &len, FALSE)) { - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); - ret = -1; - } - else { - ret = 0; //read ok - } - break; - default: - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); - ret = -1; - break; - } - } - } - - if (0 == ret) { - return len; - } - else { - return -1; - } + DWORD len; + int ret = 0; + ResetEvent(g_olr.hEvent); + + if (!ReadFile(dev->tun_fd, buf, (DWORD)size, &len, &g_olr)) + { + if (GetLastError() != ERROR_IO_PENDING) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + } + else + { + switch (WaitForSingleObject(g_olr.hEvent, INFINITE)) + { + case WAIT_OBJECT_0: + if (!GetOverlappedResult(dev->tun_fd, &g_olr, &len, FALSE)) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + } + else { + ret = 0; //read ok + } + break; + default: + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + break; + } + } + } + + if (0 == ret) { + return len; + } + else { + return -1; + } } int tuntap_write(struct device *dev, void *buf, size_t size) { - DWORD len; - int ret = 0; - ResetEvent(g_olw.hEvent); - - if (!WriteFile(dev->tun_fd, buf, (DWORD)size, &len, &g_olw)) - { - if (GetLastError() != ERROR_IO_PENDING) { - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); - ret = -1; - } - else - { - switch (WaitForSingleObject(g_olw.hEvent, INFINITE)) - { - case WAIT_OBJECT_0: - if (!GetOverlappedResult(dev->tun_fd, &g_olw, &len, FALSE)) { - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); - ret = -1; - } - else { - ret = 0; //write ok - } - break; - default: - tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); - ret = -1; - break; - } - } - } - - if (0 == ret) { - return len; - } - else { - return -1; - } + DWORD len; + int ret = 0; + ResetEvent(g_olw.hEvent); + + if (!WriteFile(dev->tun_fd, buf, (DWORD)size, &len, &g_olw)) + { + if (GetLastError() != ERROR_IO_PENDING) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + } + else + { + switch (WaitForSingleObject(g_olw.hEvent, INFINITE)) + { + case WAIT_OBJECT_0: + if (!GetOverlappedResult(dev->tun_fd, &g_olw, &len, FALSE)) { + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + } + else { + ret = 0; //write ok + } + break; + default: + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", GetLastError())); + ret = -1; + break; + } + } + } + + if (0 == ret) { + return len; + } + else { + return -1; + } } int tuntap_get_readable(struct device *dev) { - (void)dev; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_get_readable()"); - return -1; + (void)dev; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_get_readable()"); + return -1; } int tuntap_set_nonblocking(struct device *dev, int set) { - (void)dev; - (void)set; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_nonblocking()"); - return -1; + (void)dev; + (void)set; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_nonblocking()"); + return -1; } int tuntap_set_debug(struct device *dev, int set) { - (void)dev; - (void)set; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_debug()"); - return -1; + (void)dev; + (void)set; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_debug()"); + return -1; } int tuntap_set_descr(struct device *dev, const char *descr) { - (void)dev; - (void)descr; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_descr()"); - return -1; + (void)dev; + (void)descr; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_descr()"); + return -1; } int tuntap_set_ifname(struct device *dev, const char *name) { - /* TODO: Check Windows API to know how to rename an interface */ - (void)dev; - (void)name; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_ifname()"); - return -1; + /* TODO: Check Windows API to know how to rename an interface */ + (void)dev; + (void)name; + tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_set_ifname()"); + return -1; }