From f172a28f24664d95611b5943f78c6a2c1cc6efbd Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Tue, 15 Dec 2015 12:03:47 +1100 Subject: [PATCH] net: include both ipv4 and ipv6 netsh output in TestInterfacesWithNetsh Also include test for interface state (up or down). Updates #13606 Change-Id: I03538d65525ddd9c2d0254761861c2df7fc5bd5a Reviewed-on: https://go-review.googlesource.com/17850 Reviewed-by: Russ Cox Reviewed-by: Mikio Hara Run-TryBot: Russ Cox --- src/net/net_windows_test.go | 86 ++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/src/net/net_windows_test.go b/src/net/net_windows_test.go index ce002a62b0..ef71b8d680 100644 --- a/src/net/net_windows_test.go +++ b/src/net/net_windows_test.go @@ -177,6 +177,18 @@ func isWindowsXP(t *testing.T) bool { return major < 6 } +var ( + modkernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetACP = modkernel32.NewProc("GetACP") +) + +func isEnglishOS(t *testing.T) bool { + const windows_1252 = 1252 // ANSI Latin 1; Western European (Windows) + r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0) + acp := uint32(r0) + return acp == windows_1252 +} + func runCmd(args ...string) ([]byte, error) { removeUTF8BOM := func(b []byte) []byte { if len(b) >= 3 && b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF { @@ -213,40 +225,87 @@ func runCmd(args ...string) ([]byte, error) { return removeUTF8BOM(out), nil } -func netshInterfaceIPShowConfig() ([]string, error) { - out, err := runCmd("netsh", "interface", "ip", "show", "config") +func netshInterfaceIPShowInterface(ipver string, ifaces map[string]bool) error { + out, err := runCmd("netsh", "interface", ipver, "show", "interface", "level=verbose") if err != nil { - return nil, err + return err } + // interface information is listed like: + // + //Interface Local Area Connection Parameters + //---------------------------------------------- + //IfLuid : ethernet_6 + //IfIndex : 11 + //State : connected + //Metric : 10 + //... + var name string lines := bytes.Split(out, []byte{'\r', '\n'}) - names := make([]string, 0) for _, line := range lines { - f := bytes.Split(line, []byte{'"'}) - if len(f) == 3 { - names = append(names, string(f[1])) + if bytes.HasPrefix(line, []byte("Interface ")) && bytes.HasSuffix(line, []byte(" Parameters")) { + f := line[len("Interface "):] + f = f[:len(f)-len(" Parameters")] + name = string(f) + continue + } + var isup bool + switch string(line) { + case "State : connected": + isup = true + case "State : disconnected": + isup = false + default: + continue + } + if name != "" { + if v, ok := ifaces[name]; ok && v != isup { + return fmt.Errorf("%s:%s isup=%v: ipv4 and ipv6 report different interface state", ipver, name, isup) + } + ifaces[name] = isup + name = "" } } - return names, nil + return nil } func TestInterfacesWithNetsh(t *testing.T) { if isWindowsXP(t) { t.Skip("Windows XP netsh command does not provide required functionality") } + if !isEnglishOS(t) { + t.Skip("English version of OS required for this test") + } + + toString := func(name string, isup bool) string { + if isup { + return name + ":up" + } + return name + ":down" + } + ift, err := Interfaces() if err != nil { t.Fatal(err) } have := make([]string, 0) for _, ifi := range ift { - have = append(have, ifi.Name) + have = append(have, toString(ifi.Name, ifi.Flags&FlagUp != 0)) } sort.Strings(have) - want, err := netshInterfaceIPShowConfig() + ifaces := make(map[string]bool) + err = netshInterfaceIPShowInterface("ipv6", ifaces) if err != nil { t.Fatal(err) } + err = netshInterfaceIPShowInterface("ipv4", ifaces) + if err != nil { + t.Fatal(err) + } + want := make([]string, 0) + for name, isup := range ifaces { + want = append(want, toString(name, isup)) + } sort.Strings(want) if strings.Join(want, "/") != strings.Join(have, "/") { @@ -324,6 +383,9 @@ func TestInterfaceAddrsWithNetsh(t *testing.T) { if isWindowsXP(t) { t.Skip("Windows XP netsh command does not provide required functionality") } + if !isEnglishOS(t) { + t.Skip("English version of OS required for this test") + } ift, err := Interfaces() if err != nil { t.Fatal(err) @@ -377,6 +439,10 @@ func TestInterfaceHardwareAddrWithGetmac(t *testing.T) { if isWindowsXP(t) { t.Skip("Windows XP does not have powershell command") } + if !isEnglishOS(t) { + t.Skip("English version of OS required for this test") + } + ift, err := Interfaces() if err != nil { t.Fatal(err)