github.com/slackhq/nebula@v1.9.0/dist/windows/wintun/README.md (about) 1 # [Wintun Network Adapter](https://www.wintun.net/) 2 ### TUN Device Driver for Windows 3 4 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. 5 6 ## Installation 7 8 Wintun is deployed as a platform-specific `wintun.dll` file. Install the `wintun.dll` file side-by-side with your application. Download the dll from [wintun.net](https://www.wintun.net/), alongside the header file for your application described below. 9 10 ## Usage 11 12 Include the [`wintun.h` file](https://git.zx2c4.com/wintun/tree/api/wintun.h) in your project simply by copying it there 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) to resolve each function, using the typedefs provided in the header file. The [`InitializeWintun` function in the example.c code](https://git.zx2c4.com/wintun/tree/example/example.c) provides this in a function that you can simply copy and paste. 13 14 With the library setup, Wintun can then be used by first creating an adapter, configuring it, and then setting its status to "up". Adapters have names (e.g. "OfficeNet") and types (e.g. "Wintun"). 15 16 ```C 17 WINTUN_ADAPTER_HANDLE Adapter1 = WintunCreateAdapter(L"OfficeNet", L"Wintun", &SomeFixedGUID1); 18 WINTUN_ADAPTER_HANDLE Adapter2 = WintunCreateAdapter(L"HomeNet", L"Wintun", &SomeFixedGUID2); 19 WINTUN_ADAPTER_HANDLE Adapter3 = WintunCreateAdapter(L"Data Center", L"Wintun", &SomeFixedGUID3); 20 ``` 21 22 After creating an adapter, we can use it by starting a session: 23 24 ```C 25 WINTUN_SESSION_HANDLE Session = WintunStartSession(Adapter2, 0x400000); 26 ``` 27 28 Then, the `WintunAllocateSendPacket` and `WintunSendPacket` functions can be used for sending packets ([used by `SendPackets` in the example.c code](https://git.zx2c4.com/wintun/tree/example/example.c)): 29 30 ```C 31 BYTE *OutgoingPacket = WintunAllocateSendPacket(Session, PacketDataSize); 32 if (OutgoingPacket) 33 { 34 memcpy(OutgoingPacket, PacketData, PacketDataSize); 35 WintunSendPacket(Session, OutgoingPacket); 36 } 37 else if (GetLastError() != ERROR_BUFFER_OVERFLOW) // Silently drop packets if the ring is full 38 Log(L"Packet write failed"); 39 ``` 40 41 And the `WintunReceivePacket` and `WintunReleaseReceivePacket` functions can be used for receiving packets ([used by `ReceivePackets` in the example.c code](https://git.zx2c4.com/wintun/tree/example/example.c)): 42 43 ```C 44 for (;;) 45 { 46 DWORD IncomingPacketSize; 47 BYTE *IncomingPacket = WintunReceivePacket(Session, &IncomingPacketSize); 48 if (IncomingPacket) 49 { 50 DoSomethingWithPacket(IncomingPacket, IncomingPacketSize); 51 WintunReleaseReceivePacket(Session, IncomingPacket); 52 } 53 else if (GetLastError() == ERROR_NO_MORE_ITEMS) 54 WaitForSingleObject(WintunGetReadWaitEvent(Session), INFINITE); 55 else 56 { 57 Log(L"Packet read failed"); 58 break; 59 } 60 } 61 ``` 62 63 Some high performance use cases may want to spin on `WintunReceivePackets` for a number of cycles before falling back to waiting on the read-wait event. 64 65 You are **highly encouraged** to read the [**example.c short example**](https://git.zx2c4.com/wintun/tree/example/example.c) to see how to put together a simple userspace network tunnel. 66 67 The various functions and definitions are [documented in the reference below](#Reference). 68 69 ## Reference 70 71 ### Macro Definitions 72 73 #### WINTUN\_MAX\_POOL 74 75 `#define WINTUN_MAX_POOL 256` 76 77 Maximum pool name length including zero terminator 78 79 #### WINTUN\_MIN\_RING\_CAPACITY 80 81 `#define WINTUN_MIN_RING_CAPACITY 0x20000 /* 128kiB */` 82 83 Minimum ring capacity. 84 85 #### WINTUN\_MAX\_RING\_CAPACITY 86 87 `#define WINTUN_MAX_RING_CAPACITY 0x4000000 /* 64MiB */` 88 89 Maximum ring capacity. 90 91 #### WINTUN\_MAX\_IP\_PACKET\_SIZE 92 93 `#define WINTUN_MAX_IP_PACKET_SIZE 0xFFFF` 94 95 Maximum IP packet size 96 97 ### Typedefs 98 99 #### WINTUN\_ADAPTER\_HANDLE 100 101 `typedef void* WINTUN_ADAPTER_HANDLE` 102 103 A handle representing Wintun adapter 104 105 #### WINTUN\_ENUM\_CALLBACK 106 107 `typedef BOOL(* WINTUN_ENUM_CALLBACK) (WINTUN_ADAPTER_HANDLE Adapter, LPARAM Param)` 108 109 Called by WintunEnumAdapters for each adapter in the pool. 110 111 **Parameters** 112 113 - *Adapter*: Adapter handle, which will be freed when this function returns. 114 - *Param*: An application-defined value passed to the WintunEnumAdapters. 115 116 **Returns** 117 118 Non-zero to continue iterating adapters; zero to stop. 119 120 #### WINTUN\_LOGGER\_CALLBACK 121 122 `typedef void(* WINTUN_LOGGER_CALLBACK) (WINTUN_LOGGER_LEVEL Level, DWORD64 Timestamp, const WCHAR *Message)` 123 124 Called by internal logger to report diagnostic messages 125 126 **Parameters** 127 128 - *Level*: Message level. 129 - *Timestamp*: Message timestamp in in 100ns intervals since 1601-01-01 UTC. 130 - *Message*: Message text. 131 132 #### WINTUN\_SESSION\_HANDLE 133 134 `typedef void* WINTUN_SESSION_HANDLE` 135 136 A handle representing Wintun session 137 138 ### Enumeration Types 139 140 #### WINTUN\_LOGGER\_LEVEL 141 142 `enum WINTUN_LOGGER_LEVEL` 143 144 Determines the level of logging, passed to WINTUN\_LOGGER\_CALLBACK. 145 146 - *WINTUN\_LOG\_INFO*: Informational 147 - *WINTUN\_LOG\_WARN*: Warning 148 - *WINTUN\_LOG\_ERR*: Error 149 150 Enumerator 151 152 ### Functions 153 154 #### WintunCreateAdapter() 155 156 `WINTUN_ADAPTER_HANDLE WintunCreateAdapter (const WCHAR * Name, const WCHAR * TunnelType, const GUID * RequestedGUID)` 157 158 Creates a new Wintun adapter. 159 160 **Parameters** 161 162 - *Name*: The requested name of the adapter. Zero-terminated string of up to MAX\_ADAPTER\_NAME-1 characters. 163 - *Name*: Name of the adapter tunnel type. Zero-terminated string of up to MAX\_ADAPTER\_NAME-1 characters. 164 - *RequestedGUID*: The GUID of the created network adapter, which then influences NLA generation deterministically. If it is set to NULL, the GUID is chosen by the system at random, and hence a new NLA entry is created for each new adapter. It is called "requested" GUID because the API it uses is completely undocumented, and so there could be minor interesting complications with its usage. 165 166 **Returns** 167 168 If the function succeeds, the return value is the adapter handle. Must be released with WintunCloseAdapter. If the function fails, the return value is NULL. To get extended error information, call GetLastError. 169 170 #### WintunOpenAdapter() 171 172 `WINTUN_ADAPTER_HANDLE WintunOpenAdapter (const WCHAR * Name)` 173 174 Opens an existing Wintun adapter. 175 176 **Parameters** 177 178 - *Name*: The requested name of the adapter. Zero-terminated string of up to MAX\_ADAPTER\_NAME-1 characters. 179 180 **Returns** 181 182 If the function succeeds, the return value is adapter handle. Must be released with WintunCloseAdapter. If the function fails, the return value is NULL. To get extended error information, call GetLastError. 183 184 #### WintunCloseAdapter() 185 186 `void WintunCloseAdapter (WINTUN_ADAPTER_HANDLE Adapter)` 187 188 Releases Wintun adapter resources and, if adapter was created with WintunCreateAdapter, removes adapter. 189 190 **Parameters** 191 192 - *Adapter*: Adapter handle obtained with WintunCreateAdapter or WintunOpenAdapter. 193 194 #### WintunDeleteDriver() 195 196 `BOOL WintunDeleteDriver ()` 197 198 Deletes the Wintun driver if there are no more adapters in use. 199 200 **Returns** 201 202 If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. 203 204 #### WintunGetAdapterLuid() 205 206 `void WintunGetAdapterLuid (WINTUN_ADAPTER_HANDLE Adapter, NET_LUID * Luid)` 207 208 Returns the LUID of the adapter. 209 210 **Parameters** 211 212 - *Adapter*: Adapter handle obtained with WintunOpenAdapter or WintunCreateAdapter 213 - *Luid*: Pointer to LUID to receive adapter LUID. 214 215 #### WintunGetRunningDriverVersion() 216 217 `DWORD WintunGetRunningDriverVersion (void )` 218 219 Determines the version of the Wintun driver currently loaded. 220 221 **Returns** 222 223 If the function succeeds, the return value is the version number. If the function fails, the return value is zero. To get extended error information, call GetLastError. Possible errors include the following: ERROR\_FILE\_NOT\_FOUND Wintun not loaded 224 225 #### WintunSetLogger() 226 227 `void WintunSetLogger (WINTUN_LOGGER_CALLBACK NewLogger)` 228 229 Sets logger callback function. 230 231 **Parameters** 232 233 - *NewLogger*: Pointer to callback function to use as a new global logger. NewLogger may be called from various threads concurrently. Should the logging require serialization, you must handle serialization in NewLogger. Set to NULL to disable. 234 235 #### WintunStartSession() 236 237 `WINTUN_SESSION_HANDLE WintunStartSession (WINTUN_ADAPTER_HANDLE Adapter, DWORD Capacity)` 238 239 Starts Wintun session. 240 241 **Parameters** 242 243 - *Adapter*: Adapter handle obtained with WintunOpenAdapter or WintunCreateAdapter 244 - *Capacity*: Rings capacity. Must be between WINTUN\_MIN\_RING\_CAPACITY and WINTUN\_MAX\_RING\_CAPACITY (incl.) Must be a power of two. 245 246 **Returns** 247 248 Wintun session handle. Must be released with WintunEndSession. If the function fails, the return value is NULL. To get extended error information, call GetLastError. 249 250 #### WintunEndSession() 251 252 `void WintunEndSession (WINTUN_SESSION_HANDLE Session)` 253 254 Ends Wintun session. 255 256 **Parameters** 257 258 - *Session*: Wintun session handle obtained with WintunStartSession 259 260 #### WintunGetReadWaitEvent() 261 262 `HANDLE WintunGetReadWaitEvent (WINTUN_SESSION_HANDLE Session)` 263 264 Gets Wintun session's read-wait event handle. 265 266 **Parameters** 267 268 - *Session*: Wintun session handle obtained with WintunStartSession 269 270 **Returns** 271 272 Pointer to receive event handle to wait for available data when reading. Should WintunReceivePackets return ERROR\_NO\_MORE\_ITEMS (after spinning on it for a while under heavy load), wait for this event to become signaled before retrying WintunReceivePackets. Do not call CloseHandle on this event - it is managed by the session. 273 274 #### WintunReceivePacket() 275 276 `BYTE* WintunReceivePacket (WINTUN_SESSION_HANDLE Session, DWORD * PacketSize)` 277 278 Retrieves one or packet. After the packet content is consumed, call WintunReleaseReceivePacket with Packet returned from this function to release internal buffer. This function is thread-safe. 279 280 **Parameters** 281 282 - *Session*: Wintun session handle obtained with WintunStartSession 283 - *PacketSize*: Pointer to receive packet size. 284 285 **Returns** 286 287 Pointer to layer 3 IPv4 or IPv6 packet. Client may modify its content at will. If the function fails, the return value is NULL. To get extended error information, call GetLastError. Possible errors include the following: ERROR\_HANDLE\_EOF Wintun adapter is terminating; ERROR\_NO\_MORE\_ITEMS Wintun buffer is exhausted; ERROR\_INVALID\_DATA Wintun buffer is corrupt 288 289 #### WintunReleaseReceivePacket() 290 291 `void WintunReleaseReceivePacket (WINTUN_SESSION_HANDLE Session, const BYTE * Packet)` 292 293 Releases internal buffer after the received packet has been processed by the client. This function is thread-safe. 294 295 **Parameters** 296 297 - *Session*: Wintun session handle obtained with WintunStartSession 298 - *Packet*: Packet obtained with WintunReceivePacket 299 300 #### WintunAllocateSendPacket() 301 302 `BYTE* WintunAllocateSendPacket (WINTUN_SESSION_HANDLE Session, DWORD PacketSize)` 303 304 Allocates memory for a packet to send. After the memory is filled with packet data, call WintunSendPacket to send and release internal buffer. WintunAllocateSendPacket is thread-safe and the WintunAllocateSendPacket order of calls define the packet sending order. 305 306 **Parameters** 307 308 - *Session*: Wintun session handle obtained with WintunStartSession 309 - *PacketSize*: Exact packet size. Must be less or equal to WINTUN\_MAX\_IP\_PACKET\_SIZE. 310 311 **Returns** 312 313 Returns pointer to memory where to prepare layer 3 IPv4 or IPv6 packet for sending. If the function fails, the return value is NULL. To get extended error information, call GetLastError. Possible errors include the following: ERROR\_HANDLE\_EOF Wintun adapter is terminating; ERROR\_BUFFER\_OVERFLOW Wintun buffer is full; 314 315 #### WintunSendPacket() 316 317 `void WintunSendPacket (WINTUN_SESSION_HANDLE Session, const BYTE * Packet)` 318 319 Sends the packet and releases internal buffer. WintunSendPacket is thread-safe, but the WintunAllocateSendPacket order of calls define the packet sending order. This means the packet is not guaranteed to be sent in the WintunSendPacket yet. 320 321 **Parameters** 322 323 - *Session*: Wintun session handle obtained with WintunStartSession 324 - *Packet*: Packet obtained with WintunAllocateSendPacket 325 326 ## Building 327 328 **Do not distribute drivers or files named "Wintun", as they will most certainly clash with official deployments. Instead distribute [`wintun.dll` as downloaded from wintun.net](https://www.wintun.net).** 329 330 General requirements: 331 332 - [Visual Studio 2019](https://visualstudio.microsoft.com/downloads/) with Windows SDK 333 - [Windows Driver Kit](https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk) 334 335 `wintun.sln` may be opened in Visual Studio for development and building. Be sure to run `bcdedit /set testsigning on` and then reboot before to enable unsigned driver loading. The default run sequence (F5) in Visual Studio will build the example project and its dependencies. 336 337 ## License 338 339 The entire contents of [the repository](https://git.zx2c4.com/wintun/), including all documentation and example code, is "Copyright © 2018-2021 WireGuard LLC. All Rights Reserved." Source code is licensed under the [GPLv2](COPYING). Prebuilt binaries from [wintun.net](https://www.wintun.net/) are released under a more permissive license suitable for more forms of software contained inside of the .zip files distributed there.