From 8ce155d843806be4ad23491b4401e4eda02e2a1c Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Mon, 3 May 2021 15:16:33 -0700 Subject: [PATCH] add support for error replies in v4 ping on osx and bsd --- CHANGELOG | 3 + jc/parsers/ping.py | 56 +++++++++++-------- .../osx-10.14.6/ping-ip-unreachable.json | 1 + .../osx-10.14.6/ping-ip-unreachable.out | 35 ++++++++++++ tests/test_ping.py | 14 ++++- 5 files changed, 86 insertions(+), 23 deletions(-) create mode 100644 tests/fixtures/osx-10.14.6/ping-ip-unreachable.json create mode 100644 tests/fixtures/osx-10.14.6/ping-ip-unreachable.out diff --git a/CHANGELOG b/CHANGELOG index f25f1bb0..3603b017 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ jc changelog +20210510 v1.15.4 +- Update ping parser to support error responses in OSX and BSD + 20210426 v1.15.3 - Add ufw status command parser tested on linux - Add ufw-appinfo command parser tested on linux diff --git a/jc/parsers/ping.py b/jc/parsers/ping.py index bcc3a015..f216616c 100644 --- a/jc/parsers/ping.py +++ b/jc/parsers/ping.py @@ -157,7 +157,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`ping` and `ping6` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -496,10 +496,15 @@ def _bsd_parse(data): err = _error_type(line) if err: response = { - 'type': err, - 'bytes': line.split()[0], - 'response_ip': line.split()[4].strip(':').strip('(').strip(')'), + 'type': err } + + try: + response['bytes'] = line.split()[0] + response['response_ip'] = line.split()[4].strip(':').strip('(').strip(')') + except Exception: + pass + ping_error = True continue @@ -508,24 +513,31 @@ def _bsd_parse(data): continue else: error_line = line.split() - response.update( - { - 'vr': int(error_line[0], 16), - 'hl': int(error_line[1], 16), - 'tos': int(error_line[2], 16), - 'len': int(error_line[3], 16), - 'id': int(error_line[4], 16), - 'flg': int(error_line[5], 16), - 'off': int(error_line[6], 16), - 'ttl': int(error_line[7], 16), - 'pro': int(error_line[8], 16), - 'cks': int(error_line[9], 16), - 'src': error_line[10], - 'dst': error_line[11], - } - ) - ping_responses.append(response) - error_line = False + + try: + response.update( + { + 'vr': int(error_line[0], 16), # convert from hex to decimal + 'hl': int(error_line[1], 16), + 'tos': int(error_line[2], 16), + 'len': int(error_line[3], 16), + 'id': int(error_line[4], 16), + 'flg': int(error_line[5], 16), + 'off': int(error_line[6], 16), + 'ttl': int(error_line[7], 16), + 'pro': int(error_line[8], 16), + 'cks': int(error_line[9], 16), + 'src': error_line[10], + 'dst': error_line[11], + } + ) + except Exception: + pass + + if response: + ping_responses.append(response) + + ping_error = False continue # normal response diff --git a/tests/fixtures/osx-10.14.6/ping-ip-unreachable.json b/tests/fixtures/osx-10.14.6/ping-ip-unreachable.json new file mode 100644 index 00000000..ad481bb3 --- /dev/null +++ b/tests/fixtures/osx-10.14.6/ping-ip-unreachable.json @@ -0,0 +1 @@ +{"destination_ip":"192.168.1.220","data_bytes":56,"pattern":null,"destination":"192.168.1.220","packets_transmitted":8,"packets_received":0,"packet_loss_percent":100.0,"duplicates":0,"responses":[{"type":"timeout","icmp_seq":0,"duplicate":false},{"type":"timeout","icmp_seq":1,"duplicate":false},{"type":"destination_host_unreachable","bytes":92,"response_ip":"192.168.1.220","vr":4,"hl":5,"tos":0,"len":21504,"id":22139,"flg":0,"off":0,"ttl":63,"pro":1,"cks":40996,"src":"192.168.1.221","dst":"192.168.1.220"},{"type":"destination_host_unreachable","bytes":92,"response_ip":"192.168.1.220","vr":4,"hl":5,"tos":0,"len":21504,"id":11887,"flg":0,"off":0,"ttl":63,"pro":1,"cks":51248,"src":"192.168.1.221","dst":"192.168.1.220"},{"type":"destination_host_unreachable","bytes":92,"response_ip":"192.168.1.220","vr":4,"hl":5,"tos":0,"len":21504,"id":41453,"flg":0,"off":0,"ttl":63,"pro":1,"cks":21682,"src":"192.168.1.221","dst":"192.168.1.220"},{"type":"timeout","icmp_seq":2,"duplicate":false},{"type":"timeout","icmp_seq":3,"duplicate":false},{"type":"timeout","icmp_seq":4,"duplicate":false},{"type":"destination_host_unreachable","bytes":92,"response_ip":"192.168.1.220","vr":4,"hl":5,"tos":0,"len":21504,"id":40674,"flg":0,"off":0,"ttl":63,"pro":1,"cks":22461,"src":"192.168.1.221","dst":"192.168.1.220"},{"type":"destination_host_unreachable","bytes":92,"response_ip":"192.168.1.220","vr":4,"hl":5,"tos":0,"len":21504,"id":31035,"flg":0,"off":0,"ttl":63,"pro":1,"cks":32100,"src":"192.168.1.221","dst":"192.168.1.220"},{"type":"destination_host_unreachable","bytes":92,"response_ip":"192.168.1.220","vr":4,"hl":5,"tos":0,"len":21504,"id":53536,"flg":0,"off":0,"ttl":63,"pro":1,"cks":9599,"src":"192.168.1.221","dst":"192.168.1.220"},{"type":"timeout","icmp_seq":5,"duplicate":false},{"type":"timeout","icmp_seq":6,"duplicate":false}]} diff --git a/tests/fixtures/osx-10.14.6/ping-ip-unreachable.out b/tests/fixtures/osx-10.14.6/ping-ip-unreachable.out new file mode 100644 index 00000000..e62f9ade --- /dev/null +++ b/tests/fixtures/osx-10.14.6/ping-ip-unreachable.out @@ -0,0 +1,35 @@ +PING 192.168.1.220 (192.168.1.220): 56 data bytes +Request timeout for icmp_seq 0 +Request timeout for icmp_seq 1 +92 bytes from fgt1.attlocal.net (192.168.1.220): Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 5 00 5400 567b 0 0000 3f 01 a024 192.168.1.221 192.168.1.220 + +92 bytes from fgt1.attlocal.net (192.168.1.220): Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 5 00 5400 2e6f 0 0000 3f 01 c830 192.168.1.221 192.168.1.220 + +92 bytes from fgt1.attlocal.net (192.168.1.220): Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 5 00 5400 a1ed 0 0000 3f 01 54b2 192.168.1.221 192.168.1.220 + +Request timeout for icmp_seq 2 +Request timeout for icmp_seq 3 +Request timeout for icmp_seq 4 +92 bytes from fgt1.attlocal.net (192.168.1.220): Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 5 00 5400 9ee2 0 0000 3f 01 57bd 192.168.1.221 192.168.1.220 + +92 bytes from fgt1.attlocal.net (192.168.1.220): Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 5 00 5400 793b 0 0000 3f 01 7d64 192.168.1.221 192.168.1.220 + +92 bytes from fgt1.attlocal.net (192.168.1.220): Destination Host Unreachable +Vr HL TOS Len ID Flg off TTL Pro cks Src Dst + 4 5 00 5400 d120 0 0000 3f 01 257f 192.168.1.221 192.168.1.220 + +Request timeout for icmp_seq 5 +Request timeout for icmp_seq 6 + +--- 192.168.1.220 ping statistics --- +8 packets transmitted, 0 packets received, 100.0% packet loss diff --git a/tests/test_ping.py b/tests/test_ping.py index fa0508af..be903337 100644 --- a/tests/test_ping.py +++ b/tests/test_ping.py @@ -157,6 +157,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/ping-ip.out'), 'r', encoding='utf-8') as f: self.osx_10_14_6_ping_ip = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/ping-ip-unreachable.out'), 'r', encoding='utf-8') as f: + self.osx_10_14_6_ping_ip_unreachable = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/ping6-hostname-p.out'), 'r', encoding='utf-8') as f: self.osx_10_14_6_ping6_hostname_p = f.read() @@ -336,6 +339,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/ping-ip.json'), 'r', encoding='utf-8') as f: self.osx_10_14_6_ping_ip_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/ping-ip-unreachable.json'), 'r', encoding='utf-8') as f: + self.osx_10_14_6_ping_ip_unreachable_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/ping6-hostname-p.json'), 'r', encoding='utf-8') as f: self.osx_10_14_6_ping6_hostname_p_json = json.loads(f.read()) @@ -651,10 +657,16 @@ class MyTests(unittest.TestCase): def test_ping_ip_osx_10_14_6(self): """ - Test 'ping6 ' on osx 10.14.6 + Test 'ping ' on osx 10.14.6 """ self.assertEqual(jc.parsers.ping.parse(self.osx_10_14_6_ping_ip, quiet=True), self.osx_10_14_6_ping_ip_json) + def test_ping_ip_unreachable_osx_10_14_6(self): + """ + Test 'ping ' with host unreachable error on osx 10.14.6 + """ + self.assertEqual(jc.parsers.ping.parse(self.osx_10_14_6_ping_ip_unreachable, quiet=True), self.osx_10_14_6_ping_ip_unreachable_json) + def test_ping6_hostname_p_osx_10_14_6(self): """ Test 'ping6 -p' on osx 10.14.6