diff options
author | Simon Rozman <simon@rozman.si> | 2019-02-07 22:02:51 +0100 |
---|---|---|
committer | Simon Rozman <simon@rozman.si> | 2019-02-07 22:02:51 +0100 |
commit | d87cbeeb2fb152b5f377758c68c655e09fe177f3 (patch) | |
tree | 1eb353b53e458b5b573fb2b2e552b15904ba5600 | |
parent | 043b7e8013674d58757fe3d3f4e4cacf89c46112 (diff) |
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.go | 16 | ||||
-rw-r--r-- | tun/wintun/wintun_windows.go | 39 |
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") } } |