diff --git a/api/api.vcxproj b/api/api.vcxproj
index 327ee44..d864f0c 100644
--- a/api/api.vcxproj
+++ b/api/api.vcxproj
@@ -101,11 +101,6 @@
true
true
-
- rundll32.exe
- $(OutDir)$(TargetName)$(TargetExt),DoThingsForDebugging
- WindowsLocalDebugger
-
_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
@@ -171,7 +166,6 @@ lib.exe /def:nci.def /out:"$(IntDir)nci.lib" /machine:$(PlatformTarget) /nologo
-
diff --git a/api/api.vcxproj.filters b/api/api.vcxproj.filters
index 7d29920..c1db346 100644
--- a/api/api.vcxproj.filters
+++ b/api/api.vcxproj.filters
@@ -58,9 +58,6 @@
Header Files
-
- Header Files
-
diff --git a/api/rundll32.c b/api/rundll32.c
index 05a8323..85121a5 100644
--- a/api/rundll32.c
+++ b/api/rundll32.c
@@ -5,7 +5,6 @@
#include "adapter.h"
#include "logger.h"
-#include "session.h"
#include "wintun.h"
#include
@@ -17,12 +16,6 @@
#if defined(ACCEPT_WOW64) || defined(_DEBUG)
-static
-#ifndef _DEBUG
-const
-#endif
-BOOL WriteToConsole = FALSE;
-
static DWORD
WriteFormatted(_In_ DWORD StdHandle, _In_z_ const WCHAR *Template, ...)
{
@@ -38,10 +31,7 @@ WriteFormatted(_In_ DWORD StdHandle, _In_z_ const WCHAR *Template, ...)
(void *)&FormattedMessage,
0,
&Arguments);
- if (WriteToConsole)
- WriteConsoleW(GetStdHandle(StdHandle), FormattedMessage, Len, &SizeWritten, NULL);
- else
- WriteFile(GetStdHandle(StdHandle), FormattedMessage, Len * sizeof(WCHAR), &SizeWritten, NULL);
+ WriteFile(GetStdHandle(StdHandle), FormattedMessage, Len * sizeof(WCHAR), &SizeWritten, NULL);
LocalFree(FormattedMessage);
va_end(Arguments);
return SizeWritten / sizeof(WCHAR);
@@ -158,30 +148,4 @@ VOID __stdcall DeleteDriver(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int n
Done();
}
-#ifdef _DEBUG
-VOID __stdcall DoThingsForDebugging(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
-{
-# pragma EXPORT
- UNREFERENCED_PARAMETER(hwnd);
- UNREFERENCED_PARAMETER(hinst);
- UNREFERENCED_PARAMETER(lpszCmdLine);
- UNREFERENCED_PARAMETER(nCmdShow);
-
- AllocConsole();
- WriteToConsole = TRUE;
- Init();
- GUID TestGuid = { 0xdeadbabe, 0xcafe, 0xbeef, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef } };
- WINTUN_ADAPTER *Adapter;
- BOOL RebootRequired;
- assert(WintunCreateAdapter(L"Wintun", L"Test", &TestGuid, &Adapter, &RebootRequired) == ERROR_SUCCESS);
- assert(!RebootRequired);
- TUN_SESSION *Session;
- assert(WintunStartSession(Adapter, WINTUN_MIN_RING_CAPACITY, &Session) == ERROR_SUCCESS);
- WintunEndSession(Session);
- assert(WintunDeleteAdapter(Adapter, TRUE, &RebootRequired) == ERROR_SUCCESS);
- assert(!RebootRequired);
- system("pause");
-}
-#endif
-
#endif
diff --git a/api/session.c b/api/session.c
index 9c3d682..ddfa61d 100644
--- a/api/session.c
+++ b/api/session.c
@@ -7,7 +7,6 @@
#include "elevate.h"
#include "entry.h"
#include "logger.h"
-#include "session.h"
#include "wintun.h"
#include
diff --git a/api/session.h b/api/session.h
deleted file mode 100644
index 6813ef3..0000000
--- a/api/session.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0
- *
- * Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
- */
-
-#pragma once
-
-#include "wintun.h"
-#include
-
-typedef struct _TUN_SESSION TUN_SESSION;
-
-/**
- * @copydoc WINTUN_START_SESSION_FUNC
- */
-WINTUN_STATUS WINAPI
-WintunStartSession(
- _In_ const WINTUN_ADAPTER *Adapter,
- _In_ DWORD Capacity,
- _Out_ TUN_SESSION **Session);
-
-/**
- * @copydoc WINTUN_END_SESSION_FUNC
- */
-void WINAPI
-WintunEndSession(_In_ TUN_SESSION *Session);
-
-/**
- * @copydoc WINTUN_GET_READ_WAIT_EVENT_FUNC
- */
-HANDLE WINAPI
-WintunGetReadWaitEvent(_In_ TUN_SESSION *Session);
-
-/**
- * @copydoc WINTUN_RECEIVE_PACKET_FUNC
- */
-WINTUN_STATUS WINAPI
-WintunReceivePacket(_In_ TUN_SESSION *Session, _Out_bytecapcount_(*PacketSize) BYTE **Packet, _Out_ DWORD *PacketSize);
-
-/**
- * @copydoc WINTUN_RECEIVE_RELEASE_FUNC
- */
-void WINAPI
-WintunReceiveRelease(_In_ TUN_SESSION *Session, _In_ const BYTE *Packet);
-
-/**
- * @copydoc WINTUN_ALLOCATE_SEND_PACKET
- */
-WINTUN_STATUS WINAPI
-WintunAllocateSendPacket(
- _In_ TUN_SESSION *Session,
- _In_ DWORD PacketSize,
- _Out_bytecapcount_(PacketSize) BYTE **Packet);
-
-/**
- * @copydoc WINTUN_SEND_PACKET
- */
-void WINAPI
-WintunSendPacket(_In_ TUN_SESSION *Session, _In_ const BYTE *Packet);
diff --git a/example/example.c b/example/example.c
index 02e1443..0914f3c 100644
--- a/example/example.c
+++ b/example/example.c
@@ -3,16 +3,31 @@
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
*/
-#include "../api/wintun.h"
+#include
+#include
+#include
+#include
+#include
#include
#include
+#include "wintun.h"
-static WINTUN_GET_VERSION_FUNC WintunGetVersion;
-static WINTUN_SET_LOGGER_FUNC WintunSetLogger;
static WINTUN_CREATE_ADAPTER_FUNC WintunCreateAdapter;
static WINTUN_DELETE_ADAPTER_FUNC WintunDeleteAdapter;
+static WINTUN_DELETE_DRIVER_FUNC WintunDeleteDriver;
+static WINTUN_ENUM_ADAPTERS_FUNC WintunEnumAdapters;
+static WINTUN_FREE_ADAPTER_FUNC WintunFreeAdapter;
+static WINTUN_GET_ADAPTER_FUNC WintunGetAdapter;
+static WINTUN_GET_ADAPTER_DEVICE_OBJECT_FUNC WintunGetAdapterDeviceObject;
+static WINTUN_GET_ADAPTER_GUID_FUNC WintunGetAdapterGUID;
+static WINTUN_GET_ADAPTER_LUID_FUNC WintunGetAdapterLUID;
+static WINTUN_GET_ADAPTER_NAME_FUNC WintunGetAdapterName;
+static WINTUN_SET_ADAPTER_NAME_FUNC WintunSetAdapterName;
+static WINTUN_GET_VERSION_FUNC WintunGetVersion;
+static WINTUN_SET_LOGGER_FUNC WintunSetLogger;
static WINTUN_START_SESSION_FUNC WintunStartSession;
static WINTUN_END_SESSION_FUNC WintunEndSession;
+static WINTUN_GET_READ_WAIT_EVENT_FUNC WintunGetReadWaitEvent;
static WINTUN_RECEIVE_PACKET_FUNC WintunReceivePacket;
static WINTUN_RECEIVE_RELEASE_FUNC WintunReceiveRelease;
static WINTUN_ALLOCATE_SEND_PACKET_FUNC WintunAllocateSendPacket;
@@ -59,9 +74,8 @@ ConsoleLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *LogLine)
}
static DWORD
-LogLastError(_In_z_ const WCHAR *Prefix)
+LogError(_In_z_ const WCHAR *Prefix, _In_ DWORD Error)
{
- DWORD Error = GetLastError();
WCHAR *SystemMessage = NULL, *FormattedMessage = NULL;
FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK,
@@ -84,7 +98,6 @@ LogLastError(_In_z_ const WCHAR *Prefix)
ConsoleLogger(WINTUN_LOG_ERR, FormattedMessage);
LocalFree(FormattedMessage);
LocalFree(SystemMessage);
- SetLastError(Error);
return Error;
}
@@ -100,7 +113,7 @@ Log(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *Format, ...)
}
static BOOL WINAPI
-CtrlHandler(DWORD CtrlType)
+CtrlHandler(_In_ DWORD CtrlType)
{
switch (CtrlType)
{
@@ -109,6 +122,7 @@ CtrlHandler(DWORD CtrlType)
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
+ Log(WINTUN_LOG_INFO, L"Cleaning up and shutting down...");
HaveQuit = TRUE;
SetEvent(QuitEvent);
return TRUE;
@@ -116,143 +130,249 @@ CtrlHandler(DWORD CtrlType)
return FALSE;
}
-static DWORD WINAPI
-TestAdapter(_Inout_ DWORD_PTR Index)
+static void
+PrintPacket(_In_ const BYTE *Packet, _In_ DWORD PacketSize)
{
- /* Create adapter. */
- WCHAR AdapterName[MAX_ADAPTER_NAME];
- _snwprintf_s(
- AdapterName,
- _countof(AdapterName),
- _TRUNCATE,
- L"test-%d.%d-%zu",
- WINTUN_VERSION_MAJ,
- WINTUN_VERSION_MIN,
- Index);
- const GUID AdapterGuid = { 0xeef7ebf,
- WINTUN_VERSION_MAJ,
- WINTUN_VERSION_MIN,
- { (BYTE)Index & 0xff, 0xa, 0x33, 0xbf, 0x5c, 0x8, 0x4a, 0xc6 } };
+ if (PacketSize < 20)
+ {
+ Log(WINTUN_LOG_INFO, L"Received packet without room for an IP header");
+ return;
+ }
+ BYTE IpVersion = Packet[0] >> 4, Proto;
+ WCHAR Src[46], Dst[46];
+ if (IpVersion == 4)
+ {
+ RtlIpv4AddressToStringW((struct in_addr *)&Packet[12], Src);
+ RtlIpv4AddressToStringW((struct in_addr *)&Packet[16], Dst);
+ Proto = Packet[9];
+ Packet += 20, PacketSize -= 20;
+ }
+ else if (IpVersion == 6 && PacketSize < 40)
+ {
+ Log(WINTUN_LOG_INFO, L"Received packet without room for an IP header");
+ return;
+ }
+ else if (IpVersion == 6)
+ {
+ RtlIpv6AddressToStringW((struct in6_addr *)&Packet[8], Src);
+ RtlIpv6AddressToStringW((struct in6_addr *)&Packet[24], Dst);
+ Proto = Packet[6];
+ Packet += 40, PacketSize -= 40;
+ }
+ else
+ {
+ Log(WINTUN_LOG_INFO, L"Received packet that was not IP");
+ return;
+ }
+ if (Proto == 1 && PacketSize >= 8 && Packet[0] == 0)
+ Log(WINTUN_LOG_INFO, L"Received IPv%d ICMP echo reply from %s to %s", IpVersion, Src, Dst);
+ else
+ Log(WINTUN_LOG_INFO, L"Received IPv%d proto 0x%x packet from %s to %s", IpVersion, Proto, Src, Dst);
+}
+
+static USHORT
+IPChecksum(BYTE *Buffer, DWORD Len)
+{
+ ULONG Sum = 0;
+ for (; Len > 1; Len -= 2, Buffer += 2)
+ Sum += *(USHORT *)Buffer;
+ if (Len)
+ Sum += *Buffer;
+ Sum = (Sum >> 16) + (Sum & 0xffff);
+ Sum += (Sum >> 16);
+ return (USHORT)(~Sum);
+}
+
+static void
+MakeICMP(_Inout_ BYTE Packet[28])
+{
+ memset(Packet, 0, 28);
+ Packet[0] = 0x45;
+ *(USHORT *)&Packet[2] = htons(28);
+ Packet[8] = 255;
+ Packet[9] = 1;
+ *(ULONG *)&Packet[12] = htonl((10 << 24) | (6 << 16) | (7 << 8) | (8 << 0)); /* 10.6.7.8 */
+ *(ULONG *)&Packet[16] = htonl((10 << 24) | (6 << 16) | (7 << 8) | (7 << 0)); /* 10.6.7.7 */
+ *(USHORT *)&Packet[10] = IPChecksum(Packet, 20);
+ Packet[20] = 8;
+ *(USHORT *)&Packet[22] = IPChecksum(&Packet[20], 8);
+ Log(WINTUN_LOG_INFO, L"Sending IPv4 ICMP echo request to 10.6.7.8 from 10.6.7.7");
+}
+
+static DWORD WINAPI
+ReceivePackets(_Inout_ DWORD_PTR SessionPtr)
+{
+ WINTUN_SESSION_HANDLE Session = (WINTUN_SESSION_HANDLE)SessionPtr;
+ HANDLE WaitHandles[] = { WintunGetReadWaitEvent(Session), QuitEvent };
+
while (!HaveQuit)
{
- WINTUN_ADAPTER_HANDLE Adapter;
- BOOL RebootRequired = FALSE;
- DWORD Result = WintunCreateAdapter(L"Example", AdapterName, &AdapterGuid, &Adapter, &RebootRequired);
- if (Result != ERROR_SUCCESS)
+ BYTE *Packet;
+ DWORD PacketSize;
+ DWORD Result = WintunReceivePacket(Session, &Packet, &PacketSize);
+ switch (Result)
{
- Log(WINTUN_LOG_ERR, L"%s adapter creation failed.\n", AdapterName);
+ case ERROR_SUCCESS:
+ PrintPacket(Packet, PacketSize);
+ WintunReceiveRelease(Session, Packet);
+ continue;
+ case ERROR_NO_MORE_ITEMS:
+ if (WaitForMultipleObjects(_countof(WaitHandles), WaitHandles, FALSE, INFINITE) == WAIT_OBJECT_0)
+ continue;
+ return ERROR_SUCCESS;
+ default:
+ LogError(L"Packet read failed", Result);
return Result;
}
-
- DWORDLONG WintunVersion = WintunGetVersion();
- Log(WINTUN_LOG_INFO,
- L"%s adapter created (Wintun %d.%d.%d.%d, reboot: %d).\n",
- AdapterName,
- (WintunVersion >> 48) & 0xffff,
- (WintunVersion >> 32) & 0xffff,
- (WintunVersion >> 16) & 0xffff,
- (WintunVersion >> 0) & 0xffff,
- RebootRequired ? 1 : 0);
-
- WINTUN_SESSION_HANDLE Session;
- HANDLE WaitHandles[2] = { NULL, QuitEvent };
- Result = WintunStartSession(Adapter, 0x100000, &Session, &WaitHandles[0]);
- if (Result != ERROR_SUCCESS)
- {
- Log(WINTUN_LOG_ERR, L"%s session creation failed.\n", AdapterName);
- goto cleanupAdapter;
- }
- while (!HaveQuit)
- {
- BYTE *Packet;
- DWORD PacketSize;
- Result = WintunReceivePacket(Session, &Packet, &PacketSize);
- switch (Result)
- {
- case ERROR_SUCCESS:
- // TODO: Process packet.
- WintunReceiveRelease(Session, Packet);
- continue;
- case ERROR_NO_MORE_ITEMS:
- if (WaitForMultipleObjects(_countof(WaitHandles), WaitHandles, FALSE, INFINITE) == WAIT_OBJECT_0)
- continue;
- goto cleanupSession;
- }
- Log(WINTUN_LOG_ERR, L"%s packet read failed (Code 0x%08X).\n", AdapterName, Result);
- goto cleanupSession;
- }
- cleanupSession:
- WintunEndSession(Session);
- cleanupAdapter:
- WintunDeleteAdapter(Adapter, TRUE, &RebootRequired);
}
return ERROR_SUCCESS;
}
+static DWORD WINAPI
+SendPackets(_Inout_ DWORD_PTR SessionPtr)
+{
+ WINTUN_SESSION_HANDLE Session = (WINTUN_SESSION_HANDLE)SessionPtr;
+ while (!HaveQuit)
+ {
+ BYTE *Packet;
+ WintunAllocateSendPacket(Session, 28, &Packet);
+ MakeICMP(Packet);
+ WintunSendPacket(Session, Packet);
+
+ switch (WaitForSingleObject(QuitEvent, 1000 /* 1 second */))
+ {
+ case WAIT_ABANDONED:
+ case WAIT_OBJECT_0:
+ return ERROR_SUCCESS;
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
+static HMODULE
+InitializeWintun(void)
+{
+ HMODULE Wintun =
+ LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (!Wintun)
+ return NULL;
+#define X(Name, Type) ((Name = (Type)GetProcAddress(Wintun, #Name)) == NULL)
+ if (X(WintunCreateAdapter, WINTUN_CREATE_ADAPTER_FUNC) || X(WintunDeleteAdapter, WINTUN_DELETE_ADAPTER_FUNC) ||
+ X(WintunDeleteDriver, WINTUN_DELETE_DRIVER_FUNC) || X(WintunEnumAdapters, WINTUN_ENUM_ADAPTERS_FUNC) ||
+ X(WintunFreeAdapter, WINTUN_FREE_ADAPTER_FUNC) || X(WintunGetAdapter, WINTUN_GET_ADAPTER_FUNC) ||
+ X(WintunGetAdapterDeviceObject, WINTUN_GET_ADAPTER_DEVICE_OBJECT_FUNC) ||
+ X(WintunGetAdapterGUID, WINTUN_GET_ADAPTER_GUID_FUNC) ||
+ X(WintunGetAdapterLUID, WINTUN_GET_ADAPTER_LUID_FUNC) ||
+ X(WintunGetAdapterName, WINTUN_GET_ADAPTER_NAME_FUNC) ||
+ X(WintunSetAdapterName, WINTUN_SET_ADAPTER_NAME_FUNC) || X(WintunGetVersion, WINTUN_GET_VERSION_FUNC) ||
+ X(WintunSetLogger, WINTUN_SET_LOGGER_FUNC) || X(WintunStartSession, WINTUN_START_SESSION_FUNC) ||
+ X(WintunEndSession, WINTUN_END_SESSION_FUNC) || X(WintunGetReadWaitEvent, WINTUN_GET_READ_WAIT_EVENT_FUNC) ||
+ X(WintunReceivePacket, WINTUN_RECEIVE_PACKET_FUNC) || X(WintunReceiveRelease, WINTUN_RECEIVE_RELEASE_FUNC) ||
+ X(WintunAllocateSendPacket, WINTUN_ALLOCATE_SEND_PACKET_FUNC) || X(WintunSendPacket, WINTUN_SEND_PACKET_FUNC))
+#undef X
+ {
+ DWORD Result = GetLastError();
+ FreeLibrary(Wintun);
+ SetLastError(Result);
+ return NULL;
+ }
+ SetLastError(ERROR_SUCCESS);
+ return Wintun;
+}
+
int
main(void)
{
- Log(WINTUN_LOG_INFO, L"Wintun Test v%d.%d\n", WINTUN_VERSION_MAJ, WINTUN_VERSION_MIN);
-
- HMODULE Wintun =
- LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
+ HMODULE Wintun = InitializeWintun();
if (!Wintun)
- return LogLastError(L"Failed to load wintun.dll");
- DWORD Result;
- if ((WintunGetVersion = (WINTUN_GET_VERSION_FUNC)GetProcAddress(Wintun, "WintunGetVersion")) == NULL ||
- (WintunSetLogger = (WINTUN_SET_LOGGER_FUNC)GetProcAddress(Wintun, "WintunSetLogger")) == NULL ||
- (WintunCreateAdapter = (WINTUN_CREATE_ADAPTER_FUNC)GetProcAddress(Wintun, "WintunCreateAdapter")) == NULL ||
- (WintunDeleteAdapter = (WINTUN_DELETE_ADAPTER_FUNC)GetProcAddress(Wintun, "WintunDeleteAdapter")) == NULL ||
- (WintunStartSession = (WINTUN_START_SESSION_FUNC)GetProcAddress(Wintun, "WintunStartSession")) == NULL ||
- (WintunEndSession = (WINTUN_END_SESSION_FUNC)GetProcAddress(Wintun, "WintunEndSession")) == NULL ||
- (WintunReceivePacket = (WINTUN_RECEIVE_PACKET_FUNC)GetProcAddress(Wintun, "WintunReceivePacket")) == NULL ||
- (WintunReceiveRelease = (WINTUN_RECEIVE_RELEASE_FUNC)GetProcAddress(Wintun, "WintunReceiveRelease")) == NULL ||
- (WintunAllocateSendPacket =
- (WINTUN_ALLOCATE_SEND_PACKET_FUNC)GetProcAddress(Wintun, "WintunAllocateSendPacket")) == NULL ||
- (WintunSendPacket = (WINTUN_SEND_PACKET_FUNC)GetProcAddress(Wintun, "WintunSendPacket")) == NULL)
- {
- Result = LogLastError(L"Failed to get wintun.dll entries");
- goto cleanupWintun;
- }
+ return LogError(L"Failed to initialize Wintun", GetLastError());
+ WintunSetLogger(ConsoleLogger);
+ Log(WINTUN_LOG_INFO, L"Wintun library loaded");
+ DWORD Result;
HaveQuit = FALSE;
QuitEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!QuitEvent)
{
- Result = LogLastError(L"Failed to create event");
+ Result = LogError(L"Failed to create event", GetLastError());
goto cleanupWintun;
}
- WintunSetLogger(ConsoleLogger);
if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
{
- Result = LogLastError(L"Failed to set console handler");
+ Result = LogError(L"Failed to set console handler", GetLastError());
goto cleanupQuit;
}
- HANDLE Workers[MAXIMUM_WAIT_OBJECTS] = { 0 };
- for (size_t i = 0; i < _countof(Workers); ++i)
- if (!Workers[i])
- {
- Workers[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TestAdapter, (LPVOID)i, 0, NULL);
- if (!Workers[i])
- {
- Result = LogLastError(L"Failed to create thread");
- goto cleanupWorkers;
- }
- }
+ GUID ExampleGuid = { 0xdeadbabe, 0xcafe, 0xbeef, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef } };
+ WINTUN_ADAPTER_HANDLE Adapter;
+ Result = WintunGetAdapter(L"Example", L"Demo", &Adapter);
+ if (Result != ERROR_SUCCESS)
+ Result = WintunCreateAdapter(L"Example", L"Demo", &ExampleGuid, &Adapter, NULL);
+ if (Result != ERROR_SUCCESS)
+ {
+ LogError(L"Failed to create adapter", Result);
+ goto cleanupQuit;
+ }
+
+ DWORDLONG Version = WintunGetVersion();
+ Log(WINTUN_LOG_INFO,
+ L"Wintun v%d.%d.%d.%d loaded",
+ (Version >> 48) & 0xff,
+ (Version >> 32) & 0xff,
+ (Version >> 16) & 0xff,
+ (Version >> 0) & 0xff,
+ WINTUN_VERSION_MIN);
+
+ MIB_UNICASTIPADDRESS_ROW AddressRow;
+ InitializeUnicastIpAddressEntry(&AddressRow);
+ WintunGetAdapterLUID(Adapter, &AddressRow.InterfaceLuid);
+ AddressRow.Address.Ipv4.sin_family = AF_INET;
+ AddressRow.Address.Ipv4.sin_addr.S_un.S_addr = htonl((10 << 24) | (6 << 16) | (7 << 8) | (7 << 0)); /* 10.6.7.7 */
+ AddressRow.OnLinkPrefixLength = 24; /* This is a /24 network */
+ Result = CreateUnicastIpAddressEntry(&AddressRow);
+ if (Result != ERROR_SUCCESS)
+ {
+ LogError(L"Failed to set IP address", Result);
+ goto cleanupAdapter;
+ }
+
+ WINTUN_SESSION_HANDLE Session;
+ Result = WintunStartSession(Adapter, 0x40000, &Session);
+ if (Result != ERROR_SUCCESS)
+ {
+ LogError(L"Failed to create adapter", Result);
+ goto cleanupAdapter;
+ }
+
+ Log(WINTUN_LOG_INFO, L"Launching threads and mangling packets...");
+
+ HANDLE Workers[] = { CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceivePackets, (LPVOID)Session, 0, NULL),
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SendPackets, (LPVOID)Session, 0, NULL) };
+ if (!Workers[0] || !Workers[1])
+ {
+ Result = LogError(L"Failed to create threads", GetLastError());
+ goto cleanupWorkers;
+ }
WaitForMultipleObjectsEx(_countof(Workers), Workers, TRUE, INFINITE, TRUE);
Result = ERROR_SUCCESS;
+
cleanupWorkers:
HaveQuit = TRUE;
SetEvent(QuitEvent);
for (size_t i = 0; i < _countof(Workers); ++i)
+ {
if (Workers[i])
{
WaitForSingleObject(Workers[i], INFINITE);
CloseHandle(Workers[i]);
}
- SetConsoleCtrlHandler(CtrlHandler, FALSE);
+ }
+ WintunEndSession(Session);
+cleanupAdapter:
+ WintunDeleteAdapter(Adapter, FALSE, NULL);
+ WintunFreeAdapter(Adapter);
cleanupQuit:
+ SetConsoleCtrlHandler(CtrlHandler, FALSE);
CloseHandle(QuitEvent);
cleanupWintun:
FreeLibrary(Wintun);
diff --git a/example/example.vcxproj b/example/example.vcxproj
index 4deb367..3c8d8d1 100644
--- a/example/example.vcxproj
+++ b/example/example.vcxproj
@@ -52,17 +52,14 @@
- Application
true
- v142
- Unicode
- false
- Application
- false
- v142
true
+
+
+ Application
+ v142
Unicode
false
@@ -107,7 +104,15 @@
UseLinkTimeCodeGeneration
+
+
+ iphlpapi.lib;kernel32.lib;ntdll.lib;ws2_32.lib;%(AdditionalDependencies)
+
+
+ ..\api
+
+
-
+
\ No newline at end of file
diff --git a/example/example.vcxproj.filters b/example/example.vcxproj.filters
index d292814..eb29fb9 100644
--- a/example/example.vcxproj.filters
+++ b/example/example.vcxproj.filters
@@ -5,14 +5,6 @@
{4FC737F1-C7A5-4376-A066-2A32D752A2FF}
cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
diff --git a/wintun.sln b/wintun.sln
index 61788f9..19f6f49 100644
--- a/wintun.sln
+++ b/wintun.sln
@@ -64,13 +64,21 @@ Global
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.ActiveCfg = Release|Win32
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.Build.0 = Release|Win32
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|amd64.ActiveCfg = Debug|x64
+ {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|amd64.Build.0 = Debug|x64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm.ActiveCfg = Debug|ARM
+ {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm.Build.0 = Debug|ARM
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm64.ActiveCfg = Debug|ARM64
+ {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm64.Build.0 = Debug|ARM64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|x86.ActiveCfg = Debug|Win32
+ {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|x86.Build.0 = Debug|Win32
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|amd64.ActiveCfg = Release|x64
+ {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|amd64.Build.0 = Release|x64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm.ActiveCfg = Release|ARM
+ {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm.Build.0 = Release|ARM
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm64.ActiveCfg = Release|ARM64
+ {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm64.Build.0 = Release|ARM64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|x86.ActiveCfg = Release|Win32
+ {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE