]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
wintun: Detect if a foreign interface with the same name exists
authorSimon Rozman <simon@rozman.si>
Thu, 7 Feb 2019 21:02:51 +0000 (22:02 +0100)
committerSimon Rozman <simon@rozman.si>
Thu, 7 Feb 2019 21:02:51 +0000 (22:02 +0100)
Signed-off-by: Simon Rozman <simon@rozman.si>
tun/tun_windows.go
tun/wintun/wintun_windows.go

index 5f4f22aff3a256daecc2bdadedc3fa5c018bf20a..5c231e708c0589d6fd3d1738a11ece8553daa17f 100644 (file)
@@ -55,16 +55,26 @@ type nativeTun struct {
 func CreateTUN(ifname string) (TUNDevice, error) {
        // Does an interface with this name already exist?
        wt, err := wintun.GetInterface(ifname, 0)
-       if wt == nil || err != nil {
+       if wt == nil {
                // Interface does not exist or an error occured. Create one.
                wt, _, err = wintun.CreateInterface("WireGuard Tunnel Adapter", 0)
                if err != nil {
                        return nil, err
                }
+       } else if err != nil {
+               // Foreign interface with the same name found.
+               // We could create a Wintun interface under a temporary name. But, should our
+               // proces die without deleting this interface first, the interface would remain
+               // orphaned.
+               return nil, err
+       }
 
-               // Set interface name. (Ignore errors.)
-               wt.SetInterfaceName(ifname)
+       err = wt.SetInterfaceName(ifname)
+       if err != nil {
+               wt.DeleteInterface(0)
+               return nil, err
        }
+
        err = wt.FlushInterface()
        if err != nil {
                wt.DeleteInterface(0)
index 75180d52911974d44eca86fc7e82daa9a9628a82..f9fc309a3d1b149464ea11451c09fa02764b62bc 100644 (file)
@@ -35,7 +35,8 @@ const TUN_HWID = "Wintun"
 // hwndParent to 0.
 //
 // Function returns interface ID when the interface was found, or nil
-// otherwise.
+// otherwise. If the interface is found but not Wintun-class, the function
+// returns interface ID with an error.
 //
 func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
        // Create a list of network devices.
@@ -79,8 +80,40 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
                }
 
                if ifname == strings.ToLower(ifname2) {
-                       // Interface name found.
-                       return (*Wintun)(ifid), nil
+                       // Interface name found. Check its driver.
+                       const driverType = setupapi.SPDIT_COMPATDRIVER
+                       err = devInfoList.BuildDriverInfoList(deviceData, driverType)
+                       if err != nil {
+                               return nil, err
+                       }
+                       defer devInfoList.DestroyDriverInfoList(deviceData, driverType)
+
+                       for index := 0; ; index++ {
+                               // Get a driver from the list.
+                               driverData, err := devInfoList.EnumDriverInfo(deviceData, driverType, index)
+                               if err != nil {
+                                       if errWin, ok := err.(syscall.Errno); ok && errWin == 259 /*ERROR_NO_MORE_ITEMS*/ {
+                                               break
+                                       }
+                                       // Something is wrong with this driver. Skip it.
+                                       continue
+                               }
+
+                               // Get driver info details.
+                               driverDetailData, err := devInfoList.GetDriverInfoDetail(deviceData, driverData)
+                               if err != nil {
+                                       // Something is wrong with this driver. Skip it.
+                                       continue
+                               }
+
+                               if driverDetailData.IsCompatible(TUN_HWID) {
+                                       // Matching hardware ID found.
+                                       return (*Wintun)(ifid), nil
+                               }
+                       }
+
+                       // This interface is not using Wintun driver.
+                       return (*Wintun)(ifid), errors.New("Foreign network interface with the same name exists")
                }
        }