29#include <tap-windows.h>
61#define WINTUN_COMPONENT_ID "wintun"
62#define DCO_WIN_REFERENCE_STRING "ovpn-dco"
65#if defined(_WIN32) || defined(TARGET_ANDROID)
67#define TUN_ADAPTER_INDEX_INVALID ((DWORD)-1)
70#define IPW32_SET_ADAPTIVE_DELAY_WINDOW 300
71#define IPW32_SET_ADAPTIVE_TRY_NETSH 20
74#define DHCP_OPTIONS_DHCP_OPTIONAL (1<<0)
75#define DHCP_OPTIONS_DHCP_REQUIRED (1<<1)
81#define IPW32_SET_MANUAL 0
82#define IPW32_SET_NETSH 1
83#define IPW32_SET_IPAPI 2
84#define IPW32_SET_DHCP_MASQ 3
85#define IPW32_SET_ADAPTIVE 4
130#define N_SEARCH_LIST_LEN 10
146#if defined(TARGET_ANDROID)
147 const char *http_proxy;
152#elif defined(TARGET_LINUX)
183#define TUNNEL_TYPE(tt) ((tt) ? ((tt)->type) : DEV_TYPE_UNDEF)
186#define TUNNEL_TOPOLOGY(tt) ((tt) ? ((tt)->topology) : TOP_UNDEF)
258 return tt && tt->
hand != NULL;
260 return tt && tt->fd >= 0;
282void open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
288 const char **device_guid,
struct gc_arena *
gc);
296void tuncfg(
const char *dev,
const char *dev_type,
const char *dev_node,
297 int persist_mode,
const char *username,
302 const char *dev_type,
303 const char *dev_node,
307 const char *dev_type,
309 const char *ifconfig_local_parm,
310 const char *ifconfig_remote_netmask_parm,
311 const char *ifconfig_ipv6_local_parm,
312 int ifconfig_ipv6_netbits_parm,
313 const char *ifconfig_ipv6_remote_parm,
314 struct addrinfo *local_public,
315 struct addrinfo *remote_public,
316 const bool strict_warn,
348bool is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type);
371#define IFCONFIG_BEFORE_TUN_OPEN 0
372#define IFCONFIG_AFTER_TUN_OPEN 1
374#define IFCONFIG_DEFAULT IFCONFIG_AFTER_TUN_OPEN
383#if defined(TARGET_LINUX)
385#elif defined(TARGET_SOLARIS)
387#elif defined(TARGET_OPENBSD)
389#elif defined(TARGET_DARWIN)
391#elif defined(TARGET_NETBSD)
395#elif defined(TARGET_ANDROID)
402#define ROUTE_BEFORE_TUN 0
403#define ROUTE_AFTER_TUN 1
404#define ROUTE_ORDER_DEFAULT ROUTE_AFTER_TUN
413#if defined(TARGET_ANDROID)
460const IP_ADAPTER_INFO *
get_adapter(
const IP_ADAPTER_INFO *ai, DWORD index);
508 return GetLastError() == ERROR_FILE_NOT_FOUND;
521 return GetLastError() == ERROR_OPERATION_ABORTED;
548 ULONG aligned_packet_size;
555 msg(
M_INFO,
"Wintun: ring capacity exceeded");
569 msg(
M_INFO,
"Wintun: incomplete packet header in send ring");
577 msg(
M_INFO,
"Wintun: packet too big in send ring");
583 if (aligned_packet_size > content_len)
585 msg(
M_INFO,
"Wintun: incomplete packet in send ring");
629 ULONG aligned_packet_size;
636 msg(
D_LOW,
"write_wintun(): drop invalid IP packet");
642 msg(
M_INFO,
"write_wintun(): head/tail value is over capacity");
648 if (aligned_packet_size > buf_space)
650 msg(
M_INFO,
"write_wintun(): ring is full");
751 unsigned int rwflags,
753 unsigned int *persistent)
761 if (!persistent || *persistent != rwflags)
766 *persistent = rwflags;
char * string_alloc(const char *str, struct gc_arena *gc)
static bool buf_write(struct buffer *dest, const void *src, size_t size)
static void event_ctl(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
static SERVICE_STATUS status
#define OPENVPN_IPH_GET_VER(v)
#define WINTUN_PACKET_ALIGN
#define WINTUN_MAX_PACKET_SIZE
#define WINTUN_RING_CAPACITY
UCHAR data[WINTUN_MAX_PACKET_SIZE]
Wrapper structure for dynamically allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
const char * device_interface
struct device_instance_id_interface * next
LPBYTE net_cfg_instance_id
Packet geometry parameters.
Garbage collection arena used to keep track of dynamically allocated memory.
enum tun_driver_type windows_driver
Wintun ring buffer See https://github.com/WireGuard/wintun#ring-layout.
UCHAR data[WINTUN_RING_CAPACITY+WINTUN_RING_TRAILING_BYTES]
struct in6_addr dns6[N_DHCP_ADDR]
in_addr_t nbdd[N_DHCP_ADDR]
in_addr_t ntp[N_DHCP_ADDR]
in_addr_t wins[N_DHCP_ADDR]
in_addr_t dns[N_DHCP_ADDR]
const char * netbios_scope
bool dhcp_masq_custom_offset
int domain_search_list_len
const char * domain_search_list[N_SEARCH_LIST_LEN]
unsigned int rwflags_debug
struct rw_handle rw_handle
enum tun_driver_type backend_driver
The backend driver that used for this tun/tap device.
HANDLE wintun_receive_ring_handle
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
struct in6_addr remote_ipv6
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
struct overlapped_io writes
in_addr_t adapter_netmask
struct tun_ring * wintun_receive_ring
struct overlapped_io reads
struct in6_addr local_ipv6
HANDLE wintun_send_ring_handle
struct tun_ring * wintun_send_ring
bool ipapi_context_defined
void ipconfig_register_dns(const struct env_set *es)
void tun_show_debug(struct tuntap *tt)
static bool tuntap_abort(int status)
void open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt, openvpn_net_ctx_t *ctx)
int dev_type_enum(const char *dev, const char *dev_type)
void close_tun_handle(struct tuntap *tt)
void fork_register_dns_action(struct tuntap *tt)
#define IFCONFIG_AFTER_TUN_OPEN
static void read_wintun(struct tuntap *tt, struct buffer *buf)
#define N_SEARCH_LIST_LEN
static bool tuntap_is_wintun(struct tuntap *tt)
#define IFCONFIG_BEFORE_TUN_OPEN
bool dhcp_renew_by_adapter_index(const DWORD adapter_index)
int ascii2ipset(const char *name)
const IP_ADAPTER_INFO * get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
bool is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
static bool tuntap_ring_empty(struct tuntap *tt)
const IP_ADAPTER_INFO * get_adapter_info(DWORD index, struct gc_arena *gc)
struct tuntap * init_tun(const char *dev, const char *dev_type, int topology, const char *ifconfig_local_parm, const char *ifconfig_remote_netmask_parm, const char *ifconfig_ipv6_local_parm, int ifconfig_ipv6_netbits_parm, const char *ifconfig_ipv6_remote_parm, struct addrinfo *local_public, struct addrinfo *remote_public, const bool strict_warn, struct env_set *es, openvpn_net_ctx_t *ctx, struct tuntap *tt)
const char * tun_stat(const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
static bool is_ip_packet_valid(const struct buffer *buf)
const IP_PER_ADAPTER_INFO * get_per_adapter_info(const DWORD index, struct gc_arena *gc)
static bool tuntap_is_dco_win(struct tuntap *tt)
#define ROUTE_ORDER_DEFAULT
void show_tap_win_adapters(int msglev, int warnlev)
int tun_write_win32(struct tuntap *tt, struct buffer *buf)
bool is_ip_in_adapter_subnet(const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
struct afunix_context afunix_context_t
const char * tap_win_getinfo(const struct tuntap *tt, struct gc_arena *gc)
void show_adapters(int msglev)
bool is_dev_type(const char *dev, const char *dev_type, const char *match_type)
static int write_tun_buffered(struct tuntap *tt, struct buffer *buf)
int tun_write_queue(struct tuntap *tt, struct buffer *buf)
static bool tuntap_defined(const struct tuntap *tt)
bool dhcp_release_by_adapter_index(const DWORD adapter_index)
bool tun_standby(struct tuntap *tt)
void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu, const struct env_set *es, openvpn_net_ctx_t *ctx)
do_ifconfig - configure the tunnel interface
const char * dev_type_string(const char *dev, const char *dev_type)
static int write_wintun(struct tuntap *tt, struct buffer *buf)
@ WINDOWS_DRIVER_UNSPECIFIED
@ DRIVER_UTUN
macOS internal tun driver
@ DRIVER_AFUNIX
using an AF_UNIX socket to pass packets from/to an external program.
@ WINDOWS_DRIVER_TAP_WINDOWS6
void close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
const IP_ADAPTER_INFO * get_adapter_info_list(struct gc_arena *gc)
static ULONG wintun_ring_packet_align(ULONG size)
void tap_allow_nonadmin_access(const char *dev_node)
bool tun_name_is_fixed(const char *dev)
const IP_ADAPTER_INFO * get_adapter(const IP_ADAPTER_INFO *ai, DWORD index)
static void tun_set(struct tuntap *tt, struct event_set *es, unsigned int rwflags, void *arg, unsigned int *persistent)
void warn_on_use_of_common_subnets(openvpn_net_ctx_t *ctx)
int tun_read_queue(struct tuntap *tt, int maxsize)
static event_t tun_event_handle(const struct tuntap *tt)
int read_tun(struct tuntap *tt, uint8_t *buf, int len)
void init_tun_post(struct tuntap *tt, const struct frame *frame, const struct tuntap_options *options)
static int ifconfig_order(struct tuntap *tt)
static void open_tun_null(struct tuntap *tt)
const char * ifconfig_options_string(const struct tuntap *tt, bool remote, bool disable, struct gc_arena *gc)
const char * guess_tuntap_dev(const char *dev, const char *dev_type, const char *dev_node, struct gc_arena *gc)
const char * ipset2ascii(int index)
void do_ifconfig_setenv(const struct tuntap *tt, struct env_set *es)
static bool tuntap_is_dco_win_timeout(struct tuntap *tt, int status)
void undo_ifconfig(struct tuntap *tt, openvpn_net_ctx_t *ctx)
undo_ifconfig - undo configuration of the tunnel interface
bool is_tun_p2p(const struct tuntap *tt)
const char * ipset2ascii_all(struct gc_arena *gc)
static int route_order(struct tuntap *tt)
void tun_standby_init(struct tuntap *tt)
void show_valid_win32_tun_subnets(void)
static bool tuntap_stop(int status)
const char * print_tun_backend_driver(enum tun_driver_type driver)
Return a string representation of the tun backed driver type.
static ULONG wintun_ring_wrap(ULONG value)
static bool is_tun_type_set(const struct tuntap *tt)
DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
int write_tun(struct tuntap *tt, uint8_t *buf, int len)
void tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid, struct gc_arena *gc)
void verify_255_255_255_252(in_addr_t local, in_addr_t remote)
void tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options, openvpn_net_ctx_t *ctx)