diff --git a/agent/go/cmd/rmm-agent/main.go b/agent/go/cmd/rmm-agent/main.go index bd3fa92..7275a39 100644 --- a/agent/go/cmd/rmm-agent/main.go +++ b/agent/go/cmd/rmm-agent/main.go @@ -1484,7 +1484,7 @@ func connectivityChecks(targets []string) []map[string]any { func parsePacketLoss(output string) float64 { for _, part := range strings.Split(output, ",") { if strings.Contains(part, "packet loss") { - clean := strings.TrimSpace(strings.ReplaceAll(part, "% packet loss", "")) + clean := packetLossNumber(part) value, err := strconv.ParseFloat(clean, 64) if err == nil { return value @@ -1494,6 +1494,24 @@ func parsePacketLoss(output string) float64 { return 100 } +func packetLossNumber(value string) string { + percent := strings.IndexByte(value, '%') + if percent < 0 { + return "" + } + value = strings.TrimSpace(value[:percent]) + start := len(value) + for start > 0 { + r := rune(value[start-1]) + if (r >= '0' && r <= '9') || r == '.' { + start-- + continue + } + break + } + return value[start:] +} + func parseLatency(output string) float64 { for _, line := range strings.Split(output, "\n") { if !strings.Contains(line, "min/avg/max") && !strings.Contains(line, "round-trip") { diff --git a/agent/go/cmd/rmm-agent/main_test.go b/agent/go/cmd/rmm-agent/main_test.go index c23e5eb..340428f 100644 --- a/agent/go/cmd/rmm-agent/main_test.go +++ b/agent/go/cmd/rmm-agent/main_test.go @@ -47,3 +47,34 @@ func TestLooksLikeMAC(t *testing.T) { } } } + +func TestParsePacketLossBusyBox(t *testing.T) { + output := `PING 10.10.10.10 (10.10.10.10): 56 data bytes +64 bytes from 10.10.10.10: seq=0 ttl=64 time=1.157 ms +64 bytes from 10.10.10.10: seq=1 ttl=64 time=0.883 ms +64 bytes from 10.10.10.10: seq=2 ttl=64 time=0.952 ms + +--- 10.10.10.10 ping statistics --- +3 packets transmitted, 3 packets received, 0% packet loss +round-trip min/avg/max = 0.883/0.997/1.157 ms` + + if loss := parsePacketLoss(output); loss != 0 { + t.Fatalf("expected 0%% packet loss, got %v", loss) + } + if latency := parseLatency(output); latency != 0.997 { + t.Fatalf("expected avg latency 0.997, got %v", latency) + } +} + +func TestParsePacketLossGNU(t *testing.T) { + output := `--- 1.1.1.1 ping statistics --- +3 packets transmitted, 2 received, 33.3333% packet loss, time 2002ms +rtt min/avg/max/mdev = 10.100/11.200/12.300/0.100 ms` + + if loss := parsePacketLoss(output); loss != 33.3333 { + t.Fatalf("expected 33.3333%% packet loss, got %v", loss) + } + if latency := parseLatency(output); latency != 11.2 { + t.Fatalf("expected avg latency 11.2, got %v", latency) + } +}