diff --git a/CHANGELOG b/CHANGELOG index 8603c04b..cc00a3d0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ jc changelog 20240907 v1.25.4 +- Enhance `ifconfig` parser to support `utun` interfaces with assigned IPv4 addresses on macOS - Fix `mount` parser for cases where there are spaces in the filesystem name - Fix `ip-address` parser for Python 3.13 changes to IPv4 mapped IPv6 addresses - Fix `uptime` parser for data that contains `user` instead of `users` diff --git a/jc/parsers/ifconfig.py b/jc/parsers/ifconfig.py index d24b9147..021f5026 100644 --- a/jc/parsers/ifconfig.py +++ b/jc/parsers/ifconfig.py @@ -212,14 +212,14 @@ Examples: """ import re from ipaddress import IPv4Network -from typing import List, Dict, Optional +from typing import List, Dict from jc.jc_types import JSONDictType import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '2.3' + version = '2.4' description = '`ifconfig` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -548,6 +548,11 @@ def parse( broadcast\s+(?P(?:[0-9]{1,3}\.){3}[0-9]{1,3}))? ''', re.IGNORECASE | re.VERBOSE ) + re_freebsd_ipv4_utun = re.compile(r''' + inet\s(?P
(?:[0-9]{1,3}\.){3}[0-9]{1,3})\s-->\s(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})\s + netmask\s(?P\S*) + ''', re.IGNORECASE | re.VERBOSE + ) re_freebsd_ipv6 = re.compile(r''' \s?inet6\s(?P
.*?) (?:\%(?P\w+\d+))?\s @@ -624,14 +629,14 @@ def parse( re_openbsd_rx_stats, re_openbsd_tx, re_openbsd_tx_stats ] re_freebsd = [ - re_freebsd_interface, re_freebsd_ipv4, re_freebsd_ipv4_v2, re_freebsd_ipv6, + re_freebsd_interface, re_freebsd_ipv4, re_freebsd_ipv4_v2, re_freebsd_ipv4_utun, re_freebsd_ipv6, re_freebsd_details, re_freebsd_status, re_freebsd_nd6_options, re_freebsd_plugged, re_freebsd_vendor_pn_sn_date, re_freebsd_temp_volts, re_freebsd_hwaddr, re_freebsd_media, re_freebsd_tx_rx_power, re_freebsd_options ] interface_patterns = [re_linux_interface, re_openbsd_interface, re_freebsd_interface] - ipv4_patterns = [re_linux_ipv4, re_openbsd_ipv4, re_freebsd_ipv4, re_freebsd_ipv4_v2] + ipv4_patterns = [re_linux_ipv4, re_openbsd_ipv4, re_freebsd_ipv4, re_freebsd_ipv4_v2, re_freebsd_ipv4_utun] ipv6_patterns = [re_linux_ipv6, re_openbsd_ipv6, re_freebsd_ipv6] if jc.utils.has_data(data): diff --git a/tests/test_ifconfig.py b/tests/test_ifconfig.py index 58ea8f3f..9f9953b4 100644 --- a/tests/test_ifconfig.py +++ b/tests/test_ifconfig.py @@ -148,5 +148,17 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.ifconfig.parse(self.osx_freebsd12_ifconfig_extra_fields4, quiet=True), self.freebsd12_ifconfig_extra_fields4_json) + def test_ifconfig_utun_ipv4(self): + """ + Test 'ifconfig' with ipv4 utun addresses (macOS) + """ + data = r'''utun2: flags=8051 mtu 1400 + inet 10.85.40.243 --> 10.85.40.243 netmask 0xffffffff + inet6 fe80::3af9:d3ff:fe69:1732%utun2 prefixlen 64 scopeid 0xd + inet6 fdae:f7e0:9f37:64::146 prefixlen 128 + nd6 options=201''' + expected = [{"name":"utun2","flags":8051,"state":["UP","POINTOPOINT","RUNNING","MULTICAST"],"mtu":1400,"type":None,"mac_addr":None,"ipv4_addr":"10.85.40.243","ipv4_mask":"255.255.255.255","ipv4_bcast":None,"ipv6_addr":"fdae:f7e0:9f37:64::146","ipv6_mask":128,"ipv6_scope":None,"ipv6_type":None,"metric":None,"rx_packets":None,"rx_errors":None,"rx_dropped":None,"rx_overruns":None,"rx_frame":None,"tx_packets":None,"tx_errors":None,"tx_dropped":None,"tx_overruns":None,"tx_carrier":None,"tx_collisions":None,"rx_bytes":None,"tx_bytes":None,"ipv6_scope_id":None,"nd6_options":201,"nd6_flags":["PERFORMNUD","DAD"],"ipv4":[{"address":"10.85.40.243","mask":"255.255.255.255"}],"ipv6":[{"address":"fe80::3af9:d3ff:fe69:1732","scope_id":"utun2","mask":64,"scope":"0xd"},{"address":"fdae:f7e0:9f37:64::146","scope_id":None,"mask":128,"scope":None}]}] + self.assertEqual(jc.parsers.ifconfig.parse(self.osx_freebsd12_ifconfig_extra_fields4, quiet=True), self.freebsd12_ifconfig_extra_fields4_json) + if __name__ == '__main__': unittest.main()