A simple TUN/TAP library written in native Go (golang).
Latest commit f87d228 May 11, 2016 @songgao Merge pull request #8 from spurserh/master
add port accessors and modifiers for TCP/UDP



water is a native Go library for TUN/TAP interfaces.

water is designed to be simple and efficient. It

  • wraps almost only syscalls and uses only Go standard types;
  • exposes standard interfaces; plays well with standard packages like io, bufio, etc..
  • does not handle memory management (allocating/destructing slice). It's up to user to decide how to deal with buffers; whether to use GC.

water/waterutil has some useful functions to interpret MAC frame headers and IP packet headers. It also contains some constants such as protocol numbers and ethernet frame types.


go get -u github.com/songgao/water
go get -u github.com/songgao/water/waterutil





package main

import (

const BUFFERSIZE = 1522

func main() {
    ifce, err := water.NewTAP("")
    fmt.Printf("%v, %v\n\n", err, ifce)
    buffer := make([]byte, BUFFERSIZE)
    for {
        _, err = ifce.Read(buffer)
        if err != nil {
        ethertype := waterutil.MACEthertype(buffer)
        if ethertype == waterutil.IPv4 {
            packet := waterutil.MACPayload(buffer)
            if waterutil.IsIPv4(packet) {
                fmt.Printf("Source:      %v [%v]\n", waterutil.MACSource(buffer), waterutil.IPv4Source(packet))
                fmt.Printf("Destination: %v [%v]\n", waterutil.MACDestination(buffer), waterutil.IPv4Destination(packet))
                fmt.Printf("Protocol:    %v\n\n", waterutil.IPv4Protocol(packet))

This piece of code creates a TAP interface, and prints some header information for every IPv4 packet. After pull up the main.go, you'll need to bring up the interface and assign IP address. All of these need root permission.

sudo go run main.go
sudo ip link set dev tap0 up
sudo ip addr add dev tap0

Now, try sending some ICMP broadcast message:

ping -b

You'll see the main.go print something like:

<nil>, &{true 0xf84003f058 tap0}

Source:      42:35:da:af:2b:00 []
Destination: ff:ff:ff:ff:ff:ff []
Protocol:    1

Source:      42:35:da:af:2b:00 []
Destination: ff:ff:ff:ff:ff:ff []
Protocol:    1

Source:      42:35:da:af:2b:00 []
Destination: ff:ff:ff:ff:ff:ff []
Protocol:    1


  • IPv6 Support in waterutil
  • Darwin(Mac) Support


BSD 3-Clause License


tuntap: https://code.google.com/p/tuntap/