mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2025-10-09 02:30:05 +08:00
71 lines
1.1 KiB
Go
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
|
|
}
|