wintun/api/wintun.h
Simon Rozman 4b8f879fd6 api: add ring management
Rather than every client reinvent the art of using the Wintun and its
ring buffers, we offer helper structs and functions to unify and
simplify Wintun usage.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-10-30 16:51:01 +01:00

337 lines
12 KiB
C

/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
*/
#pragma once
#include <Windows.h>
#include <IPExport.h>
typedef _Return_type_success_(return == ERROR_SUCCESS) DWORD WINTUN_STATUS;
/**
* A handle representing Wintun adapter
*/
typedef void *WINTUN_ADAPTER_HANDLE;
#define MAX_POOL 256
/**
* Creates a Wintun adapter.
*
* @param Pool Name of the adapter pool.
*
* @param Name The requested name of the adapter.
*
* @param 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.
*
* @param Adapter Pointer to a handle to receive the adapter handle. Must be released with
* WintunFreeAdapter.
*
* @param RebootRequired Pointer to a boolean flag to be set to TRUE in case SetupAPI suggests a reboot. Must be
* initialised to FALSE manually before this function is called.
*
* @return ERROR_SUCCESS on success; Win32 error code otherwise.
*/
typedef WINTUN_STATUS(WINAPI *WINTUN_CREATE_ADAPTER_FUNC)(
_In_z_count_c_(MAX_POOL) const WCHAR *Pool,
_In_z_count_c_(MAX_ADAPTER_NAME) const WCHAR *Name,
_In_opt_ const GUID *RequestedGUID,
_Out_ WINTUN_ADAPTER_HANDLE *Adapter,
_Inout_ BOOL *RebootRequired);
/**
* Deletes a Wintun adapter.
*
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter.
*
* @param RebootRequired Pointer to a boolean flag to be set to TRUE in case SetupAPI suggests a reboot. Must be
* initialised to FALSE manually before this function is called.
*
* @return ERROR_SUCCESS on success or the adapter was not found; Win32 error code otherwise.
*/
typedef WINTUN_STATUS(
WINAPI *WINTUN_DELETE_ADAPTER_FUNC)(_In_ WINTUN_ADAPTER_HANDLE Adapter, _Inout_ BOOL *RebootRequired);
/**
* Called by WintunEnumAdapters for each adapter in the pool.
*
* @param Adapter Adapter handle.
*
* @param Param An application-defined value passed to the WintunEnumAdapters.
*
* @return Non-zero to continue iterating adapters; zero to stop.
*/
typedef BOOL(CALLBACK *WINTUN_ENUM_FUNC)(_In_ WINTUN_ADAPTER_HANDLE Adapter, _In_ LPARAM Param);
/**
* Enumerates all Wintun adapters.
*
* @param Pool Name of the adapter pool.
*
* @param Func Callback function. To continue enumeration, the callback function must return TRUE; to stop
* enumeration, it must return FALSE.
*
* @param Param An application-defined value to be passed to the callback function.
*
* @return ERROR_SUCCESS on success; Win32 error code otherwise.
*/
typedef WINTUN_STATUS(WINAPI *WINTUN_ENUM_ADAPTERS_FUNC)(
_In_z_count_c_(MAX_POOL) const WCHAR *Pool,
_In_ WINTUN_ENUM_FUNC Func,
_In_ LPARAM Param);
/**
* Releases Wintun adapter resources.
*
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter.
*/
typedef void(WINAPI *WINTUN_FREE_ADAPTER_FUNC)(_In_ WINTUN_ADAPTER_HANDLE Adapter);
/**
* Finds a Wintun adapter by its name.
*
* @param Pool Name of the adapter pool.
*
* @param Name Adapter name.
*
* @param Adapter Pointer to a handle to receive the adapter handle. Must be released with WintunFreeAdapter.
*
* @return ERROR_SUCCESS on success; ERROR_FILE_NOT_FOUND if adapter with given name is not found; ERROR_ALREADY_EXISTS
* if adapter is found but not a Wintun-class or not a member of the pool; Win32 error code otherwise
*/
typedef WINTUN_STATUS(WINAPI *WINTUN_GET_ADAPTER_FUNC)(
_In_z_count_c_(MAX_POOL) const WCHAR *Pool,
_In_z_count_c_(MAX_ADAPTER_NAME) const WCHAR *Name,
_Out_ WINTUN_ADAPTER_HANDLE *Adapter);
/**
* Returns a handle to the adapter device object.
*
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter.
*
* @param Handle Pointer to receive the adapter device object handle. Must be released with CloseHandle.
*
* @return ERROR_SUCCESS on success; Win32 error code otherwise.
*/
typedef WINTUN_STATUS(
WINAPI *WINTUN_GET_ADAPTER_DEVICE_OBJECT_FUNC)(_In_ WINTUN_ADAPTER_HANDLE Adapter, _Out_ HANDLE *Handle);
/**
* Returns the GUID of the adapter.
*
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
*
* @param Guid Pointer to GUID to receive adapter ID.
*/
typedef void(WINAPI *WINTUN_GET_ADAPTER_GUID_FUNC)(_In_ WINTUN_ADAPTER_HANDLE Adapter, _Out_ GUID *Guid);
/**
* Returns the LUID of the adapter.
*
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
*
* @param Luid Pointer to LUID to receive adapter LUID.
*/
typedef void(WINAPI *WINTUN_GET_ADAPTER_LUID_FUNC)(_In_ WINTUN_ADAPTER_HANDLE Adapter, _Out_ LUID *Luid);
/**
* Returns the name of the Wintun adapter.
*
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
*
* @param Name Pointer to a string to receive adapter name
*
* @return ERROR_SUCCESS on success; Win32 error code otherwise.
*/
typedef WINTUN_STATUS(WINAPI *WINTUN_GET_ADAPTER_NAME_FUNC)(
_In_ WINTUN_ADAPTER_HANDLE Adapter,
_Out_cap_c_(MAX_ADAPTER_NAME) WCHAR *Name);
/**
* Returns the version of the Wintun driver and NDIS system currently loaded.
*
* @param DriverVersionMaj Pointer to a DWORD to receive the Wintun driver major version number.
*
* @param DriverVersionMin Pointer to a DWORD to receive the Wintun driver minor version number.
*
* @param NdisVersionMaj Pointer to a DWORD to receive the NDIS major version number.
*
* @param NdisVersionMin Pointer to a DWORD to receive the NDIS minor version number.
*
* @return ERROR_SUCCESS on success; Win32 error code otherwise.
*/
typedef WINTUN_STATUS(WINAPI *WINTUN_GET_VERSION_FUNC)(
_Out_ DWORD *DriverVersionMaj,
_Out_ DWORD *DriverVersionMin,
_Out_ DWORD *NdisVersionMaj,
_Out_ DWORD *NdisVersionMin);
/**
* Sets name of the Wintun adapter.
*
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
*
* @param Name Adapter name
*
* @return ERROR_SUCCESS on success; Win32 error code otherwise.
*/
typedef WINTUN_STATUS(WINAPI *WINTUN_SET_ADAPTER_NAME_FUNC)(
_In_ WINTUN_ADAPTER_HANDLE Adapter,
_In_z_count_c_(MAX_ADAPTER_NAME) const WCHAR *Name);
typedef enum _WINTUN_LOGGER_LEVEL
{
WINTUN_LOG_INFO = 0,
WINTUN_LOG_WARN,
WINTUN_LOG_ERR
} WINTUN_LOGGER_LEVEL;
/**
* Called by internal logger to report diagnostic messages
*
* @param Level Message level.
*
* @param Message Message text.
*
* @return Anything - return value is ignored.
*/
typedef BOOL(CALLBACK *WINTUN_LOGGER_FUNC)(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *Message);
/**
* Sets logger callback function.
*
* @param 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.
*/
typedef void(WINAPI *WINTUN_SET_LOGGER_FUNC)(_In_ WINTUN_LOGGER_FUNC NewLogger);
/**
* Minimum ring capacity.
*/
#define WINTUN_MIN_RING_CAPACITY 0x20000 /* 128kiB */
/**
* Maximum ring capacity.
*/
#define WINTUN_MAX_RING_CAPACITY 0x4000000 /* 64MiB */
/**
* A handle representing Wintun session
*/
typedef void *WINTUN_SESSION_HANDLE;
/**
* Starts Wintun session.
*
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
*
* @param Capacity Rings capacity. Must be between WINTUN_MIN_RING_CAPACITY and WINTUN_MAX_RING_CAPACITY (incl.)
* Must be a power of two.
*
* @param Session Pointer to a variable to receive Wintun session handle
*
* @return ERROR_SUCCESS on success; Win32 error code otherwise.
*/
typedef WINTUN_STATUS(WINAPI *WINTUN_START_SESSION_FUNC)(
_In_ WINTUN_ADAPTER_HANDLE Adapter,
_In_ DWORD Capacity,
_Out_ WINTUN_SESSION_HANDLE *Session);
/**
* Ends Wintun session.
*
* @param Session Wintun session handle obtained with WintunStartSession
*/
typedef void(WINAPI *WINTUN_END_SESSION_FUNC)(_In_ WINTUN_SESSION_HANDLE Session);
/**
* Maximum IP packet size
*/
#define WINTUN_MAX_IP_PACKET_SIZE 0xFFFF
/**
* Packet with data
*/
typedef struct _WINTUN_PACKET
{
/**
* Pointer to next packet in queue
*/
struct _WINTUN_PACKET *Next;
/**
* Size of packet (max WINTUN_MAX_IP_PACKET_SIZE).
*/
DWORD Size;
/**
* Pointer to layer 3 IPv4 or IPv6 packet
*/
BYTE *Data;
} WINTUN_PACKET;
/**
* Peeks if there is a packet available for reading.
*
* @param Session Wintun session handle obtained with WintunStartSession
*
* @return Non-zero if there is a packet available; zero otherwise.
*/
BOOL(WINAPI *WINTUN_IS_PACKET_AVAILABLE_FUNC)(_In_ WINTUN_SESSION_HANDLE Session);
/**
* Waits for a packet to become available for reading.
*
* @param Session Wintun session handle obtained with WintunStartSession
*
* @param Milliseconds The time-out interval, in milliseconds. If a nonzero value is specified, the function waits
* until a packet is available or the interval elapses. If Milliseconds is zero, the function
* does not enter a wait state if a packet is not available; it always returns immediately.
* If Milliseconds is INFINITE, the function will return only when a packet is available.
*
* @return See WaitForSingleObject() for return values.
*/
WINTUN_STATUS(WINAPI *WINTUN_WAIT_FOR_PACKET_FUNC)(_In_ WINTUN_SESSION_HANDLE Session, _In_ DWORD Milliseconds);
/**
* Reads one or more packets.
*
* @param Session Wintun session handle obtained with WintunStartSession
*
* @param Queue A linked list of nodes to fill with packets read. The list must be NULL terminated. May
* contain only one node to read one packet at a time. All nodes should be big enough to
* accommodate WINTUN_MAX_IP_PACKET_SIZE packet. The Size field of every node should be
* initialized to something bigger than WINTUN_MAX_IP_PACKET_SIZE allowing post-festum
* detection which nodes were actually filled with packets.
*
* @return
* ERROR_HANDLE_EOF Wintun adapter is terminating.
* ERROR_NO_MORE_ITEMS Wintun buffer is exhausted.
* ERROR_INVALID_DATA Wintun buffer is corrupt.
* ERROR_SUCCESS Requested amount of packets was read successfully.
* Regardless, if the error was returned, some packets might have been read nevertheless.
*/
WINTUN_STATUS(WINAPI *WINTUN_RECEIVE_PACKETS_FUNC)
(_In_ WINTUN_SESSION_HANDLE Session, _Inout_ WINTUN_PACKET *Queue);
/**
* Sends packets.
*
* @param Session Wintun session handle obtained with WintunStartSession
*
* @param Queue Linked list of packets to send. The list must be NULL terminated.
*
* @return
* ERROR_HANDLE_EOF Wintun adapter is terminating.
* ERROR_BUFFER_OVERFLOW Wintun buffer is full. One or more packets were dropped.
* ERROR_SUCCESS All packets were sent successfully.
*/
WINTUN_STATUS(WINAPI *WINTUN_SEND_PACKETS_FUNC)(_In_ WINTUN_SESSION_HANDLE Session, _In_ const WINTUN_PACKET *Queue);