Go to file
Simon Rozman c19da2a99e Revise TunCompleteRequest() and make it universal
TunCompleteRequest() no longer sets Information field in IRP and allows
to specify custom priority boost. This makes it suitable replacement for
all "set status; complete request; release remove lock"-tuples
throughout the code.

Functional changes in this patch:

- We no longer reset Information field to 0 for canceled IRPs. In other
  words: ReadFile() of a canceled IRP will get the number of bytes read
  before request was canceled in the lpNumberOfBytesRead, instead of
  always 0.

- After write is complete, we boost user thread priority by +2
  (IO_NETWORK_INCREMENT).

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-03 10:53:11 +00:00
.editorconfig Switch from NMake to MSBuild 2019-04-19 15:25:44 +02:00
.gitignore installer: put whql assets in reasonable place 2019-04-26 14:53:20 +02:00
COPYING Initial commit 2019-03-22 16:52:31 -06:00
README.md Upgrade to VS2019 and update CSQ locking for analysis 2019-06-03 12:47:05 +02:00
undocumented.h Force handles closed if required 2019-06-03 10:53:11 +00:00
wintun.c Revise TunCompleteRequest() and make it universal 2019-06-03 10:53:11 +00:00
wintun.inf Fix driver service name 2019-03-28 14:30:44 +01:00
wintun.proj Split driver setup to EV signed (<Win10) and WHQL signed (>=Win10) 2019-04-26 13:44:44 +02:00
wintun.props Switch from NMake to MSBuild 2019-04-19 15:25:44 +02:00
wintun.rc Preset version to 0.1 2019-04-18 15:32:09 +02:00
wintun.vcxproj Force handles closed if required 2019-06-03 10:53:11 +00:00
wintun.vcxproj.filters Force handles closed if required 2019-06-03 10:53:11 +00:00
wintun.wixproj installer: put whql assets in reasonable place 2019-04-26 14:53:20 +02:00
wintun.wxs installer: better WoW64 language 2019-04-26 15:10:31 +02:00

Wintun Network Adapter

TUN Device Driver for Windows

This is a layer 3 TUN driver for Windows 7, 8, 8.1, and 10. Originally created for WireGuard, it is intended to be useful to a wide variety of projects that require layer 3 tunneling devices with implementations primarily in userspace.

Build Requirements

Digital Signing

Digital signing is integral part of the build process. By default, the driver will be test-signed using a certificate that the WDK should automatically generate. To subsequently load the driver, you will need to put your computer into test mode by executing as Administrator bcdedit /set testsigning on.

If you possess an EV certificate for kernel mode code signing you should switch TUN driver digital signing from test-signing to production-signing by authoring your wintun.vcxproj.user file to look something like this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <SignMode>ProductionSign</SignMode>
    <CrossCertificateFile>$(WDKContentRoot)CrossCertificates\DigiCert_High_Assurance_EV_Root_CA.crt</CrossCertificateFile>
    <ProductionCertificate>DF98E075A012ED8C86FBCF14854B8F9555CB3D45</ProductionCertificate>
    <TimestampServer>http://timestamp.digicert.com</TimestampServer>
  </PropertyGroup>
</Project>

Modify the <CrossCertificateFile> to contain the full path to the cross-signing certificate of CA that issued your certificate. You should be able to find its .crt file in C:\Program Files (x86)\Windows Kits\10\CrossCertificates. Note that the $(WDKContentRoot) expands to C:\Program Files (x86)\Windows Kits\10\.

If you already have wintun.vcxproj.user file, just add the <PropertyGroup> section.

Building from Command Line

Open Developer Command Prompt for VS 2019 and use the msbuild command:

msbuild wintun.proj [/t:<target>]

Targets

  • Build: Builds the driver release configurations of all supported platforms. This is the default target.

  • Clean: Deletes all intermediate and output files.

  • Rebuild: Alias for Clean followed by Build.

  • SDV: Runs Static Driver Verifier, which includes a clean driver build, only for AMD64 release configuration.

  • DVL: Runs the SDV, and creates a Driver Verification Log, only for AMD64 release configurations.

  • MSM: Builds Microsoft Installer Merge Modules in <output folder>\wintun-<platform>-<version>.msm. Requires WHQL signed driver.

The driver output folders are:

Platform and Configuration Folder
x86 Debug x86\Debug\wintun
x86 Release x86\Release\wintun
AMD64 Debug amd64\Debug\wintun
AMD64 Release amd64\Release\wintun
ARM64 Debug arm64\Debug\wintun
ARM64 Release arm64\Release\wintun

Building Microsoft Installer Merge Modules

  1. msbuild wintun.proj /t:DVL;Build.
  2. Perform Windows Hardware Lab Kit tests.
  3. Submit submission package to Microsoft.
  4. Copy WHQL-signed driver to x86\Release\whql\ and amd64\Release\whql\ subfolders.
  5. msbuild wintun.proj /t:MSM
  6. MSM files are placed in dist subfolder.

Note: due to the use of SHA256 signatures throughout, Windows 7 users who would like a prompt-less installation generally need to have the KB2921916 hotfix installed, which can be obtained from these mirrors: amd64 and x86.

Usage

After loading the driver and creating a network interface the typical way using SetupAPI, open \\.\Device\WINTUN%d as Local System, where %d is the LUID index (NetLuidIndex member) of the network device. You may then ReadFile and WriteFile bundles of packets of the following format:

+------------------------------+
| size_0                       |
|   4 bytes, native endian     |
+------------------------------+
|                              |
| padding                      |
|   12 bytes, all zero         |
|                              |
+------------------------------+
|                              |
| packet_0                     |
|   size_0 bytes               |
|                              |
~                              ~
|                              |
+------------------------------+
| padding                      |
|   16-(size_0&15) bytes,      |
|   all zero                   |
+------------------------------+
| size_1                       |
|   4 bytes, native endian     |
+------------------------------+
|                              |
| padding                      |
|   12 bytes, all zero         |
|                              |
+------------------------------+
|                              |
| packet_1                     |
|   size_1 bytes               |
|                              |
~                              ~

Each packet segment should contain a layer 3 IPv4 or IPv6 packet. Up to 256 packets may be read or written during each call to ReadFile or WriteFile.

It is advisable to use overlapped I/O for this. If using blocking I/O instead, it may be desirable to open separate handles for reading and writing.