vtun/tun/tun.go
2023-07-16 09:15:43 +08:00

151 lines
5.9 KiB
Go

package tun
import (
"log"
"net"
"runtime"
"strconv"
"github.com/net-byte/vtun/common/config"
"github.com/net-byte/vtun/common/netutil"
"github.com/net-byte/water"
)
// CreateTun creates a tun interface
func CreateTun(config config.Config) (iFace *water.Interface) {
c := water.Config{DeviceType: water.TUN}
c.PlatformSpecificParams = water.PlatformSpecificParams{}
os := runtime.GOOS
if os == "windows" {
c.PlatformSpecificParams.Name = "vtun"
c.PlatformSpecificParams.Network = []string{config.CIDR, config.CIDRv6}
}
if config.DeviceName != "" {
c.PlatformSpecificParams.Name = config.DeviceName
}
iFace, err := water.New(c)
if err != nil {
log.Fatalln("failed to create tun interface:", err)
}
log.Printf("interface created %v", iFace.Name())
setRoute(config, iFace)
return iFace
}
// setRoute sets the system routes
func setRoute(config config.Config, iFace *water.Interface) {
ip, _, err := net.ParseCIDR(config.CIDR)
if err != nil {
log.Panicf("error cidr %v", config.CIDR)
}
ipv6, _, err := net.ParseCIDR(config.CIDRv6)
if err != nil {
log.Panicf("error ipv6 cidr %v", config.CIDRv6)
}
os := runtime.GOOS
if os == "linux" {
netutil.ExecCmd("/sbin/ip", "link", "set", "dev", iFace.Name(), "mtu", strconv.Itoa(config.MTU))
netutil.ExecCmd("/sbin/ip", "addr", "add", config.CIDR, "dev", iFace.Name())
netutil.ExecCmd("/sbin/ip", "-6", "addr", "add", config.CIDRv6, "dev", iFace.Name())
netutil.ExecCmd("/sbin/ip", "link", "set", "dev", iFace.Name(), "up")
if !config.ServerMode && config.GlobalMode {
physicaliFace := netutil.GetInterface()
serverAddrIP := netutil.LookupServerAddrIP(config.ServerAddr)
if physicaliFace != "" && serverAddrIP != nil {
if config.LocalGateway != "" {
netutil.ExecCmd("/sbin/ip", "route", "add", "0.0.0.0/1", "dev", iFace.Name())
netutil.ExecCmd("/sbin/ip", "route", "add", "128.0.0.0/1", "dev", iFace.Name())
if serverAddrIP.To4() != nil {
netutil.ExecCmd("/sbin/ip", "route", "add", serverAddrIP.To4().String()+"/32", "via", config.LocalGateway, "dev", physicaliFace)
}
}
if config.LocalGatewayv6 != "" {
netutil.ExecCmd("/sbin/ip", "-6", "route", "add", "::/1", "dev", iFace.Name())
if serverAddrIP.To16() != nil {
netutil.ExecCmd("/sbin/ip", "-6", "route", "add", serverAddrIP.To16().String()+"/128", "via", config.LocalGatewayv6, "dev", physicaliFace)
}
}
}
}
} else if os == "darwin" {
netutil.ExecCmd("ifconfig", iFace.Name(), "inet", ip.String(), config.ServerIP, "up")
netutil.ExecCmd("ifconfig", iFace.Name(), "inet6", ipv6.String(), config.ServerIPv6, "up")
if !config.ServerMode && config.GlobalMode {
physicaliFace := netutil.GetInterface()
serverAddrIP := netutil.LookupServerAddrIP(config.ServerAddr)
if physicaliFace != "" && serverAddrIP != nil {
if config.LocalGateway != "" {
netutil.ExecCmd("route", "add", "default", config.ServerIP)
netutil.ExecCmd("route", "change", "default", config.ServerIP)
netutil.ExecCmd("route", "add", "0.0.0.0/1", "-interface", iFace.Name())
netutil.ExecCmd("route", "add", "128.0.0.0/1", "-interface", iFace.Name())
if serverAddrIP.To4() != nil {
netutil.ExecCmd("route", "add", serverAddrIP.To4().String(), config.LocalGateway)
}
}
if config.LocalGatewayv6 != "" {
netutil.ExecCmd("route", "add", "-inet6", "default", config.ServerIPv6)
netutil.ExecCmd("route", "change", "-inet6", "default", config.ServerIPv6)
netutil.ExecCmd("route", "add", "-inet6", "::/1", "-interface", iFace.Name())
if serverAddrIP.To16() != nil {
netutil.ExecCmd("route", "add", "-inet6", serverAddrIP.To16().String(), config.LocalGatewayv6)
}
}
}
}
} else if os == "windows" {
if !config.ServerMode && config.GlobalMode {
serverAddrIP := netutil.LookupServerAddrIP(config.ServerAddr)
if serverAddrIP != nil {
if config.LocalGateway != "" {
netutil.ExecCmd("cmd", "/C", "route", "delete", "0.0.0.0", "mask", "0.0.0.0")
netutil.ExecCmd("cmd", "/C", "route", "add", "0.0.0.0", "mask", "0.0.0.0", config.ServerIP, "metric", "6")
if serverAddrIP.To4() != nil {
netutil.ExecCmd("cmd", "/C", "route", "add", serverAddrIP.To4().String()+"/32", config.LocalGateway, "metric", "5")
}
}
if config.LocalGatewayv6 != "" {
netutil.ExecCmd("cmd", "/C", "route", "-6", "delete", "::/0", "mask", "::/0")
netutil.ExecCmd("cmd", "/C", "route", "-6", "add", "::/0", "mask", "::/0", config.ServerIPv6, "metric", "6")
if serverAddrIP.To16() != nil {
netutil.ExecCmd("cmd", "/C", "route", "-6", "add", serverAddrIP.To16().String()+"/128", config.LocalGatewayv6, "metric", "5")
}
}
}
}
} else {
log.Printf("not support os %v", os)
}
log.Printf("interface configured %v", iFace.Name())
}
// ResetRoute resets the system routes
func ResetRoute(config config.Config) {
if config.ServerMode || !config.GlobalMode {
return
}
os := runtime.GOOS
if os == "darwin" {
if config.LocalGateway != "" {
netutil.ExecCmd("route", "add", "default", config.LocalGateway)
netutil.ExecCmd("route", "change", "default", config.LocalGateway)
}
if config.LocalGatewayv6 != "" {
netutil.ExecCmd("route", "add", "-inet6", "default", config.LocalGatewayv6)
netutil.ExecCmd("route", "change", "-inet6", "default", config.LocalGatewayv6)
}
} else if os == "windows" {
serverAddrIP := netutil.LookupServerAddrIP(config.ServerAddr)
if serverAddrIP != nil {
if config.LocalGateway != "" {
netutil.ExecCmd("cmd", "/C", "route", "delete", "0.0.0.0", "mask", "0.0.0.0")
netutil.ExecCmd("cmd", "/C", "route", "add", "0.0.0.0", "mask", "0.0.0.0", config.LocalGateway, "metric", "6")
}
if config.LocalGatewayv6 != "" {
netutil.ExecCmd("cmd", "/C", "route", "-6", "delete", "::/0", "mask", "::/0")
netutil.ExecCmd("cmd", "/C", "route", "-6", "add", "::/0", "mask", "::/0", config.LocalGatewayv6, "metric", "6")
}
}
}
}