2019-03-28 16:54:38 +01:00
# [Wintun Network Adapter](https://www.wintun.net/)
2019-03-08 22:33:15 +01:00
### TUN Device Driver for Windows
This is a layer 3 TUN driver for Windows 7, 8, 8.1, and 10. Originally created for [WireGuard ](https://www.wireguard.com/ ), it is intended to be useful to a wide variety of projects that require layer 3 tunneling devices with implementations primarily in userspace.
2019-08-01 17:42:54 +02:00
## Installation
2019-03-08 22:33:15 +01:00
2020-10-25 00:23:33 +02:00
Wintun is deployed as a platform-specific `wintun.dll` file. Install the `wintun.dll` file side-by-side with your application.
2019-04-13 19:15:23 +02:00
2019-03-27 10:54:25 +01:00
## Usage
2020-10-25 00:23:33 +02:00
Include `wintun.h` file in your project and dynamically load the `wintun.dll` using [`LoadLibraryEx()` ](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa ) and [`GetProcAddress()` ](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress ).
2019-03-27 10:54:25 +01:00
2020-10-25 00:23:33 +02:00
Each function has its function typedef in `wintun.h` with additional usage documentation.
2019-07-08 11:01:39 +02:00
```C
2020-10-25 00:23:33 +02:00
#include "wintun.h"
⋮
HMODULE Wintun = LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
if (!Wintun)
return GetLastError();
WINTUN_CREATE_ADAPTER_FUNC WintunCreateAdapter = (WINTUN_CREATE_ADAPTER_FUNC)GetProcAddress(Wintun, "WintunCreateAdapter");
WINTUN_DELETE_ADAPTER_FUNC WintunDeleteAdapter = (WINTUN_DELETE_ADAPTER_FUNC)GetProcAddress(Wintun, "WintunDeleteAdapter");
2019-07-08 11:01:39 +02:00
```
2020-10-25 00:23:33 +02:00
### Adapter management
2019-07-08 11:01:39 +02:00
2020-10-25 00:23:33 +02:00
Adapters are grouped together in pools to allow various clients on the same machine. Each client vendor should pick own unique pool name.
2019-07-08 11:01:39 +02:00
2020-10-25 00:23:33 +02:00
Manage the network adapters using following functions:
2019-07-08 11:01:39 +02:00
2020-10-25 00:23:33 +02:00
- `WintunCreateAdapter()` creates a new adapter.
- `WintunDeleteAdapter()` deletes the adapter.
- `WintunEnumAdapters()` enumerates all existing adapters.
- `WintunGetAdapter()` gets existing adapter handle.
- `WintunFreeAdapter()` frees adapter handle.
- `WintunGetAdapterDeviceObject()` opens adapter device object.
- `WintunGetAdapterGUID()` gets adapter GUID.
- `WintunGetAdapterLUID()` gets adapter LUID.
- `WintunGetAdapterName()` gets adapter name.
- `WintunSetAdapterName()` sets adapter name.
2019-07-08 11:01:39 +02:00
2020-10-25 00:23:33 +02:00
Example:
2019-07-08 11:01:39 +02:00
```C
2020-10-25 00:23:33 +02:00
DWORD Result;
WINTUN_ADAPTER_HANDLE Adapter;
BOOL RebootRequired;
Result = WintunCreateAdapter(L"com.contoso.myapp", "My VPN adapter", NULL, & Adapter, &RebootRequired);
if (Result != ERROR_SUCCESS)
return Result;
2019-07-08 11:01:39 +02:00
```
2020-10-25 00:23:33 +02:00
### Session management
2019-07-08 11:01:39 +02:00
2020-10-25 00:23:33 +02:00
Once adapter is created, use the following functions to start a session and transfer packets:
2019-07-08 11:01:39 +02:00
2020-10-25 00:23:33 +02:00
- `WintunStartSession()` starts a session. One adapter may have only one session.
- `WintunEndSession()` ends and frees the session.
- `WintunIsPacketAvailable()` checks if there is a receive packet available.
- `WintunWaitForPacket()` waits for a receive packet to become available.
2020-10-25 10:01:35 +01:00
- `WintunReceivePacket()` receives one packet.
- `WintunReceiveRelease()` releases internal buffer after client processed the receive packet.
- `WintunAllocateSendPacket()` allocates memory for send packet.
- `WintunSendPacket()` sends the packet.
2019-07-17 15:54:12 +02:00
2020-10-25 00:23:33 +02:00
#### Writing to and from rings
Reading packets from the adapter may be done as:
2019-07-08 11:01:39 +02:00
```C
2020-10-25 00:23:33 +02:00
// TODO: Preallocate WINTUN_PACKET *Queue linked list with WINTUN_MAX_IP_PACKET_SIZE packets.
for (;;) {
if (!WintunIsPacketAvailable(Session))
WintunWaitForPacket(Session, INFINITE);
for (WINTUN_PACKET *p = Queue; p & & p->Size < = WINTUN_MAX_IP_PACKET_SIZE; p = p->Next)
p->Size = DWORD_MAX;
2020-10-25 10:01:35 +01:00
BYTE *Packet;
DWORD PacketSize;
DWORD Result = WintunReceivePacket(Session, & Packet, &PacketSize);
if (Result != ERROR_SUCCESS)
2020-10-25 00:23:33 +02:00
return Result;
2020-10-25 10:01:35 +01:00
// TODO: Process packet.
WintunReceiveRelease(Session, Packet);
2020-10-25 00:23:33 +02:00
}
2019-03-27 10:54:25 +01:00
```
2019-07-08 11:01:39 +02:00
2020-10-25 00:23:33 +02:00
It may be desirable to spin on `WintunIsPacketAvailable()` for some time under heavy use before waiting with `WintunWaitForPacket()` , in order to reduce latency.
2019-07-17 15:54:12 +02:00
2020-10-25 00:23:33 +02:00
Writing packets to the adapter may be done as:
2019-07-08 11:01:39 +02:00
```C
2020-10-25 10:01:35 +01:00
// TODO: Calculate packet size.
BYTE *Packet;
DWORD Result = WintunAllocateSendPacket(Session, PacketSize, &Packet);
if (Result != ERROR_SUCCESS)
return Result;
// TODO: Fill the packet.
WintunSendPacket(Session, Packet);
2019-07-08 11:01:39 +02:00
```
2020-10-25 00:23:33 +02:00
### Misc functions
Other `wintun.dll` functions are:
2019-07-17 15:54:12 +02:00
2020-10-25 00:23:33 +02:00
- `WintunGetVersion()` returns driver and NDIS major and minor versions.
- `WintunSetLogger()` sets global logging callback function.
2019-07-08 11:01:39 +02:00
2020-10-25 00:23:33 +02:00
Example:
2019-07-08 11:01:39 +02:00
```C
2020-10-25 00:23:33 +02:00
static BOOL CALLBACK
ConsoleLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_ const WCHAR *LogLine)
{
const WCHAR *Template;
switch (Level)
{
case WINTUN_LOG_INFO: Template = L"[+] %s\n"; break;
case WINTUN_LOG_WARN: Template = L"[-] %s\n"; break;
case WINTUN_LOG_ERR: Template = L"[!] %s\n"; break;
default: return FALSE;
}
fwprintf(stderr, Template, LogLine);
return TRUE;
2019-07-08 11:01:39 +02:00
}
2020-10-25 00:23:33 +02:00
⋮
WintunSetLogger(ConsoleLogger);
2019-03-27 10:54:25 +01:00
```
2019-08-01 17:42:54 +02:00
## Building
2020-10-25 00:23:33 +02:00
**Do not distribute drivers named "Wintun", as they will most certainly clash with official deployments. Instead distribute `wintun.dll` .**
2019-08-02 13:30:19 +02:00
2019-08-01 17:42:54 +02:00
General requirements:
- [Visual Studio 2019 ](https://visualstudio.microsoft.com/downloads/ )
- [Windows Driver Kit for Windows 10, version 1903 ](https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk )
2019-08-02 13:30:19 +02:00
`wintun.sln` may be opened in Visual Studio for development and building. Be sure to run `bcdedit /set testsigning on` before to enable unsigned driver loading. The default run sequence (F5) in Visual Studio will build and insert Wintun.
2019-08-02 13:00:35 +02:00
## License
The entire contents of this repository, including all documentation code, is "Copyright © 2018-2019 WireGuard LLC. All Rights Reserved." and is licensed under the [GPLv2 ](COPYING ).