From 679fefc1558fc6a416ef3564d7cef1c2be091cf3 Mon Sep 17 00:00:00 2001 From: Michal Wieczorek Date: Wed, 20 Jul 2016 22:13:50 +0200 Subject: [PATCH 1/2] Link speed for windows network fingerprinting --- client/fingerprint/network_default.go | 2 +- client/fingerprint/network_windows.go | 47 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 client/fingerprint/network_windows.go diff --git a/client/fingerprint/network_default.go b/client/fingerprint/network_default.go index f24479b85..3faa93881 100644 --- a/client/fingerprint/network_default.go +++ b/client/fingerprint/network_default.go @@ -1,4 +1,4 @@ -// +build !linux +// +build !linux,!windows package fingerprint diff --git a/client/fingerprint/network_windows.go b/client/fingerprint/network_windows.go new file mode 100644 index 000000000..4d17b57b3 --- /dev/null +++ b/client/fingerprint/network_windows.go @@ -0,0 +1,47 @@ +package fingerprint + +import ( + "fmt" + "os/exec" + "strconv" + "strings" +) + +// linkSpeed returns link speed in Mb/s, or 0 when unable to determine it. +func (f *NetworkFingerprint) linkSpeed(device string) int { + command := fmt.Sprintf("Get-NetAdapter -IncludeHidden | Where name -eq '%s' | Select -ExpandProperty LinkSpeed", device) + path := "powershell.exe" + outBytes, err := exec.Command(path, command).Output() + + if err != nil { + f.logger.Printf("[WARN] fingerprint.network: Error calling %s (%s): %v", path, command, err) + return 0 + } + + output := strings.TrimSpace(string(outBytes)) + args := strings.Split(output, " ") + if len(args) != 2 { + f.logger.Printf("[WARN] fingerprint.network: Couldn't split LinkSpeed (%s)", output) + return 0 + } + + unit := strings.Replace(args[1], "\r\n", "", -1) + value, err := strconv.Atoi(args[0]) + if err != nil { + f.logger.Printf("[WARN] fingerprint.network: Unable to parse LinkSpeed value (%s)", output) + return 0 + } + + switch unit { + case "Mbps": + return value + case "Kbps": + return value / 1000 + case "Gbps": + return value * 1000 + case "bps": + return value / 1000000 + } + + return 0 +} From b6b3e245412626ed81548fd1dbc126ce29ead9ee Mon Sep 17 00:00:00 2001 From: Michal Wieczorek Date: Fri, 22 Jul 2016 22:41:36 +0200 Subject: [PATCH 2/2] Link speed for windows network fingerprinting - tests --- client/fingerprint/network_windows.go | 11 +++++--- client/fingerprint/network_windows_test.go | 30 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 client/fingerprint/network_windows_test.go diff --git a/client/fingerprint/network_windows.go b/client/fingerprint/network_windows.go index 4d17b57b3..8617a65a8 100644 --- a/client/fingerprint/network_windows.go +++ b/client/fingerprint/network_windows.go @@ -19,16 +19,21 @@ func (f *NetworkFingerprint) linkSpeed(device string) int { } output := strings.TrimSpace(string(outBytes)) - args := strings.Split(output, " ") + + return f.parseLinkSpeed(output) +} + +func (f *NetworkFingerprint) parseLinkSpeed(commandOutput string) int { + args := strings.Split(commandOutput, " ") if len(args) != 2 { - f.logger.Printf("[WARN] fingerprint.network: Couldn't split LinkSpeed (%s)", output) + f.logger.Printf("[WARN] fingerprint.network: Couldn't split LinkSpeed (%s)", commandOutput) return 0 } unit := strings.Replace(args[1], "\r\n", "", -1) value, err := strconv.Atoi(args[0]) if err != nil { - f.logger.Printf("[WARN] fingerprint.network: Unable to parse LinkSpeed value (%s)", output) + f.logger.Printf("[WARN] fingerprint.network: Unable to parse LinkSpeed value (%s)", commandOutput) return 0 } diff --git a/client/fingerprint/network_windows_test.go b/client/fingerprint/network_windows_test.go new file mode 100644 index 000000000..0cc8acfdf --- /dev/null +++ b/client/fingerprint/network_windows_test.go @@ -0,0 +1,30 @@ +package fingerprint + +import "testing" + +func TestNetworkFingerPrint_linkspeed_parse(t *testing.T) { + f := &NetworkFingerprint{logger: testLogger(), interfaceDetector: &DefaultNetworkInterfaceDetector{}} + + var outputTests = []struct { + in string + out int + }{ + {"10 Mbps", 10}, + {"2 bps", 0}, + {"1 Gbps", 1000}, + {"2Mbps", 0}, + {"1000 Kbps", 1}, + {"1 Kbps", 0}, + {"0 Mbps", 0}, + {"2 2 Mbps", 0}, + {"a Mbps", 0}, + {"1 Tbps", 0}, + } + + for _, ot := range outputTests { + out := f.parseLinkSpeed(ot.in) + if out != ot.out { + t.Errorf("parseLinkSpeed(%s) => %d, should be %d", ot.in, out, ot.out) + } + } +}