tun: freebsd: remove horrific hack for getting tunnel name
As of FreeBSD 12.1, there's TUNGIFNAME. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
b0e5b19969
commit
3d3e30beb8
@ -6,7 +6,6 @@
|
|||||||
package tun
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
@ -19,12 +18,10 @@ import (
|
|||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// _TUNSIFHEAD, value derived from sys/net/{if_tun,ioccom}.h
|
|
||||||
// const _TUNSIFHEAD = ((0x80000000) | (((4) & ((1 << 13) - 1) ) << 16) | (uint32(byte('t')) << 8) | (96))
|
|
||||||
const (
|
const (
|
||||||
_TUNSIFHEAD = 0x80047460
|
_TUNSIFHEAD = 0x80047460
|
||||||
_TUNSIFMODE = 0x8004745e
|
_TUNSIFMODE = 0x8004745e
|
||||||
_TUNSIFPID = 0x2000745f
|
_TUNGIFNAME = 0x4020745d
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: move into x/sys/unix
|
// TODO: move into x/sys/unix
|
||||||
@ -40,6 +37,12 @@ const _IFSTATMAX = 800
|
|||||||
|
|
||||||
const SIZEOF_UINTPTR = 4 << (^uintptr(0) >> 32 & 1)
|
const SIZEOF_UINTPTR = 4 << (^uintptr(0) >> 32 & 1)
|
||||||
|
|
||||||
|
// structure for iface requests for just the name
|
||||||
|
type ifreq_name struct {
|
||||||
|
Name [unix.IFNAMSIZ]byte
|
||||||
|
Pad0 [16]byte
|
||||||
|
}
|
||||||
|
|
||||||
// structure for iface requests with a pointer
|
// structure for iface requests with a pointer
|
||||||
type ifreq_ptr struct {
|
type ifreq_ptr struct {
|
||||||
Name [unix.IFNAMSIZ]byte
|
Name [unix.IFNAMSIZ]byte
|
||||||
@ -54,12 +57,6 @@ type ifreq_mtu struct {
|
|||||||
Pad0 [12]byte
|
Pad0 [12]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Structure for interface status request ioctl
|
|
||||||
type ifstat struct {
|
|
||||||
IfsName [unix.IFNAMSIZ]byte
|
|
||||||
Ascii [_IFSTATMAX]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// Structures for nd6 flag manipulation
|
// Structures for nd6 flag manipulation
|
||||||
type in6_ndireq struct {
|
type in6_ndireq struct {
|
||||||
Name [unix.IFNAMSIZ]byte
|
Name [unix.IFNAMSIZ]byte
|
||||||
@ -110,10 +107,10 @@ func (tun *NativeTun) routineRouteListener(tunIfindex int) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if data[3 /* type */] != unix.RTM_IFINFO {
|
if data[3 /* type */ ] != unix.RTM_IFINFO {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ifindex := int(*(*uint16)(unsafe.Pointer(&data[12 /* ifindex */])))
|
ifindex := int(*(*uint16)(unsafe.Pointer(&data[12 /* ifindex */ ])))
|
||||||
if ifindex != tunIfindex {
|
if ifindex != tunIfindex {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -143,80 +140,12 @@ func (tun *NativeTun) routineRouteListener(tunIfindex int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tunName(fd uintptr) (string, error) {
|
func tunName(fd uintptr) (string, error) {
|
||||||
// Terrible hack to make up for freebsd not having a TUNGIFNAME
|
var ifreq ifreq_name
|
||||||
|
_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, _TUNGIFNAME, uintptr(unsafe.Pointer(&ifreq)))
|
||||||
// First, make sure the tun pid matches this proc's pid
|
if err != 0 {
|
||||||
_, _, errno := unix.Syscall(
|
|
||||||
unix.SYS_IOCTL,
|
|
||||||
uintptr(fd),
|
|
||||||
uintptr(_TUNSIFPID),
|
|
||||||
uintptr(0),
|
|
||||||
)
|
|
||||||
|
|
||||||
if errno != 0 {
|
|
||||||
return "", fmt.Errorf("failed to set tun device PID: %s", errno.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open iface control socket
|
|
||||||
|
|
||||||
confd, err := unix.Socket(
|
|
||||||
unix.AF_INET,
|
|
||||||
unix.SOCK_DGRAM,
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
return unix.ByteSliceToString(ifreq.Name[:]), nil
|
||||||
defer unix.Close(confd)
|
|
||||||
|
|
||||||
procPid := os.Getpid()
|
|
||||||
|
|
||||||
// Try to find interface with matching PID
|
|
||||||
for i := 1; ; i++ {
|
|
||||||
iface, _ := net.InterfaceByIndex(i)
|
|
||||||
if err != nil || iface == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// Structs for getting data in and out of SIOCGIFSTATUS ioctl
|
|
||||||
var ifstatus ifstat
|
|
||||||
copy(ifstatus.IfsName[:], iface.Name)
|
|
||||||
|
|
||||||
// Make the syscall to get the status string
|
|
||||||
_, _, errno := unix.Syscall(
|
|
||||||
unix.SYS_IOCTL,
|
|
||||||
uintptr(confd),
|
|
||||||
uintptr(unix.SIOCGIFSTATUS),
|
|
||||||
uintptr(unsafe.Pointer(&ifstatus)),
|
|
||||||
)
|
|
||||||
|
|
||||||
if errno != 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
nullStr := ifstatus.Ascii[:]
|
|
||||||
i := bytes.IndexByte(nullStr, 0)
|
|
||||||
if i < 1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
statStr := string(nullStr[:i])
|
|
||||||
var pidNum int = 0
|
|
||||||
|
|
||||||
// Finally get the owning PID
|
|
||||||
// Format string taken from sys/net/if_tun.c
|
|
||||||
_, err := fmt.Sscanf(statStr, "\tOpened by PID %d\n", &pidNum)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if pidNum == procPid {
|
|
||||||
return iface.Name, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy a named system interface
|
// Destroy a named system interface
|
||||||
|
Loading…
Reference in New Issue
Block a user