mirror of https://github.com/oxen-io/lokinet
Merge remote-tracking branch 'rick/dev' into dev
This commit is contained in:
commit
e91d7cf88f
|
@ -7,6 +7,7 @@ project(${PROJECT_NAME} C CXX ASM)
|
|||
option(USE_LIBABYSS "enable libabyss" )
|
||||
option(USE_CXX17 "enable c++17 features" )
|
||||
option(USE_AVX2 "enable avx2 code" )
|
||||
|
||||
# Require C++11
|
||||
# or C++17 on win32
|
||||
if (NOT WIN32)
|
||||
|
@ -35,18 +36,10 @@ add_compile_options(-Wvla)
|
|||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fpermissive>)
|
||||
add_compile_options(-Wno-unused-function -Wno-deprecated-declarations -Wno-unknown-pragmas)
|
||||
|
||||
if (WOW64_CROSS_COMPILE OR WIN64_CROSS_COMPILE)
|
||||
# dynamic linking does this all the time
|
||||
if(CMAKE_HOST_WIN32)
|
||||
add_compile_options(-Wno-cast-function-type)
|
||||
endif()
|
||||
if (USING_CLANG)
|
||||
add_compile_options(-Wno-unused-command-line-argument -Wno-c++11-narrowing)
|
||||
# because clang is insane enough to inline whole sections of the C++ library!
|
||||
# May have been fixed in llvm-7.
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-multiple-definition --rtlib=libgcc")
|
||||
endif(USING_CLANG)
|
||||
endif()
|
||||
if(WIN32)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-bad-function-cast>)
|
||||
set(FS_LIB stdc++fs)
|
||||
endif(WIN32)
|
||||
|
||||
if(DEBIAN)
|
||||
add_definitions(-DDEBIAN)
|
||||
|
@ -107,16 +100,15 @@ if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
|
|||
endif()
|
||||
|
||||
if(NOT ANDROID)
|
||||
if (USE_AVX2)
|
||||
set(CRYPTO_FLAGS -march=native)
|
||||
set(CMAKE_ASM_FLAGS "-march=native ${CMAKE_ASM_FLAGS} $ENV{ASFLAGS}")
|
||||
if (NOT USE_AVX2)
|
||||
set(CRYPTO_FLAGS -march=core2 -mtune=native)
|
||||
set(CMAKE_ASM_FLAGS "-march=core2")
|
||||
else()
|
||||
if(WIN32)
|
||||
set(CRYPTO_FLAGS -march=core2)
|
||||
set(CMAKE_ASM_FLAGS "-march=core2 ${CMAKE_ASM_FLAGS} $ENV{ASFLAGS}")
|
||||
endif()
|
||||
set(CRYPTO_FLAGS -march=haswell -mtune=native)
|
||||
set(CMAKE_ASM_FLAGS "-march=haswell -mtune=native ${CMAKE_ASM_FLAGS} $ENV{ASFLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(RPI)
|
||||
add_definitions(-DRPI)
|
||||
set(WITH_STATIC ON)
|
||||
|
@ -149,10 +141,6 @@ if(JEMALLOC)
|
|||
set(MALLOC_LIB jemalloc)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(FS_LIB stdc++fs)
|
||||
endif(WIN32)
|
||||
|
||||
# FS_LIB should resolve to nothing on all other platforms
|
||||
# it is only required on win32 -rick
|
||||
set(LIBS Threads::Threads ${MALLOC_LIB} ${FS_LIB})
|
||||
|
@ -273,9 +261,6 @@ set(LIB_PLATFORM_SRC
|
|||
${ISOLATE_PROC_SRC}
|
||||
# tun
|
||||
${LIBTUNTAP_SRC}
|
||||
# win32 inline code
|
||||
llarp/win32_inet.c
|
||||
llarp/win32_intrnl.c
|
||||
# c++17 compat code
|
||||
${CXX_COMPAT_SRC}
|
||||
)
|
||||
|
|
|
@ -23,7 +23,12 @@
|
|||
#include <tmmintrin.h>
|
||||
|
||||
#ifndef __amd64__
|
||||
#ifdef __clang__
|
||||
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sse2")))
|
||||
#else
|
||||
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __target__("sse2")))
|
||||
#endif
|
||||
|
||||
static __inline__ __m128i __DEFAULT_FN_ATTRS
|
||||
_mm_cvtsi64_si128(long long __a)
|
||||
{
|
||||
|
|
|
@ -23,7 +23,12 @@
|
|||
#include <tmmintrin.h>
|
||||
|
||||
#ifndef __amd64__
|
||||
#ifdef __clang__
|
||||
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sse2")))
|
||||
#else
|
||||
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __target__("sse2")))
|
||||
#endif
|
||||
|
||||
static __inline__ __m128i __DEFAULT_FN_ATTRS
|
||||
_mm_cvtsi64_si128(long long __a)
|
||||
{
|
||||
|
|
|
@ -221,7 +221,12 @@ main(int argc, char *argv[])
|
|||
struct sockaddr_in m_address;
|
||||
int m_sockfd;
|
||||
|
||||
m_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
#ifndef _WIN32
|
||||
m_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
#else
|
||||
m_sockfd =
|
||||
WSASocket(AF_INET, SOCK_DGRAM, 0, nullptr, 0, WSA_FLAG_OVERLAPPED);
|
||||
#endif
|
||||
m_address.sin_family = AF_INET;
|
||||
m_address.sin_addr.s_addr = INADDR_ANY;
|
||||
m_address.sin_port = htons(server_port);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#ifndef ssize_t
|
||||
#define ssize_t long
|
||||
#endif
|
||||
|
|
|
@ -3,21 +3,6 @@
|
|||
#if defined(_WIN32) || defined(__MINGW32__)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
// because this shit is not defined for Windows NT reeeee
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#if _WIN32_WINNT < 0x600
|
||||
const char*
|
||||
inet_ntop(int af, const void* src, char* dst, size_t size);
|
||||
int
|
||||
inet_pton(int af, const char* src, void* dst);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
typedef unsigned short in_port_t;
|
||||
typedef unsigned int in_addr_t;
|
||||
#else
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#define inet_aton(x, y) inet_pton(AF_INET, x, y)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -25,23 +25,8 @@
|
|||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#include "libutp_inet_ntop.h"
|
||||
|
||||
// we already have our own definition of these
|
||||
// -despair
|
||||
#ifndef inet_ntop
|
||||
namespace
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
int
|
||||
inet_pton(int af, const char *src, void *dst);
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
//######################################################################
|
||||
const char *
|
||||
libutp::inet_ntop(int af, const void *src, char *dest, size_t length)
|
||||
|
|
|
@ -603,7 +603,7 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp,
|
|||
llarp::LogDebug("Header got client responses for id: ", hdr->id);
|
||||
|
||||
// if we sent this out, then there's an id
|
||||
struct dns_tracker *tracker = (struct dns_tracker *)udp->user;
|
||||
struct dns_tracker *tracker = (struct dns_tracker *)udp->user;
|
||||
struct dnsc_answer_request *request = tracker->client_request[hdr->id].get();
|
||||
|
||||
// sometimes we'll get double responses
|
||||
|
@ -694,7 +694,7 @@ void
|
|||
llarp_host_resolved(dnsc_answer_request *const request)
|
||||
{
|
||||
dns_tracker *tracker = (dns_tracker *)request->context->tracker;
|
||||
auto val = std::find_if(
|
||||
auto val = std::find_if(
|
||||
tracker->client_request.begin(), tracker->client_request.end(),
|
||||
[request](
|
||||
std::pair< const uint32_t, std::unique_ptr< dnsc_answer_request > >
|
||||
|
@ -735,7 +735,7 @@ llarp_dnsc_init(struct dnsc_context *const dnsc,
|
|||
llarp::LogInfo("DNSc adding relay ", dnsc_sockaddr);
|
||||
dnsc->resolvers.push_back(dnsc_sockaddr);
|
||||
dnsc->tracker = &dns_udp_tracker;
|
||||
dnsc->logic = logic;
|
||||
dnsc->logic = logic;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
12
llarp/ev.hpp
12
llarp/ev.hpp
|
@ -141,20 +141,13 @@ namespace llarp
|
|||
virtual ssize_t
|
||||
do_write(void* data, size_t sz)
|
||||
{
|
||||
DWORD w;
|
||||
//DWORD w;
|
||||
if(std::holds_alternative< HANDLE >(fd))
|
||||
{
|
||||
WriteFile(std::get< HANDLE >(fd), data, sz, nullptr, &portfd[1]);
|
||||
GetOverlappedResult(std::get< HANDLE >(fd), &portfd[1], &w, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteFile((HANDLE)std::get< SOCKET >(fd), data, sz, nullptr,
|
||||
&portfd[1]);
|
||||
GetOverlappedResult((HANDLE)std::get< SOCKET >(fd), &portfd[1], &w,
|
||||
TRUE);
|
||||
}
|
||||
return w;
|
||||
return sz;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -246,6 +239,7 @@ namespace llarp
|
|||
}
|
||||
/// reset errno
|
||||
errno = 0;
|
||||
SetLastError(0);
|
||||
}
|
||||
|
||||
std::unique_ptr< LossyWriteQueue_t > m_LossyWriteQueue;
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include "ev.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#ifdef sizeof
|
||||
#undef sizeof
|
||||
#endif
|
||||
|
||||
// TODO: convert all socket errno calls to WSAGetLastError(3),
|
||||
// don't think winsock sets regular errno to this day
|
||||
namespace llarp
|
||||
|
@ -62,7 +66,7 @@ namespace llarp
|
|||
{
|
||||
socklen_t slen = sizeof(sockaddr_in);
|
||||
if(_addr.ss_family == AF_UNIX)
|
||||
slen = sizeof(sockaddr_un);
|
||||
slen = 115;
|
||||
else if(_addr.ss_family == AF_INET6)
|
||||
slen = sizeof(sockaddr_in6);
|
||||
int result =
|
||||
|
@ -132,13 +136,14 @@ namespace llarp
|
|||
virtual int
|
||||
read(void* buf, size_t sz)
|
||||
{
|
||||
printf("read\n");
|
||||
sockaddr_in6 src;
|
||||
socklen_t slen = sizeof(src);
|
||||
sockaddr* addr = (sockaddr*)&src;
|
||||
unsigned long flags = 0;
|
||||
WSABUF wbuf = {(u_long)sz, static_cast< char* >(buf)};
|
||||
// WSARecvFrom
|
||||
llarp::LogDebug("read ", sz, " bytes into socket");
|
||||
llarp::LogDebug("read ", sz, " bytes from socket");
|
||||
int ret = ::WSARecvFrom(std::get< SOCKET >(fd), &wbuf, 1, nullptr, &flags,
|
||||
addr, &slen, &portfd[0], nullptr);
|
||||
// 997 is the error code for queued ops
|
||||
|
@ -155,6 +160,7 @@ namespace llarp
|
|||
virtual int
|
||||
sendto(const sockaddr* to, const void* data, size_t sz)
|
||||
{
|
||||
printf("sendto\n");
|
||||
socklen_t slen;
|
||||
WSABUF wbuf = {(u_long)sz, (char*)data};
|
||||
switch(to->sa_family)
|
||||
|
@ -289,16 +295,10 @@ struct llarp_win32_loop : public llarp_ev_loop
|
|||
tcp_connect(struct llarp_tcp_connecter* tcp, const sockaddr* remoteaddr)
|
||||
{
|
||||
// create socket
|
||||
DWORD on = 1;
|
||||
SOCKET fd = ::socket(remoteaddr->sa_family, SOCK_STREAM, 0);
|
||||
SOCKET fd = WSASocket(remoteaddr->sa_family, SOCK_STREAM, 0, nullptr, 0,
|
||||
WSA_FLAG_OVERLAPPED);
|
||||
if(fd == INVALID_SOCKET)
|
||||
return false;
|
||||
// set non blocking
|
||||
if(ioctlsocket(fd, FIONBIO, &on) == SOCKET_ERROR)
|
||||
{
|
||||
::closesocket(fd);
|
||||
return false;
|
||||
}
|
||||
llarp::tcp_conn* conn = new llarp::tcp_conn(this, fd, remoteaddr, tcp);
|
||||
add_ev(conn, true);
|
||||
conn->connect();
|
||||
|
@ -315,8 +315,8 @@ struct llarp_win32_loop : public llarp_ev_loop
|
|||
llarp::ev_io*
|
||||
bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr)
|
||||
{
|
||||
DWORD on = 1;
|
||||
SOCKET fd = ::socket(bindaddr->sa_family, SOCK_STREAM, 0);
|
||||
SOCKET fd = WSASocket(bindaddr->sa_family, SOCK_STREAM, 0, nullptr, 0,
|
||||
WSA_FLAG_OVERLAPPED);
|
||||
if(fd == INVALID_SOCKET)
|
||||
return nullptr;
|
||||
socklen_t sz = sizeof(sockaddr_in);
|
||||
|
@ -345,7 +345,6 @@ struct llarp_win32_loop : public llarp_ev_loop
|
|||
llarp::ev_io* serv = new llarp::tcp_serv(this, fd, tcp);
|
||||
tcp->impl = serv;
|
||||
|
||||
ioctlsocket(fd, FIONBIO, &on);
|
||||
return serv;
|
||||
}
|
||||
|
||||
|
@ -366,27 +365,31 @@ struct llarp_win32_loop : public llarp_ev_loop
|
|||
tick(int ms)
|
||||
{
|
||||
OVERLAPPED_ENTRY events[1024];
|
||||
ULONG numEvents = 0;
|
||||
if(::GetQueuedCompletionStatusEx(iocpfd, events, 1024, &numEvents, ms,
|
||||
false))
|
||||
memset(&events, 0, sizeof(OVERLAPPED_ENTRY) * 1024);
|
||||
ULONG result = 0;
|
||||
::GetQueuedCompletionStatusEx(iocpfd, events, 1024, &result, ms, false);
|
||||
ULONG idx = 0;
|
||||
while(idx < result)
|
||||
{
|
||||
for(ULONG idx = 0; idx < numEvents; ++idx)
|
||||
llarp::ev_io* ev =
|
||||
reinterpret_cast< llarp::ev_io* >(events[idx].lpCompletionKey);
|
||||
if(ev && events[idx].lpOverlapped)
|
||||
{
|
||||
llarp::ev_io* ev =
|
||||
reinterpret_cast< llarp::ev_io* >(events[idx].lpCompletionKey);
|
||||
if(ev)
|
||||
auto amount =
|
||||
std::min(EV_READ_BUF_SZ, events[idx].dwNumberOfBytesTransferred);
|
||||
if(ev->write)
|
||||
ev->flush_write_buffers(amount);
|
||||
else
|
||||
{
|
||||
if(ev->write)
|
||||
ev->flush_write();
|
||||
auto amount =
|
||||
std::min(EV_READ_BUF_SZ, events[idx].dwNumberOfBytesTransferred);
|
||||
memcpy(readbuf, events[idx].lpOverlapped->Pointer, amount);
|
||||
ev->read(readbuf, amount);
|
||||
}
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
tick_listeners();
|
||||
return 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ok apparently this isn't being used yet...
|
||||
|
@ -444,8 +447,8 @@ struct llarp_win32_loop : public llarp_ev_loop
|
|||
default:
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
DWORD on = 1;
|
||||
SOCKET fd = ::socket(addr->sa_family, SOCK_DGRAM, 0);
|
||||
SOCKET fd = WSASocket(addr->sa_family, SOCK_DGRAM, 0, nullptr, 0,
|
||||
WSA_FLAG_OVERLAPPED);
|
||||
if(fd == INVALID_SOCKET)
|
||||
{
|
||||
perror("WSASocket()");
|
||||
|
@ -475,7 +478,6 @@ struct llarp_win32_loop : public llarp_ev_loop
|
|||
return INVALID_SOCKET;
|
||||
}
|
||||
llarp::LogDebug("socket fd is ", fd);
|
||||
ioctlsocket(fd, FIONBIO, &on);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -630,4 +632,4 @@ struct llarp_win32_loop : public llarp_ev_loop
|
|||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -17,7 +17,6 @@
|
|||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#endif
|
||||
|
||||
namespace llarp
|
||||
|
|
183
llarp/net.cpp
183
llarp/net.cpp
|
@ -68,25 +68,8 @@ operator==(const sockaddr_in6& a, const sockaddr_in6& b)
|
|||
#include <iphlpapi.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
// current strategy: mingw 32-bit builds call an inlined version of the function
|
||||
// microsoft c++ and mingw 64-bit builds call the normal function
|
||||
#define DEFAULT_BUFFER_SIZE 15000
|
||||
|
||||
// the inline monkey patch for downlevel platforms
|
||||
#ifndef _MSC_VER
|
||||
extern "C" DWORD FAR PASCAL
|
||||
_GetAdaptersAddresses(ULONG Family, ULONG Flags, PVOID Reserved,
|
||||
PIP_ADAPTER_ADDRESSES pAdapterAddresses,
|
||||
PULONG pOutBufLen);
|
||||
#endif
|
||||
|
||||
// in any case, we still need to implement some form of
|
||||
// getifaddrs(3) with compatible semantics on NT...
|
||||
// daemon.ini section [bind] will have something like
|
||||
// [bind]
|
||||
// Ethernet=1090
|
||||
// inside, since that's what we use in windows to refer to
|
||||
// network interfaces
|
||||
struct llarp_nt_ifaddrs_t
|
||||
{
|
||||
struct llarp_nt_ifaddrs_t* ifa_next; /* Pointer to the next structure. */
|
||||
|
@ -140,148 +123,6 @@ llarp_nt_sockaddr_pton(const char* src, struct sockaddr* dst)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* NB: IP_ADAPTER_INFO size varies size due to sizeof (time_t), the API assumes
|
||||
* 4-byte datatype whilst compiler uses an 8-byte datatype. Size can be forced
|
||||
* with -D_USE_32BIT_TIME_T with side effects to everything else.
|
||||
*
|
||||
* Only supports IPv4 addressing similar to SIOCGIFCONF socket option.
|
||||
*
|
||||
* Interfaces that are not "operationally up" will return the address 0.0.0.0,
|
||||
* this includes adapters with static IP addresses but with disconnected cable.
|
||||
* This is documented under the GetIpAddrTable API. Interface status can only
|
||||
* be determined by the address, a separate flag is introduced with the
|
||||
* GetAdapterAddresses API.
|
||||
*
|
||||
* The IPv4 loopback interface is not included.
|
||||
*
|
||||
* Available in Windows 2000 and Wine 1.0.
|
||||
*/
|
||||
static bool
|
||||
_llarp_nt_getadaptersinfo(struct llarp_nt_ifaddrs_t** ifap)
|
||||
{
|
||||
DWORD dwRet;
|
||||
ULONG ulOutBufLen = DEFAULT_BUFFER_SIZE;
|
||||
PIP_ADAPTER_INFO pAdapterInfo = nullptr;
|
||||
PIP_ADAPTER_INFO pAdapter = nullptr;
|
||||
|
||||
/* loop to handle interfaces coming online causing a buffer overflow
|
||||
* between first call to list buffer length and second call to enumerate.
|
||||
*/
|
||||
for(unsigned i = 3; i; i--)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "IP_ADAPTER_INFO buffer length %lu bytes.\n", ulOutBufLen);
|
||||
#endif
|
||||
pAdapterInfo = (IP_ADAPTER_INFO*)_llarp_nt_heap_alloc(ulOutBufLen);
|
||||
dwRet = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
|
||||
if(ERROR_BUFFER_OVERFLOW == dwRet)
|
||||
{
|
||||
_llarp_nt_heap_free(pAdapterInfo);
|
||||
pAdapterInfo = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(dwRet)
|
||||
{
|
||||
case ERROR_SUCCESS: /* NO_ERROR */
|
||||
break;
|
||||
case ERROR_BUFFER_OVERFLOW:
|
||||
errno = ENOBUFS;
|
||||
if(pAdapterInfo)
|
||||
_llarp_nt_heap_free(pAdapterInfo);
|
||||
return false;
|
||||
default:
|
||||
errno = dwRet;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "system call failed: %lu\n", GetLastError());
|
||||
#endif
|
||||
if(pAdapterInfo)
|
||||
_llarp_nt_heap_free(pAdapterInfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* count valid adapters */
|
||||
int n = 0, k = 0;
|
||||
for(pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next)
|
||||
{
|
||||
for(IP_ADDR_STRING* pIPAddr = &pAdapter->IpAddressList; pIPAddr;
|
||||
pIPAddr = pIPAddr->Next)
|
||||
{
|
||||
/* skip null adapters */
|
||||
if(strlen(pIPAddr->IpAddress.String) == 0)
|
||||
continue;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "GetAdaptersInfo() discovered %d interfaces.\n", n);
|
||||
#endif
|
||||
|
||||
/* contiguous block for adapter list */
|
||||
struct _llarp_nt_ifaddrs_t* ifa =
|
||||
llarp_nt_new0(struct _llarp_nt_ifaddrs_t, n);
|
||||
struct _llarp_nt_ifaddrs_t* ift = ifa;
|
||||
|
||||
/* now populate list */
|
||||
for(pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next)
|
||||
{
|
||||
for(IP_ADDR_STRING* pIPAddr = &pAdapter->IpAddressList; pIPAddr;
|
||||
pIPAddr = pIPAddr->Next)
|
||||
{
|
||||
/* skip null adapters */
|
||||
if(strlen(pIPAddr->IpAddress.String) == 0)
|
||||
continue;
|
||||
|
||||
/* address */
|
||||
ift->_ifa.ifa_addr = (struct sockaddr*)&ift->_addr;
|
||||
assert(1
|
||||
== llarp_nt_sockaddr_pton(pIPAddr->IpAddress.String,
|
||||
ift->_ifa.ifa_addr));
|
||||
|
||||
/* name */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "name:%s IPv4 index:%lu\n", pAdapter->AdapterName,
|
||||
pAdapter->Index);
|
||||
#endif
|
||||
ift->_ifa.ifa_name = ift->_name;
|
||||
StringCchCopyN(ift->_ifa.ifa_name, 128, pAdapter->AdapterName, 128);
|
||||
|
||||
/* flags: assume up, broadcast and multicast */
|
||||
ift->_ifa.ifa_flags = IFF_UP | IFF_BROADCAST | IFF_MULTICAST;
|
||||
if(pAdapter->Type == MIB_IF_TYPE_LOOPBACK)
|
||||
ift->_ifa.ifa_flags |= IFF_LOOPBACK;
|
||||
|
||||
/* netmask */
|
||||
ift->_ifa.ifa_netmask = (sockaddr*)&ift->_netmask;
|
||||
assert(1
|
||||
== llarp_nt_sockaddr_pton(pIPAddr->IpMask.String,
|
||||
ift->_ifa.ifa_netmask));
|
||||
|
||||
/* next */
|
||||
if(k++ < (n - 1))
|
||||
{
|
||||
ift->_ifa.ifa_next = (struct llarp_nt_ifaddrs_t*)(ift + 1);
|
||||
ift = (struct _llarp_nt_ifaddrs_t*)(ift->_ifa.ifa_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
ift->_ifa.ifa_next = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pAdapterInfo)
|
||||
_llarp_nt_heap_free(pAdapterInfo);
|
||||
*ifap = (struct llarp_nt_ifaddrs_t*)ifa;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Supports both IPv4 and IPv6 addressing. The size of IP_ADAPTER_ADDRESSES
|
||||
* changes between Windows XP, XP SP1, and Vista with additional members.
|
||||
*
|
||||
|
@ -295,9 +136,6 @@ _llarp_nt_getadaptersinfo(struct llarp_nt_ifaddrs_t** ifap)
|
|||
* and lower layer down.
|
||||
*
|
||||
* Available in Windows XP and Wine 1.3.
|
||||
*
|
||||
* NOTE(despair): an inline implementation is provided, much like
|
||||
* getaddrinfo(3) for old hosts. See "win32_intrnl.*"
|
||||
*/
|
||||
static bool
|
||||
_llarp_nt_getadaptersaddresses(struct llarp_nt_ifaddrs_t** ifap)
|
||||
|
@ -314,7 +152,7 @@ _llarp_nt_getadaptersaddresses(struct llarp_nt_ifaddrs_t** ifap)
|
|||
fprintf(stderr, "IP_ADAPTER_ADDRESSES buffer length %lu bytes.\n", dwSize);
|
||||
#endif
|
||||
pAdapterAddresses = (IP_ADAPTER_ADDRESSES*)_llarp_nt_heap_alloc(dwSize);
|
||||
dwRet = _GetAdaptersAddresses(
|
||||
dwRet = GetAdaptersAddresses(
|
||||
AF_UNSPEC,
|
||||
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST
|
||||
| GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME
|
||||
|
@ -609,6 +447,10 @@ _llarp_nt_getadaptersaddresses(struct llarp_nt_ifaddrs_t** ifap)
|
|||
ift->_ifa.ifa_next = (struct llarp_nt_ifaddrs_t*)(ift + 1);
|
||||
ift = (struct _llarp_nt_ifaddrs_t*)(ift->_ifa.ifa_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
ift->_ifa.ifa_next = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -617,18 +459,13 @@ _llarp_nt_getadaptersaddresses(struct llarp_nt_ifaddrs_t** ifap)
|
|||
*ifap = (struct llarp_nt_ifaddrs_t*)ifa;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// an implementation of if_nametoindex(3) based on GetAdapterIndex(2)
|
||||
// with a fallback to GetAdaptersAddresses(2) commented out for now
|
||||
// unless it becomes evident that the first codepath fails in certain
|
||||
// edge cases?
|
||||
static unsigned
|
||||
_llarp_nt_getadaptersaddresses_nametoindex(const char* ifname)
|
||||
{
|
||||
ULONG ifIndex;
|
||||
DWORD /* dwSize = 4096,*/ dwRet;
|
||||
// IP_ADAPTER_ADDRESSES *pAdapterAddresses = nullptr, *adapter;
|
||||
DWORD dwSize = 4096, dwRet;
|
||||
IP_ADAPTER_ADDRESSES *pAdapterAddresses = nullptr, *adapter;
|
||||
char szAdapterName[256];
|
||||
|
||||
if(!ifname)
|
||||
|
@ -642,7 +479,6 @@ _llarp_nt_getadaptersaddresses_nametoindex(const char* ifname)
|
|||
else
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
/* fallback to finding index via iterating adapter list */
|
||||
|
||||
/* loop to handle interfaces coming online causing a buffer overflow
|
||||
|
@ -651,7 +487,7 @@ _llarp_nt_getadaptersaddresses_nametoindex(const char* ifname)
|
|||
for(unsigned i = 3; i; i--)
|
||||
{
|
||||
pAdapterAddresses = (IP_ADAPTER_ADDRESSES*)_llarp_nt_heap_alloc(dwSize);
|
||||
dwRet = _GetAdaptersAddresses(
|
||||
dwRet = GetAdaptersAddresses(
|
||||
AF_UNSPEC,
|
||||
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER
|
||||
| GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_SKIP_MULTICAST,
|
||||
|
@ -697,7 +533,6 @@ _llarp_nt_getadaptersaddresses_nametoindex(const char* ifname)
|
|||
if(pAdapterAddresses)
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// the emulated getifaddrs(3) itself.
|
||||
|
@ -709,7 +544,7 @@ llarp_nt_getifaddrs(struct llarp_nt_ifaddrs_t** ifap)
|
|||
fprintf(stderr, "llarp_nt_getifaddrs (ifap:%p error:%p)\n", (void*)ifap,
|
||||
(void*)errno);
|
||||
#endif
|
||||
return _llarp_nt_getadaptersinfo(ifap);
|
||||
return _llarp_nt_getadaptersaddresses(ifap);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#define inet_aton(x, y) inet_pton(AF_INET, x, y)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,315 +0,0 @@
|
|||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
/*
|
||||
* Contains routines missing from WS2_32.DLL until 2006, if yer using
|
||||
* Microsoft C/C++, then this code is irrelevant, as the official
|
||||
* Platform SDK already links against these routines in the correct
|
||||
* libraries.
|
||||
*
|
||||
* -despair86 30/07/18
|
||||
*/
|
||||
|
||||
// these need to be in a specific order
|
||||
#include <assert.h>
|
||||
#include <llarp/net.h>
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
#if WINNT_CROSS_COMPILE && !NTSTATUS
|
||||
typedef LONG NTSTATUS;
|
||||
#endif
|
||||
#include "win32_intrnl.h"
|
||||
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
{
|
||||
int address_length;
|
||||
DWORD string_length = size;
|
||||
struct sockaddr_storage sa;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
address_length = sizeof(struct sockaddr_in);
|
||||
sin->sin_family = af;
|
||||
memcpy(&sin->sin_addr, src, sizeof(struct in_addr));
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
address_length = sizeof(struct sockaddr_in6);
|
||||
sin6->sin6_family = af;
|
||||
memcpy(&sin6->sin6_addr, src, sizeof(struct in6_addr));
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(WSAAddressToString((LPSOCKADDR)&sa, address_length, NULL, dst,
|
||||
&string_length)
|
||||
== 0)
|
||||
{
|
||||
return dst;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
int address_length;
|
||||
struct sockaddr_storage sa;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
|
||||
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
address_length = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
address_length = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(WSAStringToAddress((LPTSTR)src, af, NULL, (LPSOCKADDR)&sa, &address_length)
|
||||
== 0)
|
||||
{
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
memcpy(dst, &sin->sin_addr, sizeof(struct in_addr));
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
memcpy(dst, &sin6->sin6_addr, sizeof(struct in6_addr));
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct _InterfaceIndexTable
|
||||
{
|
||||
DWORD numIndexes;
|
||||
IF_INDEX indexes[1];
|
||||
} InterfaceIndexTable;
|
||||
|
||||
// windows 2000
|
||||
// todo(despair86): implement IPv6 detection using
|
||||
// the ipv6 preview stack/adv net pack from 1999/2001
|
||||
DWORD FAR PASCAL
|
||||
_GetAdaptersAddresses(ULONG Family, ULONG Flags, PVOID Reserved,
|
||||
PIP_ADAPTER_ADDRESSES pAdapterAddresses,
|
||||
PULONG pOutBufLen)
|
||||
{
|
||||
InterfaceIndexTable *indexTable;
|
||||
IFInfo ifInfo;
|
||||
int i;
|
||||
ULONG ret, requiredSize = 0;
|
||||
PIP_ADAPTER_ADDRESSES currentAddress;
|
||||
PUCHAR currentLocation;
|
||||
HANDLE tcpFile;
|
||||
|
||||
(void)(Family);
|
||||
if(!pOutBufLen)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if(Reserved)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
indexTable = getInterfaceIndexTable();
|
||||
if(!indexTable)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
ret = openTcpFile(&tcpFile, FILE_READ_DATA);
|
||||
if(!NT_SUCCESS(ret))
|
||||
return ERROR_NO_DATA;
|
||||
|
||||
for(i = indexTable->numIndexes; i >= 0; i--)
|
||||
{
|
||||
if(NT_SUCCESS(
|
||||
getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
||||
{
|
||||
/* The whole struct */
|
||||
requiredSize += sizeof(IP_ADAPTER_ADDRESSES);
|
||||
|
||||
/* Friendly name */
|
||||
if(!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
||||
requiredSize +=
|
||||
strlen((char *)ifInfo.if_info.ent.if_descr) + 1; // FIXME
|
||||
|
||||
/* Adapter name */
|
||||
requiredSize += strlen((char *)ifInfo.if_info.ent.if_descr) + 1;
|
||||
|
||||
/* Unicast address */
|
||||
if(!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||
requiredSize += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
|
||||
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||
|
||||
/* FIXME: Implement dns suffix and description */
|
||||
requiredSize += 2 * sizeof(WCHAR);
|
||||
|
||||
/* We're only going to implement what's required for XP SP0 */
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "size: %ld, requiredSize: %ld\n", *pOutBufLen, requiredSize);
|
||||
#endif
|
||||
if(!pAdapterAddresses || *pOutBufLen < requiredSize)
|
||||
{
|
||||
*pOutBufLen = requiredSize;
|
||||
closeTcpFile(tcpFile);
|
||||
free(indexTable);
|
||||
return ERROR_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
RtlZeroMemory(pAdapterAddresses, requiredSize);
|
||||
|
||||
/* Let's set up the pointers */
|
||||
currentAddress = pAdapterAddresses;
|
||||
for(i = indexTable->numIndexes; i >= 0; i--)
|
||||
{
|
||||
if(NT_SUCCESS(
|
||||
getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
||||
{
|
||||
currentLocation =
|
||||
(PUCHAR)currentAddress + (ULONG_PTR)sizeof(IP_ADAPTER_ADDRESSES);
|
||||
|
||||
/* FIXME: Friendly name */
|
||||
if(!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
||||
{
|
||||
currentAddress->FriendlyName = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* Adapter name */
|
||||
currentAddress->AdapterName = (PVOID)currentLocation;
|
||||
currentLocation += strlen((char *)ifInfo.if_info.ent.if_descr) + 1;
|
||||
|
||||
/* Unicast address */
|
||||
if(!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||
{
|
||||
currentAddress->FirstUnicastAddress = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
currentAddress->FirstUnicastAddress->Address.lpSockaddr =
|
||||
(PVOID)currentLocation;
|
||||
currentLocation += sizeof(struct sockaddr);
|
||||
}
|
||||
|
||||
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||
|
||||
/* FIXME: Implement dns suffix and description */
|
||||
currentAddress->DnsSuffix = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(WCHAR);
|
||||
|
||||
currentAddress->Description = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(WCHAR);
|
||||
|
||||
currentAddress->Next = (PVOID)currentLocation;
|
||||
/* Terminate the last address correctly */
|
||||
if(i == 0)
|
||||
currentAddress->Next = NULL;
|
||||
|
||||
/* We're only going to implement what's required for XP SP0 */
|
||||
|
||||
currentAddress = currentAddress->Next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now again, for real this time */
|
||||
|
||||
currentAddress = pAdapterAddresses;
|
||||
for(i = indexTable->numIndexes; i >= 0; i--)
|
||||
{
|
||||
if(NT_SUCCESS(
|
||||
getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
||||
{
|
||||
/* Make sure we're not looping more than we hoped for */
|
||||
assert(currentAddress);
|
||||
|
||||
/* Alignment information */
|
||||
currentAddress->Length = sizeof(IP_ADAPTER_ADDRESSES);
|
||||
currentAddress->IfIndex = indexTable->indexes[i];
|
||||
|
||||
/* Adapter name */
|
||||
strcpy(currentAddress->AdapterName, (char *)ifInfo.if_info.ent.if_descr);
|
||||
|
||||
if(!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||
{
|
||||
currentAddress->FirstUnicastAddress->Length =
|
||||
sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
currentAddress->FirstUnicastAddress->Flags = 0; // FIXME
|
||||
currentAddress->FirstUnicastAddress->Next =
|
||||
NULL; // FIXME: Support more than one address per adapter
|
||||
currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_family =
|
||||
AF_INET;
|
||||
memcpy(currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_data,
|
||||
&ifInfo.ip_addr.iae_addr, sizeof(ifInfo.ip_addr.iae_addr));
|
||||
currentAddress->FirstUnicastAddress->Address.iSockaddrLength =
|
||||
sizeof(ifInfo.ip_addr.iae_addr) + sizeof(USHORT);
|
||||
currentAddress->FirstUnicastAddress->PrefixOrigin =
|
||||
IpPrefixOriginOther; // FIXME
|
||||
currentAddress->FirstUnicastAddress->SuffixOrigin =
|
||||
IpSuffixOriginOther; // FIXME
|
||||
currentAddress->FirstUnicastAddress->DadState =
|
||||
IpDadStatePreferred; // FIXME
|
||||
currentAddress->FirstUnicastAddress->ValidLifetime =
|
||||
0xFFFFFFFF; // FIXME
|
||||
currentAddress->FirstUnicastAddress->PreferredLifetime =
|
||||
0xFFFFFFFF; // FIXME
|
||||
currentAddress->FirstUnicastAddress->LeaseLifetime =
|
||||
0xFFFFFFFF; // FIXME
|
||||
}
|
||||
|
||||
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||
currentAddress->FirstAnycastAddress = NULL;
|
||||
currentAddress->FirstMulticastAddress = NULL;
|
||||
currentAddress->FirstDnsServerAddress = NULL;
|
||||
|
||||
/* FIXME: Implement dns suffix, description, and friendly name */
|
||||
currentAddress->DnsSuffix[0] = UNICODE_NULL;
|
||||
currentAddress->Description[0] = UNICODE_NULL;
|
||||
currentAddress->FriendlyName[0] = UNICODE_NULL;
|
||||
|
||||
/* Physical Address */
|
||||
memcpy(currentAddress->PhysicalAddress, ifInfo.if_info.ent.if_physaddr,
|
||||
ifInfo.if_info.ent.if_physaddrlen);
|
||||
currentAddress->PhysicalAddressLength = ifInfo.if_info.ent.if_physaddrlen;
|
||||
|
||||
/* Flags */
|
||||
currentAddress->Flags = 0; // FIXME
|
||||
|
||||
/* MTU */
|
||||
currentAddress->Mtu = ifInfo.if_info.ent.if_mtu;
|
||||
|
||||
/* Interface type */
|
||||
currentAddress->IfType = ifInfo.if_info.ent.if_type;
|
||||
|
||||
/* Operational status */
|
||||
if(ifInfo.if_info.ent.if_operstatus >= IF_OPER_STATUS_CONNECTING)
|
||||
currentAddress->OperStatus = IfOperStatusUp;
|
||||
else
|
||||
currentAddress->OperStatus = IfOperStatusDown;
|
||||
|
||||
/* We're only going to implement what's required for XP SP0 */
|
||||
|
||||
/* Move to the next address */
|
||||
currentAddress = currentAddress->Next;
|
||||
}
|
||||
}
|
||||
|
||||
closeTcpFile(tcpFile);
|
||||
free(indexTable);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
#endif
|
|
@ -1,572 +0,0 @@
|
|||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
/*
|
||||
* All the user-mode scaffolding necessary to backport GetAdaptersAddresses(2))
|
||||
* to the NT 5.x series. See further comments for any limitations.
|
||||
* NOTE: this is dead code, i haven't had time to debug it yet due to illness.
|
||||
* For now, downlevel platforms use GetAdaptersInfo(2) which is inet4 only.
|
||||
* -despair86 20/08/18
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// apparently mingw-w64 loses its shit over this
|
||||
// but only for 32-bit builds, naturally
|
||||
#ifdef WIN32_LEAN_AND_MEAN
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
// these need to be in a specific order
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <tdi.h>
|
||||
#include "win32_intrnl.h"
|
||||
|
||||
const PWCHAR TcpFileName = L"\\Device\\Tcp";
|
||||
|
||||
// from ntdll.dll
|
||||
typedef void(FAR PASCAL *pRtlInitUString)(UNICODE_STRING *, const WCHAR *);
|
||||
typedef NTSTATUS(FAR PASCAL *pNTOpenFile)(HANDLE *, ACCESS_MASK,
|
||||
OBJECT_ATTRIBUTES *,
|
||||
IO_STATUS_BLOCK *, ULONG, ULONG);
|
||||
typedef NTSTATUS(FAR PASCAL *pNTClose)(HANDLE);
|
||||
|
||||
#define FSCTL_TCP_BASE FILE_DEVICE_NETWORK
|
||||
|
||||
#define _TCP_CTL_CODE(Function, Method, Access) \
|
||||
CTL_CODE(FSCTL_TCP_BASE, Function, Method, Access)
|
||||
|
||||
#define IOCTL_TCP_QUERY_INFORMATION_EX \
|
||||
_TCP_CTL_CODE(0, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
|
||||
typedef struct _InterfaceIndexTable
|
||||
{
|
||||
DWORD numIndexes;
|
||||
DWORD numAllocated;
|
||||
DWORD indexes[1];
|
||||
} InterfaceIndexTable;
|
||||
|
||||
NTSTATUS
|
||||
tdiGetMibForIfEntity(HANDLE tcpFile, TDIEntityID *ent,
|
||||
IFEntrySafelySized *entry)
|
||||
{
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req;
|
||||
NTSTATUS status = 0;
|
||||
DWORD returnSize;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "TdiGetMibForIfEntity(tcpFile %x,entityId %x)\n",
|
||||
(int)tcpFile, (int)ent->tei_instance);
|
||||
#endif
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
||||
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||
req.ID.toi_id = 1;
|
||||
req.ID.toi_entity = *ent;
|
||||
|
||||
status =
|
||||
DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req,
|
||||
sizeof(req), entry, sizeof(*entry), &returnSize, NULL);
|
||||
|
||||
if(!status)
|
||||
{
|
||||
perror("IOCTL Failed\n");
|
||||
return 0xc0000001;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"TdiGetMibForIfEntity() => {\n"
|
||||
" if_index ....................... %lx\n"
|
||||
" if_type ........................ %lx\n"
|
||||
" if_mtu ......................... %ld\n"
|
||||
" if_speed ....................... %lx\n"
|
||||
" if_physaddrlen ................. %ld\n",
|
||||
entry->ent.if_index, entry->ent.if_type, entry->ent.if_mtu,
|
||||
entry->ent.if_speed, entry->ent.if_physaddrlen);
|
||||
fprintf(stderr,
|
||||
" if_physaddr .................... %02x:%02x:%02x:%02x:%02x:%02x\n"
|
||||
" if_descr ....................... %s\n",
|
||||
entry->ent.if_physaddr[0] & 0xff, entry->ent.if_physaddr[1] & 0xff,
|
||||
entry->ent.if_physaddr[2] & 0xff, entry->ent.if_physaddr[3] & 0xff,
|
||||
entry->ent.if_physaddr[4] & 0xff, entry->ent.if_physaddr[5] & 0xff,
|
||||
entry->ent.if_descr);
|
||||
fprintf(stderr, "} status %08lx\n", status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
tdiGetSetOfThings(HANDLE tcpFile, DWORD toiClass, DWORD toiType, DWORD toiId,
|
||||
DWORD teiEntity, DWORD teiInstance, DWORD fixedPart,
|
||||
DWORD entrySize, PVOID *tdiEntitySet, PDWORD numEntries)
|
||||
{
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req;
|
||||
PVOID entitySet = 0;
|
||||
NTSTATUS status = 0;
|
||||
DWORD allocationSizeForEntityArray = entrySize * MAX_TDI_ENTITIES,
|
||||
arraySize = entrySize * MAX_TDI_ENTITIES;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.ID.toi_class = toiClass;
|
||||
req.ID.toi_type = toiType;
|
||||
req.ID.toi_id = toiId;
|
||||
req.ID.toi_entity.tei_entity = teiEntity;
|
||||
req.ID.toi_entity.tei_instance = teiInstance;
|
||||
|
||||
/* There's a subtle problem here...
|
||||
* If an interface is added at this exact instant, (as if by a PCMCIA
|
||||
* card insertion), the array will still not have enough entries after
|
||||
* have allocated it after the first DeviceIoControl call.
|
||||
*
|
||||
* We'll get around this by repeating until the number of interfaces
|
||||
* stabilizes.
|
||||
*/
|
||||
do
|
||||
{
|
||||
status =
|
||||
DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req,
|
||||
sizeof(req), 0, 0, &allocationSizeForEntityArray, NULL);
|
||||
|
||||
if(!status)
|
||||
return 0xc0000001;
|
||||
|
||||
arraySize = allocationSizeForEntityArray;
|
||||
entitySet = HeapAlloc(GetProcessHeap(), 0, arraySize);
|
||||
|
||||
if(!entitySet)
|
||||
{
|
||||
status = ((NTSTATUS)0xC000009A);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req,
|
||||
sizeof(req), entitySet, arraySize,
|
||||
&allocationSizeForEntityArray, NULL);
|
||||
|
||||
/* This is why we have the loop -- we might have added an adapter */
|
||||
if(arraySize == allocationSizeForEntityArray)
|
||||
break;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, entitySet);
|
||||
entitySet = 0;
|
||||
|
||||
if(!status)
|
||||
return 0xc0000001;
|
||||
} while(TRUE); /* We break if the array we received was the size we
|
||||
* expected. Therefore, we got here because it wasn't */
|
||||
|
||||
*numEntries = (arraySize - fixedPart) / entrySize;
|
||||
*tdiEntitySet = entitySet;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
tdiGetEntityIDSet(HANDLE tcpFile, TDIEntityID **entitySet, PDWORD numEntities)
|
||||
{
|
||||
NTSTATUS status =
|
||||
tdiGetSetOfThings(tcpFile, INFO_CLASS_GENERIC, INFO_TYPE_PROVIDER,
|
||||
ENTITY_LIST_ID, GENERIC_ENTITY, 0, 0,
|
||||
sizeof(TDIEntityID), (PVOID *)entitySet, numEntities);
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
tdiGetIpAddrsForIpEntity(HANDLE tcpFile, TDIEntityID *ent, IPAddrEntry **addrs,
|
||||
PDWORD numAddrs)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "TdiGetIpAddrsForIpEntity(tcpFile 0x%p, entityId 0x%lx)\n",
|
||||
tcpFile, ent->tei_instance);
|
||||
#endif
|
||||
|
||||
status = tdiGetSetOfThings(tcpFile, INFO_CLASS_PROTOCOL, INFO_TYPE_PROVIDER,
|
||||
0x102, CL_NL_ENTITY, ent->tei_instance, 0,
|
||||
sizeof(IPAddrEntry), (PVOID *)addrs, numAddrs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VOID
|
||||
tdiFreeThingSet(PVOID things)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, things);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
openTcpFile(PHANDLE tcpFile, ACCESS_MASK DesiredAccess)
|
||||
{
|
||||
UNICODE_STRING fileName;
|
||||
OBJECT_ATTRIBUTES objectAttributes;
|
||||
IO_STATUS_BLOCK ioStatusBlock;
|
||||
NTSTATUS status;
|
||||
pRtlInitUString _RtlInitUnicodeString;
|
||||
pNTOpenFile _NTOpenFile;
|
||||
HANDLE ntdll;
|
||||
|
||||
ntdll = GetModuleHandle("ntdll.dll");
|
||||
_RtlInitUnicodeString =
|
||||
(pRtlInitUString)GetProcAddress(ntdll, "RtlInitUnicodeString");
|
||||
_NTOpenFile = (pNTOpenFile)GetProcAddress(ntdll, "NtOpenFile");
|
||||
_RtlInitUnicodeString(&fileName, TcpFileName);
|
||||
InitializeObjectAttributes(&objectAttributes, &fileName, OBJ_CASE_INSENSITIVE,
|
||||
NULL, NULL);
|
||||
status = _NTOpenFile(tcpFile, DesiredAccess | SYNCHRONIZE, &objectAttributes,
|
||||
&ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
/* String does not need to be freed: it points to the constant
|
||||
* string we provided */
|
||||
if(!NT_SUCCESS(status))
|
||||
*tcpFile = INVALID_HANDLE_VALUE;
|
||||
return status;
|
||||
}
|
||||
VOID
|
||||
closeTcpFile(HANDLE h)
|
||||
{
|
||||
pNTClose _NTClose;
|
||||
HANDLE ntdll = GetModuleHandle("ntdll.dll");
|
||||
_NTClose = (pNTClose)GetProcAddress(ntdll, "NtClose");
|
||||
assert(h != INVALID_HANDLE_VALUE);
|
||||
_NTClose(h);
|
||||
}
|
||||
|
||||
BOOL
|
||||
isLoopback(HANDLE tcpFile, TDIEntityID *loop_maybe)
|
||||
{
|
||||
IFEntrySafelySized entryInfo;
|
||||
NTSTATUS status;
|
||||
|
||||
status = tdiGetMibForIfEntity(tcpFile, loop_maybe, &entryInfo);
|
||||
|
||||
return NT_SUCCESS(status)
|
||||
&& (entryInfo.ent.if_type == IFENT_SOFTWARE_LOOPBACK);
|
||||
}
|
||||
|
||||
BOOL
|
||||
isIpEntity(HANDLE tcpFile, TDIEntityID *ent)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(tcpFile);
|
||||
return (ent->tei_entity == CL_NL_ENTITY || ent->tei_entity == CO_NL_ENTITY);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getNthIpEntity(HANDLE tcpFile, DWORD index, TDIEntityID *ent)
|
||||
{
|
||||
DWORD numEntities = 0;
|
||||
DWORD numRoutes = 0;
|
||||
TDIEntityID *entitySet = 0;
|
||||
NTSTATUS status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
||||
unsigned i;
|
||||
|
||||
if(!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
for(i = 0; i < numEntities; i++)
|
||||
{
|
||||
if(isIpEntity(tcpFile, &entitySet[i]))
|
||||
{
|
||||
fprintf(stderr, "Entity %d is an IP Entity\n", i);
|
||||
if(numRoutes == index)
|
||||
break;
|
||||
else
|
||||
numRoutes++;
|
||||
}
|
||||
}
|
||||
|
||||
if(numRoutes == index && i < numEntities)
|
||||
{
|
||||
fprintf(stderr, "Index %lu is entity #%d - %04lx:%08lx\n", index, i,
|
||||
entitySet[i].tei_entity, entitySet[i].tei_instance);
|
||||
memcpy(ent, &entitySet[i], sizeof(*ent));
|
||||
tdiFreeThingSet(entitySet);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdiFreeThingSet(entitySet);
|
||||
return 0xc000001;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
isInterface(TDIEntityID *if_maybe)
|
||||
{
|
||||
return if_maybe->tei_entity == IF_ENTITY;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoSet(HANDLE tcpFile, IFInfo **infoSet, PDWORD numInterfaces)
|
||||
{
|
||||
DWORD numEntities;
|
||||
TDIEntityID *entIDSet = NULL;
|
||||
NTSTATUS status = tdiGetEntityIDSet(tcpFile, &entIDSet, &numEntities);
|
||||
IFInfo *infoSetInt = 0;
|
||||
int curInterf = 0;
|
||||
unsigned i;
|
||||
|
||||
if(!NT_SUCCESS(status))
|
||||
{
|
||||
fprintf(stderr, "getInterfaceInfoSet: tdiGetEntityIDSet() failed: 0x%lx\n",
|
||||
status);
|
||||
return status;
|
||||
}
|
||||
|
||||
infoSetInt = HeapAlloc(GetProcessHeap(), 0, sizeof(IFInfo) * numEntities);
|
||||
|
||||
if(infoSetInt)
|
||||
{
|
||||
for(i = 0; i < numEntities; i++)
|
||||
{
|
||||
if(isInterface(&entIDSet[i]))
|
||||
{
|
||||
infoSetInt[curInterf].entity_id = entIDSet[i];
|
||||
status = tdiGetMibForIfEntity(tcpFile, &entIDSet[i],
|
||||
&infoSetInt[curInterf].if_info);
|
||||
fprintf(stderr, "tdiGetMibForIfEntity: %08lx\n", status);
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
DWORD numAddrs;
|
||||
IPAddrEntry *addrs;
|
||||
TDIEntityID ip_ent;
|
||||
unsigned j;
|
||||
|
||||
status = getNthIpEntity(tcpFile, curInterf, &ip_ent);
|
||||
if(NT_SUCCESS(status))
|
||||
status =
|
||||
tdiGetIpAddrsForIpEntity(tcpFile, &ip_ent, &addrs, &numAddrs);
|
||||
for(j = 0; NT_SUCCESS(status) && j < numAddrs; j++)
|
||||
{
|
||||
fprintf(stderr, "ADDR %d: index %ld (target %ld)\n", j,
|
||||
addrs[j].iae_index,
|
||||
infoSetInt[curInterf].if_info.ent.if_index);
|
||||
if(addrs[j].iae_index == infoSetInt[curInterf].if_info.ent.if_index)
|
||||
{
|
||||
memcpy(&infoSetInt[curInterf].ip_addr, &addrs[j],
|
||||
sizeof(addrs[j]));
|
||||
curInterf++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(NT_SUCCESS(status))
|
||||
tdiFreeThingSet(addrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tdiFreeThingSet(entIDSet);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
*infoSet = infoSetInt;
|
||||
*numInterfaces = curInterf;
|
||||
}
|
||||
else
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, infoSetInt);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdiFreeThingSet(entIDSet);
|
||||
return ((NTSTATUS)0xC000009A);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByName(HANDLE tcpFile, char *name, IFInfo *info)
|
||||
{
|
||||
IFInfo *ifInfo;
|
||||
DWORD numInterfaces;
|
||||
unsigned i;
|
||||
NTSTATUS status = getInterfaceInfoSet(tcpFile, &ifInfo, &numInterfaces);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
for(i = 0; i < numInterfaces; i++)
|
||||
{
|
||||
if(!strcmp((PCHAR)ifInfo[i].if_info.ent.if_descr, name))
|
||||
{
|
||||
memcpy(info, &ifInfo[i], sizeof(*info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ifInfo);
|
||||
|
||||
return i < numInterfaces ? 0 : 0xc0000001;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByIndex(HANDLE tcpFile, DWORD index, IFInfo *info)
|
||||
{
|
||||
IFInfo *ifInfo;
|
||||
DWORD numInterfaces;
|
||||
NTSTATUS status = getInterfaceInfoSet(tcpFile, &ifInfo, &numInterfaces);
|
||||
unsigned i;
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
for(i = 0; i < numInterfaces; i++)
|
||||
{
|
||||
if(ifInfo[i].if_info.ent.if_index == index)
|
||||
{
|
||||
memcpy(info, &ifInfo[i], sizeof(*info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ifInfo);
|
||||
|
||||
return i < numInterfaces ? 0 : 0xc0000001;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getIPAddrEntryForIf(HANDLE tcpFile, char *name, DWORD index, IFInfo *ifInfo)
|
||||
{
|
||||
NTSTATUS status = name ? getInterfaceInfoByName(tcpFile, name, ifInfo)
|
||||
: getInterfaceInfoByIndex(tcpFile, index, ifInfo);
|
||||
|
||||
if(!NT_SUCCESS(status))
|
||||
{
|
||||
fprintf(stderr, "getIPAddrEntryForIf returning %lx\n", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
InterfaceIndexTable *
|
||||
getInterfaceIndexTableInt(BOOL nonLoopbackOnly)
|
||||
{
|
||||
DWORD numInterfaces, curInterface = 0;
|
||||
unsigned i;
|
||||
IFInfo *ifInfo;
|
||||
InterfaceIndexTable *ret = 0;
|
||||
HANDLE tcpFile;
|
||||
NTSTATUS status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
||||
|
||||
ifInfo = NULL;
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
status = getInterfaceInfoSet(tcpFile, &ifInfo, &numInterfaces);
|
||||
|
||||
fprintf(stderr, "InterfaceInfoSet: %08lx, %04lx:%08lx\n", status,
|
||||
ifInfo->entity_id.tei_entity, ifInfo->entity_id.tei_instance);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
ret = (InterfaceIndexTable *)calloc(
|
||||
1, sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
|
||||
|
||||
if(ret)
|
||||
{
|
||||
ret->numAllocated = numInterfaces;
|
||||
fprintf(stderr, "NumInterfaces = %ld\n", numInterfaces);
|
||||
|
||||
for(i = 0; i < numInterfaces; i++)
|
||||
{
|
||||
fprintf(stderr, "Examining interface %d\n", i);
|
||||
if(!nonLoopbackOnly || !isLoopback(tcpFile, &ifInfo[i].entity_id))
|
||||
{
|
||||
fprintf(stderr, "Interface %d matches (%ld)\n", i, curInterface);
|
||||
ret->indexes[curInterface++] = ifInfo[i].if_info.ent.if_index;
|
||||
}
|
||||
}
|
||||
|
||||
ret->numIndexes = curInterface;
|
||||
}
|
||||
|
||||
tdiFreeThingSet(ifInfo);
|
||||
}
|
||||
closeTcpFile(tcpFile);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
InterfaceIndexTable *
|
||||
getInterfaceIndexTable(void)
|
||||
{
|
||||
return getInterfaceIndexTableInt(FALSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// there's probably an use case for a _newer_ implementation
|
||||
// of pthread_setname_np(3), in fact, I may just merge _this_
|
||||
// upstream...
|
||||
#if 0
|
||||
#include <windows.h>
|
||||
|
||||
typedef HRESULT(FAR PASCAL *p_SetThreadDescription)(void *, const wchar_t *);
|
||||
#define EXCEPTION_SET_THREAD_NAME ((DWORD)0x406D1388)
|
||||
|
||||
typedef struct _THREADNAME_INFO
|
||||
{
|
||||
DWORD dwType; /* must be 0x1000 */
|
||||
LPCSTR szName; /* pointer to name (in user addr space) */
|
||||
DWORD dwThreadID; /* thread ID (-1=caller thread) */
|
||||
DWORD dwFlags; /* reserved for future use, must be zero */
|
||||
} THREADNAME_INFO;
|
||||
|
||||
void
|
||||
SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
|
||||
{
|
||||
THREADNAME_INFO info;
|
||||
DWORD infosize;
|
||||
HANDLE hThread;
|
||||
/* because loonix is SHIT and limits thread names to 16 bytes */
|
||||
wchar_t thr_name_w[16];
|
||||
p_SetThreadDescription _SetThreadDescription;
|
||||
|
||||
/* current win10 flights now have a new named-thread API, let's try to use
|
||||
* that first! */
|
||||
/* first, dlsym(2) the new call from system library */
|
||||
hThread = NULL;
|
||||
_SetThreadDescription = (p_SetThreadDescription)GetProcAddress(
|
||||
GetModuleHandle("kernel32"), "SetThreadDescription");
|
||||
if(_SetThreadDescription)
|
||||
{
|
||||
/* grab another reference to the thread */
|
||||
hThread = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, dwThreadID);
|
||||
/* windows takes unicode, our input is utf-8 or plain ascii */
|
||||
MultiByteToWideChar(CP_ACP, 0, szThreadName, -1, thr_name_w, 16);
|
||||
if(hThread)
|
||||
_SetThreadDescription(hThread, thr_name_w);
|
||||
else
|
||||
goto old; /* for whatever reason, we couldn't get a handle to the thread.
|
||||
Just use the old method. */
|
||||
}
|
||||
else
|
||||
{
|
||||
old:
|
||||
info.dwType = 0x1000;
|
||||
info.szName = szThreadName;
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
|
||||
infosize = sizeof(info) / sizeof(DWORD);
|
||||
|
||||
__try
|
||||
{
|
||||
RaiseException(EXCEPTION_SET_THREAD_NAME, 0, infosize, (DWORD *)&info);
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
}
|
||||
/* clean up */
|
||||
if(hThread)
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
#endif
|
|
@ -1,111 +0,0 @@
|
|||
#ifndef WIN32_INTRNL_H
|
||||
#define WIN32_INTRNL_H
|
||||
/* if yer using Microsoft C++, then downlevel platforms are irrelevant to you */
|
||||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
#ifndef NT_SUCCESS
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#endif
|
||||
#include <tdiinfo.h>
|
||||
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned int uint;
|
||||
|
||||
/* forward declare, each module has their own idea of what this is */
|
||||
typedef struct _InterfaceIndexTable InterfaceIndexTable;
|
||||
|
||||
typedef struct IFEntry
|
||||
{
|
||||
ulong if_index;
|
||||
ulong if_type;
|
||||
ulong if_mtu;
|
||||
ulong if_speed;
|
||||
ulong if_physaddrlen;
|
||||
uchar if_physaddr[8];
|
||||
ulong if_adminstatus;
|
||||
ulong if_operstatus;
|
||||
ulong if_lastchange;
|
||||
ulong if_inoctets;
|
||||
ulong if_inucastpkts;
|
||||
ulong if_innucastpkts;
|
||||
ulong if_indiscards;
|
||||
ulong if_inerrors;
|
||||
ulong if_inunknownprotos;
|
||||
ulong if_outoctets;
|
||||
ulong if_outucastpkts;
|
||||
ulong if_outnucastpkts;
|
||||
ulong if_outdiscards;
|
||||
ulong if_outerrors;
|
||||
ulong if_outqlen;
|
||||
ulong if_descrlen;
|
||||
uchar if_descr[1];
|
||||
} IFEntry;
|
||||
|
||||
typedef struct IPAddrEntry
|
||||
{
|
||||
ulong iae_addr;
|
||||
ulong iae_index;
|
||||
ulong iae_mask;
|
||||
ulong iae_bcastaddr;
|
||||
ulong iae_reasmsize;
|
||||
ushort iae_context;
|
||||
ushort iae_pad;
|
||||
} IPAddrEntry;
|
||||
|
||||
typedef union _IFEntrySafelySized {
|
||||
CHAR MaxSize[sizeof(DWORD) + sizeof(IFEntry) + 128 + 1];
|
||||
IFEntry ent;
|
||||
} IFEntrySafelySized;
|
||||
|
||||
#ifndef IFENT_SOFTWARE_LOOPBACK
|
||||
#define IFENT_SOFTWARE_LOOPBACK 24 /* This is an SNMP constant from rfc1213 */
|
||||
#endif /*IFENT_SOFTWARE_LOOPBACK*/
|
||||
|
||||
/* Encapsulates information about an interface */
|
||||
typedef struct _IFInfo
|
||||
{
|
||||
TDIEntityID entity_id;
|
||||
IFEntrySafelySized if_info;
|
||||
IPAddrEntry ip_addr;
|
||||
} IFInfo;
|
||||
|
||||
/* functions */
|
||||
NTSTATUS
|
||||
openTcpFile(PHANDLE tcpFile, ACCESS_MASK DesiredAccess);
|
||||
|
||||
VOID
|
||||
closeTcpFile(HANDLE h);
|
||||
|
||||
BOOL
|
||||
isLoopback(HANDLE tcpFile, TDIEntityID* loop_maybe);
|
||||
|
||||
BOOL
|
||||
isIpEntity(HANDLE tcpFile, TDIEntityID* ent);
|
||||
|
||||
NTSTATUS
|
||||
getNthIpEntity(HANDLE tcpFile, DWORD index, TDIEntityID* ent);
|
||||
|
||||
BOOL
|
||||
isInterface(TDIEntityID* if_maybe);
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoSet(HANDLE tcpFile, IFInfo** infoSet, PDWORD numInterfaces);
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByName(HANDLE tcpFile, char* name, IFInfo* info);
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByIndex(HANDLE tcpFile, DWORD index, IFInfo* info);
|
||||
|
||||
NTSTATUS
|
||||
getIPAddrEntryForIf(HANDLE tcpFile, char* name, DWORD index, IFInfo* ifInfo);
|
||||
|
||||
InterfaceIndexTable*
|
||||
getInterfaceIndexTableInt(BOOL nonLoopbackOnly);
|
||||
|
||||
InterfaceIndexTable*
|
||||
getInterfaceIndexTable(void);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -30,13 +30,6 @@
|
|||
#if defined Windows
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#if _WIN32_WINNT < 0x0600
|
||||
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 <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
|
|
@ -39,8 +39,9 @@ VersionInfoTextVersion=0.3.0-dev
|
|||
VersionInfoProductName=loki-network
|
||||
VersionInfoProductVersion=0.3.0
|
||||
VersionInfoProductTextVersion=0.3.0-dev
|
||||
InternalCompressLevel=ultra64
|
||||
MinVersion=0,5.0
|
||||
InternalCompressLevel=ultra64
|
||||
; rip D:
|
||||
MinVersion=0,6.0
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
VersionInfoCopyright=Copyright ©2018 Loki Project
|
||||
AlwaysRestart=yes
|
||||
|
@ -65,52 +66,22 @@ Source: "{#DevPath}build\rcutil.exe"; DestDir: "{app}"; Flags: ignoreversion
|
|||
; and download an initial RC
|
||||
Source: "{#DevPath}lokinet-bootstrap.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall
|
||||
Source: "{#DevPath}win32-setup\7z.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall
|
||||
Source: "{tmp}\inet6.7z"; DestDir: "{app}"; Flags: ignoreversion external deleteafterinstall; MinVersion: 0,5.0; OnlyBelowVersion: 0,5.1
|
||||
; Copy the correct tuntap driver for the selected platform
|
||||
Source: "{tmp}\tuntapv9.7z"; DestDir: "{app}"; Flags: ignoreversion external deleteafterinstall; OnlyBelowVersion: 0, 6.0
|
||||
Source: "{tmp}\tuntapv9_n6.7z"; DestDir: "{app}"; Flags: ignoreversion external deleteafterinstall; MinVersion: 0,6.0
|
||||
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
[UninstallDelete]
|
||||
Type: filesandordirs; Name: "{app}\tap-windows*"
|
||||
Type: filesandordirs; Name: "{app}\inet6_driver"; MinVersion: 0,5.0; OnlyBelowVersion: 0,5.1
|
||||
Type: filesandordirs; Name: "{userappdata}\.lokinet"
|
||||
|
||||
[UninstallRun]
|
||||
Filename: "{app}\tap-windows-9.21.2\remove.bat"; WorkingDir: "{app}\tap-windows-9.21.2"; MinVersion: 0,6.0; Flags: runascurrentuser
|
||||
Filename: "{app}\tap-windows-9.9.2\remove.bat"; WorkingDir: "{app}\tap-windows-9.9.2"; OnlyBelowVersion: 0,6.0; Flags: runascurrentuser
|
||||
|
||||
[Registry]
|
||||
; TODO: BindView to activate inet6 protocol driver after restart
|
||||
Root: "HKLM"; Subkey: "Software\Microsoft\Windows\CurrentVersion\RunOnce"; ValueType: string; ValueName: "ActivateInet6"; ValueData: "[insert bindview cmd line here]"; MinVersion: 0,5.0; OnlyBelowVersion: 0,5.1
|
||||
|
||||
[Code]
|
||||
procedure InitializeWizard();
|
||||
var
|
||||
Version: TWindowsVersion;
|
||||
S: String;
|
||||
begin
|
||||
GetWindowsVersionEx(Version);
|
||||
if Version.NTPlatform and
|
||||
(Version.Major < 6) then
|
||||
begin
|
||||
// Windows 2000, XP, .NET Svr 2003
|
||||
// these have a horribly crippled WinInet that issues Triple-DES as its most secure
|
||||
// cipher suite
|
||||
idpAddFile('http://www.rvx86.net/files/tuntapv9.7z', ExpandConstant('{tmp}\tuntapv9.7z'));
|
||||
// Windows 2000 only, we need to install inet6 separately
|
||||
if (FileExists(ExpandConstant('{sys}\drivers\tcpip6.sys')) = false) and (Version.Major = 5) and (Version.Minor = 0) then
|
||||
begin
|
||||
idpAddFile('http://www.rvx86.net/files/inet6.7z', ExpandConstant('{tmp}\inet6.7z'));
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// current versions of windows :-)
|
||||
// (Arguably, one could pull this from any of the forks.)
|
||||
idpAddFile('https://github.com/despair86/loki-network/raw/master/contrib/tuntapv9-ndis/tap-windows-9.21.2.7z', ExpandConstant('{tmp}\tuntapv9_n6.7z'));
|
||||
end;
|
||||
idpDownloadAfter(wpReady);
|
||||
end;
|
||||
|
||||
|
@ -125,13 +96,7 @@ Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBa
|
|||
[Run]
|
||||
Filename: "{app}\{#MyAppExeName}"; Flags: nowait postinstall skipifsilent; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"
|
||||
; wait until either one or two of these terminates
|
||||
Filename: "{tmp}\7z.exe"; Parameters: "x tuntapv9.7z"; WorkingDir: "{app}"; Flags: runascurrentuser waituntilterminated; Description: "extract TUN/TAP-v9 driver"; StatusMsg: "Extracting driver..."; OnlyBelowVersion: 0, 6.0
|
||||
Filename: "{tmp}\7z.exe"; Parameters: "x tuntapv9_n6.7z"; WorkingDir: "{app}"; Flags: runascurrentuser waituntilterminated; Description: "extract TUN/TAP-v9 driver"; StatusMsg: "Extracting driver..."; MinVersion: 0, 6.0
|
||||
Filename: "{tmp}\7z.exe"; Parameters: "x inet6.7z"; WorkingDir: "{app}"; Flags: runascurrentuser waituntilterminated; Description: "extract inet6 driver"; StatusMsg: "Extracting IPv6 driver..."; MinVersion: 0, 5.0; OnlyBelowVersion: 0, 5.1
|
||||
Filename: "{tmp}\lokinet-bootstrap.exe"; WorkingDir: "{app}"; Flags: runascurrentuser waituntilterminated; Description: "bootstrap dht"; StatusMsg: "Downloading initial RC..."
|
||||
; then ask to install drivers
|
||||
Filename: "{app}\tap-windows-9.9.2\install.bat"; WorkingDir: "{app}\tap-windows-9.9.2\"; Flags: runascurrentuser waituntilterminated; Description: "Install TUN/TAP-v9 driver"; StatusMsg: "Installing driver..."; OnlyBelowVersion: 0, 6.0
|
||||
Filename: "{app}\tap-windows-9.21.2\install.bat"; WorkingDir: "{app}\tap-windows-9.21.2\"; Flags: runascurrentuser waituntilterminated; Description: "Install TUN/TAP-v9 driver"; StatusMsg: "Installing driver..."; MinVersion: 0, 6.0
|
||||
; install inet6 if not present. (I'd assume netsh displays something helpful if inet6 is already set up and configured.)
|
||||
Filename: "{app}\inet6_driver\setup\hotfix.exe"; Parameters: "/m /z"; WorkingDir: "{app}\inet6_driver\setup\"; Flags: runascurrentuser waituntilterminated; Description: "Install IPv6 driver"; StatusMsg: "Installing IPv6..."; OnlyBelowVersion: 0, 5.1
|
||||
Filename: "{sys}\netsh.exe"; Parameters: "int ipv6 install"; Flags: runascurrentuser waituntilterminated; Description: "install ipv6 on whistler"; StatusMsg: "Installing IPv6..."; MinVersion: 0,5.1; OnlyBelowVersion: 0,6.0
|
||||
Filename: "{app}\tap-windows-9.21.2\install.bat"; WorkingDir: "{app}\tap-windows-9.21.2\"; Flags: runascurrentuser waituntilterminated; Description: "Install TUN/TAP-v9 driver"; StatusMsg: "Installing driver..."; MinVersion: 0, 6.0
|
Loading…
Reference in New Issue