Wintun Windows TUN virtual network interface

The Wintun virtual network device functions as a TUN interface. It allows users to create a virtual network adapter that enables direct access to network-layer (IP) packets using standard file read/write operations. Just like a physical network card, it supports setting IP addresses, configuring routes, and transmitting data. However, unlike a physical card, all data transmission (reading and writing) is handled entirely by user-defined programs.

In order to develop WireGuard for Windows, Wintun was developed and open sourced, distributed as a dynamic library.

Download wintun

Wintun is developed in C language and distributed as a dynamic library. wintun

After downloading, unzip the file and the directory is as follows:

wintun_platform

\bin The dynamic libraries of various platform versions are stored in the .txt file. Here you only need to select the appropriate dynamic library according to the platform.

amd64: Windows 64-bit

x86: Windows 32-bit

Getting Started

https://github.com/mascarenhasmelson/wintun-tunnel

Create a virtual network card

WireGuard developed Wintun GO interface binding, install WireGuardGO dependencies

golang.zx2c4.com/wireguard/tun

If the program displays an “Unable to load library” error during execution, please ensure that wintun.dll is located in the same directory as the executable file. wintun_library

You may still see this error message when running the code, but it can be safely ignored as long as wintun.dll is correctly placed in the same folder as main.go and the compiled binary. Next, run the following command to compile main.go into an executable file named interface.exe

go build -o interface.exe

After running the command, you will see the interface.exe file generated in the current directory. executable

Run interface.exe with administrator privileges. network_adapter

You can find the virtual network adapter listed under Network Connections.

Set network card IP and routing

To set the network card IP, you need to use the Windows API. I copied some APIs from wireguard wireguard-windows/winipcfg WireGuard To the project

project

After obtaining the device, perform a type cast to retrieve its LUID (Locally Unique Identifier), then use the appropriate APIs to complete the configuration.

  //luid
	id := &windows.GUID{
		0xdeadbabe,
		0xcafe,
		 0xbeef,
		[8]byte{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
	}
	ifname := "Test"
	dev, err := tun.CreateTUNWithRequestedGUID(ifname, id, 0)
	if err != nil {
		panic(err)
	}
	defer dev.Close()

	nativeTunDevice := dev.(*tun.NativeTun)

	link := winipcfg.LUID(nativeTunDevice.LUID())

	ip, err := netip.ParsePrefix("10.10.0.1/24")
	if err != nil {
		panic(err)
	}
	err = link.SetIPAddresses([]netip.Prefix{ip})
	if err != nil {
		panic(err)
	}

Once the program is running, you can verify that the IP was successfully set by running the ipconfig command. ipconfig

You can also verify that the routing is successfully configured by running the command route print -v.

iproute

You can verify connectivity by using the ping command to ping the interface’s IP address.

ping

Data Reading and Writing

After setting up the IP and routing, you can use the API to Read and Write IP packets. For example, here’s how to read ICMP packets

//Read packets
for {
  n = 2048
  n, err = dev.Read(buf, 0)
  if err != nil {
    panic(err)
  }
  const ProtocolICMP = 1
  header, err := ipv4.ParseHeader(buf[:n])
  if err != nil {
    continue
  }
  if header.Protocol == ProtocolICMP {
    log.Println("Src:", header.Src, " dst:", header.Dst)
    msg, _ := icmp.ParseMessage(ProtocolICMP, buf[header.Len:])
    log.Println(">> ICMP:", msg.Type)
  }
}

After running the program, you can ping any IP address within the subnet, such as 10.10.0.2, or other IP addresses in the same network segment.

ping 10.10.0.2

can be seen printed in the console:

console_print

Note: When deploying your application, make sure to include wintun.dll in the same directory as the executable. This DLL is essential for the program to function properly. If you’re distributing the software to others, ensure they have wintun.dll alongside the executable to avoid runtime errors.

Reference