vtun/tun/tun.go
2021-09-12 00:25:40 +08:00

74 lines
2.2 KiB
Go

package tun
import (
"fmt"
"log"
"net"
"os"
"os/exec"
"runtime"
"github.com/net-byte/vtun/common/config"
"github.com/songgao/water"
)
func CreateTun(config config.Config) (iface *water.Interface) {
c := water.Config{DeviceType: water.TUN}
iface, err := water.New(c)
if err != nil {
log.Fatalln("failed to allocate TUN interface:", err)
}
log.Println("interface allocated:", iface.Name())
configTun(config, iface)
return iface
}
func configTun(config config.Config, iface *water.Interface) {
os := runtime.GOOS
ip, ipNet, err := net.ParseCIDR(config.CIDR)
if err != nil {
log.Panicf("error cidr %v", config.CIDR)
}
if os == "linux" {
execCmd("/sbin/ip", "link", "set", "dev", iface.Name(), "mtu", "1500")
execCmd("/sbin/ip", "addr", "add", config.CIDR, "dev", iface.Name())
execCmd("/sbin/ip", "link", "set", "dev", iface.Name(), "up")
if config.Route != "" {
addRoute := fmt.Sprintf("route add %s dev %s", config.Route, iface.Name())
execCmd("/sbin/ip", addRoute)
}
} else if os == "darwin" {
execCmd("ifconfig", iface.Name(), "inet", ip.String(), config.Gateway, "up")
if config.Route != "" {
addRoute := fmt.Sprintf("add -net %s -interface %s", config.Route, iface.Name())
execCmd("route", addRoute)
}
} else if os == "windows" {
setAddress := fmt.Sprintf("interface ip set address name=%s source=static addr=%s mask=%s gateway=none", iface.Name(), ip.String(), ipMask(ipNet.Mask))
execCmd("netsh.exe", setAddress)
if config.Route != "" {
deleteRoute := fmt.Sprintf("interface ip delete route prefix=%s interface=%s store=active", config.Route, iface.Name())
addRoute := fmt.Sprintf("interface ip add route prefix=%s interface=%s store=active", config.Route, iface.Name())
execCmd("netsh.exe", deleteRoute)
execCmd("netsh.exe", addRoute)
}
} else {
log.Printf("not support os:%v", os)
}
}
func execCmd(c string, args ...string) {
cmd := exec.Command(c, args...)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
err := cmd.Run()
if err != nil {
log.Fatalln("failed to exec cmd:", err)
}
}
func ipMask(mask net.IPMask) string {
return fmt.Sprintf("%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3])
}