diff --git a/docs/parsers/ping.md b/docs/parsers/ping.md index 64ad3c9f..6d8e8134 100644 --- a/docs/parsers/ping.md +++ b/docs/parsers/ping.md @@ -125,19 +125,21 @@ Returns: "packets_transmitted": integer, "packets_received": integer, "packet_loss_percent": float, + "duplicates": integer, "round_trip_ms_min": float, "round_trip_ms_avg": float, "round_trip_ms_max": float, "round_trip_ms_stddev": float, "responses": [ { - "type": string, ('reply' or 'timeout') + "type": string, ('reply' or 'timeout') "timestamp": float, "bytes": integer, "response_ip": string, "icmp_seq": integer, "ttl": integer, - "time_ms": float + "time_ms": float, + "duplicate": boolean } ] } diff --git a/jc/parsers/ping.py b/jc/parsers/ping.py index c15dc80e..6ad8e206 100644 --- a/jc/parsers/ping.py +++ b/jc/parsers/ping.py @@ -135,24 +135,26 @@ def process(proc_data): "packets_transmitted": integer, "packets_received": integer, "packet_loss_percent": float, + "duplicates": integer, "round_trip_ms_min": float, "round_trip_ms_avg": float, "round_trip_ms_max": float, "round_trip_ms_stddev": float, "responses": [ { - "type": string, ('reply' or 'timeout') + "type": string, ('reply' or 'timeout') "timestamp": float, "bytes": integer, "response_ip": string, "icmp_seq": integer, "ttl": integer, - "time_ms": float + "time_ms": float, + "duplicate": boolean } ] } """ - int_list = ['data_bytes', 'packets_transmitted', 'packets_received', 'bytes', 'icmp_seq', 'ttl'] + int_list = ['data_bytes', 'packets_transmitted', 'packets_received', 'bytes', 'icmp_seq', 'ttl', 'duplicates'] float_list = ['packet_loss_percent', 'round_trip_ms_min', 'round_trip_ms_avg', 'round_trip_ms_max', 'round_trip_ms_stddev', 'timestamp', 'time_ms'] @@ -200,6 +202,9 @@ def linux_parse(data): if linedata[0].startswith('PATTERN: '): pattern = linedata.pop(0).split(': ')[1] + while not linedata[0].startswith('PING '): + linedata.pop(0) + ipv4 = True if 'bytes of data' in linedata[0] else False if ipv4 and linedata[0][5] not in string.digits: @@ -239,15 +244,28 @@ def linux_parse(data): if footer: if 'packets transmitted' in line: - raw_output.update( - { - 'packets_transmitted': line.split()[0], - 'packets_received': line.split()[3], - 'packet_loss_percent': line.split()[5].rstrip('%'), - 'time_ms': line.split()[9].replace('ms', '') - } - ) - continue + if ' duplicates,' in line: + raw_output.update( + { + 'packets_transmitted': line.split()[0], + 'packets_received': line.split()[3], + 'packet_loss_percent': line.split()[7].rstrip('%'), + 'duplicates': line.split()[5].lstrip('+'), + 'time_ms': line.split()[11].replace('ms', '') + } + ) + continue + else: + raw_output.update( + { + 'packets_transmitted': line.split()[0], + 'packets_received': line.split()[3], + 'packet_loss_percent': line.split()[5].rstrip('%'), + 'duplicates': '0', + 'time_ms': line.split()[9].replace('ms', '') + } + ) + continue else: split_line = line.split(' = ')[1] @@ -257,7 +275,7 @@ def linux_parse(data): 'round_trip_ms_min': split_line[0], 'round_trip_ms_avg': split_line[1], 'round_trip_ms_max': split_line[2], - 'round_trip_ms_stddev': split_line[3].replace(' ms', '') + 'round_trip_ms_stddev': split_line[3].split()[0] } ) @@ -309,8 +327,10 @@ def linux_parse(data): 'response_ip': line.split()[rip].rstrip(':'), 'icmp_seq': line.split()[iseq], 'ttl': line.split()[t2l], - 'time_ms': line.split()[tms] + 'time_ms': line.split()[tms], + 'duplicate': True if 'DUP!' in line else False } + ping_responses.append(response) continue @@ -361,14 +381,26 @@ def bsd_parse(data): if footer: if 'packets transmitted' in line: - raw_output.update( - { - 'packets_transmitted': line.split()[0], - 'packets_received': line.split()[3], - 'packet_loss_percent': line.split()[6].rstrip('%') - } - ) - continue + if ' duplicates,' in line: + raw_output.update( + { + 'packets_transmitted': line.split()[0], + 'packets_received': line.split()[3], + 'packet_loss_percent': line.split()[8].rstrip('%'), + 'duplicates': line.split()[6].lstrip('+'), + } + ) + continue + else: + raw_output.update( + { + 'packets_transmitted': line.split()[0], + 'packets_received': line.split()[3], + 'packet_loss_percent': line.split()[6].rstrip('%'), + 'duplicates': '0', + } + ) + continue else: split_line = line.split(' = ')[1] @@ -424,6 +456,13 @@ def bsd_parse(data): ping_responses.append(response) continue + # identify duplicates in responses + if ping_responses: + seq_list = [] + for reply in ping_responses: + seq_list.append(reply['icmp_seq']) + reply['duplicate'] = True if seq_list.count(reply['icmp_seq']) > 1 else False + raw_output['responses'] = ping_responses return raw_output diff --git a/tests/fixtures/centos-7.7/ping-ip-dup.out b/tests/fixtures/centos-7.7/ping-ip-dup.out new file mode 100644 index 00000000..35dd734f --- /dev/null +++ b/tests/fixtures/centos-7.7/ping-ip-dup.out @@ -0,0 +1,27 @@ +WARNING: pinging broadcast address +PING 192.168.1.255 (192.168.1.255) 56(84) bytes of data. +64 bytes from 192.168.1.221: icmp_seq=1 ttl=64 time=0.586 ms +64 bytes from 192.168.1.88: icmp_seq=1 ttl=64 time=382 ms (DUP!) +64 bytes from 192.168.1.78: icmp_seq=1 ttl=128 time=382 ms (DUP!) +64 bytes from 192.168.1.217: icmp_seq=1 ttl=255 time=387 ms (DUP!) +64 bytes from 192.168.1.186: icmp_seq=1 ttl=64 time=389 ms (DUP!) +64 bytes from 192.168.1.89: icmp_seq=1 ttl=64 time=389 ms (DUP!) +64 bytes from 192.168.1.75: icmp_seq=1 ttl=64 time=584 ms (DUP!) +64 bytes from 192.168.1.221: icmp_seq=2 ttl=64 time=0.861 ms +64 bytes from 192.168.1.78: icmp_seq=2 ttl=128 time=4.17 ms (DUP!) +64 bytes from 192.168.1.88: icmp_seq=2 ttl=64 time=4.19 ms (DUP!) +64 bytes from 192.168.1.89: icmp_seq=2 ttl=64 time=12.7 ms (DUP!) +64 bytes from 192.168.1.81: icmp_seq=1 ttl=64 time=1029 ms (DUP!) +64 bytes from 192.168.1.72: icmp_seq=1 ttl=64 time=1276 ms (DUP!) +64 bytes from 192.168.1.251: icmp_seq=1 ttl=64 time=1276 ms (DUP!) +64 bytes from 192.168.1.251: icmp_seq=2 ttl=64 time=262 ms (DUP!) +64 bytes from 192.168.1.72: icmp_seq=2 ttl=64 time=263 ms (DUP!) +64 bytes from 192.168.1.246: icmp_seq=2 ttl=255 time=263 ms (DUP!) +64 bytes from 192.168.1.217: icmp_seq=2 ttl=255 time=919 ms (DUP!) +64 bytes from 192.168.1.186: icmp_seq=2 ttl=64 time=919 ms (DUP!) +64 bytes from 192.168.1.75: icmp_seq=2 ttl=64 time=919 ms (DUP!) +64 bytes from 192.168.1.81: icmp_seq=2 ttl=64 time=919 ms (DUP!) + +--- 192.168.1.255 ping statistics --- +2 packets transmitted, 2 received, +19 duplicates, 0% packet loss, time 1013ms +rtt min/avg/max/mdev = 0.586/504.260/1276.448/417.208 ms, pipe 2 diff --git a/tests/fixtures/osx-10.14.6/ping-ip-dup.out b/tests/fixtures/osx-10.14.6/ping-ip-dup.out new file mode 100644 index 00000000..4cbc8aa8 --- /dev/null +++ b/tests/fixtures/osx-10.14.6/ping-ip-dup.out @@ -0,0 +1,20 @@ +PING 192.168.1.255 (192.168.1.255): 56 data bytes +64 bytes from 192.168.1.221: icmp_seq=0 ttl=64 time=0.235 ms +64 bytes from 192.168.1.88: icmp_seq=0 ttl=64 time=4.224 ms +64 bytes from 192.168.1.89: icmp_seq=0 ttl=64 time=8.370 ms +64 bytes from 192.168.1.72: icmp_seq=0 ttl=64 time=62.635 ms +64 bytes from 192.168.1.246: icmp_seq=0 ttl=255 time=62.805 ms +64 bytes from 192.168.1.78: icmp_seq=0 ttl=128 time=63.803 ms +64 bytes from 192.168.1.251: icmp_seq=0 ttl=64 time=63.857 ms +64 bytes from 192.168.1.217: icmp_seq=0 ttl=255 time=672.974 ms +64 bytes from 192.168.1.186: icmp_seq=0 ttl=64 time=673.123 ms +64 bytes from 192.168.1.75: icmp_seq=0 ttl=64 time=673.358 ms +64 bytes from 192.168.1.221: icmp_seq=1 ttl=64 time=0.291 ms +64 bytes from 192.168.1.78: icmp_seq=1 ttl=128 time=7.898 ms +64 bytes from 192.168.1.88: icmp_seq=1 ttl=64 time=7.927 ms +64 bytes from 192.168.1.89: icmp_seq=1 ttl=64 time=10.077 ms +64 bytes from 192.168.1.250: icmp_seq=0 ttl=64 time=1084.262 ms + +--- 192.168.1.255 ping statistics --- +2 packets transmitted, 2 packets received, +13 duplicates, 0.0% packet loss +round-trip min/avg/max/stddev = 0.235/226.389/1084.262/344.729 ms