Refined code and documentations.

This commit is contained in:
lucus 2016-12-26 04:22:06 +09:00
parent c871518ca0
commit b090a0ff67
2 changed files with 21 additions and 22 deletions

2
if.go
View file

@ -52,6 +52,7 @@ func New(config Config) (ifce *Interface, err error) {
// NewTAP creates a new TAP interface whose name is ifName. If ifName is empty, a // NewTAP creates a new TAP interface whose name is ifName. If ifName is empty, a
// default name (tap0, tap1, ... ) will be assigned. ifName should not exceed // default name (tap0, tap1, ... ) will be assigned. ifName should not exceed
// 16 bytes. TAP interfaces are not supported on darwin. // 16 bytes. TAP interfaces are not supported on darwin.
// ifName cannot be specified on windows, you will need ifce.Name() to use some cmds.
// //
// Note: this function is deprecated and will be removed from the library. // Note: this function is deprecated and will be removed from the library.
// Please use New() instead. // Please use New() instead.
@ -61,6 +62,7 @@ func NewTAP(ifName string) (ifce *Interface, err error) {
// NewTUN creates a new TUN interface whose name is ifName. If ifName is empty, a // NewTUN creates a new TUN interface whose name is ifName. If ifName is empty, a
// default name (tap0, tap1, ... ) will be assigned. ifName should not exceed // default name (tap0, tap1, ... ) will be assigned. ifName should not exceed
// ifName cannot be specified on windows, you will need ifce.Name() to use some cmds.
// //
// Note: this function is deprecated and will be removed from the library. // Note: this function is deprecated and will be removed from the library.
// Please use New() instead. // Please use New() instead.

View file

@ -7,6 +7,7 @@
package water package water
import ( import (
"bytes"
"errors" "errors"
"net" "net"
"os" "os"
@ -17,7 +18,8 @@ import (
var ( var (
IfceNameNotFound = errors.New("Failed to find the name of interface.") IfceNameNotFound = errors.New("Failed to find the name of interface.")
TapDeviceNotFound = errors.New("Failed to find the tap device in registry.") TapDeviceNotFound = errors.New("Failed to find the tap device with specified ComponentId in registry, TAP driver may not installed.")
RegistryOpenErr = errors.New("Failed to open the adapter registry, TAP driver may not installed.")
// Device Control Codes // Device Control Codes
tap_win_ioctl_get_mac = tap_control_code(1, 0) tap_win_ioctl_get_mac = tap_control_code(1, 0)
tap_win_ioctl_get_version = tap_control_code(2, 0) tap_win_ioctl_get_version = tap_control_code(2, 0)
@ -31,6 +33,9 @@ var (
tap_ioctl_config_tun = tap_control_code(10, 0) tap_ioctl_config_tun = tap_control_code(10, 0)
// w32 api // w32 api
file_device_unknown = uint32(0x00000022) file_device_unknown = uint32(0x00000022)
// Driver maker specified ComponentId
// ComponentId is defined here: https://github.com/OpenVPN/tap-windows6/blob/master/version.m4#L5
componentId = "tap0901"
) )
func ctl_code(device_type, function, method, access uint32) uint32 { func ctl_code(device_type, function, method, access uint32) uint32 {
@ -41,39 +46,40 @@ func tap_control_code(request, method uint32) uint32 {
return ctl_code(file_device_unknown, request, method, 0) return ctl_code(file_device_unknown, request, method, 0)
} }
// getdeviceid finds out a TAP device from registry, it requires privileged right. // getdeviceid finds out a TAP device from registry, it *may* requires privileged right to prevent some weird issue.
func getdeviceid() (string, error) { func getdeviceid() (string, error) {
// TAP driver key location // TAP driver key location
regkey := `SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}` regkey := `SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}`
k, err := registry.OpenKey(registry.LOCAL_MACHINE, regkey, registry.ALL_ACCESS) k, err := registry.OpenKey(registry.LOCAL_MACHINE, regkey, registry.READ)
if err != nil { if err != nil {
return "", err return "", RegistryOpenErr
} }
defer k.Close() defer k.Close()
// read all subkeys // read all subkeys, it should not return an err here
keys, err := k.ReadSubKeyNames(-1) keys, err := k.ReadSubKeyNames(-1)
if err != nil { if err != nil {
return "", err return "", err
} }
// find the one with ComponentId == "tap0901" // find the one matched ComponentId
for _, v := range keys { for _, v := range keys {
key, err := registry.OpenKey(registry.LOCAL_MACHINE, regkey+"\\"+v, registry.ALL_ACCESS) key, err := registry.OpenKey(registry.LOCAL_MACHINE, regkey+"\\"+v, registry.READ)
if err != nil { if err != nil {
continue continue
} }
val, _, err := key.GetStringValue("ComponentId") val, _, err := key.GetStringValue("ComponentId")
if err != nil { if err != nil {
goto next key.Close()
continue
} }
if val == "tap0901" { if val == componentId {
val, _, err = key.GetStringValue("NetCfgInstanceId") val, _, err = key.GetStringValue("NetCfgInstanceId")
if err != nil { if err != nil {
goto next key.Close()
continue
} }
key.Close() key.Close()
return val, nil return val, nil
} }
next:
key.Close() key.Close()
} }
return "", TapDeviceNotFound return "", TapDeviceNotFound
@ -82,7 +88,7 @@ func getdeviceid() (string, error) {
// openDev find and open an interface. // openDev find and open an interface.
func openDev(isTAP bool) (ifce *Interface, err error) { func openDev(isTAP bool) (ifce *Interface, err error) {
// ifName won't work // ifName won't work
// find the device in registrym you need privileged right. // find the device in registry.
deviceid, err := getdeviceid() deviceid, err := getdeviceid()
if err != nil { if err != nil {
return nil, err return nil, err
@ -135,22 +141,13 @@ func openDev(isTAP bool) (ifce *Interface, err error) {
return return
} }
// find the name of tap interface(u need it to set the ip or other command) // find the name of tap interface(u need it to set the ip or other command)
hwaddr_equal := func(a net.HardwareAddr, b []byte) bool {
for i := 0; i < 6; i++ {
if a[i] != b[i] {
return false
}
}
return true
}
ifces, err := net.Interfaces() ifces, err := net.Interfaces()
if err != nil { if err != nil {
return return
} }
for _, v := range ifces { for _, v := range ifces {
if hwaddr_equal(v.HardwareAddr[:6], mac[:6]) { if bytes.Equal(v.HardwareAddr[:6], mac[:6]) {
ifce.name = v.Name ifce.name = v.Name
return return
} }