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.