From c3ca971f6ca5351c14085b70724179618d946b9d Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Fri, 27 Dec 2019 21:51:26 +0800 Subject: [PATCH] tun: add Windows support --- tun_linux.go | 2 -- tun_win.go | 15 --------------- tun_windows.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 17 deletions(-) delete mode 100644 tun_win.go create mode 100644 tun_windows.go diff --git a/tun_linux.go b/tun_linux.go index 997b41f..e2764a6 100644 --- a/tun_linux.go +++ b/tun_linux.go @@ -1,5 +1,3 @@ -// +build linux - package gost import ( diff --git a/tun_win.go b/tun_win.go deleted file mode 100644 index 68e4b5c..0000000 --- a/tun_win.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build windows - -package gost - -import ( - "errors" - "net" -) - -//TODO: wintun for Windows: https://www.wintun.net/ -// https://godoc.org/golang.zx2c4.com/wireguard/tun/wintun -func createTun(cfg TunConfig) (conn net.Conn, ipNet *net.IPNet, err error) { - err = errors.New("tun is not supported on Windows") - return -} diff --git a/tun_windows.go b/tun_windows.go new file mode 100644 index 0000000..9e0680b --- /dev/null +++ b/tun_windows.go @@ -0,0 +1,51 @@ +package gost + +import ( + "fmt" + "net" + "os/exec" + + "github.com/go-log/log" + "github.com/songgao/water" +) + +func createTun(cfg TunConfig) (conn net.Conn, ipNet *net.IPNet, err error) { + ip, ipNet, err := net.ParseCIDR(cfg.Addr) + if err != nil { + return + } + + ifce, err := water.New(water.Config{ + DeviceType: water.TUN, + PlatformSpecificParams: water.PlatformSpecificParams{ + ComponentID: "tap0901", + InterfaceName: cfg.Name, + Network: cfg.Addr, + }, + }) + if err != nil { + return + } + + cmd := fmt.Sprintf("netsh interface ip set address name=%s "+ + "source=static addr=%s mask=%s gateway=none", + ifce.Name(), ip.String(), ipMask(ipNet.Mask)) + log.Log("[tun]", cmd) + if er := exec.Command("netsh", + "interface", "ip", "set", "address", + "name="+ifce.Name(), "source=static", + "addr="+ip.String(), "mask="+ipMask(ipNet.Mask), "gateway=none").Run(); er != nil { + err = fmt.Errorf("%s: %v", cmd, er) + return + } + + conn = &tunConn{ + ifce: ifce, + addr: &net.IPAddr{IP: ip}, + } + return +} + +func ipMask(mask net.IPMask) string { + return fmt.Sprintf("%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3]) +}