]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
tun: freebsd: remove horrific hack for getting tunnel name
authorJason A. Donenfeld <Jason@zx2c4.com>
Mon, 19 Apr 2021 02:26:32 +0000 (20:26 -0600)
committerJason A. Donenfeld <Jason@zx2c4.com>
Mon, 19 Apr 2021 18:03:16 +0000 (12:03 -0600)
As of FreeBSD 12.1, there's TUNGIFNAME.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
tun/tun_freebsd.go

index 53d1584f2aff34a423227b35d53ccf3122d0186d..e618be3dab0a045545e8a911d0afb752f347921b 100644 (file)
@@ -6,7 +6,6 @@
 package tun
 
 import (
-       "bytes"
        "errors"
        "fmt"
        "net"
@@ -19,12 +18,10 @@ import (
        "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 (
        _TUNSIFHEAD = 0x80047460
        _TUNSIFMODE = 0x8004745e
-       _TUNSIFPID  = 0x2000745f
+       _TUNGIFNAME = 0x4020745d
 )
 
 // TODO: move into x/sys/unix
@@ -40,6 +37,12 @@ const _IFSTATMAX = 800
 
 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
 type ifreq_ptr struct {
        Name [unix.IFNAMSIZ]byte
@@ -54,12 +57,6 @@ type ifreq_mtu struct {
        Pad0 [12]byte
 }
 
-// Structure for interface status request ioctl
-type ifstat struct {
-       IfsName [unix.IFNAMSIZ]byte
-       Ascii   [_IFSTATMAX]byte
-}
-
 // Structures for nd6 flag manipulation
 type in6_ndireq struct {
        Name          [unix.IFNAMSIZ]byte
@@ -110,10 +107,10 @@ func (tun *NativeTun) routineRouteListener(tunIfindex int) {
                        continue
                }
 
-               if data[3 /* type */] != unix.RTM_IFINFO {
+               if data[3 /* type */ ] != unix.RTM_IFINFO {
                        continue
                }
-               ifindex := int(*(*uint16)(unsafe.Pointer(&data[12 /* ifindex */])))
+               ifindex := int(*(*uint16)(unsafe.Pointer(&data[12 /* ifindex */ ])))
                if ifindex != tunIfindex {
                        continue
                }
@@ -143,80 +140,12 @@ func (tun *NativeTun) routineRouteListener(tunIfindex int) {
 }
 
 func tunName(fd uintptr) (string, error) {
-       // Terrible hack to make up for freebsd not having a TUNGIFNAME
-
-       // First, make sure the tun pid matches this proc's pid
-       _, _, 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 {
+       var ifreq ifreq_name
+       _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, _TUNGIFNAME, uintptr(unsafe.Pointer(&ifreq)))
+       if err != 0 {
                return "", err
        }
-
-       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
+       return unix.ByteSliceToString(ifreq.Name[:]), nil
 }
 
 // Destroy a named system interface