From 46b827da6b438be73fab168c3f05298483b141e4 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 6 Dec 2019 13:22:51 -0800 Subject: [PATCH] add osx compatibility --- changelog.txt | 1 + jc/parsers/arp.py | 27 +++++++++++++++++++++++---- tests/fixtures/osx-10.11.6/arp-a.json | 1 + tests/fixtures/osx-10.11.6/arp-a.out | 13 +++++++++++++ tests/fixtures/osx-10.14.6/arp-a.json | 1 + tests/fixtures/osx-10.14.6/arp-a.out | 12 ++++++++++++ tests/test_arp.py | 24 ++++++++++++++++++++++++ 7 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/osx-10.11.6/arp-a.json create mode 100755 tests/fixtures/osx-10.11.6/arp-a.out create mode 100644 tests/fixtures/osx-10.14.6/arp-a.json create mode 100644 tests/fixtures/osx-10.14.6/arp-a.out diff --git a/changelog.txt b/changelog.txt index c6824e36..c0c408c4 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,7 @@ jc changelog 2019xxxx v1.6.1 - Add OSX support for the ifconfig parser +- Add OSX support for the arp parser - Updated ifconfig parser to output state as an array 20191117 v1.5.1 diff --git a/jc/parsers/arp.py b/jc/parsers/arp.py index 1fab219c..2cb7163e 100644 --- a/jc/parsers/arp.py +++ b/jc/parsers/arp.py @@ -128,7 +128,7 @@ def parse(data, raw=False, quiet=False): """ # compatible options: linux, darwin, cygwin, win32, aix, freebsd - compatible = ['linux', 'aix', 'freebsd'] + compatible = ['linux', 'aix', 'freebsd', 'darwin'] if not quiet: jc.utils.compatibility(__name__, compatible) @@ -139,11 +139,29 @@ def parse(data, raw=False, quiet=False): cleandata = data.splitlines() # remove final Entries row if -v was used - if cleandata[-1].find("Entries:") == 0: + if cleandata[-1].find('Entries:') == 0: cleandata.pop(-1) - # detect if linux or bsd style was used - if cleandata[0].find('Address') == 0: + # detect if osx style was used + if cleandata[0].find(' ifscope ') != -1: + raw_output = [] + for line in cleandata: + line = line.split() + output_line = {} + output_line['name'] = line[0] + output_line['address'] = line[1].lstrip('(').rstrip(')') + output_line['hwtype'] = line[-1].lstrip('[').rstrip(']') + output_line['hwaddress'] = line[3] + output_line['iface'] = line[5] + raw_output.append(output_line) + + if raw: + return raw_output + else: + return process(raw_output) + + # detect if linux style was used + elif cleandata[0].find('Address') == 0: # fix header row to change Flags Mask to flags_mask cleandata[0] = cleandata[0].replace('Flags Mask', 'flags_mask') @@ -157,6 +175,7 @@ def parse(data, raw=False, quiet=False): else: return process(raw_output) + # otherwise, try bsd style else: raw_output = [] for line in cleandata: diff --git a/tests/fixtures/osx-10.11.6/arp-a.json b/tests/fixtures/osx-10.11.6/arp-a.json new file mode 100644 index 00000000..6db3e947 --- /dev/null +++ b/tests/fixtures/osx-10.11.6/arp-a.json @@ -0,0 +1 @@ +[{"name": "dev.attlocal.net", "address": "192.168.1.63", "hwtype": "ethernet", "hwaddress": "e0:33:8e:67:38:d6", "iface": "en0"}, {"name": "air.attlocal.net", "address": "192.168.1.66", "hwtype": "ethernet", "hwaddress": "60:c5:47:b:cf:a", "iface": "en0"}, {"name": "ipad.attlocal.net", "address": "192.168.1.76", "hwtype": "ethernet", "hwaddress": "4c:56:9d:6f:b7:4c", "iface": "en0"}, {"name": "storage.attlocal.net", "address": "192.168.1.81", "hwtype": "ethernet", "hwaddress": "0:90:a9:fd:e4:35", "iface": "en0"}, {"name": "family-room.attlocal.net", "address": "192.168.1.89", "hwtype": "ethernet", "hwaddress": "c8:d0:83:cd:f3:2d", "iface": "en0"}, {"name": "bedroom.attlocal.net", "address": "192.168.1.80", "hwtype": "ethernet", "hwaddress": "d0:3:4b:3b:29:d5", "iface": "en0"}, {"name": "upstairs.attlocal.net", "address": "192.168.1.187", "hwtype": "ethernet", "hwaddress": "50:32:37:e7:f5:9b", "iface": "en0"}, {"name": "rb.attlocal.net", "address": "192.168.1.218", "hwtype": "ethernet", "hwaddress": "3c:37:86:15:bd:f7", "iface": "en0"}, {"name": "mac.attlocal.net", "address": "192.168.1.220", "hwtype": "ethernet", "hwaddress": "a4:83:f7:2d:62:8f", "iface": "en0"}, {"name": "rbs.attlocal.net", "address": "192.168.1.252", "hwtype": "ethernet", "hwaddress": "3c:37:86:15:de:b3", "iface": "en0"}, {"name": "dev1.attlocal.net", "address": "192.168.1.253", "hwtype": "ethernet", "hwaddress": "fc:ae:34:a1:3b:80", "iface": "en0"}, {"name": null, "address": "224.0.0.251", "hwtype": "ethernet", "hwaddress": "1:0:5e:0:0:fb", "iface": "en0"}, {"name": null, "address": "239.255.255.250", "hwtype": "ethernet", "hwaddress": "1:0:5e:7f:ff:fa", "iface": "en0"}] diff --git a/tests/fixtures/osx-10.11.6/arp-a.out b/tests/fixtures/osx-10.11.6/arp-a.out new file mode 100755 index 00000000..365a6565 --- /dev/null +++ b/tests/fixtures/osx-10.11.6/arp-a.out @@ -0,0 +1,13 @@ +dev.attlocal.net (192.168.1.63) at e0:33:8e:67:38:d6 on en0 ifscope [ethernet] +air.attlocal.net (192.168.1.66) at 60:c5:47:b:cf:a on en0 ifscope [ethernet] +ipad.attlocal.net (192.168.1.76) at 4c:56:9d:6f:b7:4c on en0 ifscope [ethernet] +storage.attlocal.net (192.168.1.81) at 0:90:a9:fd:e4:35 on en0 ifscope [ethernet] +family-room.attlocal.net (192.168.1.89) at c8:d0:83:cd:f3:2d on en0 ifscope [ethernet] +bedroom.attlocal.net (192.168.1.80) at d0:3:4b:3b:29:d5 on en0 ifscope [ethernet] +upstairs.attlocal.net (192.168.1.187) at 50:32:37:e7:f5:9b on en0 ifscope [ethernet] +rb.attlocal.net (192.168.1.218) at 3c:37:86:15:bd:f7 on en0 ifscope [ethernet] +mac.attlocal.net (192.168.1.220) at a4:83:f7:2d:62:8f on en0 ifscope [ethernet] +rbs.attlocal.net (192.168.1.252) at 3c:37:86:15:de:b3 on en0 ifscope [ethernet] +dev1.attlocal.net (192.168.1.253) at fc:ae:34:a1:3b:80 on en0 ifscope [ethernet] +? (224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet] +? (239.255.255.250) at 1:0:5e:7f:ff:fa on en0 ifscope permanent [ethernet] diff --git a/tests/fixtures/osx-10.14.6/arp-a.json b/tests/fixtures/osx-10.14.6/arp-a.json new file mode 100644 index 00000000..785b8840 --- /dev/null +++ b/tests/fixtures/osx-10.14.6/arp-a.json @@ -0,0 +1 @@ +[{"name": "xxx.attlocal.net", "address": "192.168.1.63", "hwtype": "ethernet", "hwaddress": "e0:33:8e:67:38:d6", "iface": "en0"}, {"name": "mbp.attlocal.net", "address": "192.168.1.74", "hwtype": "ethernet", "hwaddress": "f0:18:98:5:d8:39", "iface": "en0"}, {"name": "tablet.attlocal.net", "address": "192.168.1.77", "hwtype": "ethernet", "hwaddress": "4c:56:9d:5f:b8:4c", "iface": "en0"}, {"name": "living-room.attlocal.net", "address": "192.168.1.80", "hwtype": "ethernet", "hwaddress": "c8:d0:83:cd:f3:2d", "iface": "en0"}, {"name": "outside.attlocal.net", "address": "192.168.1.99", "hwtype": "ethernet", "hwaddress": "d0:3:4b:3b:27:d5", "iface": "en0"}, {"name": "tv.attlocal.net", "address": "192.168.1.187", "hwtype": "ethernet", "hwaddress": "50:32:37:d7:f4:9b", "iface": "en0"}, {"name": "device.attlocal.net", "address": "192.168.1.217", "hwtype": "ethernet", "hwaddress": "3c:37:86:14:ad:f7", "iface": "en0"}, {"name": "mac.attlocal.net", "address": "192.168.1.222", "hwtype": "ethernet", "hwaddress": "a4:83:e7:2d:63:8f", "iface": "en0"}, {"name": "dev2.attlocal.net", "address": "192.168.1.251", "hwtype": "ethernet", "hwaddress": "3c:37:86:15:df:b3", "iface": "en0"}, {"name": "laptop.attlocal.net", "address": "192.168.1.250", "hwtype": "ethernet", "hwaddress": "fc:ae:34:a1:3a:80", "iface": "en0"}, {"name": null, "address": "224.0.0.251", "hwtype": "ethernet", "hwaddress": "1:0:5e:0:0:fb", "iface": "en0"}, {"name": null, "address": "239.255.255.250", "hwtype": "ethernet", "hwaddress": "1:0:5e:7f:ff:fa", "iface": "en0"}] diff --git a/tests/fixtures/osx-10.14.6/arp-a.out b/tests/fixtures/osx-10.14.6/arp-a.out new file mode 100644 index 00000000..5def799c --- /dev/null +++ b/tests/fixtures/osx-10.14.6/arp-a.out @@ -0,0 +1,12 @@ +xxx.attlocal.net (192.168.1.63) at e0:33:8e:67:38:d6 on en0 ifscope [ethernet] +mbp.attlocal.net (192.168.1.74) at f0:18:98:5:d8:39 on en0 ifscope [ethernet] +tablet.attlocal.net (192.168.1.77) at 4c:56:9d:5f:b8:4c on en0 ifscope [ethernet] +living-room.attlocal.net (192.168.1.80) at c8:d0:83:cd:f3:2d on en0 ifscope [ethernet] +outside.attlocal.net (192.168.1.99) at d0:3:4b:3b:27:d5 on en0 ifscope [ethernet] +tv.attlocal.net (192.168.1.187) at 50:32:37:d7:f4:9b on en0 ifscope [ethernet] +device.attlocal.net (192.168.1.217) at 3c:37:86:14:ad:f7 on en0 ifscope [ethernet] +mac.attlocal.net (192.168.1.222) at a4:83:e7:2d:63:8f on en0 ifscope permanent [ethernet] +dev2.attlocal.net (192.168.1.251) at 3c:37:86:15:df:b3 on en0 ifscope [ethernet] +laptop.attlocal.net (192.168.1.250) at fc:ae:34:a1:3a:80 on en0 ifscope [ethernet] +? (224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet] +? (239.255.255.250) at 1:0:5e:7f:ff:fa on en0 ifscope permanent [ethernet] diff --git a/tests/test_arp.py b/tests/test_arp.py index b9fadf81..5468024f 100644 --- a/tests/test_arp.py +++ b/tests/test_arp.py @@ -28,6 +28,12 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/arp-v.out'), 'r') as f: self.ubuntu_18_4_arp_v = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.11.6/arp-a.out'), 'r') as f: + self.osx_10_11_6_arp_a = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/arp-a.out'), 'r') as f: + self.osx_10_14_6_arp_a = f.read() + # output with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/arp.json'), 'r') as f: self.centos_7_7_arp_json = json.loads(f.read()) @@ -47,6 +53,12 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/arp-v.json'), 'r') as f: self.ubuntu_18_4_arp_v_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.11.6/arp-a.json'), 'r') as f: + self.osx_10_11_6_arp_a_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/arp-a.json'), 'r') as f: + self.osx_10_14_6_arp_a_json = json.loads(f.read()) + def test_arp_centos_7_7(self): """ Test 'arp' on Centos 7.7 @@ -83,6 +95,18 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.arp.parse(self.ubuntu_18_4_arp_v, quiet=True), self.ubuntu_18_4_arp_v_json) + def test_arp_a_osx_10_11_6(self): + """ + Test 'arp -a' on OSX 10.11.6 + """ + self.assertEqual(jc.parsers.arp.parse(self.osx_10_11_6_arp_a, quiet=True), self.osx_10_11_6_arp_a_json) + + def test_arp_a_osx_10_14_6(self): + """ + Test 'arp -a' on OSX 10.14.6 + """ + self.assertEqual(jc.parsers.arp.parse(self.osx_10_14_6_arp_a, quiet=True), self.osx_10_14_6_arp_a_json) + if __name__ == '__main__': unittest.main()