From 8ac7d4f6dc3be3192e70538092ad477ea3737be4 Mon Sep 17 00:00:00 2001 From: despair86 Date: Sat, 29 Sep 2018 03:16:54 -0500 Subject: [PATCH] if we didn't specify a path to save our config in, only create .lokinet on the assumption that $HOME or $APPDATA (on NT) already exist add win32 tun glue, fix llarp timebase (In fact, _both_ of these are guaranteed to exist on their respective platforms.) also, tuntap is now wired up to the windows port --- CMakeLists.txt | 22 +- daemon/main.cpp | 33 +- include/llarp/net.hpp | 4 +- include/llarp/service/IntroSet.hpp | 1 + include/tuntap.h | 8 +- llarp/config.cpp | 4 + llarp/ev.hpp | 160 +++--- llarp/ev_win32.hpp | 91 +++- llarp/nodedb.cpp | 2 +- llarp/time.cpp | 28 +- vendor/libtuntap-master/tuntap-windows.c | 600 +++++++++++++---------- vendor/libtuntap-master/tuntap.cpp | 6 + 12 files changed, 580 insertions(+), 379 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bd7b1111..1bb6e7b11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,10 @@ else() set(THREAD_LIB pthread) endif() +# This merely allows the Microsoft C++ compiler +# to substitute AVX opcodes for SSE or i687 opcodes +# in the reference implementation, if it chooses to +# do so in the optimisation pass. if(MSVC) option (BUILD_AVX2 "Enable AVX2 FPU vector instructions." OFF) if (BUILD_AVX2) @@ -97,7 +101,7 @@ set(OPTIMIZE_FLAGS "-O2") set(DEBUG_FLAGS "-Od -ZI") else() set(OPTIMIZE_FLAGS "-O3") -set(DEBUG_FLAGS "-O0 -g") +set(DEBUG_FLAGS "-O0 -g3") endif() if(ASAN) @@ -228,11 +232,12 @@ set(LIBTUNTAP_SRC_BASE ${LIBTUNTAP_IMPL}) if (UNIX) - set(LIBTUNTAP_SRC +set(LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix.c ${LIBTUNTAP_SRC_BASE}) -endif() - +else() +set(LIBTUNTAP_SRC ${LIBTUNTAP_SRC_BASE}) +endif(UNIX) set(CPP_BACKPORT_SRC vendor/cppbackport-master/lib/fs/rename.cpp vendor/cppbackport-master/lib/fs/filestatus.cpp @@ -289,6 +294,14 @@ set(LIB_PLATFORM_SRC contrib/msc/getopt1.c ) +# this is written _entirely_ using +# Unix compiler extensions, normally +# it should not be possible to use +# operators on vector types. +# GCC and Clang do so, and emit the proper +# opcode to perform the specified operation +# to each value in parallel. +if(NOT MSVC) set(NTRU_AVX_SRC crypto/libntrup/src/avx/randomsmall.c crypto/libntrup/src/avx/weight.c @@ -307,6 +320,7 @@ set(NTRU_AVX_SRC crypto/libntrup/src/avx/rq.c crypto/libntrup/src/avx/rq_mod3.c ) +endif(NOT MSVC) set(NTRU_REF_SRC crypto/libntrup/src/ref/randomsmall.c diff --git a/daemon/main.cpp b/daemon/main.cpp index 315302e26..a49fd8887 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -4,7 +4,9 @@ #include #include #include +#ifndef _MSC_VER #include +#endif #include "fs.hpp" #ifdef _WIN32 @@ -28,6 +30,25 @@ printHelp(const char *argv0, int code = 1) return code; } +#ifdef _WIN32 +int +startWinsock() +{ + WSADATA wsockd; + int err; + // We used to defer starting winsock until + // we got to the iocp event loop + // but getaddrinfo(3) requires that winsock be in core already + err = ::WSAStartup(MAKEWORD(2, 2), &wsockd); + if(err) + { + perror("Failed to start Windows Sockets"); + return err; + } + return 0; +} +#endif + int main(int argc, char *argv[]) { @@ -38,6 +59,11 @@ main(int argc, char *argv[]) multiThreaded = false; } +#ifdef _WIN32 + if(startWinsock()) + return -1; +#endif + int opt = 0; bool genconfigOnly = false; while((opt = getopt(argc, argv, "hg")) != -1) @@ -96,7 +122,9 @@ main(int argc, char *argv[]) fs::path fpath = basepath / "lokinet.ini"; std::error_code ec; - if(!fs::create_directories(basepath, ec)) + // These paths are guaranteed to exist - $APPDATA or $HOME + // so only create .lokinet/* + if(!fs::create_directory(basepath, ec)) { if(ec) { @@ -127,5 +155,8 @@ main(int argc, char *argv[]) llarp_main_free(ctx); } exit(code); +#ifdef _WIN32 + ::WSACleanup(); +#endif return code; } diff --git a/include/llarp/net.hpp b/include/llarp/net.hpp index a5ebee322..2bdcbf714 100644 --- a/include/llarp/net.hpp +++ b/include/llarp/net.hpp @@ -439,7 +439,7 @@ namespace llarp isOneSevenPrivate(uint32_t byte) { uint8_t byte1 = byte >> 24 & 0xff; - uint8_t byte2 = (0x00ff0000 & byte >> 16); + uint8_t byte2 = (0x00ff0000 & byte) >> 16; return byte1 == 172 && (byte2 >= 16 || byte2 <= 31); } @@ -447,7 +447,7 @@ namespace llarp isOneNinePrivate(uint32_t byte) { uint8_t byte1 = byte >> 24 & 0xff; - uint8_t byte2 = (0x00ff0000 & byte >> 16); + uint8_t byte2 = (0x00ff0000 & byte) >> 16; return byte1 == 192 && byte2 == 168; } diff --git a/include/llarp/service/IntroSet.hpp b/include/llarp/service/IntroSet.hpp index 6632e0b8c..f6865da0a 100644 --- a/include/llarp/service/IntroSet.hpp +++ b/include/llarp/service/IntroSet.hpp @@ -10,6 +10,7 @@ #include #include +#include namespace llarp { diff --git a/include/tuntap.h b/include/tuntap.h index a2637ecd3..2f0447309 100644 --- a/include/tuntap.h +++ b/include/tuntap.h @@ -92,7 +92,7 @@ typedef struct in6_addr t_tun_in6_addr; * Windows helpers */ #if defined Windows -#define strncat(x, y, z) strncat_s((x), _countof(x), (y), (z)); +//#define strncat(x, y, z) strncat_s((x), _countof(x), (y), (z)); #define strdup(x) _strdup(x) #endif @@ -119,10 +119,12 @@ typedef struct in6_addr t_tun_in6_addr; /* Handle Windows symbols export */ #if defined Windows -#if defined(tuntap_EXPORTS) /* CMake generated goo */ +#if defined(tuntap_EXPORTS) && defined(_USRDLL) /* CMake generated goo */ #define TUNTAP_EXPORT __declspec(dllexport) -#else +#elif defined(tuntap_EXPORTS) #define TUNTAP_EXPORT __declspec(dllimport) +#else +#define TUNTAP_EXPORT extern #endif #else /* Unix */ #define TUNTAP_EXPORT extern diff --git a/llarp/config.cpp b/llarp/config.cpp index 6da883b48..44ca2073a 100644 --- a/llarp/config.cpp +++ b/llarp/config.cpp @@ -102,7 +102,11 @@ extern "C" if(basedir) { basepath = basedir; +#ifndef _WIN32 basepath += "/"; +#else + basepath += "\\"; +#endif } std::ofstream f(fname); diff --git a/llarp/ev.hpp b/llarp/ev.hpp index eaf19ed9d..dbabc3849 100644 --- a/llarp/ev.hpp +++ b/llarp/ev.hpp @@ -45,94 +45,100 @@ namespace llarp virtual bool do_write(void* data, size_t sz) { - return write(fd, data, sz) != -1; - } - - /// called in event loop when fd is ready for writing - /// requeues anything not written - /// this assumes fd is set to non blocking - virtual void - flush_write() - { - m_writeq.Process([&](WriteBuffer& buffer) { - // todo: wtf??? #ifndef _WIN32 - do_write(buffer.buf, buffer.bufsz); - // if we would block we save the entries for later - - // discard entry + return write(fd, data, sz) != -1; #else - // writefile +return WriteFile((void*)fd, data, sz, nullptr, nullptr); +#endif +} +/// called in event loop when fd is ready for writing +/// requeues anything not written +/// this assumes fd is set to non blocking +virtual void +flush_write() +{ + m_writeq.Process([&](WriteBuffer& buffer) { + // todo: wtf??? +#ifndef _WIN32 + do_write(buffer.buf, buffer.bufsz); + // if we would block we save the entries for later + // discard entry +#else + WriteFile((void*)fd, buffer.buf, buffer.bufsz, nullptr, nullptr); +#endif + }); + /// reset errno + errno = 0; +#if _WIN32 + SetLastError(0); #endif - }); - /// reset errno - errno = 0; +} + +struct WriteBuffer +{ + llarp_time_t timestamp = 0; + size_t bufsz; + byte_t buf[1500]; + + WriteBuffer() = default; + + WriteBuffer(const void* ptr, size_t sz) + { + if(sz <= sizeof(buf)) + { + bufsz = sz; + memcpy(buf, ptr, bufsz); } + else + bufsz = 0; + } - struct WriteBuffer + struct GetTime + { + llarp_time_t + operator()(const WriteBuffer& w) const { - llarp_time_t timestamp = 0; - size_t bufsz; - byte_t buf[1500]; - - WriteBuffer() = default; - - WriteBuffer(const void* ptr, size_t sz) - { - if(sz <= sizeof(buf)) - { - bufsz = sz; - memcpy(buf, ptr, bufsz); - } - else - bufsz = 0; - } - - struct GetTime - { - llarp_time_t - operator()(const WriteBuffer& w) const - { - return w.timestamp; - } - }; - - struct PutTime - { - void - operator()(WriteBuffer& w) const - { - w.timestamp = llarp_time_now_ms(); - } - }; - - struct Compare - { - bool - operator()(const WriteBuffer& left, const WriteBuffer& right) const - { - return left.timestamp < right.timestamp; - } - }; - }; - - llarp::util::CoDelQueue< WriteBuffer, WriteBuffer::GetTime, - WriteBuffer::PutTime, WriteBuffer::Compare, - llarp::util::NullMutex, llarp::util::NullLock > - m_writeq; - - virtual ~ev_io() + return w.timestamp; + } + }; + + struct PutTime + { + void + operator()(WriteBuffer& w) const { + w.timestamp = llarp_time_now_ms(); + } + }; + + struct Compare + { + bool + operator()(const WriteBuffer& left, const WriteBuffer& right) const + { + return left.timestamp < right.timestamp; + } + }; +}; + +llarp::util::CoDelQueue< WriteBuffer, WriteBuffer::GetTime, + WriteBuffer::PutTime, WriteBuffer::Compare, + llarp::util::NullMutex, llarp::util::NullLock > + m_writeq; + +virtual ~ev_io() +{ #ifndef _WIN32 - ::close(fd); + ::close(fd); #else - closesocket(fd); + closesocket(fd); #endif - }; - }; - -}; // namespace llarp +}; +} +; +} +; // namespace llarp struct llarp_ev_loop { diff --git a/llarp/ev_win32.hpp b/llarp/ev_win32.hpp index d61e4f2a4..993485830 100644 --- a/llarp/ev_win32.hpp +++ b/llarp/ev_win32.hpp @@ -85,6 +85,81 @@ namespace llarp return 0; } }; + + struct tun : public ev_io + { + llarp_tun_io* t; + device* tunif; + tun(llarp_tun_io* tio) + : ev_io(-1) + , t(tio) + , tunif(tuntap_init()) + + { + + }; + + int + sendto(const sockaddr* to, const void* data, size_t sz) + { + return -1; + } + + void + flush_write() + { + if(t->before_write) + { + t->before_write(t); + } + ev_io::flush_write(); + } + + int + read(void* buf, size_t sz) + { + ssize_t ret = tuntap_read(tunif, buf, sz); + if(ret > 0 && t->recvpkt) + { + t->recvpkt(t, buf, ret); + } + return ret; + } + + bool + setup() + { + llarp::LogDebug("set ifname to ", t->ifname); + strncpy(tunif->if_name, t->ifname, sizeof(tunif->if_name)); + + if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, 0) == -1) + { + llarp::LogWarn("failed to start interface"); + return false; + } + if(tuntap_up(tunif) == -1) + { + llarp::LogWarn("failed to put interface up: ", strerror(errno)); + return false; + } + if(tuntap_set_ip(tunif, t->ifaddr, t->ifaddr, t->netmask) == -1) + { + llarp::LogWarn("failed to set ip"); + return false; + } + fd = (SOCKET)tunif->tun_fd; + if(fd == -1) + return false; + + // set non blocking + int on = 1; + return ioctlsocket(fd, FIONBIO, (u_long*)&on) != -1; + } + + ~tun() + { + } + }; }; // namespace llarp struct llarp_win32_loop : public llarp_ev_loop @@ -93,22 +168,13 @@ struct llarp_win32_loop : public llarp_ev_loop llarp_win32_loop() : iocpfd(INVALID_HANDLE_VALUE) { - WSADATA wsockd; - int err; - // So, what I was told last time was that we can defer - // loading winsock2 up to this point, as we reach this ctor - // early on during daemon startup. - err = ::WSAStartup(MAKEWORD(2, 2), &wsockd); - if(err) - perror("Failed to start Windows Sockets"); + } ~llarp_win32_loop() { if(iocpfd != INVALID_HANDLE_VALUE) ::CloseHandle(iocpfd); - - ::WSACleanup(); } bool @@ -287,7 +353,10 @@ struct llarp_win32_loop : public llarp_ev_loop llarp::ev_io* create_tun(llarp_tun_io* tun) { - // TODO implement me + llarp::tun* t = new llarp::tun(tun); + if(t->setup()) + return t; + delete t; return nullptr; } diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 885bc5f40..fe56da241 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -313,7 +313,7 @@ llarp_nodedb_ensure_dir(const char *dir) std::error_code ec; if(!fs::exists(dir, ec)) - fs::create_directories(path, ec); + fs::create_directory(path, ec); if(ec) return false; diff --git a/llarp/time.cpp b/llarp/time.cpp index 4cd814667..300db04e0 100644 --- a/llarp/time.cpp +++ b/llarp/time.cpp @@ -1,28 +1,22 @@ #include -#include - -namespace llarp -{ - typedef std::chrono::system_clock clock_t; - - template < typename Res, typename IntType > - static IntType - time_since_epoch() - { - return std::chrono::duration_cast< Res >( - llarp::clock_t::now().time_since_epoch()) - .count(); - } -} // namespace llarp +#include +// these _should_ be 32-bit safe... llarp_time_t llarp_time_now_ms() { - return llarp::time_since_epoch< std::chrono::milliseconds, llarp_time_t >(); + struct timeval tv; + gettimeofday(&tv, nullptr); + llarp_time_t timeNow = + (llarp_time_t)(tv.tv_sec) * 1000 + (llarp_time_t)(tv.tv_usec) / 1000; + return timeNow; } llarp_seconds_t llarp_time_now_sec() { - return llarp::time_since_epoch< std::chrono::seconds, llarp_seconds_t >(); + struct timeval tv; + gettimeofday(&tv, nullptr); + llarp_time_t timeNow = tv.tv_sec; + return timeNow; } diff --git a/vendor/libtuntap-master/tuntap-windows.c b/vendor/libtuntap-master/tuntap-windows.c index 7161afda0..7b65a9b92 100644 --- a/vendor/libtuntap-master/tuntap-windows.c +++ b/vendor/libtuntap-master/tuntap-windows.c @@ -22,352 +22,426 @@ #include #include #include - #include "tuntap.h" +// DDK macros +#define CTL_CODE(DeviceType, Function, Method, Access) \ + (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_ANY_ACCESS 0x00000000 +#define METHOD_BUFFERED 0 + /* 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) -#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) -#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) -#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) -#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE (10, METHOD_BUFFERED) +#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) +#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE(3, METHOD_BUFFERED) +#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE(4, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE(5, METHOD_BUFFERED) +#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE(6, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE(7, METHOD_BUFFERED) +#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE(8, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE(9, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE(10, METHOD_BUFFERED) /* Windows registry crap */ #define MAX_KEY_LENGTH 255 #define MAX_VALUE_NAME 16383 -#define NETWORK_ADAPTERS "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define NETWORK_ADAPTERS \ + "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-" \ + "08002BE10318}" +#define ETHER_ADDR_LEN 6 /* From OpenVPN tap driver, proto.h */ typedef unsigned long IPADDR; /* This one is from Fabien Pichot, in the tNETacle source code */ static LPWSTR -formated_error(LPWSTR pMessage, DWORD m, ...) { - LPWSTR pBuffer = NULL; +formated_error(LPWSTR pMessage, DWORD m, ...) +{ + 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) */ +/* 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 */ - 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; +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 */ + 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; } void -tuntap_sys_destroy(struct device *dev) { - (void)dev; - return; +tuntap_sys_destroy(struct device *dev) +{ + (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; +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; } void -tuntap_release(struct device *dev) { - (void)CloseHandle(dev->tun_fd); - free(dev); +tuntap_release(struct device *dev) +{ + (void)CloseHandle(dev->tun_fd); + 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; +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; } 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_set_hwaddr(struct device *dev, const char *hwaddr) +{ + 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; - - 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]; - - (void)_snprintf_s(buf, sizeof buf, sizeof buf, "Status: %s", flag ? "Up" : "Down"); - tuntap_log(TUNTAP_LOG_DEBUG, buf); - return 0; - } +tuntap_sys_set_updown(struct device *dev, ULONG flag) +{ + DWORD len; + + 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]; + + (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; +tuntap_up(struct device *dev) +{ + 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; +tuntap_down(struct device *dev) +{ + 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; - - 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_get_mtu(struct device *dev) +{ + 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(); + + 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; +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; } 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; +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; } 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; +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; } int -tuntap_read(struct device *dev, void *buf, size_t size) { - DWORD len; +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(); + 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; - } + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; + } - return 0; + return 0; } int -tuntap_write(struct device *dev, void *buf, size_t size) { - DWORD len; +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(); + 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; - } + tuntap_log(TUNTAP_LOG_ERR, (const char *)formated_error(L"%1%0", errcode)); + return -1; + } - return 0; + return 0; } int -tuntap_get_readable(struct device *dev) { - (void)dev; - tuntap_log(TUNTAP_LOG_NOTICE, "Your system does not support tuntap_get_readable()"); - return -1; +tuntap_get_readable(struct device *dev) +{ + (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; +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; } 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; +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; } 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; +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; } 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; +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; } diff --git a/vendor/libtuntap-master/tuntap.cpp b/vendor/libtuntap-master/tuntap.cpp index 06b1271bf..e821714a1 100644 --- a/vendor/libtuntap-master/tuntap.cpp +++ b/vendor/libtuntap-master/tuntap.cpp @@ -31,6 +31,12 @@ #include #include #include +#ifndef _MSC_VER +extern "C" int +inet_pton(int af, const char *src, void *dst); +extern "C" const char * +inet_ntop(int af, const void *src, char *dst, size_t size); +#endif #else #include #include