aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rozman <simon@rozman.si>2019-02-07 22:02:51 +0100
committerSimon Rozman <simon@rozman.si>2019-02-07 22:02:51 +0100
commitd87cbeeb2fb152b5f377758c68c655e09fe177f3 (patch)
tree1eb353b53e458b5b573fb2b2e552b15904ba5600
parentwintun: Clean excessive setupapi.DevInfo.GetDeviceInfoListDetail() call (diff)
downloadwireguard-go-d87cbeeb2fb152b5f377758c68c655e09fe177f3.tar.xz
wireguard-go-d87cbeeb2fb152b5f377758c68c655e09fe177f3.zip
wintun: Detect if a foreign interface with the same name exists
Signed-off-by: Simon Rozman <simon@rozman.si>
-rw-r--r--tun/tun_windows.go16
-rw-r--r--tun/wintun/wintun_windows.go39
2 files changed, 49 insertions, 6 deletions
diff --git a/tun/tun_windows.go b/tun/tun_windows.go
index 5f4f22a..5c231e7 100644
--- a/tun/tun_windows.go
+++ b/tun/tun_windows.go
@@ -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)
diff --git a/tun/wintun/wintun_windows.go b/tun/wintun/wintun_windows.go
index 75180d5..f9fc309 100644
--- a/tun/wintun/wintun_windows.go
+++ b/tun/wintun/wintun_windows.go
@@ -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")
}
}