diff --git a/CHANGELOG b/CHANGELOG index 06ae27f2..4ef7f8dc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ jc changelog +20220828 v1.21.1 +- Fix IP Address string parser for older python versions that don't cleanly + accept decimal input format (e.g. python 3.6) +- Fix `arp -a` parser for cases where incomplete hardware addresses are found + in the arp table on linux + 20220821 v1.21.0 - Add IP Address string parser - Add Syslog standard and streaming string parsers (RFC 3164 and RFC 5424) diff --git a/docs/parsers/arp.md b/docs/parsers/arp.md index 59750bf3..294128c7 100644 --- a/docs/parsers/arp.md +++ b/docs/parsers/arp.md @@ -140,4 +140,4 @@ Returns: ### Parser Information Compatibility: linux, aix, freebsd, darwin -Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.11 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ip_address.md b/docs/parsers/ip_address.md index aa664e73..909f17bd 100644 --- a/docs/parsers/ip_address.md +++ b/docs/parsers/ip_address.md @@ -487,4 +487,4 @@ Returns: ### Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/jc/lib.py b/jc/lib.py index 9356323d..b4698536 100644 --- a/jc/lib.py +++ b/jc/lib.py @@ -6,7 +6,7 @@ import importlib from typing import Dict, List, Iterable, Union, Iterator from jc import appdirs -__version__ = '1.21.0' +__version__ = '1.21.1' parsers = [ 'acpi', diff --git a/jc/parsers/arp.py b/jc/parsers/arp.py index e06003fd..e1e24f0c 100644 --- a/jc/parsers/arp.py +++ b/jc/parsers/arp.py @@ -119,7 +119,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.10' + version = '1.11' description = '`arp` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -221,13 +221,24 @@ def parse( else: for line in cleandata: splitline = line.split() - output_line = { - 'name': splitline[0], - 'address': splitline[1].lstrip('(').rstrip(')'), - 'hwtype': splitline[4].lstrip('[').rstrip(']'), - 'hwaddress': splitline[3], - 'iface': splitline[6], - } + if '' not in splitline: + output_line = { + 'name': splitline[0], + 'address': splitline[1].lstrip('(').rstrip(')'), + 'hwtype': splitline[4].lstrip('[').rstrip(']'), + 'hwaddress': splitline[3], + 'iface': splitline[6], + } + + else: + output_line = { + 'name': splitline[0], + 'address': splitline[1].lstrip('(').rstrip(')'), + 'hwtype': None, + 'hwaddress': None, + 'iface': splitline[5], + } + raw_output.append(output_line) return raw_output if raw else _process(raw_output) diff --git a/jc/parsers/ip_address.py b/jc/parsers/ip_address.py index e470d08e..1b807dde 100644 --- a/jc/parsers/ip_address.py +++ b/jc/parsers/ip_address.py @@ -468,7 +468,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.0' + version = '1.1' description = 'IPv4 and IPv6 Address string parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -565,10 +565,20 @@ def parse( broadcast_string = str(network.broadcast_address) broadcast_ipobj = ipaddress.ip_address(broadcast_string) - hostmask_string = str(interface.with_hostmask).split('/')[1] + # older versions of python (e.g. 3.6) don't provide hostmask when a decimal IP is entered + try: + hostmask_string = str(interface.hostmask) + except AttributeError: + hostmask_string = '0.0.0.0' + hostmask_ipobj = ipaddress.ip_address(hostmask_string) - netmask_string = str(interface.with_netmask).split('/')[1] + # older versions of python (e.g. 3.6) don't provide netmask when a decimal IP is entered + try: + netmask_string = str(interface.netmask) + except AttributeError: + netmask_string = '255.255.255.255' + netmask_ipobj = ipaddress.ip_address(netmask_string) bare_ip_string = str(interface.ip) diff --git a/man/jc.1 b/man/jc.1 index 8febd814..7b3d3da3 100644 --- a/man/jc.1 +++ b/man/jc.1 @@ -1,4 +1,4 @@ -.TH jc 1 2022-08-24 1.21.0 "JSON Convert" +.TH jc 1 2022-08-28 1.21.1 "JSON Convert" .SH NAME \fBjc\fP \- JSON Convert JSONifies the output of many CLI tools and file-types .SH SYNOPSIS diff --git a/setup.py b/setup.py index d92354ab..8634cf8a 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ with open('README.md', 'r') as f: setuptools.setup( name='jc', - version='1.21.0', + version='1.21.1', author='Kelly Brazil', author_email='kellyjonbrazil@gmail.com', description='Converts the output of popular command-line tools and file-types to JSON.', diff --git a/tests/fixtures/centos-8/arp-a.json b/tests/fixtures/centos-8/arp-a.json new file mode 100644 index 00000000..c85f2008 --- /dev/null +++ b/tests/fixtures/centos-8/arp-a.json @@ -0,0 +1 @@ +[{"name":null,"address":"192.168.71.21","hwtype":null,"hwaddress":null,"iface":"ens33"},{"name":null,"address":"192.168.71.128","hwtype":null,"hwaddress":null,"iface":"ens33"},{"name":null,"address":"192.168.71.254","hwtype":"ether","hwaddress":"00:50:56:e2:91:0e","iface":"ens33"},{"name":null,"address":"192.168.71.226","hwtype":null,"hwaddress":null,"iface":"ens33"}] diff --git a/tests/fixtures/centos-8/arp-a.out b/tests/fixtures/centos-8/arp-a.out new file mode 100644 index 00000000..a2c47922 --- /dev/null +++ b/tests/fixtures/centos-8/arp-a.out @@ -0,0 +1,4 @@ +? (192.168.71.21) at on ens33 +? (192.168.71.128) at on ens33 +? (192.168.71.254) at 00:50:56:e2:91:0e [ether] on ens33 +? (192.168.71.226) at on ens33 diff --git a/tests/test_arp.py b/tests/test_arp.py index 0d0e6850..5ac7a6c3 100644 --- a/tests/test_arp.py +++ b/tests/test_arp.py @@ -40,6 +40,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/freebsd12/arp-a.out'), 'r', encoding='utf-8') as f: self.freebsd_arp_a = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-8/arp-a.out'), 'r', encoding='utf-8') as f: + self.centos8_arp_a = f.read() + # output with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/arp.json'), 'r', encoding='utf-8') as f: self.centos_7_7_arp_json = json.loads(f.read()) @@ -71,6 +74,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/freebsd12/arp-a.json'), 'r', encoding='utf-8') as f: self.freebsd12_arp_a_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-8/arp-a.json'), 'r', encoding='utf-8') as f: + self.centos8_arp_a_json = json.loads(f.read()) + def test_arp_nodata(self): """ Test 'arp' with no data @@ -137,6 +143,12 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.arp.parse(self.freebsd_arp_a, quiet=True), self.freebsd12_arp_a_json) + def test_arp_a_centos8(self): + """ + Test 'arp -a' on CentOS 8 with incomplete hw addresses + """ + self.assertEqual(jc.parsers.arp.parse(self.centos8_arp_a, quiet=True), self.centos8_arp_a_json) + if __name__ == '__main__': unittest.main()