Files
tun2socks/internal/dev/tun/tun_darwin.go
xjasonlyu e1e96c8cfb v2
2020-11-05 18:41:15 +08:00

71 lines
1.1 KiB
Go

package tun
import (
"fmt"
"io"
"syscall"
"unsafe"
"github.com/songgao/water"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"github.com/xjasonlyu/tun2socks/pkg/link/rwc"
)
func Open(name string) (ep stack.LinkEndpoint, c io.Closer, err error) {
config := water.Config{
DeviceType: water.TUN,
}
config.Name = name
var ifce *water.Interface
ifce, err = water.New(config)
if err != nil {
return
}
var mtu uint32
mtu, err = getMTU(name)
if err != nil {
return
}
ep, err = rwc.New(ifce, mtu)
c = ifce
return
}
func getMTU(name string) (uint32, error) {
// open datagram socket
fd, err := syscall.Socket(
syscall.AF_INET,
syscall.SOCK_DGRAM,
0,
)
if err != nil {
return 0, err
}
defer syscall.Close(fd)
// do ioctl call
var ifr struct {
name [16]byte
mtu uint32
}
copy(ifr.name[:], name)
_, _, errno := syscall.Syscall(
syscall.SYS_IOCTL,
uintptr(fd),
uintptr(syscall.SIOCGIFMTU),
uintptr(unsafe.Pointer(&ifr)),
)
if errno != 0 {
return 0, fmt.Errorf("get MTU on %s: %s", name, errno.Error())
}
return ifr.mtu, nil
}