diff --git a/plugins/inputs/ping/ping_notwindows.go b/plugins/inputs/ping/ping_notwindows.go index a4d41090e4d62..a014a8237e8e7 100644 --- a/plugins/inputs/ping/ping_notwindows.go +++ b/plugins/inputs/ping/ping_notwindows.go @@ -104,7 +104,13 @@ func (p *Ping) args(url string, system string) []string { switch system { case "darwin": args = append(args, "-W", strconv.FormatFloat(p.Timeout*1000, 'f', -1, 64)) - case "freebsd", "netbsd", "openbsd": + case "freebsd": + if strings.Contains(p.Binary, "ping6") { + args = append(args, "-x", strconv.FormatFloat(p.Timeout*1000, 'f', -1, 64)) + } else { + args = append(args, "-W", strconv.FormatFloat(p.Timeout*1000, 'f', -1, 64)) + } + case "netbsd", "openbsd": args = append(args, "-W", strconv.FormatFloat(p.Timeout*1000, 'f', -1, 64)) case "linux": args = append(args, "-W", strconv.FormatFloat(p.Timeout, 'f', -1, 64)) @@ -115,7 +121,13 @@ func (p *Ping) args(url string, system string) []string { } if p.Deadline > 0 { switch system { - case "darwin", "freebsd", "netbsd", "openbsd": + case "freebsd": + if strings.Contains(p.Binary, "ping6") { + args = append(args, "-X", strconv.Itoa(p.Deadline)) + } else { + args = append(args, "-t", strconv.Itoa(p.Deadline)) + } + case "darwin", "netbsd", "openbsd": args = append(args, "-t", strconv.Itoa(p.Deadline)) case "linux": args = append(args, "-w", strconv.Itoa(p.Deadline)) @@ -160,7 +172,7 @@ func processPingOutput(out string) (int, int, int, float64, float64, float64, fl lines := strings.Split(out, "\n") for _, line := range lines { // Reading only first TTL, ignoring other TTL messages - if ttl == -1 && strings.Contains(line, "ttl=") { + if ttl == -1 && (strings.Contains(line, "ttl=") || strings.Contains(line, "hlim=")) { ttl, err = getTTL(line) } else if strings.Contains(line, "transmitted") && strings.Contains(line, "received") { @@ -191,9 +203,9 @@ func getPacketStats(line string, trans, recv int) (int, int, error) { } func getTTL(line string) (int, error) { - ttlLine := regexp.MustCompile(`ttl=(\d+)`) + ttlLine := regexp.MustCompile(`(ttl|hlim)=(\d+)`) ttlMatch := ttlLine.FindStringSubmatch(line) - return strconv.Atoi(ttlMatch[1]) + return strconv.Atoi(ttlMatch[2]) } func checkRoundTripTimeStats(line string, min, avg, max, diff --git a/plugins/inputs/ping/ping_test.go b/plugins/inputs/ping/ping_test.go index d6f78bb793220..0c8cfb0939daa 100644 --- a/plugins/inputs/ping/ping_test.go +++ b/plugins/inputs/ping/ping_test.go @@ -29,6 +29,20 @@ PING www.google.com (216.58.217.36): 56 data bytes round-trip min/avg/max/stddev = 15.087/20.224/27.263/4.076 ms ` +// FreeBSD ping6 output +var freebsdPing6Output = ` +PING6(64=40+8+16 bytes) 2001:db8::1 --> 2a00:1450:4001:824::2004 +24 bytes from 2a00:1450:4001:824::2004, icmp_seq=0 hlim=117 time=93.870 ms +24 bytes from 2a00:1450:4001:824::2004, icmp_seq=1 hlim=117 time=40.278 ms +24 bytes from 2a00:1450:4001:824::2004, icmp_seq=2 hlim=120 time=59.077 ms +24 bytes from 2a00:1450:4001:824::2004, icmp_seq=3 hlim=117 time=37.102 ms +24 bytes from 2a00:1450:4001:824::2004, icmp_seq=4 hlim=117 time=35.727 ms + +--- www.google.com ping6 statistics --- +5 packets transmitted, 5 packets received, 0.0% packet loss +round-trip min/avg/max/std-dev = 35.727/53.211/93.870/22.000 ms +` + // Linux ping output var linuxPingOutput = ` PING www.google.com (216.58.218.164) 56(84) bytes of data. @@ -67,17 +81,27 @@ func TestProcessPingOutput(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 55, ttl, "ttl value is 55") assert.Equal(t, 5, trans, "5 packets were transmitted") - assert.Equal(t, 5, rec, "5 packets were transmitted") + assert.Equal(t, 5, rec, "5 packets were received") assert.InDelta(t, 15.087, min, 0.001) assert.InDelta(t, 20.224, avg, 0.001) assert.InDelta(t, 27.263, max, 0.001) assert.InDelta(t, 4.076, stddev, 0.001) + trans, rec, ttl, min, avg, max, stddev, err = processPingOutput(freebsdPing6Output) + assert.NoError(t, err) + assert.Equal(t, 117, ttl, "ttl value is 117") + assert.Equal(t, 5, trans, "5 packets were transmitted") + assert.Equal(t, 5, rec, "5 packets were received") + assert.InDelta(t, 35.727, min, 0.001) + assert.InDelta(t, 53.211, avg, 0.001) + assert.InDelta(t, 93.870, max, 0.001) + assert.InDelta(t, 22.000, stddev, 0.001) + trans, rec, ttl, min, avg, max, stddev, err = processPingOutput(linuxPingOutput) assert.NoError(t, err) assert.Equal(t, 63, ttl, "ttl value is 63") assert.Equal(t, 5, trans, "5 packets were transmitted") - assert.Equal(t, 5, rec, "5 packets were transmitted") + assert.Equal(t, 5, rec, "5 packets were received") assert.InDelta(t, 35.225, min, 0.001) assert.InDelta(t, 43.628, avg, 0.001) assert.InDelta(t, 51.806, max, 0.001) @@ -87,7 +111,7 @@ func TestProcessPingOutput(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 56, ttl, "ttl value is 56") assert.Equal(t, 4, trans, "4 packets were transmitted") - assert.Equal(t, 4, rec, "4 packets were transmitted") + assert.Equal(t, 4, rec, "4 packets were received") assert.InDelta(t, 15.810, min, 0.001) assert.InDelta(t, 17.611, avg, 0.001) assert.InDelta(t, 22.559, max, 0.001) @@ -128,7 +152,7 @@ func TestErrorProcessPingOutput(t *testing.T) { assert.Error(t, err, "Error was expected from processPingOutput") } -// Test that arg lists and created correctly +// Test that default arg lists are created correctly func TestArgs(t *testing.T) { p := Ping{ Count: 2, @@ -156,6 +180,35 @@ func TestArgs(t *testing.T) { } } +// Test that default arg lists for ping6 are created correctly +func TestArgs6(t *testing.T) { + p := Ping{ + Count: 2, + Interface: "eth0", + Timeout: 12.0, + Deadline: 24, + PingInterval: 1.2, + Binary: "ping6", + } + + var systemCases = []struct { + system string + output []string + }{ + {"freebsd", []string{"-c", "2", "-n", "-s", "16", "-i", "1.2", "-x", "12000", "-X", "24", "-S", "eth0", "www.google.com"}}, + {"linux", []string{"-c", "2", "-n", "-s", "16", "-i", "1.2", "-W", "12", "-w", "24", "-I", "eth0", "www.google.com"}}, + {"anything else", []string{"-c", "2", "-n", "-s", "16", "-i", "1.2", "-W", "12", "-w", "24", "-i", "eth0", "www.google.com"}}, + } + for i := range systemCases { + actual := p.args("www.google.com", systemCases[i].system) + expected := systemCases[i].output + sort.Strings(actual) + sort.Strings(expected) + require.True(t, reflect.DeepEqual(expected, actual), + "Expected: %s Actual: %s", expected, actual) + } +} + func TestArguments(t *testing.T) { arguments := []string{"-c", "3"} expected := append(arguments, "www.google.com")