From 2b9b6550a7264fbbae547f71b80170d979cd74af Mon Sep 17 00:00:00 2001 From: Mabuchin Date: Sat, 27 Jan 2024 07:42:08 +0900 Subject: [PATCH] Fix data_bytes is null in ping -I option (#520) * fixed header parsing when specifying ping interface * add source_ip parsing test for ping/ping-s --------- Co-authored-by: Kelly Brazil --- jc/parsers/ping.py | 21 ++++++---- jc/parsers/ping_s.py | 22 ++++++---- .../ubuntu-22.04/ping-hostname-source-ip.json | 1 + .../ubuntu-22.04/ping-hostname-source-ip.out | 8 ++++ .../ubuntu-22.04/ping-ip-source-ip.json | 1 + .../ubuntu-22.04/ping-ip-source-ip.out | 8 ++++ .../ping6-hostname-source-ip.json | 1 + .../ubuntu-22.04/ping6-hostname-source-ip.out | 7 ++++ .../ubuntu-22.04/ping6-ip-source-ip.json | 1 + .../ubuntu-22.04/ping6-ip-source-ip.out | 8 ++++ tests/test_ping.py | 40 +++++++++++++++++++ 11 files changed, 104 insertions(+), 14 deletions(-) create mode 100644 tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.json create mode 100644 tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.out create mode 100644 tests/fixtures/ubuntu-22.04/ping-ip-source-ip.json create mode 100644 tests/fixtures/ubuntu-22.04/ping-ip-source-ip.out create mode 100644 tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.json create mode 100644 tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.out create mode 100644 tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.json create mode 100644 tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.out diff --git a/jc/parsers/ping.py b/jc/parsers/ping.py index 3d623445..cc5e7875 100644 --- a/jc/parsers/ping.py +++ b/jc/parsers/ping.py @@ -298,14 +298,21 @@ def _linux_parse(data): for line in filter(None, linedata): if line.startswith('PING '): - if ipv4 and not hostname: - dst_ip, dta_byts = (2, 3) - elif ipv4 and hostname: - dst_ip, dta_byts = (2, 3) - elif not ipv4 and not hostname: - dst_ip, dta_byts = (2, 3) + source_ip = 'from' in line + if ipv4: + if source_ip: + dst_ip, dta_byts = (2, 6) + else: + dst_ip, dta_byts = (2, 3) else: - dst_ip, dta_byts = (3, 4) + if source_ip and hostname: + dst_ip, dta_byts = (3, 7) + elif source_ip and not hostname: + dst_ip, dta_byts = (2, 6) + elif not source_ip and hostname: + dst_ip, dta_byts = (3, 4) + else: + dst_ip, dta_byts = (2, 3) line = line.replace('(', ' ').replace(')', ' ') raw_output.update( diff --git a/jc/parsers/ping_s.py b/jc/parsers/ping_s.py index 639fa83a..9658d3c7 100644 --- a/jc/parsers/ping_s.py +++ b/jc/parsers/ping_s.py @@ -138,6 +138,7 @@ class _state: linux = None bsd = None ipv4 = None + source_ip = None hostname = None destination_ip = None sent_bytes = None @@ -347,6 +348,7 @@ def _linux_parse(line, s): if line.startswith('PING '): s.ipv4 = 'bytes of data' in line + s.source_ip = 'from' in line if s.ipv4 and line[5] not in string.digits: s.hostname = True @@ -359,14 +361,20 @@ def _linux_parse(line, s): else: s.hostname = False - if s.ipv4 and not s.hostname: - dst_ip, dta_byts = (2, 3) - elif s.ipv4 and s.hostname: - dst_ip, dta_byts = (2, 3) - elif not s.ipv4 and not s.hostname: - dst_ip, dta_byts = (2, 3) + if s.ipv4: + if s.source_ip: + dst_ip, dta_byts = (2, 6) + else: + dst_ip, dta_byts = (2, 3) else: - dst_ip, dta_byts = (3, 4) + if s.source_ip and s.hostname: + dst_ip, dta_byts = (3, 7) + elif s.source_ip and not s.hostname: + dst_ip, dta_byts = (2, 6) + elif not s.source_ip and s.hostname: + dst_ip, dta_byts = (3, 4) + else: + dst_ip, dta_byts = (2, 3) line = line.replace('(', ' ').replace(')', ' ') s.destination_ip = line.split()[dst_ip].lstrip('(').rstrip(')') diff --git a/tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.json b/tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.json new file mode 100644 index 00000000..d0c85c78 --- /dev/null +++ b/tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.json @@ -0,0 +1 @@ +{"destination_ip":"10.0.0.1","data_bytes":56,"pattern":null,"destination":"example.com","duplicates":0,"packets_transmitted":3,"packets_received":3,"packet_loss_percent":0.0,"time_ms":2000.0,"round_trip_ms_min":1.0,"round_trip_ms_avg":1.0,"round_trip_ms_max":1.0,"round_trip_ms_stddev":1.0,"responses":[{"type":"reply","timestamp":null,"bytes":64,"response_ip":"10.0.0.1","icmp_seq":1,"ttl":119,"time_ms":1.0,"duplicate":false},{"type":"reply","timestamp":null,"bytes":64,"response_ip":"10.0.0.1","icmp_seq":2,"ttl":119,"time_ms":1.0,"duplicate":false},{"type":"reply","timestamp":null,"bytes":64,"response_ip":"10.0.0.1","icmp_seq":3,"ttl":119,"time_ms":1.0,"duplicate":false}]} \ No newline at end of file diff --git a/tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.out b/tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.out new file mode 100644 index 00000000..938f9b35 --- /dev/null +++ b/tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.out @@ -0,0 +1,8 @@ +PING example.com (10.0.0.1) from 10.0.0.2 eth0: 56(84) bytes of data. +64 bytes from example.com (10.0.0.1): icmp_seq=1 ttl=119 time=1.00 ms +64 bytes from example.com (10.0.0.1): icmp_seq=2 ttl=119 time=1.00 ms +64 bytes from example.com (10.0.0.1): icmp_seq=3 ttl=119 time=1.00 ms + +--- example.com ping statistics --- +3 packets transmitted, 3 received, 0% packet loss, time 2000ms +rtt min/avg/max/mdev = 1.000/1.000/1.000/1.000 ms \ No newline at end of file diff --git a/tests/fixtures/ubuntu-22.04/ping-ip-source-ip.json b/tests/fixtures/ubuntu-22.04/ping-ip-source-ip.json new file mode 100644 index 00000000..5ebe7b1d --- /dev/null +++ b/tests/fixtures/ubuntu-22.04/ping-ip-source-ip.json @@ -0,0 +1 @@ +{"destination_ip": "10.0.0.1", "data_bytes": 56, "pattern": null, "destination": "10.0.0.1", "duplicates": 0, "packets_transmitted": 3, "packets_received": 3, "packet_loss_percent": 0.0, "time_ms": 2000.0, "round_trip_ms_min": 1.0, "round_trip_ms_avg": 1.0, "round_trip_ms_max": 1.0, "round_trip_ms_stddev": 1.0, "responses": [{"type": "reply", "timestamp": null, "bytes": 64, "response_ip": "10.0.0.1", "icmp_seq": 1, "ttl": 119, "time_ms": 1.0, "duplicate": false}, {"type": "reply", "timestamp": null, "bytes": 64, "response_ip": "10.0.0.1", "icmp_seq": 2, "ttl": 119, "time_ms": 1.0, "duplicate": false}, {"type": "reply", "timestamp": null, "bytes": 64, "response_ip": "10.0.0.1", "icmp_seq": 3, "ttl": 119, "time_ms": 1.0, "duplicate": false}]} \ No newline at end of file diff --git a/tests/fixtures/ubuntu-22.04/ping-ip-source-ip.out b/tests/fixtures/ubuntu-22.04/ping-ip-source-ip.out new file mode 100644 index 00000000..2fee3d30 --- /dev/null +++ b/tests/fixtures/ubuntu-22.04/ping-ip-source-ip.out @@ -0,0 +1,8 @@ +PING 10.0.0.1 (10.0.0.1) from 10.0.0.2 eth0: 56(84) bytes of data. +64 bytes from 10.0.0.1: icmp_seq=1 ttl=119 time=1.00 ms +64 bytes from 10.0.0.1: icmp_seq=2 ttl=119 time=1.00 ms +64 bytes from 10.0.0.1: icmp_seq=3 ttl=119 time=1.00 ms + +--- 10.0.0.1 ping statistics --- +3 packets transmitted, 3 received, 0% packet loss, time 2000ms +rtt min/avg/max/mdev = 1.000/1.000/1.000/1.000 ms \ No newline at end of file diff --git a/tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.json b/tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.json new file mode 100644 index 00000000..d5fa7a39 --- /dev/null +++ b/tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.json @@ -0,0 +1 @@ +{"destination_ip":"2001:0db8::1","data_bytes":56,"pattern":null,"destination":"example.com","duplicates":0,"packets_transmitted":2,"packets_received":2,"packet_loss_percent":0.0,"time_ms":1001.0,"round_trip_ms_min":11.314,"round_trip_ms_avg":13.495,"round_trip_ms_max":15.676,"round_trip_ms_stddev":2.181,"responses":[{"type":"reply","timestamp":null,"bytes":64,"response_ip":"2001:0db8::1","icmp_seq":1,"ttl":114,"time_ms":15.7,"duplicate":false},{"type":"reply","timestamp":null,"bytes":64,"response_ip":"2001:0db8::1","icmp_seq":2,"ttl":114,"time_ms":11.3,"duplicate":false}]} \ No newline at end of file diff --git a/tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.out b/tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.out new file mode 100644 index 00000000..e06f354a --- /dev/null +++ b/tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.out @@ -0,0 +1,7 @@ +PING example.com(example.com (2001:0db8::1)) from 2001:0db8::2 : 56 data bytes +64 bytes from example.com (2001:0db8::1): icmp_seq=1 ttl=114 time=15.7 ms +64 bytes from example.com (2001:0db8::1): icmp_seq=2 ttl=114 time=11.3 ms + +--- example.com ping statistics --- +2 packets transmitted, 2 received, 0% packet loss, time 1001ms +rtt min/avg/max/mdev = 11.314/13.495/15.676/2.181 ms \ No newline at end of file diff --git a/tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.json b/tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.json new file mode 100644 index 00000000..5bacaecd --- /dev/null +++ b/tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.json @@ -0,0 +1 @@ +{"destination_ip":"2001:0db8::1","data_bytes":56,"pattern":null,"destination":"2001:0db8::1","duplicates":0,"packets_transmitted":2,"packets_received":2,"packet_loss_percent":0.0,"time_ms":1002.0,"round_trip_ms_min":11.021,"round_trip_ms_avg":12.204,"round_trip_ms_max":13.388,"round_trip_ms_stddev":1.183,"responses":[{"type":"reply","timestamp":null,"bytes":64,"response_ip":"2001:0db8::1","icmp_seq":1,"ttl":114,"time_ms":13.4,"duplicate":false},{"type":"reply","timestamp":null,"bytes":64,"response_ip":"2001:0db8::1","icmp_seq":2,"ttl":114,"time_ms":11.0,"duplicate":false},{"type":"reply","timestamp":null,"bytes":64,"response_ip":"2001:0db8::1","icmp_seq":2,"ttl":114,"time_ms":11.0,"duplicate":false}]} \ No newline at end of file diff --git a/tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.out b/tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.out new file mode 100644 index 00000000..67a7eb3f --- /dev/null +++ b/tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.out @@ -0,0 +1,8 @@ +PING 2001:0db8::1(2001:0db8::1) from 2001:0db8::2 : 56 data bytes +64 bytes from 2001:0db8::1: icmp_seq=1 ttl=114 time=13.4 ms +64 bytes from 2001:0db8::1: icmp_seq=2 ttl=114 time=11.0 ms +64 bytes from 2001:0db8::1: icmp_seq=2 ttl=114 time=11.0 ms + +--- 2001:0db8::1 ping statistics --- +2 packets transmitted, 2 received, 0% packet loss, time 1002ms +rtt min/avg/max/mdev = 11.021/12.204/13.388/1.183 ms \ No newline at end of file diff --git a/tests/test_ping.py b/tests/test_ping.py index ae56d40c..b8cab42f 100644 --- a/tests/test_ping.py +++ b/tests/test_ping.py @@ -84,6 +84,14 @@ class MyTests(unittest.TestCase): # ubuntu 22.4 with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping-dest-unreachable.out'), 'r', encoding='utf-8') as f: ubuntu_22_4_ping_dest_unreachable = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping-ip-source-ip.out'), 'r', encoding='utf-8') as f: + ubuntu_22_4_ping_ip_source_ip = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.out'), 'r', encoding='utf-8') as f: + ubuntu_22_4_ping_hostname_source_ip = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.out'), 'r', encoding='utf-8') as f: + ubuntu_22_4_ping6_ip_source_ip = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.out'), 'r', encoding='utf-8') as f: + ubuntu_22_4_ping6_hostname_source_ip = f.read() # fedora with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/fedora32/ping-ip-O.out'), 'r', encoding='utf-8') as f: @@ -292,6 +300,14 @@ class MyTests(unittest.TestCase): # ubuntu 22.4 with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping-dest-unreachable.json'), 'r', encoding='utf-8') as f: ubuntu_22_4_ping_dest_unreachable_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping-ip-source-ip.json'), 'r', encoding='utf-8') as f: + ubuntu_22_4_ping_ip_source_ip_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping-hostname-source-ip.json'), 'r', encoding='utf-8') as f: + ubuntu_22_4_ping_hostname_source_ip_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping6-ip-source-ip.json'), 'r', encoding='utf-8') as f: + ubuntu_22_4_ping6_ip_source_ip_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-22.04/ping6-hostname-source-ip.json'), 'r', encoding='utf-8') as f: + ubuntu_22_4_ping6_hostname_source_ip_json = json.loads(f.read()) # fedora with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/fedora32/ping-ip-O.json'), 'r', encoding='utf-8') as f: @@ -569,6 +585,30 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.ping.parse(self.ubuntu_22_4_ping_dest_unreachable, quiet=True), self.ubuntu_22_4_ping_dest_unreachable_json) + def test_ping_ip_source_ip_ubuntu_22_4(self): + """ + Test 'ping -I ' on Ubuntu 22.4 + """ + self.assertEqual(jc.parsers.ping.parse(self.ubuntu_22_4_ping_ip_source_ip, quiet=True), self.ubuntu_22_4_ping_ip_source_ip_json) + + def test_ping_hostname_source_ip_ubuntu_22_4(self): + """ + Test 'ping -I ' on Ubuntu 22.4 + """ + self.assertEqual(jc.parsers.ping.parse(self.ubuntu_22_4_ping_hostname_source_ip, quiet=True), self.ubuntu_22_4_ping_hostname_source_ip_json) + + def test_ping6_ip_source_ip_ubuntu_22_4(self): + """ + Test 'ping6 -I ' on Ubuntu 22.4 with source IP address + """ + self.assertEqual(jc.parsers.ping.parse(self.ubuntu_22_4_ping6_ip_source_ip, quiet=True), self.ubuntu_22_4_ping6_ip_source_ip_json) + + def test_ping6_hostname_source_ip_ubuntu_22_4(self): + """ + Test 'ping6 -I ' on Ubuntu 22.4 with source IP address + """ + self.assertEqual(jc.parsers.ping.parse(self.ubuntu_22_4_ping6_hostname_source_ip, quiet=True), self.ubuntu_22_4_ping6_hostname_source_ip_json) + def test_ping_ip_O_fedora32(self): """ Test 'ping -O' on fedora32