/
iface.go
72 lines (57 loc) · 1.26 KB
/
iface.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package gtund
import (
"fmt"
"os/exec"
"runtime"
"github.com/songgao/water"
)
type InterfaceConfig struct {
IsTap bool `toml:"istap"`
}
type Interface struct {
*water.Interface
ip string
cidr string
}
func NewInterface(cfg *InterfaceConfig, ip, cidr string) (*Interface, error) {
iface := &Interface{
ip: ip,
cidr: cidr,
}
ifconfig := water.Config{}
if cfg.IsTap {
ifconfig.DeviceType = water.TAP
} else {
ifconfig.DeviceType = water.TUN
}
ifce, err := water.New(ifconfig)
if err != nil {
return nil, err
}
err = setupDevice(ifce.Name(), ip, cidr)
if err != nil {
return nil, err
}
iface.Interface = ifce
return iface, nil
}
func setupDevice(dev, ip, cidr string) (err error) {
switch runtime.GOOS {
case "linux":
out, err := execCmd("ifconfig", []string{dev, "up"})
if err != nil {
return fmt.Errorf("ifconfig fail: %s %v", out, err)
}
out, err = execCmd("ip", []string{"addr", "add", cidr, "dev", dev})
if err != nil {
return fmt.Errorf("ip add addr fail: %s %v", out, err)
}
default:
return fmt.Errorf("unsupported: %s %s", runtime.GOOS, runtime.GOARCH)
}
return nil
}
func execCmd(cmd string, args []string) (string, error) {
b, err := exec.Command(cmd, args...).CombinedOutput()
return string(b), err
}