wintun: Detect if a foreign interface with the same name exists

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2019-02-07 22:02:51 +01:00
parent 043b7e8013
commit d87cbeeb2f
2 changed files with 50 additions and 7 deletions

View file

@ -55,16 +55,26 @@ type nativeTun struct {
func CreateTUN(ifname string) (TUNDevice, error) { func CreateTUN(ifname string) (TUNDevice, error) {
// Does an interface with this name already exist? // Does an interface with this name already exist?
wt, err := wintun.GetInterface(ifname, 0) wt, err := wintun.GetInterface(ifname, 0)
if wt == nil || err != nil { if wt == nil {
// Interface does not exist or an error occured. Create one. // Interface does not exist or an error occured. Create one.
wt, _, err = wintun.CreateInterface("WireGuard Tunnel Adapter", 0) wt, _, err = wintun.CreateInterface("WireGuard Tunnel Adapter", 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else if err != nil {
// Set interface name. (Ignore errors.) // Foreign interface with the same name found.
wt.SetInterfaceName(ifname) // 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
} }
err = wt.SetInterfaceName(ifname)
if err != nil {
wt.DeleteInterface(0)
return nil, err
}
err = wt.FlushInterface() err = wt.FlushInterface()
if err != nil { if err != nil {
wt.DeleteInterface(0) wt.DeleteInterface(0)

View file

@ -35,7 +35,8 @@ const TUN_HWID = "Wintun"
// hwndParent to 0. // hwndParent to 0.
// //
// Function returns interface ID when the interface was found, or nil // 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) { func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
// Create a list of network devices. // Create a list of network devices.
@ -79,11 +80,43 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
} }
if ifname == strings.ToLower(ifname2) { if ifname == strings.ToLower(ifname2) {
// Interface name found. // 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 return (*Wintun)(ifid), nil
} }
} }
// This interface is not using Wintun driver.
return (*Wintun)(ifid), errors.New("Foreign network interface with the same name exists")
}
}
return nil, nil return nil, nil
} }